import React from 'react';
import {
_t,
_tDom,
TranslatedString,
setLanguage,
setMissingEntryGenerator,
substitute,
} from '../../src/languageHandler';
import { stubClient } from '../test-utils';
describe('languageHandler', function() {
const basicString = 'Rooms';
const selfClosingTagSub = 'Accept to continue:';
const textInTagSub = 'Upgrade to your own domain';
const plurals = 'and %(count)s others...';
const variableSub = 'You are now ignoring %(userId)s';
type TestCase = [string, string, Record, Record, TranslatedString];
const testCasesEn: TestCase[] = [
['translates a basic string', basicString, {}, undefined, 'Rooms'],
[
'handles plurals when count is 0',
plurals,
{ count: 0 },
undefined,
'and 0 others...',
],
[
'handles plurals when count is 1',
plurals,
{ count: 1 },
undefined,
'and one other...',
],
[
'handles plurals when count is not 1',
plurals,
{ count: 2 },
undefined,
'and 2 others...',
],
[
'handles simple variable substitution',
variableSub,
{ userId: 'foo' },
undefined,
'You are now ignoring foo',
],
[
'handles simple tag substitution',
selfClosingTagSub,
{},
{ 'policyLink': () => 'foo' },
'Accept foo to continue:',
],
['handles text in tags', textInTagSub, {}, { 'a': (sub) => `x${sub}x` }, 'xUpgradex to your own domain'],
[
'handles variable substitution with React function component',
variableSub,
{ userId: () => foo },
undefined,
// eslint-disable-next-line react/jsx-key
You are now ignoring foo,
],
[
'handles variable substitution with react node',
variableSub,
{ userId: foo },
undefined,
// eslint-disable-next-line react/jsx-key
You are now ignoring foo,
],
[
'handles tag substitution with React function component',
selfClosingTagSub,
{},
{ 'policyLink': () => foo },
// eslint-disable-next-line react/jsx-key
Accept foo to continue:,
],
];
describe('when translations exist in language', () => {
beforeEach(function(done) {
stubClient();
setLanguage('en').then(done);
setMissingEntryGenerator(key => key.split("|", 2)[1]);
});
it('translates a string to german', function(done) {
setLanguage('de').then(function() {
const translated = _t(basicString);
expect(translated).toBe('Räume');
}).then(done);
});
it.each(testCasesEn)("%s", async (_d, translationString, variables, tags, result) => {
expect(_t(translationString, variables, tags)).toEqual(result);
});
it('replacements in the wrong order', function() {
const text = '%(var1)s %(var2)s';
expect(_t(text, { var2: 'val2', var1: 'val1' })).toBe('val1 val2');
});
it('multiple replacements of the same variable', function() {
const text = '%(var1)s %(var1)s';
expect(substitute(text, { var1: 'val1' })).toBe('val1 val1');
});
it('multiple replacements of the same tag', function() {
const text = 'Click here to join the discussion! or here';
expect(substitute(text, {}, { 'a': (sub) => `x${sub}x` }))
.toBe('xClick herex to join the discussion! xor herex');
});
});
describe('for a non-en language', () => {
beforeEach(async () => {
stubClient();
await setLanguage('lv');
// counterpart doesnt expose any way to restore default config
// missingEntryGenerator is mocked in the root setup file
// reset to default here
const counterpartDefaultMissingEntryGen =
function(key) { return 'missing translation: ' + key; };
setMissingEntryGenerator(counterpartDefaultMissingEntryGen);
});
// mocked lv has only `"Uploading %(filename)s and %(count)s others|one"`
const lvExistingPlural = 'Uploading %(filename)s and %(count)s others';
const lvNonExistingPlural = '%(spaceName)s and %(count)s others';
describe('pluralization', () => {
const pluralCases = [
[
'falls back when plural string exists but not for for count',
lvExistingPlural,
{ count: 2, filename: 'test.txt' },
undefined,
'Uploading test.txt and 2 others',
],
[
'falls back when plural string does not exists at all',
lvNonExistingPlural,
{ count: 2, spaceName: 'test' },
undefined,
'test and 2 others',
],
] as TestCase[];
describe('_t', () => {
it('translated correctly when plural string exists for count', () => {
expect(_t(
lvExistingPlural,
{ count: 1, filename: 'test.txt' }, undefined)).toEqual('Качване на test.txt и 1 друг');
});
it.each(pluralCases)(
"%s",
async (_d, translationString, variables, tags, result) => {
expect(_t(translationString, variables, tags)).toEqual(result);
},
);
});
describe('_tDom()', () => {
it('translated correctly when plural string exists for count', () => {
expect(_tDom(
lvExistingPlural,
{ count: 1, filename: 'test.txt' }, undefined)).toEqual('Качване на test.txt и 1 друг');
});
it.each(pluralCases)(
"%s and translates with fallback locale, attributes fallback locale",
async (_d, translationString, variables, tags, result) => {
expect(_tDom(translationString, variables, tags)).toEqual({ result });
},
);
});
});
describe('when a translation string does not exist in active language', () => {
describe('_t', () => {
it.each(testCasesEn)(
"%s and translates with fallback locale",
async (_d, translationString, variables, tags, result) => {
expect(_t(translationString, variables, tags)).toEqual(result);
},
);
});
describe('_tDom()', () => {
it.each(testCasesEn)(
"%s and translates with fallback locale, attributes fallback locale",
async (_d, translationString, variables, tags, result) => {
expect(_tDom(translationString, variables, tags)).toEqual({ result });
},
);
});
});
});
});