summaryrefslogtreecommitdiffstats
path: root/intl/l10n/test/test_localization.js
diff options
context:
space:
mode:
Diffstat (limited to 'intl/l10n/test/test_localization.js')
-rw-r--r--intl/l10n/test/test_localization.js319
1 files changed, 319 insertions, 0 deletions
diff --git a/intl/l10n/test/test_localization.js b/intl/l10n/test/test_localization.js
new file mode 100644
index 0000000000..1b89a0549a
--- /dev/null
+++ b/intl/l10n/test/test_localization.js
@@ -0,0 +1,319 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { AppConstants } = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
+
+// Disable `xpc::IsInAutomation()` so incomplete locales do not generate
+// errors.
+Services.prefs.setBoolPref(
+ "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer",
+ false
+);
+
+add_task(function test_methods_presence() {
+ strictEqual(typeof Localization.prototype.formatValues, "function");
+ strictEqual(typeof Localization.prototype.formatMessages, "function");
+ strictEqual(typeof Localization.prototype.formatValue, "function");
+});
+
+add_task(async function test_methods_calling() {
+ const l10nReg = new L10nRegistry();
+ const fs = [
+ { path: "/localization/de/browser/menu.ftl", source: `
+key-value1 = [de] Value2
+` },
+ { path: "/localization/en-US/browser/menu.ftl", source: `
+key-value1 = [en] Value2
+key-value2 = [en] Value3
+key-attr =
+ .label = [en] Label 3
+` },
+ ];
+ const originalRequested = Services.locale.requestedLocales;
+
+ const source = L10nFileSource.createMock("test", "app", ["de", "en-US"], "/localization/{locale}", fs);
+ l10nReg.registerSources([source]);
+
+ const l10n = new Localization([
+ "/browser/menu.ftl",
+ ], false, l10nReg, ["de", "en-US"]);
+
+ {
+ let values = await l10n.formatValues([
+ {id: "key-value1"},
+ {id: "key-value2"},
+ {id: "key-missing"},
+ {id: "key-attr"}
+ ]);
+
+ strictEqual(values[0], "[de] Value2");
+ strictEqual(values[1], "[en] Value3");
+ strictEqual(values[2], null);
+ strictEqual(values[3], null);
+ }
+
+ {
+ let values = await l10n.formatValues([
+ "key-value1",
+ "key-value2",
+ "key-missing",
+ "key-attr"
+ ]);
+
+ strictEqual(values[0], "[de] Value2");
+ strictEqual(values[1], "[en] Value3");
+ strictEqual(values[2], null);
+ strictEqual(values[3], null);
+ }
+
+ {
+ strictEqual(await l10n.formatValue("key-missing"), null);
+ strictEqual(await l10n.formatValue("key-value1"), "[de] Value2");
+ strictEqual(await l10n.formatValue("key-value2"), "[en] Value3");
+ strictEqual(await l10n.formatValue("key-attr"), null);
+ }
+
+ {
+ let messages = await l10n.formatMessages([
+ {id: "key-value1"},
+ {id: "key-missing"},
+ {id: "key-value2"},
+ {id: "key-attr"},
+ ]);
+
+ strictEqual(messages[0].value, "[de] Value2");
+ strictEqual(messages[1], null);
+ strictEqual(messages[2].value, "[en] Value3");
+ strictEqual(messages[3].value, null);
+ }
+});
+
+add_task(async function test_builtins() {
+ const l10nReg = new L10nRegistry();
+ const known_platforms = {
+ "linux": "linux",
+ "win": "windows",
+ "macosx": "macos",
+ "android": "android",
+ };
+
+ const fs = [
+ { path: "/localization/en-US/test.ftl", source: `
+key = { PLATFORM() ->
+ ${ Object.values(known_platforms).map(
+ name => ` [${ name }] ${ name.toUpperCase() } Value\n`).join("") }
+ *[other] OTHER Value
+ }` },
+ ];
+
+ const source = L10nFileSource.createMock("test", "app", ["en-US"], "/localization/{locale}", fs);
+ l10nReg.registerSources([source]);
+
+ const l10n = new Localization([
+ "/test.ftl",
+ ], false, l10nReg, ["en-US"]);
+
+ let values = await l10n.formatValues([{id: "key"}]);
+
+ ok(values[0].includes(
+ `${ known_platforms[AppConstants.platform].toUpperCase() } Value`));
+});
+
+add_task(async function test_add_remove_resourceIds() {
+ const l10nReg = new L10nRegistry();
+ const fs = [
+ { path: "/localization/en-US/browser/menu.ftl", source: "key1 = Value1" },
+ { path: "/localization/en-US/toolkit/menu.ftl", source: "key2 = Value2" },
+ ];
+
+
+ const source = L10nFileSource.createMock("test", "app", ["en-US"], "/localization/{locale}", fs);
+ l10nReg.registerSources([source]);
+
+ const l10n = new Localization(["/browser/menu.ftl"], false, l10nReg, ["en-US"]);
+
+ let values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ strictEqual(values[0], "Value1");
+ strictEqual(values[1], null);
+
+ l10n.addResourceIds(["/toolkit/menu.ftl"]);
+
+ values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ strictEqual(values[0], "Value1");
+ strictEqual(values[1], "Value2");
+
+ values = await l10n.formatValues(["key1", {id: "key2"}]);
+
+ strictEqual(values[0], "Value1");
+ strictEqual(values[1], "Value2");
+
+ values = await l10n.formatValues([{id: "key1"}, "key2"]);
+
+ strictEqual(values[0], "Value1");
+ strictEqual(values[1], "Value2");
+
+ l10n.removeResourceIds(["/browser/menu.ftl"]);
+
+ values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ strictEqual(values[0], null);
+ strictEqual(values[1], "Value2");
+});
+
+add_task(async function test_switch_to_async() {
+ const l10nReg = new L10nRegistry();
+
+ const fs = [
+ { path: "/localization/en-US/browser/menu.ftl", source: "key1 = Value1" },
+ { path: "/localization/en-US/toolkit/menu.ftl", source: "key2 = Value2" },
+ ];
+
+ const source = L10nFileSource.createMock("test", "app", ["en-US"], "/localization/{locale}", fs);
+ l10nReg.registerSources([source]);
+
+ const l10n = new Localization(["/browser/menu.ftl"], true, l10nReg, ["en-US"]);
+
+ let values = l10n.formatValuesSync([{id: "key1"}, {id: "key2"}]);
+
+ strictEqual(values[0], "Value1");
+ strictEqual(values[1], null);
+
+ l10n.setAsync();
+
+ Assert.throws(() => {
+ l10n.formatValuesSync([{ id: "key1" }, { id: "key2" }]);
+ }, /Can't use formatValuesSync when state is async./);
+
+ l10n.addResourceIds(["/toolkit/menu.ftl"]);
+
+ values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+ let values2 = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ deepEqual(values, values2);
+ strictEqual(values[0], "Value1");
+ strictEqual(values[1], "Value2");
+
+ l10n.removeResourceIds(["/browser/menu.ftl"]);
+
+ values = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
+
+ strictEqual(values[0], null);
+ strictEqual(values[1], "Value2");
+});
+
+/**
+ * This test verifies that when a required resource is missing,
+ * we fallback entirely to the next locale for all entries.
+ */
+add_task(async function test_format_from_missing_required_resource() {
+ const l10nReg = new L10nRegistry();
+
+ const fs = [
+ { path: "/localization/de/browser/menu.ftl", source: `
+key-value = [de] Value1
+` },
+ { path: "/localization/de/browser/missing-in-en-US.ftl", source: `
+key-missing = [de] MissingValue
+` },
+ { path: "/localization/en-US/browser/menu.ftl", source: `
+key-value = [en] Value1
+` },
+ ];
+
+ const source = L10nFileSource.createMock("test", "app", ["de", "en-US"], "/localization/{locale}", fs);
+ l10nReg.registerSources([source]);
+
+ // returns correct contexts for [en-US, de]
+
+ let l10n = new Localization([
+ "/browser/menu.ftl",
+ "/browser/missing-in-en-US.ftl",
+ ], false, l10nReg, ["en-US", "de"]);
+
+ {
+ let values = await l10n.formatValues([
+ {id: "key-value"},
+ {id: "key-missing"},
+ ]);
+
+ strictEqual(values[0], "[de] Value1");
+ strictEqual(values[1], "[de] MissingValue");
+ }
+
+ // returns correct contexts for [de, en-US]
+
+ l10n = new Localization([
+ "/browser/menu.ftl",
+ {path: "/browser/missing-in-en-US.ftl", optional: false},
+ ], false, l10nReg, ["de", "en-US"]);
+
+ {
+ let values = await l10n.formatValues([
+ {id: "key-value"},
+ {id: "key-missing"},
+ ]);
+
+ strictEqual(values[0], "[de] Value1");
+ strictEqual(values[1], "[de] MissingValue");
+ }
+});
+
+/**
+ * This test verifies that when an optional resource is missing, we continue
+ * to populate entires from other resources in the same locale, and we only
+ * fallback entries from the missing optional resource to the next locale.
+ */
+add_task(async function test_format_from_missing_optional_resource() {
+ const l10nReg = new L10nRegistry();
+
+ const fs = [
+ { path: "/localization/de/browser/menu.ftl", source: `
+key-value = [de] Value1
+` },
+ { path: "/localization/de/browser/missing-in-en-US.ftl", source: `
+key-missing = [de] MissingValue
+` },
+ { path: "/localization/en-US/browser/menu.ftl", source: `
+key-value = [en] Value1
+` },
+ ];
+
+ const source = L10nFileSource.createMock("test", "app", ["de", "en-US"], "/localization/{locale}", fs);
+ l10nReg.registerSources([source]);
+
+ // returns correct contexts for [en-US, de]
+
+ let l10n = new Localization([
+ {path: "/browser/menu.ftl", optional: false},
+ {path: "/browser/missing-in-en-US.ftl", optional: true},
+ ], false, l10nReg, ["en-US", "de"]);
+
+ {
+ let values = await l10n.formatValues([
+ {id: "key-value"},
+ {id: "key-missing"},
+ ]);
+
+ strictEqual(values[0], "[en] Value1");
+ strictEqual(values[1], "[de] MissingValue");
+ }
+
+ // returns correct contexts for [de, en-US]
+
+ l10n = new Localization([
+ {path: "/browser/menu.ftl", optional: false},
+ {path: "/browser/missing-in-en-US.ftl", optional: true},
+ ], false, l10nReg, ["de", "en-US"]);
+
+ {
+ let values = await l10n.formatValues([
+ {id: "key-value"},
+ {id: "key-missing"},
+ ]);
+
+ strictEqual(values[0], "[de] Value1");
+ strictEqual(values[1], "[de] MissingValue");
+ }
+});