tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_l10nregistry.js (18862B)


      1 /* Any copyrighequal dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const {setTimeout} = ChromeUtils.importESModule("resource://gre/modules/Timer.sys.mjs");
      5 
      6 const l10nReg = new L10nRegistry();
      7 
      8 add_task(function test_methods_presence() {
      9  equal(typeof l10nReg.generateBundles, "function");
     10  equal(typeof l10nReg.generateBundlesSync, "function");
     11  equal(typeof l10nReg.getAvailableLocales, "function");
     12  equal(typeof l10nReg.registerSources, "function");
     13  equal(typeof l10nReg.removeSources, "function");
     14  equal(typeof l10nReg.updateSources, "function");
     15 });
     16 
     17 /**
     18 * Test that passing empty resourceIds list works.
     19 */
     20 add_task(async function test_empty_resourceids() {
     21  const fs = [];
     22 
     23  const source = L10nFileSource.createMock("test", "", ["en-US"], "/localization/{locale}", fs);
     24  l10nReg.registerSources([source]);
     25 
     26  const bundles = l10nReg.generateBundles(["en-US"], []);
     27 
     28  const done = (await bundles.next()).done;
     29 
     30  equal(done, true);
     31 
     32  // cleanup
     33  l10nReg.clearSources();
     34 });
     35 
     36 /**
     37 * Test that passing empty sources list works.
     38 */
     39 add_task(async function test_empty_sources() {
     40  const fs = [];
     41  const bundles = l10nReg.generateBundlesSync(["en-US"], fs);
     42 
     43  const done = (await bundles.next()).done;
     44 
     45  equal(done, true);
     46 
     47  // cleanup
     48  l10nReg.clearSources();
     49 });
     50 
     51 /**
     52 * This test tests generation of a proper context for a single
     53 * source scenario
     54 */
     55 add_task(async function test_methods_calling() {
     56  const fs = [
     57    { path: "/localization/en-US/browser/menu.ftl", source: "key = Value" }
     58  ];
     59  const source = L10nFileSource.createMock("test", "", ["en-US"], "/localization/{locale}", fs);
     60  l10nReg.registerSources([source]);
     61 
     62  const bundles = l10nReg.generateBundles(["en-US"], ["/browser/menu.ftl"]);
     63 
     64  const bundle = (await bundles.next()).value;
     65 
     66  equal(bundle.hasMessage("key"), true);
     67 
     68  // cleanup
     69  l10nReg.clearSources();
     70 });
     71 
     72 /**
     73 * This test verifies that the public methods return expected values
     74 * for the single source scenario
     75 */
     76 add_task(async function test_has_one_source() {
     77  const fs = [
     78    {path: "./app/data/locales/en-US/test.ftl", source: "key = value en-US"}
     79  ];
     80  let oneSource = L10nFileSource.createMock("app", "", ["en-US"], "./app/data/locales/{locale}/", fs);
     81  l10nReg.registerSources([oneSource]);
     82 
     83 
     84  // has one source
     85 
     86  equal(l10nReg.getSourceNames().length, 1);
     87  equal(l10nReg.hasSource("app"), true);
     88 
     89 
     90  // returns a single context
     91 
     92  let bundles = l10nReg.generateBundles(["en-US"], ["test.ftl"]);
     93  let bundle0 = (await bundles.next()).value;
     94  equal(bundle0.hasMessage("key"), true);
     95 
     96  equal((await bundles.next()).done, true);
     97 
     98 
     99  // returns no contexts for missing locale
    100 
    101  bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    102 
    103  equal((await bundles.next()).done, true);
    104 
    105  // cleanup
    106  l10nReg.clearSources();
    107 });
    108 
    109 /**
    110 * This test verifies that public methods return expected values
    111 * for the dual source scenario.
    112 */
    113 add_task(async function test_has_two_sources() {
    114  const fs = [
    115    { path: "./platform/data/locales/en-US/test.ftl", source: "key = platform value" },
    116    { path: "./app/data/locales/pl/test.ftl", source: "key = app value" }
    117  ];
    118  let oneSource = L10nFileSource.createMock("platform", "", ["en-US"], "./platform/data/locales/{locale}/", fs);
    119  let secondSource = L10nFileSource.createMock("app", "", ["pl"], "./app/data/locales/{locale}/", fs);
    120  l10nReg.registerSources([oneSource, secondSource]);
    121 
    122  // has two sources
    123 
    124  equal(l10nReg.getSourceNames().length, 2);
    125  equal(l10nReg.hasSource("app"), true);
    126  equal(l10nReg.hasSource("platform"), true);
    127 
    128 
    129  // returns correct contexts for en-US
    130 
    131  let bundles = l10nReg.generateBundles(["en-US"], ["test.ftl"]);
    132  let bundle0 = (await bundles.next()).value;
    133 
    134  equal(bundle0.hasMessage("key"), true);
    135  let msg = bundle0.getMessage("key");
    136  equal(bundle0.formatPattern(msg.value), "platform value");
    137 
    138  equal((await bundles.next()).done, true);
    139 
    140 
    141  // returns correct contexts for [pl, en-US]
    142 
    143  bundles = l10nReg.generateBundles(["pl", "en-US"], ["test.ftl"]);
    144  bundle0 = (await bundles.next()).value;
    145  equal(bundle0.locales[0], "pl");
    146  equal(bundle0.hasMessage("key"), true);
    147  let msg0 = bundle0.getMessage("key");
    148  equal(bundle0.formatPattern(msg0.value), "app value");
    149 
    150  let bundle1 = (await bundles.next()).value;
    151  equal(bundle1.locales[0], "en-US");
    152  equal(bundle1.hasMessage("key"), true);
    153  let msg1 = bundle1.getMessage("key");
    154  equal(bundle1.formatPattern(msg1.value), "platform value");
    155 
    156  equal((await bundles.next()).done, true);
    157 
    158  // cleanup
    159  l10nReg.clearSources();
    160 });
    161 
    162 /**
    163 * This test verifies that behavior specific to the L10nFileSource
    164 * works correctly.
    165 *
    166 * In particular it tests that L10nFileSource correctly returns
    167 * missing files as `false` instead of `undefined`.
    168 */
    169 add_task(function test_indexed() {
    170  let oneSource = new L10nFileSource("langpack-pl", "app", ["pl"], "/data/locales/{locale}/", {}, [
    171    "/data/locales/pl/test.ftl",
    172  ]);
    173  equal(oneSource.hasFile("pl", "test.ftl"), "present");
    174  equal(oneSource.hasFile("pl", "missing.ftl"), "missing");
    175 });
    176 
    177 /**
    178 * This test checks if the correct order of contexts is used for
    179 * scenarios where a new file source is added on top of the default one.
    180 */
    181 add_task(async function test_override() {
    182  const fs = [
    183    { path: "/app/data/locales/pl/test.ftl", source: "key = value" },
    184    { path: "/data/locales/pl/test.ftl", source: "key = addon value"},
    185  ];
    186  let fileSource = L10nFileSource.createMock("app", "", ["pl"], "/app/data/locales/{locale}/", fs);
    187  let oneSource = L10nFileSource.createMock("langpack-pl", "", ["pl"], "/data/locales/{locale}/", fs);
    188  l10nReg.registerSources([fileSource, oneSource]);
    189 
    190  equal(l10nReg.getSourceNames().length, 2);
    191  equal(l10nReg.hasSource("langpack-pl"), true);
    192 
    193  let bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    194  let bundle0 = (await bundles.next()).value;
    195  equal(bundle0.locales[0], "pl");
    196  equal(bundle0.hasMessage("key"), true);
    197  let msg0 = bundle0.getMessage("key");
    198  equal(bundle0.formatPattern(msg0.value), "addon value");
    199 
    200  let bundle1 = (await bundles.next()).value;
    201  equal(bundle1.locales[0], "pl");
    202  equal(bundle1.hasMessage("key"), true);
    203  let msg1 = bundle1.getMessage("key");
    204  equal(bundle1.formatPattern(msg1.value), "value");
    205 
    206  equal((await bundles.next()).done, true);
    207 
    208  // cleanup
    209  l10nReg.clearSources();
    210 });
    211 
    212 /**
    213 * This test verifies that new contexts are returned
    214 * after source update.
    215 */
    216 add_task(async function test_updating() {
    217  const fs = [
    218    { path: "/data/locales/pl/test.ftl", source: "key = value" }
    219  ];
    220  let oneSource = L10nFileSource.createMock("langpack-pl", "", ["pl"], "/data/locales/{locale}/", fs);
    221  l10nReg.registerSources([oneSource]);
    222 
    223  let bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    224  let bundle0 = (await bundles.next()).value;
    225  equal(bundle0.locales[0], "pl");
    226  equal(bundle0.hasMessage("key"), true);
    227  let msg0 = bundle0.getMessage("key");
    228  equal(bundle0.formatPattern(msg0.value), "value");
    229 
    230 
    231  const newSource = L10nFileSource.createMock("langpack-pl", "", ["pl"], "/data/locales/{locale}/", [
    232    { path: "/data/locales/pl/test.ftl", source: "key = new value" }
    233  ]);
    234  l10nReg.updateSources([newSource]);
    235 
    236  equal(l10nReg.getSourceNames().length, 1);
    237  bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    238  bundle0 = (await bundles.next()).value;
    239  msg0 = bundle0.getMessage("key");
    240  equal(bundle0.formatPattern(msg0.value), "new value");
    241 
    242  // cleanup
    243  l10nReg.clearSources();
    244 });
    245 
    246 /**
    247 * This test verifies that generated contexts return correct values
    248 * after sources are being removed.
    249 */
    250 add_task(async function test_removing() {
    251  const fs = [
    252    { path: "/app/data/locales/pl/test.ftl", source: "key = value" },
    253    { path: "/data/locales/pl/test.ftl", source: "key = addon value" },
    254  ];
    255 
    256  let fileSource = L10nFileSource.createMock("app", "", ["pl"], "/app/data/locales/{locale}/", fs);
    257  let oneSource = L10nFileSource.createMock("langpack-pl", "", ["pl"], "/data/locales/{locale}/", fs);
    258  l10nReg.registerSources([fileSource, oneSource]);
    259 
    260  equal(l10nReg.getSourceNames().length, 2);
    261  equal(l10nReg.hasSource("langpack-pl"), true);
    262 
    263  let bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    264  let bundle0 = (await bundles.next()).value;
    265  equal(bundle0.locales[0], "pl");
    266  equal(bundle0.hasMessage("key"), true);
    267  let msg0 = bundle0.getMessage("key");
    268  equal(bundle0.formatPattern(msg0.value), "addon value");
    269 
    270  let bundle1 = (await bundles.next()).value;
    271  equal(bundle1.locales[0], "pl");
    272  equal(bundle1.hasMessage("key"), true);
    273  let msg1 = bundle1.getMessage("key");
    274  equal(bundle1.formatPattern(msg1.value), "value");
    275 
    276  equal((await bundles.next()).done, true);
    277 
    278  // Remove langpack
    279 
    280  l10nReg.removeSources(["langpack-pl"]);
    281 
    282  equal(l10nReg.getSourceNames().length, 1);
    283  equal(l10nReg.hasSource("langpack-pl"), false);
    284 
    285  bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    286  bundle0 = (await bundles.next()).value;
    287  equal(bundle0.locales[0], "pl");
    288  equal(bundle0.hasMessage("key"), true);
    289  msg0 = bundle0.getMessage("key");
    290  equal(bundle0.formatPattern(msg0.value), "value");
    291 
    292  equal((await bundles.next()).done, true);
    293 
    294  // Remove app source
    295 
    296  l10nReg.removeSources(["app"]);
    297 
    298  equal(l10nReg.getSourceNames().length, 0);
    299 
    300  bundles = l10nReg.generateBundles(["pl"], ["test.ftl"]);
    301  equal((await bundles.next()).done, true);
    302 
    303  // cleanup
    304  l10nReg.clearSources();
    305 });
    306 
    307 /**
    308 * This test verifies that the logic works correctly when there's a missing
    309 * file in the FileSource scenario.
    310 */
    311 add_task(async function test_missing_file() {
    312  const fs = [
    313    { path: "./app/data/locales/en-US/test.ftl", source: "key = value en-US" },
    314    { path: "./platform/data/locales/en-US/test.ftl", source: "key = value en-US" },
    315    { path: "./platform/data/locales/en-US/test2.ftl", source: "key2 = value2 en-US" },
    316  ];
    317  let oneSource = L10nFileSource.createMock("app", "", ["en-US"], "./app/data/locales/{locale}/", fs);
    318  let twoSource = L10nFileSource.createMock("platform", "", ["en-US"], "./platform/data/locales/{locale}/", fs);
    319  l10nReg.registerSources([oneSource, twoSource]);
    320 
    321  // has two sources
    322 
    323  equal(l10nReg.getSourceNames().length, 2);
    324  equal(l10nReg.hasSource("app"), true);
    325  equal(l10nReg.hasSource("platform"), true);
    326 
    327 
    328  // returns a single context
    329 
    330  let bundles = l10nReg.generateBundles(["en-US"], ["test.ftl", "test2.ftl"]);
    331 
    332  // First permutation:
    333  //   [platform, platform] - both present
    334  let bundle1 = (await bundles.next());
    335  equal(bundle1.value.hasMessage("key"), true);
    336 
    337  // Second permutation skipped:
    338  //   [platform, app] - second missing
    339  // Third permutation:
    340  //   [app, platform] - both present
    341  let bundle2 = (await bundles.next());
    342  equal(bundle2.value.hasMessage("key"), true);
    343 
    344  // Fourth permutation skipped:
    345  //   [app, app] - second missing
    346  equal((await bundles.next()).done, true);
    347 
    348  // cleanup
    349  l10nReg.clearSources();
    350 });
    351 
    352 add_task(async function test_hasSource() {
    353  equal(l10nReg.hasSource("nonsense"), false, "Non-existing source doesn't exist");
    354  equal(l10nReg.hasSource("app"), false, "hasSource returns true before registering a source");
    355  let oneSource = new L10nFileSource("app", "app", ["en-US"], "/{locale}/");
    356  l10nReg.registerSources([oneSource]);
    357  equal(l10nReg.hasSource("app"), true, "hasSource returns true after registering a source");
    358  l10nReg.clearSources();
    359 });
    360 
    361 /**
    362 * This test verifies that we handle correctly a scenario where a source
    363 * is being removed while the iterator operates.
    364 */
    365 add_task(async function test_remove_source_mid_iter_cycle() {
    366  const fs = [
    367    { path: "./platform/data/locales/en-US/test.ftl", source: "key = platform value" },
    368    { path: "./app/data/locales/pl/test.ftl", source: "key = app value" },
    369  ];
    370  let oneSource = L10nFileSource.createMock("platform", "", ["en-US"], "./platform/data/locales/{locale}/", fs);
    371  let secondSource = L10nFileSource.createMock("app", "", ["pl"], "./app/data/locales/{locale}/", fs);
    372  l10nReg.registerSources([oneSource, secondSource]);
    373 
    374  let bundles = l10nReg.generateBundles(["en-US", "pl"], ["test.ftl"]);
    375 
    376  let bundle0 = await bundles.next();
    377 
    378  // The registry has a copy of the file sources, so it will be unaffected.
    379  l10nReg.removeSources(["app"]);
    380 
    381  let bundle1 = await bundles.next();
    382 
    383  equal((await bundles.next()).done, true);
    384 
    385  // cleanup
    386  l10nReg.clearSources();
    387 });
    388 
    389 add_task(async function test_metasources() {
    390  let fs = [
    391    { path: "/localization/en-US/browser/menu1.ftl", source: "key1 = Value" },
    392    { path: "/localization/en-US/browser/menu2.ftl", source: "key2 = Value" },
    393    { path: "/localization/en-US/browser/menu3.ftl", source: "key3 = Value" },
    394    { path: "/localization/en-US/browser/menu4.ftl", source: "key4 = Value" },
    395    { path: "/localization/en-US/browser/menu5.ftl", source: "key5 = Value" },
    396    { path: "/localization/en-US/browser/menu6.ftl", source: "key6 = Value" },
    397    { path: "/localization/en-US/browser/menu7.ftl", source: "key7 = Value" },
    398    { path: "/localization/en-US/browser/menu8.ftl", source: "key8 = Value" },
    399  ];
    400 
    401  const browser = L10nFileSource.createMock("browser", "app", ["en-US"], "/localization/{locale}", fs);
    402  const toolkit = L10nFileSource.createMock("toolkit", "app", ["en-US"], "/localization/{locale}", fs);
    403  const browser2 = L10nFileSource.createMock("browser2", "langpack", ["en-US"], "/localization/{locale}", fs);
    404  const toolkit2 = L10nFileSource.createMock("toolkit2", "langpack", ["en-US"], "/localization/{locale}", fs);
    405  l10nReg.registerSources([toolkit, browser, toolkit2, browser2]);
    406 
    407  let res = [
    408    "/browser/menu1.ftl",
    409    "/browser/menu2.ftl",
    410    "/browser/menu3.ftl",
    411    "/browser/menu4.ftl",
    412    "/browser/menu5.ftl",
    413    "/browser/menu6.ftl",
    414    "/browser/menu7.ftl",
    415    {path: "/browser/menu8.ftl", optional: false},
    416  ];
    417 
    418  const bundles = l10nReg.generateBundles(["en-US"], res);
    419 
    420  let nbundles = 0;
    421  while (!(await bundles.next()).done) {
    422    nbundles += 1;
    423  }
    424 
    425  // If metasources are working properly, we'll generate 2^8 = 256 bundles for
    426  // each metasource giving 512 bundles in total. Otherwise, we generate
    427  // 4^8 = 65536 bundles.
    428  equal(nbundles, 512);
    429 
    430  // cleanup
    431  l10nReg.clearSources();
    432 });
    433 
    434 /**
    435 * This test verifies that when a required resource is missing for a locale,
    436 * we do not produce a bundle for that locale.
    437 */
    438 add_task(async function test_missing_required_resource() {
    439  const fs = [
    440    { path: "./platform/data/locales/en-US/test.ftl", source: "test-key = en-US value" },
    441    { path: "./platform/data/locales/pl/missing-in-en-US.ftl", source: "missing-key = pl value" },
    442    { path: "./platform/data/locales/pl/test.ftl", source: "test-key = pl value" },
    443  ];
    444  let source = L10nFileSource.createMock("platform", "", ["en-US", "pl"], "./platform/data/locales/{locale}/", fs);
    445  l10nReg.registerSources([source]);
    446 
    447  equal(l10nReg.getSourceNames().length, 1);
    448  equal(l10nReg.hasSource("platform"), true);
    449 
    450 
    451  // returns correct contexts for [en-US, pl]
    452 
    453  let bundles = l10nReg.generateBundlesSync(["en-US", "pl"], ["test.ftl", "missing-in-en-US.ftl"]);
    454  let bundle0 = (await bundles.next()).value;
    455 
    456  equal(bundle0.locales[0], "pl");
    457  equal(bundle0.hasMessage("test-key"), true);
    458  equal(bundle0.hasMessage("missing-key"), true);
    459 
    460  let msg0 = bundle0.getMessage("test-key");
    461  equal(bundle0.formatPattern(msg0.value), "pl value");
    462 
    463  let msg1 = bundle0.getMessage("missing-key");
    464  equal(bundle0.formatPattern(msg1.value), "pl value");
    465 
    466  equal((await bundles.next()).done, true);
    467 
    468 
    469  // returns correct contexts for [pl, en-US]
    470 
    471  bundles = l10nReg.generateBundlesSync(["pl", "en-US"], ["test.ftl", {path: "missing-in-en-US.ftl", optional: false}]);
    472  bundle0 = (await bundles.next()).value;
    473 
    474  equal(bundle0.locales[0], "pl");
    475  equal(bundle0.hasMessage("test-key"), true);
    476 
    477  msg0 = bundle0.getMessage("test-key");
    478  equal(bundle0.formatPattern(msg0.value), "pl value");
    479 
    480  msg1 = bundle0.getMessage("missing-key");
    481  equal(bundle0.formatPattern(msg1.value), "pl value");
    482 
    483  equal((await bundles.next()).done, true);
    484 
    485  // cleanup
    486  l10nReg.clearSources();
    487 });
    488 
    489 /**
    490 * This test verifies that when an optional resource is missing, we continue
    491 * to produce a bundle for that locale. The bundle will have missing entries
    492 * with regard to the missing optional resource.
    493 */
    494 add_task(async function test_missing_optional_resource() {
    495  const fs = [
    496    { path: "./platform/data/locales/en-US/test.ftl", source: "test-key = en-US value" },
    497    { path: "./platform/data/locales/pl/missing-in-en-US.ftl", source: "missing-key = pl value" },
    498    { path: "./platform/data/locales/pl/test.ftl", source: "test-key = pl value" },
    499  ];
    500  let source = L10nFileSource.createMock("platform", "", ["en-US", "pl"], "./platform/data/locales/{locale}/", fs);
    501  l10nReg.registerSources([source]);
    502 
    503  equal(l10nReg.getSourceNames().length, 1);
    504  equal(l10nReg.hasSource("platform"), true);
    505 
    506 
    507  // returns correct contexts for [en-US, pl]
    508 
    509  let bundles = l10nReg.generateBundlesSync(["en-US", "pl"], ["test.ftl", { path: "missing-in-en-US.ftl", optional: true }]);
    510  let bundle0 = (await bundles.next()).value;
    511 
    512  equal(bundle0.locales[0], "en-US");
    513  equal(bundle0.hasMessage("test-key"), true);
    514  equal(bundle0.hasMessage("missing-key"), false);
    515 
    516  let msg0 = bundle0.getMessage("test-key");
    517  equal(bundle0.formatPattern(msg0.value), "en-US value");
    518 
    519  equal(bundle0.getMessage("missing-key"), null);
    520 
    521  let bundle1 = (await bundles.next()).value;
    522 
    523  equal(bundle1.locales[0], "pl");
    524  equal(bundle1.hasMessage("test-key"), true);
    525  equal(bundle1.hasMessage("missing-key"), true);
    526 
    527  msg0 = bundle1.getMessage("test-key");
    528  equal(bundle1.formatPattern(msg0.value), "pl value");
    529 
    530  msg1 = bundle1.getMessage("missing-key");
    531  equal(bundle1.formatPattern(msg1.value), "pl value");
    532 
    533  equal((await bundles.next()).done, true);
    534 
    535  // returns correct contexts for [pl, en-US]
    536 
    537  bundles = l10nReg.generateBundlesSync(["pl", "en-US"], ["test.ftl", { path: "missing-in-en-US.ftl", optional: true }]);
    538  bundle0 = (await bundles.next()).value;
    539 
    540  equal(bundle0.locales[0], "pl");
    541  equal(bundle0.hasMessage("test-key"), true);
    542  equal(bundle0.hasMessage("missing-key"), true);
    543 
    544  msg0 = bundle0.getMessage("test-key");
    545  equal(bundle0.formatPattern(msg0.value), "pl value");
    546 
    547  msg1 = bundle0.getMessage("missing-key");
    548  equal(bundle0.formatPattern(msg1.value), "pl value");
    549 
    550  bundle1 = (await bundles.next()).value;
    551 
    552  equal(bundle1.locales[0], "en-US");
    553  equal(bundle1.hasMessage("test-key"), true);
    554  equal(bundle1.hasMessage("missing-key"), false);
    555 
    556  msg0 = bundle1.getMessage("test-key");
    557  equal(bundle1.formatPattern(msg0.value), "en-US value");
    558 
    559  equal(bundle1.getMessage("missing-key"), null);
    560 
    561  // cleanup
    562  l10nReg.clearSources();
    563 });