From 61e69628d6f89b900cdef35c2344323f1cf07824 Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Thu, 29 Jul 2021 21:30:26 +0000 Subject: [PATCH] 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 --- .../extensions/formautofill/test/unit/head.js | 27 +-- .../browser_resource_uri.js | 9 +- intl/docs/locale.rst | 23 +- intl/l10n/test/test_l10nregistry.js | 211 +++++------------ intl/l10n/test/test_l10nregistry_sync.js | 214 +++++------------- intl/l10n/test/test_localization.js | 99 +++----- intl/l10n/test/test_localization_sync.js | 58 ++--- intl/l10n/test/test_pseudo.js | 19 +- .../extensions/test/xpcshell/test_ext_l10n.js | 4 +- .../test_mozintl_getLocaleDisplayNames.js | 30 +-- .../test/xpcshell/test_AbuseReporter.js | 7 +- .../lib/environments/privileged.js | 1 + tools/lint/eslint/modules.json | 2 +- 13 files changed, 222 insertions(+), 482 deletions(-) diff --git a/browser/extensions/formautofill/test/unit/head.js b/browser/extensions/formautofill/test/unit/head.js index c5783a14217f..24cdb0207cd8 100644 --- a/browser/extensions/formautofill/test/unit/head.js +++ b/browser/extensions/formautofill/test/unit/head.js @@ -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]); } diff --git a/dom/l10n/tests/mochitest/document_l10n/non-system-principal/browser_resource_uri.js b/dom/l10n/tests/mochitest/document_l10n/non-system-principal/browser_resource_uri.js index f040d6db75d8..91b6a24ee7e8 100644 --- a/dom/l10n/tests/mochitest/document_l10n/non-system-principal/browser_resource_uri.js +++ b/dom/l10n/tests/mochitest/document_l10n/non-system-principal/browser_resource_uri.js @@ -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); diff --git a/intl/docs/locale.rst b/intl/docs/locale.rst index 6232e9308a37..df4da61960e7 100644 --- a/intl/docs/locale.rst +++ b/intl/docs/locale.rst @@ -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]); diff --git a/intl/l10n/test/test_l10nregistry.js b/intl/l10n/test/test_l10nregistry.js index 780123b22f7d..bdb9c57ec690 100644 --- a/intl/l10n/test/test_l10nregistry.js +++ b/intl/l10n/test/test_l10nregistry.js @@ -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(); diff --git a/intl/l10n/test/test_l10nregistry_sync.js b/intl/l10n/test/test_l10nregistry_sync.js index ca60227cb0d3..e2b05c40b1e5 100644 --- a/intl/l10n/test/test_l10nregistry_sync.js +++ b/intl/l10n/test/test_l10nregistry_sync.js @@ -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(); diff --git a/intl/l10n/test/test_localization.js b/intl/l10n/test/test_localization.js index 2745ef924251..3e8ef37d8327 100644 --- a/intl/l10n/test/test_localization.js +++ b/intl/l10n/test/test_localization.js @@ -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; }); diff --git a/intl/l10n/test/test_localization_sync.js b/intl/l10n/test/test_localization_sync.js index 8d927fff7dca..c66d6c2745e7 100644 --- a/intl/l10n/test/test_localization_sync.js +++ b/intl/l10n/test/test_localization_sync.js @@ -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; }); diff --git a/intl/l10n/test/test_pseudo.js b/intl/l10n/test/test_pseudo.js index c64332df4506..0dd371cb576c 100644 --- a/intl/l10n/test/test_pseudo.js +++ b/intl/l10n/test/test_pseudo.js @@ -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; }); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_l10n.js b/toolkit/components/extensions/test/xpcshell/test_ext_l10n.js index b8eb3830fa6c..a3a8edd9e7cd 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_l10n.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_l10n.js @@ -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/" diff --git a/toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js b/toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js index 4b6e4e76e001..aca0185e5605 100644 --- a/toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js +++ b/toolkit/components/mozintl/test/test_mozintl_getLocaleDisplayNames.js @@ -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( diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js b/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js index b1a9bf0a5a10..8fafd817e688 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js @@ -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}", + [] ), ]); }); diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/privileged.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/privileged.js index 9754dc346bd4..bb77d24c7f43 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/privileged.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/privileged.js @@ -319,6 +319,7 @@ module.exports = { KeyEvent: false, KeyboardEvent: false, KeyframeEffect: false, + L10nFileSource: false, Localization: false, Location: false, MIDIAccess: false, diff --git a/tools/lint/eslint/modules.json b/tools/lint/eslint/modules.json index 749c844719b7..62e1adde8d59 100644 --- a/tools/lint/eslint/modules.json +++ b/tools/lint/eslint/modules.json @@ -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"],