chrome-devtools-frontend
Version:
Chrome DevTools UI
167 lines (125 loc) • 7.26 kB
text/typescript
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as i18n from './i18n.js';
describe('i18n', () => {
let i18nInstance: i18n.I18n.I18n;
beforeEach(() => {
i18nInstance = new i18n.I18n.I18n(['en-US', 'de-DE'], 'en-US'); // A fresh instance for each test.
});
function stringSetWith(
file: string, uiStrings: i18n.I18n.UIStrings, locale: string): i18n.LocalizedStringSet.LocalizedStringSet {
const registeredStrings = i18nInstance.registerFileStrings(file, uiStrings);
return registeredStrings.getLocalizedStringSetFor(locale);
}
it('should throw an error when no locale data is registered for the requested locale', () => {
const uiStrings = {key: 'string to translate'};
const registeredStrings = i18nInstance.registerFileStrings('test.ts', uiStrings);
assert.throws(() => registeredStrings.getLocalizedStringSetFor('en-US'), /en-US/);
});
it('should throw an error when a requested message is not part of the UIStrings string structure', () => {
i18nInstance.registerLocaleData('en-US', {'test.ts | foo': {message: 'string to translate'}});
const uiStrings = {};
const stringSet = stringSetWith('test.ts', uiStrings, 'en-US');
assert.throws(() => stringSet.getLocalizedString('string to translate'));
});
it('should provide the correct translation if its available', () => {
i18nInstance.registerLocaleData('de-DE', {'test.ts | foo': {message: 'a german foo'}});
const uiStrings = {foo: 'an english foo'};
const stringSet = stringSetWith('test.ts', uiStrings, 'de-DE');
const translatedString = stringSet.getLocalizedString(uiStrings.foo);
assert.strictEqual(translatedString, 'a german foo');
});
it('should provide the correct translation with placeholders', () => {
i18nInstance.registerLocaleData('de-DE', {'test.ts | foo': {message: 'a {PH1} german message'}});
const uiStrings = {foo: 'a {PH1} english message'};
const stringSet = stringSetWith('test.ts', uiStrings, 'de-DE');
const translatedString = stringSet.getLocalizedString(uiStrings.foo, {PH1: 'nice'});
assert.strictEqual(translatedString, 'a nice german message');
});
it('should fall back to the UIStrings message when no translation is available', () => {
i18nInstance.registerLocaleData('de-DE', {}); // Simulate string not yet translated to German.
const uiStrings = {foo: 'an english foo'};
const stringSet = stringSetWith('test.ts', uiStrings, 'de-DE');
const translatedString = stringSet.getLocalizedString(uiStrings.foo);
assert.strictEqual(translatedString, uiStrings.foo);
});
it('should fall back to the UIStrings message when the placeholder of a translation doesn\'t match the UIStrings placeholder',
() => {
i18nInstance.registerLocaleData(
'de-DE', {'test.ts | foo': {message: 'German message with old placeholder {PH_OLD}'}});
const uiStrings = {foo: 'Message with a new placeholder {PH_NEW}'};
const stringSet = stringSetWith('test.ts', uiStrings, 'de-DE');
const translatedString = stringSet.getLocalizedString(uiStrings.foo, {PH_NEW: 'PH_NEW'});
assert.strictEqual(translatedString, 'Message with a new placeholder PH_NEW');
});
it('should provide the same translation for repeated calls, but substitute placeholders correctly', () => {
i18nInstance.registerLocaleData('de-DE', {
'test.ts | foo': {message: 'a german message'},
'test.ts | bar': {message: 'a german placeholder: {PH1}'},
});
const uiStrings = {
foo: 'a english message',
bar: 'a english placeholder: {PH1}',
};
const stringSet = stringSetWith('test.ts', uiStrings, 'de-DE');
const foo1 = stringSet.getLocalizedString(uiStrings.foo);
const foo2 = stringSet.getLocalizedString(uiStrings.foo);
const bar1 = stringSet.getLocalizedString(uiStrings.bar, {PH1: 'ok'});
const bar2 = stringSet.getLocalizedString(uiStrings.bar, {PH1: 'nice'});
assert.strictEqual(foo1, 'a german message');
assert.strictEqual(foo2, 'a german message');
assert.strictEqual(bar1, 'a german placeholder: ok');
assert.strictEqual(bar2, 'a german placeholder: nice');
});
describe('placeholder formatting', () => {
beforeEach(() => {
i18nInstance.registerLocaleData('en-US', {}); // Always fall-through to UIStrings.
});
it('should throw an error when values are needed but not provided', () => {
const uiStrings = {foo: 'message with {PH1}'};
const stringSet = stringSetWith('test.ts', uiStrings, 'en-US');
assert.throws(() => stringSet.getLocalizedString(uiStrings.foo), /message with \{PH1\}/);
});
it('should throw an error when a value is missing', () => {
const uiStrings = {foo: 'message {PH1} with {PH2}'};
const stringSet = stringSetWith('test.ts', uiStrings, 'en-US');
assert.throws(() => stringSet.getLocalizedString(uiStrings.foo, {PH1: 'bar'}), /message \{PH1\} with \{PH2\}/);
});
it('should format a message with plurals', () => {
const uiStrings = {plural: '{count, plural, =1 {1 row} other {# rows}}'};
const stringSet = stringSetWith('test.ts', uiStrings, 'en-US');
const pluralString1 = stringSet.getLocalizedString(uiStrings.plural, {count: 1});
const pluralString3 = stringSet.getLocalizedString(uiStrings.plural, {count: 3});
assert.strictEqual(pluralString1, '1 row');
assert.strictEqual(pluralString3, '3 rows');
});
it('should throw an error when a plural control value is missing', () => {
const uiStrings = {plural: '{count, plural, =1 {1 row} other {# rows}}'};
const stringSet = stringSetWith('test.ts', uiStrings, 'en-US');
assert.throws(() => stringSet.getLocalizedString(uiStrings.plural));
});
it('should allow nested placeholders in message with plurals', () => {
const uiStrings = {plural: '{count, plural, =1 {1 row in {item}} other {# rows in {item}}}'};
const stringSet = stringSetWith('test.ts', uiStrings, 'en-US');
const pluralString1 = stringSet.getLocalizedString(uiStrings.plural, {count: 1, item: 'table'});
const pluralString3 = stringSet.getLocalizedString(uiStrings.plural, {count: 3, item: 'page'});
assert.strictEqual(pluralString1, '1 row in table');
assert.strictEqual(pluralString3, '3 rows in page');
});
});
describe('locales', () => {
it('should provide the exact locale if it is supported', () => {
const instance = new i18n.I18n.I18n(['en-US', 'de-DE'], 'en-US');
assert.strictEqual(instance.lookupClosestSupportedLocale('de-DE'), 'de-DE');
});
it('should provide the closest related locale if its not supported', () => {
const instance = new i18n.I18n.I18n(['en-US', 'de'], 'en-US');
assert.strictEqual(instance.lookupClosestSupportedLocale('de-AT'), 'de');
});
it('should provide the default locale if no closely related locale was found', () => {
const instance = new i18n.I18n.I18n(['en-US'], 'en-US');
assert.strictEqual(instance.lookupClosestSupportedLocale('de-AT'), 'en-US');
});
});
});