Files
openstapps/packages/core/test/translator.spec.ts
Thea Schöbl d6d4f6e5c4 fix: rebase cleanup
fix: rebase cleanup

fix: rebase cleanup
2023-05-31 14:04:38 +02:00

235 lines
10 KiB
TypeScript

/*
* Copyright (C) 2019 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {expect} from 'chai';
import clone from 'rfdc';
import {SCThingRemoteOrigin} from '../src/index.js';
import {SCDishMeta} from '../src/index.js';
import {SCThingTranslator} from '../src/index.js';
import {dish} from './dummy/dish.js';
import {setting} from './dummy/setting.js';
const translator = new SCThingTranslator('de');
const translatorEN = new SCThingTranslator('en');
// this will simulate a translator always utilizing the base language translations
const translatorWithFallback = new SCThingTranslator('tt');
const translatedThingDE = translator.translate(dish);
const translatedThingFallback = translatorWithFallback.translate(dish);
describe('Translator', function () {
this.timeout(10_000);
this.slow(5000);
describe('direct', function () {
it('should translate enum single value', function () {
expect(translator.translatedAccess(setting).inputType).to.equal('einfache Auswahl');
});
it('should translate string literal type', function () {
expect(translator.translatedAccess(dish).type).to.equal('Essen');
expect(translatedThingDE.type).to.equal('Essen');
});
it('should translate string property', function () {
expect(translator.translatedAccess(dish).name).to.equal('de-dish-name');
expect(translatedThingDE.name).to.equal('de-dish-name');
});
it('should translate array of strings', function () {
expect(translator.translatedAccess(dish).characteristics).to.deep.equal([
{name: 'de-characteristic0'},
{name: 'de-characteristic1'},
]);
expect(translatedThingDE.characteristics).to.deep.equal([
{name: 'de-characteristic0'},
{name: 'de-characteristic1'},
]);
});
it('should translate array of strings subscript', function () {
expect(translator.translatedAccess(dish).characteristics?.[1]).to.deep.equal({
name: 'de-characteristic1',
});
expect(translatedThingDE.characteristics![1]).to.deep.equal({name: 'de-characteristic1'});
});
it('should translate meta array of string', function () {
expect(translator.translatedAccess(dish).categories).to.deep.equal(['Hauptgericht', 'Nachtisch']);
expect(translatedThingDE.categories).to.deep.equal(['Hauptgericht', 'Nachtisch']);
});
it('should translate meta array of strings subscript', function () {
expect(translator.translatedAccess(dish).categories[1]).to.equal('Nachtisch');
expect(translatedThingDE.categories[1]).to.equal('Nachtisch');
});
});
describe('nested', function () {
it('should translate string literal type', function () {
expect(translator.translatedAccess(dish).offers?.[0].inPlace?.type).to.equal('Gebäude');
expect(translatedThingDE.offers![0].inPlace!.type).to.equal('Gebäude');
});
it('should translate nested string property', function () {
expect(translator.translatedAccess(dish).offers?.[0].inPlace?.name).to.equal('de-space-name');
expect(translatedThingDE.offers![0].inPlace!.name).to.equal('de-space-name');
});
it('should translate meta array of strings', function () {
expect(translator.translatedAccess(dish).offers?.[0].inPlace?.categories).to.deep.equal([
'Büro',
'Bildung',
]);
expect(translatedThingDE.offers![0].inPlace!.categories).to.deep.equal(['Büro', 'Bildung']);
});
it('should translate meta array of strings subscript', function () {
expect(translator.translatedAccess(dish).offers?.[0].inPlace?.categories[1]).to.equal('Bildung');
expect(translatedThingDE.offers![0].inPlace!.categories[1]).to.equal('Bildung');
});
});
describe('direct (fallback)', function () {
it('should translate string literal types', function () {
expect(translatorWithFallback.translatedAccess(dish).type).to.equal('dish');
expect(translatedThingFallback.type).to.equal('dish');
});
it('should translate string property', function () {
expect(translatorWithFallback.translatedAccess(dish).name).to.equal('base-dish-name');
expect(translatedThingFallback.name).to.equal('base-dish-name');
});
it('should translate array of strings subscript', function () {
expect(translatorWithFallback.translatedAccess(dish).characteristics?.[1]).to.deep.equal({
name: 'base-characteristic1',
});
expect(translatedThingFallback.characteristics![1]).to.deep.equal({name: 'base-characteristic1'});
});
it('should translate meta array of strings', function () {
expect(translatorWithFallback.translatedAccess(dish).categories).to.deep.equal([
'main dish',
'dessert',
]);
expect(translatedThingFallback.categories).to.deep.equal(['main dish', 'dessert']);
});
it('should translate meta array of string subscript', function () {
expect(translatorWithFallback.translatedAccess(dish).categories[1]).to.equal('dessert');
expect(translatedThingFallback.categories[1]).to.equal('dessert');
});
});
describe('nested (fallback)', function () {
it('should translate string literal type', function () {
expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.type).to.equal('building');
expect(translatedThingFallback.offers![0].inPlace!.type).to.equal('building');
});
it('should translate string property', function () {
expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.name).to.equal(
'base-space-name',
);
expect(translatedThingFallback.offers![0].inPlace!.name).to.equal('base-space-name');
});
it('should translate meta array of string', function () {
expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.categories).to.deep.equal([
'office',
'education',
]);
expect(translatedThingFallback.offers![0].inPlace!.categories).to.deep.equal(['office', 'education']);
});
it('should translate meta array of strings subscript', function () {
expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.categories[1]).to.equal(
'education',
);
expect(translatedThingFallback.offers![0].inPlace!.categories[1]).to.equal('education');
});
});
it('should omit LRU cache with changed source', function () {
const translatorDE = new SCThingTranslator('de');
const dishCopy = clone()(dish);
const translatedDish = translatorDE.translatedAccess(dish);
const destructivelyTranslatedDish = translatorDE.translate(dish);
(dishCopy.origin as SCThingRemoteOrigin).name = 'translator.spec';
expect(translatorDE.translatedAccess(dishCopy)).not.to.deep.equal(translatedDish);
expect(translatorDE.translate(dishCopy)).not.to.equal(destructivelyTranslatedDish);
});
it('should flush its LRU cache with changed translator language', function () {
const translatorDE = new SCThingTranslator('de');
expect(translatorDE.translatedAccess(dish).name).to.equal('de-dish-name');
expect(translatorDE.translate(dish).name).to.equal('de-dish-name');
translatorDE.language = 'en';
expect(translatorDE.translatedAccess(dish).name).to.equal('base-dish-name');
expect(translatorDE.translate(dish).name).to.equal('base-dish-name');
});
it('should force translator LRU cache to overflow', function () {
const translatorDE = new SCThingTranslator('de');
// Make sure to add more elements to the translator cache than the maximum cache capacity. See Translator.ts
for (let i = 0; i < 201; i++) {
const anotherDish = Object.assign({}, dish);
anotherDish.uid = String(i);
expect(translatorDE.translatedAccess(anotherDish).name).to.equal('de-dish-name');
}
});
});
describe('MetaTranslator', function () {
this.timeout(10_000);
this.slow(5000);
it('should have consistency with meta class', function () {
const dishMetaTranslationsDE = translator.translatedPropertyNames(dish.type);
const dishMetaTranslationsEN = translatorEN.translatedPropertyNames(dish.type);
expect(dishMetaTranslationsEN).to.not.deep.equal(dishMetaTranslationsDE);
expect(dishMetaTranslationsDE).to.deep.equal(new SCDishMeta().fieldTranslations.de);
expect(dishMetaTranslationsEN).to.deep.equal(new SCDishMeta().fieldTranslations.en);
});
it('should retrieve translated property value type', function () {
const dishTypeDE = translator.translatedPropertyValue(dish.type, 'type');
const dishTypeEN = translatorEN.translatedPropertyValue(dish.type, 'type', undefined);
const dishTypeBASE = translatorWithFallback.translatedPropertyValue(dish.type, 'type');
expect(dishTypeDE).to.deep.equal(new SCDishMeta().fieldValueTranslations.de.type);
expect(dishTypeEN).to.deep.equal(new SCDishMeta().fieldValueTranslations.en.type);
expect(dishTypeBASE).to.deep.equal(new SCDishMeta().fieldValueTranslations.en.type);
});
it('should retrieve translated property value nested', function () {
const dishTypeDE = translator.translatedPropertyValue(dish.type, 'categories', 'main dish');
const dishTypeEN = translatorEN.translatedPropertyValue(dish.type, 'categories', 'main dish');
const dishTypeBASE = translatorWithFallback.translatedPropertyValue(dish.type, 'categories', 'main dish');
expect(dishTypeDE).to.deep.equal(new SCDishMeta().fieldValueTranslations.de.categories['main dish']);
expect(dishTypeEN).to.deep.equal(dish.categories[0]);
expect(dishTypeBASE).to.deep.equal(dish.categories[0]);
});
it('should translate thing without meta class', function () {
const dishCopy = clone()(dish);
const typeNonExistent = eval("(x) => x + 'typeNonExistent';");
// this will assign a non-existent SCThingType to dishCopy
dishCopy.type = typeNonExistent();
const dishMetaTranslationsDE = translator.translatedPropertyNames(dishCopy.type);
expect(dishMetaTranslationsDE).to.be.undefined;
});
});