Bug 1672317 - [l10nfilesource] part5: Migrate tests to use L10nFileSource. r=platform-i18n-reviewers,gregtatum

Depends on D105391

Differential Revision: https://phabricator.services.mozilla.com/D103259
This commit is contained in:
Zibi Braniecki 2021-07-29 21:30:26 +00:00
parent 3ce5593a7d
commit 61e69628d6
13 changed files with 222 additions and 482 deletions

View File

@ -63,29 +63,30 @@ ChromeUtils.defineModuleGetter(
// with region names based on en-US. This is
// necessary for tests that expect to match
// on region code display names.
const { L10nRegistry, FileSource } = ChromeUtils.import(
const { L10nRegistry } = ChromeUtils.import(
"resource://gre/modules/L10nRegistry.jsm"
);
const fs = {
"toolkit/intl/regionNames.ftl": `
const fs = [
{
path: "toolkit/intl/regionNames.ftl",
source: `
region-name-us = United States
region-name-nz = New Zeland
region-name-nz = New Zealand
region-name-au = Australia
region-name-ca = Canada
region-name-tw = Taiwan
`,
};
L10nRegistry.loadSync = function(url) {
if (!fs.hasOwnProperty(url)) {
return false;
}
return fs[url];
};
},
];
let locales = Services.locale.packagedLocales;
const mockSource = new FileSource("mock", locales, "");
const mockSource = L10nFileSource.createMock(
"mock",
locales,
"resource://mock_path",
fs
);
L10nRegistry.registerSources([mockSource]);
}

View File

@ -1,4 +1,4 @@
const { L10nRegistry, FileSource } = ChromeUtils.import(
const { L10nRegistry } = ChromeUtils.import(
"resource://gre/modules/L10nRegistry.jsm"
);
@ -18,8 +18,11 @@ protocol.setSubstitution("l10n-test", Services.io.newURI(uri));
// Notice: we're using a `chrome://` protocol here only for convenience reasons.
// Real sources should use `resource://` protocol.
let locales = Services.locale.appLocalesAsBCP47;
let mockSource = new FileSource("test", locales, `${uri}localization/`);
L10nRegistry.registerSources([mockSource]);
// This source is actually using a real `FileSource` instead of a mocked one,
// because we want to test that fetching real I/O out of the `uri` works in non-system-principal.
let source = new L10nFileSource("test", locales, `${uri}localization/`);
L10nRegistry.registerSources([source]);
registerCleanupFunction(() => {
protocol.setSubstitution("l10n-test", null);

View File

@ -506,19 +506,28 @@ Testing Localization
--------------------
If the goal is to test that the correct localization ends up in the correct place,
the developer needs to register a new :js:`FileSource` in :js:`L10nRegistry` and
the developer needs to register a new :js:`L10nFileSource` in :js:`L10nRegistry` and
provide a mock cached data to be returned by the API.
It may look like this:
.. code-block:: javascript
let fs = new FileSource(["ko-KR", "ar"], "resource://mock-addon/localization/{locale}");
fs.cache = {
"resource://mock-addon/localization/ko-KR/test.ftl": "key = Value in Korean",
"resource://mock-addon/localization/ar/test.ftl": "key = Value in Arabic"
};
let source = L10nFileSource.createMock(
"mock-source",
["ko-KR", "ar"],
"resource://mock-addon/localization/{locale}",
[
{
path: "resource://mock-addon/localization/ko-KR/test.ftl",
source: "key = Value in Korean"
},
{
path: "resource://mock-addon/localization/ar/test.ftl",
source: "key = Value in Arabic"
}
]
);
L10nRegistry.registerSources([fs]);

View File

@ -3,19 +3,9 @@
const {
L10nRegistry,
FileSource,
IndexedFileSource,
} = ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
let fs;
L10nRegistry.load = async function(url) {
if (!fs.hasOwnProperty(url)) {
return Promise.reject("Resource unavailable");
}
return fs[url];
};
add_task(function test_methods_presence() {
equal(typeof L10nRegistry.generateBundles, "function");
equal(typeof L10nRegistry.getAvailableLocales, "function");
@ -28,9 +18,9 @@ add_task(function test_methods_presence() {
* Test that passing empty resourceIds list works.
*/
add_task(async function test_empty_resourceids() {
fs = {};
const fs = [];
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
const bundles = L10nRegistry.generateBundles(["en-US"], []);
@ -47,9 +37,8 @@ add_task(async function test_empty_resourceids() {
* Test that passing empty sources list works.
*/
add_task(async function test_empty_sources() {
fs = {};
const bundles = L10nRegistry.generateBundles(["en-US"], []);
const fs = [];
const bundles = L10nRegistry.generateBundlesSync(["en-US"], fs);
const done = (await bundles.next()).done;
@ -64,11 +53,10 @@ add_task(async function test_empty_sources() {
* source scenario
*/
add_task(async function test_methods_calling() {
fs = {
"/localization/en-US/browser/menu.ftl": "key = Value",
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const fs = [
{ path: "/localization/en-US/browser/menu.ftl", source: "key = Value" }
];
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
const bundles = L10nRegistry.generateBundles(["en-US"], ["/browser/menu.ftl"]);
@ -86,10 +74,10 @@ add_task(async function test_methods_calling() {
* for the single source scenario
*/
add_task(async function test_has_one_source() {
let oneSource = new FileSource("app", ["en-US"], "./app/data/locales/{locale}/");
fs = {
"./app/data/locales/en-US/test.ftl": "key = value en-US",
};
const fs = [
{path: "./app/data/locales/en-US/test.ftl", source: "key = value en-US"}
];
let oneSource = L10nFileSource.createMock("app", ["en-US"], "./app/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource]);
@ -123,14 +111,13 @@ add_task(async function test_has_one_source() {
* for the dual source scenario.
*/
add_task(async function test_has_two_sources() {
let oneSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/");
let secondSource = new FileSource("app", ["pl"], "./app/data/locales/{locale}/");
const fs = [
{ path: "./platform/data/locales/en-US/test.ftl", source: "key = platform value" },
{ path: "./app/data/locales/pl/test.ftl", source: "key = app value" }
];
let oneSource = L10nFileSource.createMock("platform", ["en-US"], "./platform/data/locales/{locale}/", fs);
let secondSource = L10nFileSource.createMock("app", ["pl"], "./app/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource, secondSource]);
fs = {
"./platform/data/locales/en-US/test.ftl": "key = platform value",
"./app/data/locales/pl/test.ftl": "key = app value",
};
// has two sources
@ -173,30 +160,18 @@ add_task(async function test_has_two_sources() {
});
/**
* This test verifies that behavior specific to the IndexedFileSource
* This test verifies that behavior specific to the L10nFileSource
* works correctly.
*
* In particular it tests that IndexedFileSource correctly returns
* In particular it tests that L10nFileSource correctly returns
* missing files as `false` instead of `undefined`.
*/
add_task(async function test_indexed() {
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
add_task(function test_indexed() {
let oneSource = new L10nFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
L10nRegistry.registerSources([oneSource]);
fs = {
"/data/locales/pl/test.ftl": "key = value",
};
equal(L10nRegistry.sources.size, 1);
equal(L10nRegistry.sources.has("langpack-pl"), true);
equal(oneSource.getPath("pl", "test.ftl"), "/data/locales/pl/test.ftl");
equal(oneSource.hasFile("pl", "test.ftl"), true);
equal(oneSource.hasFile("pl", "missing.ftl"), false);
// cleanup
L10nRegistry.sources.clear();
equal(oneSource.hasFile("pl", "test.ftl"), "present");
equal(oneSource.hasFile("pl", "missing.ftl"), "missing");
});
/**
@ -204,17 +179,14 @@ add_task(async function test_indexed() {
* scenarios where a new file source is added on top of the default one.
*/
add_task(async function test_override() {
let fileSource = new FileSource("app", ["pl"], "/app/data/locales/{locale}/");
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
const fs = [
{ path: "/app/data/locales/pl/test.ftl", source: "key = value" },
{ path: "/data/locales/pl/test.ftl", source: "key = addon value"},
];
let fileSource = L10nFileSource.createMock("app", ["pl"], "/app/data/locales/{locale}/", fs);
let oneSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", fs);
L10nRegistry.registerSources([fileSource, oneSource]);
fs = {
"/app/data/locales/pl/test.ftl": "key = value",
"/data/locales/pl/test.ftl": "key = addon value",
};
equal(L10nRegistry.sources.size, 2);
equal(L10nRegistry.sources.has("langpack-pl"), true);
@ -242,13 +214,11 @@ add_task(async function test_override() {
* after source update.
*/
add_task(async function test_updating() {
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
const fs = [
{ path: "/data/locales/pl/test.ftl", source: "key = value" }
];
let oneSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource]);
fs = {
"/data/locales/pl/test.ftl": "key = value",
};
let bundles = L10nRegistry.generateBundles(["pl"], ["test.ftl"]);
let bundle0 = (await bundles.next()).value;
@ -258,10 +228,9 @@ add_task(async function test_updating() {
equal(bundle0.formatPattern(msg0.value), "value");
const newSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
const newSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", [
{ path: "/data/locales/pl/test.ftl", source: "key = new value" }
]);
fs["/data/locales/pl/test.ftl"] = "key = new value";
L10nRegistry.updateSources([newSource]);
equal(L10nRegistry.sources.size, 1);
@ -279,16 +248,14 @@ add_task(async function test_updating() {
* after sources are being removed.
*/
add_task(async function test_removing() {
let fileSource = new FileSource("app", ["pl"], "/app/data/locales/{locale}/");
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
L10nRegistry.registerSources([fileSource, oneSource]);
const fs = [
{ path: "/app/data/locales/pl/test.ftl", source: "key = value" },
{ path: "/data/locales/pl/test.ftl", source: "key = addon value" },
];
fs = {
"/app/data/locales/pl/test.ftl": "key = value",
"/data/locales/pl/test.ftl": "key = addon value",
};
let fileSource = L10nFileSource.createMock("app", ["pl"], "/app/data/locales/{locale}/", fs);
let oneSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", fs);
L10nRegistry.registerSources([fileSource, oneSource]);
equal(L10nRegistry.sources.size, 2);
equal(L10nRegistry.sources.has("langpack-pl"), true);
@ -342,17 +309,15 @@ add_task(async function test_removing() {
* file in the FileSource scenario.
*/
add_task(async function test_missing_file() {
let oneSource = new FileSource("app", ["en-US"], "./app/data/locales/{locale}/");
let twoSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/");
const fs = [
{ path: "./app/data/locales/en-US/test.ftl", source: "key = value en-US" },
{ path: "./platform/data/locales/en-US/test.ftl", source: "key = value en-US" },
{ path: "./platform/data/locales/en-US/test2.ftl", source: "key2 = value2 en-US" },
];
let oneSource = L10nFileSource.createMock("app", ["en-US"], "./app/data/locales/{locale}/", fs);
let twoSource = L10nFileSource.createMock("platform", ["en-US"], "./platform/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource, twoSource]);
fs = {
"./app/data/locales/en-US/test.ftl": "key = value en-US",
"./platform/data/locales/en-US/test.ftl": "key = value en-US",
"./platform/data/locales/en-US/test2.ftl": "key2 = value2 en-US",
};
// has two sources
equal(L10nRegistry.sources.size, 2);
@ -384,71 +349,10 @@ add_task(async function test_missing_file() {
L10nRegistry.sources.clear();
});
/**
* This test verifies that each file is that all files requested
* by a single context are fetched at the same time, even
* if one I/O is slow.
*/
add_task(async function test_parallel_io() {
/* eslint-disable mozilla/no-arbitrary-setTimeout */
let originalLoad = L10nRegistry.load;
let fetchIndex = new Map();
L10nRegistry.load = function(url) {
if (!fetchIndex.has(url)) {
fetchIndex.set(url, 0);
}
fetchIndex.set(url, fetchIndex.get(url) + 1);
if (url === "/en-US/slow-file.ftl") {
return new Promise((resolve, reject) => {
setTimeout(() => {
// Despite slow-file being the first on the list,
// by the time the it finishes loading, the other
// two files are already fetched.
equal(fetchIndex.get("/en-US/test.ftl"), 1);
equal(fetchIndex.get("/en-US/test2.ftl"), 1);
resolve("");
}, 10);
});
}
return Promise.resolve("");
};
let oneSource = new FileSource("app", ["en-US"], "/{locale}/");
L10nRegistry.registerSources([oneSource]);
fs = {
"/en-US/test.ftl": "key = value en-US",
"/en-US/test2.ftl": "key2 = value2 en-US",
"/en-US/slow-file.ftl": "key-slow = value slow en-US",
};
// returns a single context
let bundles = L10nRegistry.generateBundles(["en-US"], ["slow-file.ftl", "test.ftl", "test2.ftl"]);
equal(fetchIndex.size, 0);
let bundle0 = await bundles.next();
equal(bundle0.done, false);
equal((await bundles.next()).done, true);
// When requested again, the cache should make the load operation not
// increase the fetchedIndex count
L10nRegistry.generateBundles(["en-US"], ["test.ftl", "test2.ftl", "slow-file.ftl"]);
// cleanup
L10nRegistry.sources.clear();
L10nRegistry.load = originalLoad;
});
add_task(async function test_hasSource() {
equal(L10nRegistry.hasSource("gobbledygook"), false, "Non-existing source doesn't exist");
equal(L10nRegistry.hasSource("app"), false, "hasSource returns true before registering a source");
let oneSource = new FileSource("app", ["en-US"], "/{locale}/");
let oneSource = new L10nFileSource("app", ["en-US"], "/{locale}/");
L10nRegistry.registerSources([oneSource]);
equal(L10nRegistry.hasSource("app"), true, "hasSource returns true after registering a source");
L10nRegistry.sources.clear();
@ -459,15 +363,14 @@ add_task(async function test_hasSource() {
* is being removed while the iterator operates.
*/
add_task(async function test_remove_source_mid_iter_cycle() {
let oneSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/");
let secondSource = new FileSource("app", ["pl"], "./app/data/locales/{locale}/");
const fs = [
{ path: "./platform/data/locales/en-US/test.ftl", source: "key = platform value" },
{ path: "./app/data/locales/pl/test.ftl", source: "key = app value" },
];
let oneSource = L10nFileSource.createMock("platform", ["en-US"], "./platform/data/locales/{locale}/", fs);
let secondSource = L10nFileSource.createMock("app", ["pl"], "./app/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource, secondSource]);
fs = {
"./platform/data/locales/en-US/test.ftl": "key = platform value",
"./app/data/locales/pl/test.ftl": "key = app value",
};
let bundles = L10nRegistry.generateBundles(["en-US", "pl"], ["test.ftl"]);
let bundle0 = await bundles.next();

View File

@ -3,20 +3,9 @@
const {
L10nRegistry,
FileSource,
IndexedFileSource,
} = ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
let fs;
L10nRegistry.loadSync = function(url) {
if (!fs.hasOwnProperty(url)) {
return false;
}
return fs[url];
};
add_task(function test_methods_presence() {
equal(typeof L10nRegistry.generateBundles, "function");
equal(typeof L10nRegistry.getAvailableLocales, "function");
@ -29,9 +18,9 @@ add_task(function test_methods_presence() {
* Test that passing empty resourceIds list works.
*/
add_task(function test_empty_resourceids() {
fs = {};
const fs = [];
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
const bundles = L10nRegistry.generateBundlesSync(["en-US"], []);
@ -48,9 +37,8 @@ add_task(function test_empty_resourceids() {
* Test that passing empty sources list works.
*/
add_task(function test_empty_sources() {
fs = {};
const bundles = L10nRegistry.generateBundlesSync(["en-US"], []);
const fs = [];
const bundles = L10nRegistry.generateBundlesSync(["en-US"], fs);
const done = (bundles.next()).done;
@ -65,11 +53,10 @@ add_task(function test_empty_sources() {
* source scenario
*/
add_task(function test_methods_calling() {
fs = {
"/localization/en-US/browser/menu.ftl": "key = Value",
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const fs = [
{ path: "/localization/en-US/browser/menu.ftl", source: "key = Value" }
];
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
const bundles = L10nRegistry.generateBundlesSync(["en-US"], ["/browser/menu.ftl"]);
@ -87,10 +74,10 @@ add_task(function test_methods_calling() {
* for the single source scenario
*/
add_task(function test_has_one_source() {
let oneSource = new FileSource("app", ["en-US"], "./app/data/locales/{locale}/");
fs = {
"./app/data/locales/en-US/test.ftl": "key = value en-US",
};
const fs = [
{path: "./app/data/locales/en-US/test.ftl", source: "key = value en-US"}
];
let oneSource = L10nFileSource.createMock("app", ["en-US"], "./app/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource]);
@ -124,14 +111,13 @@ add_task(function test_has_one_source() {
* for the dual source scenario.
*/
add_task(function test_has_two_sources() {
let oneSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/");
let secondSource = new FileSource("app", ["pl"], "./app/data/locales/{locale}/");
const fs = [
{ path: "./platform/data/locales/en-US/test.ftl", source: "key = platform value" },
{ path: "./app/data/locales/pl/test.ftl", source: "key = app value" }
];
let oneSource = L10nFileSource.createMock("platform", ["en-US"], "./platform/data/locales/{locale}/", fs);
let secondSource = L10nFileSource.createMock("app", ["pl"], "./app/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource, secondSource]);
fs = {
"./platform/data/locales/en-US/test.ftl": "key = platform value",
"./app/data/locales/pl/test.ftl": "key = app value",
};
// has two sources
@ -173,49 +159,19 @@ add_task(function test_has_two_sources() {
L10nRegistry.sources.clear();
});
/**
* This test verifies that behavior specific to the IndexedFileSource
* works correctly.
*
* In particular it tests that IndexedFileSource correctly returns
* missing files as `false` instead of `undefined`.
*/
add_task(function test_indexed() {
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
L10nRegistry.registerSources([oneSource]);
fs = {
"/data/locales/pl/test.ftl": "key = value",
};
equal(L10nRegistry.sources.size, 1);
equal(L10nRegistry.sources.has("langpack-pl"), true);
equal(oneSource.getPath("pl", "test.ftl"), "/data/locales/pl/test.ftl");
equal(oneSource.hasFile("pl", "test.ftl"), true);
equal(oneSource.hasFile("pl", "missing.ftl"), false);
// cleanup
L10nRegistry.sources.clear();
});
/**
* This test checks if the correct order of contexts is used for
* scenarios where a new file source is added on top of the default one.
*/
add_task(function test_override() {
let fileSource = new FileSource("app", ["pl"], "/app/data/locales/{locale}/");
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
const fs = [
{ path: "/app/data/locales/pl/test.ftl", source: "key = value" },
{ path: "/data/locales/pl/test.ftl", source: "key = addon value"},
];
let fileSource = L10nFileSource.createMock("app", ["pl"], "/app/data/locales/{locale}/", fs);
let oneSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", fs);
L10nRegistry.registerSources([fileSource, oneSource]);
fs = {
"/app/data/locales/pl/test.ftl": "key = value",
"/data/locales/pl/test.ftl": "key = addon value",
};
equal(L10nRegistry.sources.size, 2);
equal(L10nRegistry.sources.has("langpack-pl"), true);
@ -243,13 +199,11 @@ add_task(function test_override() {
* after source update.
*/
add_task(function test_updating() {
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
const fs = [
{ path: "/data/locales/pl/test.ftl", source: "key = value" }
];
let oneSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource]);
fs = {
"/data/locales/pl/test.ftl": "key = value",
};
let bundles = L10nRegistry.generateBundlesSync(["pl"], ["test.ftl"]);
let bundle0 = (bundles.next()).value;
@ -259,10 +213,9 @@ add_task(function test_updating() {
equal(bundle0.formatPattern(msg0.value), "value");
const newSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
const newSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", [
{ path: "/data/locales/pl/test.ftl", source: "key = new value" }
]);
fs["/data/locales/pl/test.ftl"] = "key = new value";
L10nRegistry.updateSources([newSource]);
equal(L10nRegistry.sources.size, 1);
@ -280,16 +233,15 @@ add_task(function test_updating() {
* after sources are being removed.
*/
add_task(function test_removing() {
let fileSource = new FileSource("app", ["pl"], "/app/data/locales/{locale}/");
let oneSource = new IndexedFileSource("langpack-pl", ["pl"], "/data/locales/{locale}/", [
"/data/locales/pl/test.ftl",
]);
L10nRegistry.registerSources([fileSource, oneSource]);
const fs = [
{ path: "/app/data/locales/pl/test.ftl", source: "key = value" },
{ path: "/data/locales/pl/test.ftl", source: "key = addon value" },
];
fs = {
"/app/data/locales/pl/test.ftl": "key = value",
"/data/locales/pl/test.ftl": "key = addon value",
};
let fileSource = L10nFileSource.createMock("app", ["pl"], "/app/data/locales/{locale}/", fs);
let oneSource = L10nFileSource.createMock("langpack-pl", ["pl"], "/data/locales/{locale}/", fs);
L10nRegistry.registerSources([fileSource, oneSource]);
equal(L10nRegistry.sources.size, 2);
equal(L10nRegistry.sources.has("langpack-pl"), true);
@ -343,17 +295,15 @@ add_task(function test_removing() {
* file in the FileSource scenario.
*/
add_task(function test_missing_file() {
let oneSource = new FileSource("app", ["en-US"], "./app/data/locales/{locale}/");
let twoSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/");
const fs = [
{ path: "./app/data/locales/en-US/test.ftl", source: "key = value en-US" },
{ path: "./platform/data/locales/en-US/test.ftl", source: "key = value en-US" },
{ path: "./platform/data/locales/en-US/test2.ftl", source: "key2 = value2 en-US" },
];
let oneSource = L10nFileSource.createMock("app", ["en-US"], "./app/data/locales/{locale}/", fs);
let twoSource = L10nFileSource.createMock("platform", ["en-US"], "./platform/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource, twoSource]);
fs = {
"./app/data/locales/en-US/test.ftl": "key = value en-US",
"./platform/data/locales/en-US/test.ftl": "key = value en-US",
"./platform/data/locales/en-US/test2.ftl": "key2 = value2 en-US",
};
// has two sources
equal(L10nRegistry.sources.size, 2);
@ -385,81 +335,19 @@ add_task(function test_missing_file() {
L10nRegistry.sources.clear();
});
/**
* This test verifies that each file is that all files requested
* by a single context are fetched at the same time, even
* if one I/O is slow.
*/
add_task(function test_parallel_io() {
/* eslint-disable mozilla/no-arbitrary-setTimeout */
let originalLoad = L10nRegistry.load;
let fetchIndex = new Map();
L10nRegistry.load = function(url) {
if (!fetchIndex.has(url)) {
fetchIndex.set(url, 0);
}
fetchIndex.set(url, fetchIndex.get(url) + 1);
if (url === "/en-US/slow-file.ftl") {
return new Promise((resolve, reject) => {
setTimeout(() => {
// Despite slow-file being the first on the list,
// by the time the it finishes loading, the other
// two files are already fetched.
equal(fetchIndex.get("/en-US/test.ftl"), 1);
equal(fetchIndex.get("/en-US/test2.ftl"), 1);
resolve("");
}, 10);
});
}
return Promise.resolve("");
};
let oneSource = new FileSource("app", ["en-US"], "/{locale}/");
L10nRegistry.registerSources([oneSource]);
fs = {
"/en-US/test.ftl": "key = value en-US",
"/en-US/test2.ftl": "key2 = value2 en-US",
"/en-US/slow-file.ftl": "key-slow = value slow en-US",
};
// returns a single context
let bundles = L10nRegistry.generateBundlesSync(["en-US"], ["slow-file.ftl", "test.ftl", "test2.ftl"]);
equal(fetchIndex.size, 0);
let bundle0 = bundles.next();
equal(bundle0.done, false);
equal((bundles.next()).done, true);
// When requested again, the cache should make the load operation not
// increase the fetchedIndex count
L10nRegistry.generateBundlesSync(["en-US"], ["test.ftl", "test2.ftl", "slow-file.ftl"]);
// cleanup
L10nRegistry.sources.clear();
L10nRegistry.load = originalLoad;
});
/**
* This test verifies that we handle correctly a scenario where a source
* is being removed while the iterator operates.
*/
add_task(function test_remove_source_mid_iter_cycle() {
let oneSource = new FileSource("platform", ["en-US"], "./platform/data/locales/{locale}/");
let secondSource = new FileSource("app", ["pl"], "./app/data/locales/{locale}/");
const fs = [
{ path: "./platform/data/locales/en-US/test.ftl", source: "key = platform value" },
{ path: "./app/data/locales/pl/test.ftl", source: "key = app value" },
];
let oneSource = L10nFileSource.createMock("platform", ["en-US"], "./platform/data/locales/{locale}/", fs);
let secondSource = L10nFileSource.createMock("app", ["pl"], "./app/data/locales/{locale}/", fs);
L10nRegistry.registerSources([oneSource, secondSource]);
fs = {
"./platform/data/locales/en-US/test.ftl": "key = platform value",
"./app/data/locales/pl/test.ftl": "key = app value",
};
let bundles = L10nRegistry.generateBundlesSync(["en-US", "pl"], ["test.ftl"]);
let bundle0 = bundles.next();

View File

@ -11,28 +11,23 @@ add_task(function test_methods_presence() {
});
add_task(async function test_methods_calling() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const fs = {
"/localization/de/browser/menu.ftl": `
const fs = [
{ path: "/localization/de/browser/menu.ftl", source: `
key-value1 = [de] Value2
`,
"/localization/en-US/browser/menu.ftl": `
` },
{ path: "/localization/en-US/browser/menu.ftl", source: `
key-value1 = [en] Value2
key-value2 = [en] Value3
key-attr =
.label = [en] Label 3
`,
};
const originalLoad = L10nRegistry.load;
` },
];
const originalRequested = Services.locale.requestedLocales;
L10nRegistry.load = async function(url) {
return fs[url];
};
const source = new FileSource("test", ["de", "en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["de", "en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
async function* generateBundles(resIds) {
@ -93,12 +88,11 @@ key-attr =
}
L10nRegistry.sources.clear();
L10nRegistry.load = originalLoad;
Services.locale.requestedLocales = originalRequested;
});
add_task(async function test_builtins() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const known_platforms = {
@ -108,21 +102,16 @@ add_task(async function test_builtins() {
"android": "android",
};
const fs = {
"/localization/en-US/test.ftl": `
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 originalLoad = L10nRegistry.load;
}` },
];
L10nRegistry.load = async function(url) {
return fs[url];
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
async function* generateBundles(resIds) {
@ -139,25 +128,20 @@ key = { PLATFORM() ->
`${ known_platforms[AppConstants.platform].toUpperCase() } Value`));
L10nRegistry.sources.clear();
L10nRegistry.load = originalLoad;
});
add_task(async function test_add_remove_resourceIds() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const fs = {
"/localization/en-US/browser/menu.ftl": "key1 = Value1",
"/localization/en-US/toolkit/menu.ftl": "key2 = Value2",
};
const originalLoad = L10nRegistry.load;
const fs = [
{ path: "/localization/en-US/browser/menu.ftl", source: "key1 = Value1" },
{ path: "/localization/en-US/toolkit/menu.ftl", source: "key2 = Value2" },
];
const originalRequested = Services.locale.requestedLocales;
L10nRegistry.load = async function(url) {
return fs[url];
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
async function* generateBundles(resIds) {
@ -196,36 +180,20 @@ add_task(async function test_add_remove_resourceIds() {
strictEqual(values[1], "Value2");
L10nRegistry.sources.clear();
L10nRegistry.load = originalLoad;
Services.locale.requestedLocales = originalRequested;
});
add_task(async function test_switch_to_async() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const fs = {
"/localization/en-US/browser/menu.ftl": "key1 = Value1",
"/localization/en-US/toolkit/menu.ftl": "key2 = Value2",
};
const originalLoad = L10nRegistry.load;
const originalLoadSync = L10nRegistry.loadSync;
const fs = [
{ path: "/localization/en-US/browser/menu.ftl", source: "key1 = Value1" },
{ path: "/localization/en-US/toolkit/menu.ftl", source: "key2 = Value2" },
];
const originalRequested = Services.locale.requestedLocales;
let syncLoads = 0;
let asyncLoads = 0;
L10nRegistry.load = async function(url) {
asyncLoads += 1;
return fs[url];
};
L10nRegistry.loadSync = function(url) {
syncLoads += 1;
return fs[url];
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
async function* generateBundles(resIds) {
@ -242,26 +210,17 @@ add_task(async function test_switch_to_async() {
strictEqual(values[0], "Value1");
strictEqual(values[1], null);
strictEqual(syncLoads, 0);
strictEqual(asyncLoads, 1);
l10n.setIsSync(true);
l10n.addResourceIds(["/toolkit/menu.ftl"]);
// Nothing happens when we switch, because
// the next load is lazy.
strictEqual(syncLoads, 0);
strictEqual(asyncLoads, 1);
values = l10n.formatValuesSync([{id: "key1"}, {id: "key2"}]);
let values2 = await l10n.formatValues([{id: "key1"}, {id: "key2"}]);
deepEqual(values, values2);
strictEqual(values[0], "Value1");
strictEqual(values[1], "Value2");
strictEqual(syncLoads, 1);
strictEqual(asyncLoads, 1);
l10n.removeResourceIds(["/browser/menu.ftl"]);
@ -269,11 +228,7 @@ add_task(async function test_switch_to_async() {
strictEqual(values[0], null);
strictEqual(values[1], "Value2");
strictEqual(syncLoads, 1);
strictEqual(asyncLoads, 1);
L10nRegistry.sources.clear();
L10nRegistry.load = originalLoad;
L10nRegistry.loadSync = originalLoadSync;
Services.locale.requestedLocales = originalRequested;
});

View File

@ -5,28 +5,23 @@ const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
add_task(function test_methods_calling() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const fs = {
"/localization/de/browser/menu.ftl": `
const fs = [
{ path: "/localization/de/browser/menu.ftl", source: `
key-value1 = [de] Value2
`,
"/localization/en-US/browser/menu.ftl": `
` },
{ path: "/localization/en-US/browser/menu.ftl", source: `
key-value1 = [en] Value2
key-value2 = [en] Value3
key-attr =
.label = [en] Label 3
`,
};
const originalLoadSync = L10nRegistry.loadSync;
` },
];
const originalRequested = Services.locale.requestedLocales;
L10nRegistry.loadSync = function(url) {
return fs[url];
};
const source = new FileSource("test", ["de", "en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["de", "en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
function* generateBundlesSync(resIds) {
@ -88,12 +83,11 @@ key-attr =
}
L10nRegistry.sources.clear();
L10nRegistry.loadSync = originalLoadSync;
Services.locale.requestedLocales = originalRequested;
});
add_task(function test_builtins() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const known_platforms = {
@ -103,21 +97,16 @@ add_task(function test_builtins() {
"android": "android",
};
const fs = {
"/localization/en-US/test.ftl": `
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 originalLoadSync = L10nRegistry.loadSync;
}` },
];
L10nRegistry.loadSync = function(url) {
return fs[url];
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
function* generateBundlesSync(resIds) {
@ -134,25 +123,19 @@ key = { PLATFORM() ->
`${ known_platforms[AppConstants.platform].toUpperCase() } Value`));
L10nRegistry.sources.clear();
L10nRegistry.loadSync = originalLoadSync;
});
add_task(function test_add_remove_resourceIds() {
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const fs = {
"/localization/en-US/browser/menu.ftl": "key1 = Value1",
"/localization/en-US/toolkit/menu.ftl": "key2 = Value2",
};
const originalLoadSync = L10nRegistry.loadSYnc;
const fs = [
{ path: "/localization/en-US/browser/menu.ftl", source: "key1 = Value1" },
{ path: "/localization/en-US/toolkit/menu.ftl", source: "key2 = Value2" },
];
const originalRequested = Services.locale.requestedLocales;
L10nRegistry.loadSync = function(url) {
return fs[url];
};
const source = new FileSource("test", ["en-US"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["en-US"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
function* generateBundlesSync(resIds) {
@ -191,7 +174,6 @@ add_task(function test_add_remove_resourceIds() {
strictEqual(values[1], "Value2");
L10nRegistry.sources.clear();
L10nRegistry.loadSync = originalLoadSync;
Services.locale.requestedLocales = originalRequested;
});

View File

@ -2,26 +2,21 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { L10nRegistry, FileSource } =
const { L10nRegistry } =
ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
const originalValues = {};
function addMockFileSource() {
const fs = {
"/localization/de/browser/menu.ftl": `
const fs = [
{ path: "/localization/de/browser/menu.ftl", source: `
key = This is a single message
.tooltip = This is a tooltip
.accesskey = f`,
};
originalValues.load = L10nRegistry.load;
.accesskey = f` },
];
originalValues.requested = Services.locale.requestedLocales;
L10nRegistry.load = async function(url) {
return fs[url];
};
const source = new FileSource("test", ["de"], "/localization/{locale}");
const source = L10nFileSource.createMock("test", ["de"], "/localization/{locale}", fs);
L10nRegistry.registerSources([source]);
return async function* generateMessages(resIds) {
@ -103,7 +98,6 @@ add_task(async function test_accented_works() {
}
L10nRegistry.sources.clear();
L10nRegistry.load = originalValues.load;
Services.locale.requestedLocales = originalValues.requested;
});
@ -135,6 +129,5 @@ add_task(async function test_unavailable_strategy_works() {
Services.prefs.setStringPref("intl.l10n.pseudo", "");
L10nRegistry.sources.clear();
L10nRegistry.load = originalValues.load;
Services.locale.requestedLocales = originalValues.requested;
});

View File

@ -1,6 +1,6 @@
"use strict";
const { L10nRegistry, FileSource } = ChromeUtils.import(
const { L10nRegistry } = ChromeUtils.import(
"resource://gre/modules/L10nRegistry.jsm"
);
const { FileUtils } = ChromeUtils.import(
@ -29,7 +29,7 @@ add_task(async function setup() {
resProto.setSubstitution("l10ntest", target);
const source = new FileSource(
const source = new L10nFileSource(
"test",
Services.locale.requestedLocales,
"resource://l10ntest/"

View File

@ -2,29 +2,33 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { L10nRegistry, FileSource } = ChromeUtils.import(
const { L10nRegistry } = ChromeUtils.import(
"resource://gre/modules/L10nRegistry.jsm"
);
const fs = {
"toolkit/intl/languageNames.ftl": `
const fs = [
{
path: "toolkit/intl/languageNames.ftl",
source: `
language-name-en = English
`,
"toolkit/intl/regionNames.ftl": `
},
{
path: "toolkit/intl/regionNames.ftl",
source: `
region-name-us = United States
region-name-ru = Russia
`,
};
L10nRegistry.loadSync = function(url) {
if (!fs.hasOwnProperty(url)) {
return false;
}
return fs[url];
};
},
];
let locales = Services.locale.packagedLocales;
const mockSource = new FileSource("mock", locales, "");
const mockSource = L10nFileSource.createMock(
"mock",
locales,
"resource://mock_source",
fs
);
L10nRegistry.registerSources([mockSource]);
const gLangDN = Services.intl.getLanguageDisplayNames.bind(

View File

@ -13,7 +13,7 @@ const { TelemetryController } = ChromeUtils.import(
const { TelemetryTestUtils } = ChromeUtils.import(
"resource://testing-common/TelemetryTestUtils.jsm"
);
const { L10nRegistry, FileSource } = ChromeUtils.import(
const { L10nRegistry } = ChromeUtils.import(
"resource://gre/modules/L10nRegistry.jsm"
);
@ -220,10 +220,11 @@ add_task(async function test_setup() {
// Register a fake it-IT locale (used to test localized AMO details in some
// of the test case defined in this test file).
L10nRegistry.registerSources([
new FileSource(
L10nFileSource.createMock(
"mock",
["it-IT", "fr-FR"],
"resource://fake/locales/{locale}"
"resource://fake/locales/{locale}",
[]
),
]);
});

View File

@ -319,6 +319,7 @@ module.exports = {
KeyEvent: false,
KeyboardEvent: false,
KeyframeEffect: false,
L10nFileSource: false,
Localization: false,
Location: false,
MIDIAccess: false,

View File

@ -110,7 +110,7 @@
"kinto-offline-client.js": ["Kinto"],
"kinto-storage-adapter.js": ["FirefoxAdapter"],
"kvstore.jsm": ["KeyValueService"],
"L10nRegistry.jsm": ["L10nRegistry", "FileSource", "IndexedFileSource"],
"L10nRegistry.jsm": ["L10nRegistry"],
"Launcher.jsm": ["BrowserToolboxLauncher"],
"loader-plugin-raw.jsm": ["requireRawId"],
"loader.js": ["WorkerDebuggerLoader", "worker"],