michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: "use strict"; michael@0: michael@0: const prefs = require("sdk/preferences/service"); michael@0: const { Loader } = require('sdk/test/loader'); michael@0: const { resolveURI } = require('toolkit/loader'); michael@0: const { rootURI } = require("@loader/options"); michael@0: const { usingJSON } = require('sdk/l10n/json/core'); michael@0: michael@0: const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS"; michael@0: const PREF_SELECTED_LOCALE = "general.useragent.locale"; michael@0: michael@0: function setLocale(locale) { michael@0: prefs.set(PREF_MATCH_OS_LOCALE, false); michael@0: prefs.set(PREF_SELECTED_LOCALE, locale); michael@0: } michael@0: michael@0: function resetLocale() { michael@0: prefs.reset(PREF_MATCH_OS_LOCALE); michael@0: prefs.reset(PREF_SELECTED_LOCALE); michael@0: } michael@0: michael@0: function definePseudo(loader, id, exports) { michael@0: let uri = resolveURI(id, loader.mapping); michael@0: loader.modules[uri] = { exports: exports }; michael@0: } michael@0: michael@0: function createTest(locale, testFunction) { michael@0: return function (assert, done) { michael@0: let loader = Loader(module); michael@0: // Change the locale before loading new l10n modules in order to load michael@0: // the right .json file michael@0: setLocale(locale); michael@0: // Initialize main l10n module in order to load new locale files michael@0: loader.require("sdk/l10n/loader"). michael@0: load(rootURI). michael@0: then(function success(data) { michael@0: definePseudo(loader, '@l10n/data', data); michael@0: // Execute the given test function michael@0: try { michael@0: testFunction(assert, loader, function onDone() { michael@0: loader.unload(); michael@0: resetLocale(); michael@0: done(); michael@0: }); michael@0: } michael@0: catch(e) { michael@0: console.exception(e); michael@0: } michael@0: }, michael@0: function failure(error) { michael@0: assert.fail("Unable to load locales: " + error); michael@0: }); michael@0: }; michael@0: } michael@0: michael@0: exports.testExactMatching = createTest("fr-FR", function(assert, loader, done) { michael@0: let _ = loader.require("sdk/l10n").get; michael@0: assert.equal(_("Not translated"), "Not translated", michael@0: "Key not translated"); michael@0: assert.equal(_("Translated"), "Oui", michael@0: "Simple key translated"); michael@0: michael@0: // Placeholders michael@0: assert.equal(_("placeholderString", "works"), "Placeholder works", michael@0: "Value with placeholder"); michael@0: assert.equal(_("Placeholder %s", "works"), "Placeholder works", michael@0: "Key without value but with placeholder"); michael@0: assert.equal(_("Placeholders %2s %1s %s.", "working", "are", "correctly"), michael@0: "Placeholders are working correctly.", michael@0: "Multiple placeholders"); michael@0: michael@0: // Plurals michael@0: assert.equal(_("downloadsCount", 0), michael@0: "0 téléchargement", michael@0: "PluralForm form 'one' for 0 in french"); michael@0: assert.equal(_("downloadsCount", 1), michael@0: "1 téléchargement", michael@0: "PluralForm form 'one' for 1 in french"); michael@0: assert.equal(_("downloadsCount", 2), michael@0: "2 téléchargements", michael@0: "PluralForm form 'other' for n > 1 in french"); michael@0: michael@0: done(); michael@0: }); michael@0: michael@0: exports.testHtmlLocalization = createTest("en-GB", function(assert, loader, done) { michael@0: // Ensure initing html component that watch document creations michael@0: // Note that this module is automatically initialized in michael@0: // cuddlefish.js:Loader.main in regular addons. But it isn't for unit tests. michael@0: let loaderHtmlL10n = loader.require("sdk/l10n/html"); michael@0: loaderHtmlL10n.enable(); michael@0: michael@0: let uri = require("sdk/self").data.url("test-localization.html"); michael@0: let worker = loader.require("sdk/page-worker").Page({ michael@0: contentURL: uri, michael@0: contentScript: "new " + function ContentScriptScope() { michael@0: let nodes = document.body.querySelectorAll("*[data-l10n-id]"); michael@0: self.postMessage([nodes[0].innerHTML, michael@0: nodes[1].innerHTML, michael@0: nodes[2].innerHTML, michael@0: nodes[3].innerHTML]); michael@0: }, michael@0: onMessage: function (data) { michael@0: assert.equal( michael@0: data[0], michael@0: "Kept as-is", michael@0: "Nodes with unknown id in .properties are kept 'as-is'" michael@0: ); michael@0: assert.equal(data[1], "Yes", "HTML is translated"); michael@0: assert.equal( michael@0: data[2], michael@0: "no <b>HTML</b> injection", michael@0: "Content from .properties is text content; HTML can't be injected." michael@0: ); michael@0: assert.equal(data[3], "Yes", "Multiple elements with same data-l10n-id are accepted."); michael@0: michael@0: done(); michael@0: } michael@0: }); michael@0: }); michael@0: michael@0: exports.testEnUsLocaleName = createTest("en-GB", function(assert, loader, done) { michael@0: let _ = loader.require("sdk/l10n").get; michael@0: michael@0: assert.equal(_("Not translated"), "Not translated", michael@0: "String w/o translation is kept as-is"); michael@0: assert.equal(_("Translated"), "Yes", michael@0: "String with translation is correctly translated"); michael@0: michael@0: // Check Unicode char escaping sequences michael@0: assert.equal(_("unicodeEscape"), " @ ", michael@0: "Unicode escaped sequances are correctly converted"); michael@0: michael@0: // Check plural forms regular matching michael@0: assert.equal(_("downloadsCount", 0), michael@0: "0 downloads", michael@0: "PluralForm form 'other' for 0 in english"); michael@0: assert.equal(_("downloadsCount", 1), michael@0: "one download", michael@0: "PluralForm form 'one' for 1 in english"); michael@0: assert.equal(_("downloadsCount", 2), michael@0: "2 downloads", michael@0: "PluralForm form 'other' for n != 1 in english"); michael@0: michael@0: // Check optional plural forms michael@0: assert.equal(_("pluralTest", 0), michael@0: "optional zero form", michael@0: "PluralForm form 'zero' can be optionaly specified. (Isn't mandatory in english)"); michael@0: assert.equal(_("pluralTest", 1), michael@0: "fallback to other", michael@0: "If the specific plural form is missing, we fallback to 'other'"); michael@0: michael@0: // Ensure that we can omit specifying the generic key without [other] michael@0: // key[one] = ... michael@0: // key[other] = ... # Instead of `key = ...` michael@0: assert.equal(_("explicitPlural", 1), michael@0: "one", michael@0: "PluralForm form can be omitting generic key [i.e. without ...[other] at end of key)"); michael@0: assert.equal(_("explicitPlural", 10), michael@0: "other", michael@0: "PluralForm form can be omitting generic key [i.e. without ...[other] at end of key)"); michael@0: michael@0: done(); michael@0: }); michael@0: michael@0: exports.testUsingJSON = function(assert) { michael@0: assert.equal(usingJSON, false, 'not using json'); michael@0: } michael@0: michael@0: exports.testShortLocaleName = createTest("eo", function(assert, loader, done) { michael@0: let _ = loader.require("sdk/l10n").get; michael@0: assert.equal(_("Not translated"), "Not translated", michael@0: "String w/o translation is kept as-is"); michael@0: assert.equal(_("Translated"), "jes", michael@0: "String with translation is correctly translated"); michael@0: michael@0: done(); michael@0: }); michael@0: michael@0: michael@0: // Before running tests, disable HTML service which is automatially enabled michael@0: // in api-utils/addon/runner.js michael@0: require('sdk/l10n/html').disable(); michael@0: michael@0: require("sdk/test/runner").runTestsFromModule(module);