tor-browser

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

test_localeService_negotiateLanguages.js (6161B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 const localeService = Services.locale;
      6 
      7 const data = {
      8  filtering: {
      9    "exact match": [
     10      [["en"], ["en"], ["en"]],
     11      [["en-US"], ["en-US"], ["en-US"]],
     12      [["en-Latn-US"], ["en-Latn-US"], ["en-Latn-US"]],
     13      [["en-Latn-US-windows"], ["en-Latn-US-windows"], ["en-Latn-US-windows"]],
     14      [["fr-FR"], ["de", "it", "fr-FR"], ["fr-FR"]],
     15      [
     16        ["fr", "pl", "de-DE"],
     17        ["pl", "en-US", "de-DE"],
     18        ["pl", "de-DE"],
     19      ],
     20    ],
     21    "available as range": [
     22      [["en-US"], ["en"], ["en"]],
     23      [["en-Latn-US"], ["en-US"], ["en-US"]],
     24      [["en-US-windows"], ["en-US"], ["en-US"]],
     25      [
     26        ["fr-CA", "de-DE"],
     27        ["fr", "it", "de"],
     28        ["fr", "de"],
     29      ],
     30      [["ja-JP-windows"], ["ja"], ["ja"]],
     31      [
     32        ["en-Latn-GB", "en-Latn-IN"],
     33        ["en-IN", "en-GB"],
     34        ["en-GB", "en-IN"],
     35      ],
     36    ],
     37    "should match on likely subtag": [
     38      [["en"], ["en-GB", "de", "en-US"], ["en-US", "en-GB"]],
     39      [
     40        ["en"],
     41        ["en-Latn-GB", "de", "en-Latn-US"],
     42        ["en-Latn-US", "en-Latn-GB"],
     43      ],
     44      [["fr"], ["fr-CA", "fr-FR"], ["fr-FR", "fr-CA"]],
     45      [["az-IR"], ["az-Latn", "az-Arab"], ["az-Arab"]],
     46      [["sr-RU"], ["sr-Cyrl", "sr-Latn"], ["sr-Latn"]],
     47      [["sr"], ["sr-Latn", "sr-Cyrl"], ["sr-Cyrl"]],
     48      [["zh-GB"], ["zh-Hans", "zh-Hant"], ["zh-Hant"]],
     49      [["sr", "ru"], ["sr-Latn", "ru"], ["ru"]],
     50      [["sr-RU"], ["sr-Latn-RO", "sr-Cyrl"], ["sr-Latn-RO"]],
     51    ],
     52    "should match likelySubtag region over other regions": [
     53      [["en-CA"], ["en-ZA", "en-GB", "en-US"], ["en-US", "en-ZA", "en-GB"]],
     54    ],
     55    "should match cross-region": [
     56      [["en"], ["en-US"], ["en-US"]],
     57      [["en-US"], ["en-GB"], ["en-GB"]],
     58      [["en-Latn-US"], ["en-Latn-GB"], ["en-Latn-GB"]],
     59    ],
     60    "should match cross-variant": [
     61      [["en-US-linux"], ["en-US-windows"], ["en-US-windows"]],
     62    ],
     63    "should prioritize properly": [
     64      // exact match first
     65      [
     66        ["en-US"],
     67        ["en-US-windows", "en", "en-US"],
     68        ["en-US", "en", "en-US-windows"],
     69      ],
     70      // available as range second
     71      [["en-Latn-US"], ["en-GB", "en-US"], ["en-US", "en-GB"]],
     72      // likely subtags third
     73      [["en"], ["en-Cyrl-US", "en-Latn-US"], ["en-Latn-US"]],
     74      // variant range fourth
     75      [
     76        ["en-US-macos"],
     77        ["en-US-windows", "en-GB-macos"],
     78        ["en-US-windows", "en-GB-macos"],
     79      ],
     80      // regional range fifth
     81      [["en-US-macos"], ["en-GB-windows"], ["en-GB-windows"]],
     82      [["en-US"], ["en-GB", "en"], ["en", "en-GB"]],
     83      [
     84        ["fr-CA-macos", "de-DE"],
     85        ["de-DE", "fr-FR-windows"],
     86        ["fr-FR-windows", "de-DE"],
     87      ],
     88    ],
     89    "should handle default locale properly": [
     90      [["fr"], ["de", "it"], []],
     91      [["fr"], ["de", "it"], "en-US", ["en-US"]],
     92      [["fr"], ["de", "en-US"], "en-US", ["en-US"]],
     93      [
     94        ["fr", "de-DE"],
     95        ["de-DE", "fr-CA"],
     96        "en-US",
     97        ["fr-CA", "de-DE", "en-US"],
     98      ],
     99    ],
    100    "should handle all matches on the 1st higher than any on the 2nd": [
    101      [
    102        ["fr-CA-macos", "de-DE"],
    103        ["de-DE", "fr-FR-windows"],
    104        ["fr-FR-windows", "de-DE"],
    105      ],
    106    ],
    107    "should handle cases and underscores, returning the form given in the 'available' list":
    108      [
    109        [["fr_FR"], ["fr-FR"], ["fr-FR"]],
    110        [["fr_fr"], ["fr-FR"], ["fr-FR"]],
    111        [["fr_Fr"], ["fr-fR"], ["fr-fR"]],
    112        [["fr_lAtN_fr"], ["fr-Latn-FR"], ["fr-Latn-FR"]],
    113        [["fr_FR"], ["fr_FR"], ["fr_FR"]],
    114        [["fr-FR"], ["fr_FR"], ["fr_FR"]],
    115        [["fr_Cyrl_FR_macos"], ["fr_Cyrl_fr-macos"], ["fr_Cyrl_fr-macos"]],
    116      ],
    117    "should handle mozilla specific 3-letter variants": [
    118      [
    119        ["ja-JP-mac", "de-DE"],
    120        ["ja-JP-mac", "de-DE"],
    121        ["ja-JP-mac", "de-DE"],
    122      ],
    123    ],
    124    "should not crash on invalid input": [
    125      [["fą-FŻ"], ["ór_Fń"], []],
    126      [["2"], ["ąóżł"], []],
    127      [[[""]], ["fr-FR"], []],
    128    ],
    129    "should not match on invalid input": [[["en"], ["ťŮ"], []]],
    130  },
    131  matching: {
    132    "should match only one per requested": [
    133      [
    134        ["fr", "en"],
    135        ["en-US", "fr-FR", "en", "fr"],
    136        null,
    137        localeService.langNegStrategyMatching,
    138        ["fr", "en"],
    139      ],
    140    ],
    141  },
    142  lookup: {
    143    "should match only one": [
    144      [
    145        ["fr-FR", "en"],
    146        ["en-US", "fr-FR", "en", "fr"],
    147        "en-US",
    148        localeService.langNegStrategyLookup,
    149        ["fr-FR"],
    150      ],
    151    ],
    152  },
    153 };
    154 
    155 function run_test() {
    156  const nl = localeService.negotiateLanguages;
    157 
    158  const json = JSON.stringify;
    159  for (const strategy in data) {
    160    for (const groupName in data[strategy]) {
    161      const group = data[strategy][groupName];
    162      for (const test of group) {
    163        const requested = test[0];
    164        const available = test[1];
    165        const defaultLocale = test.length > 3 ? test[2] : undefined;
    166        const strategyInner = test.length > 4 ? test[3] : undefined;
    167        const supported = test[test.length - 1];
    168 
    169        const result = nl(test[0], test[1], defaultLocale, strategyInner);
    170        deepEqual(
    171          result,
    172          supported,
    173          `\nExpected ${json(requested)} * ${json(available)} = ${json(
    174            supported
    175          )}.\n`
    176        );
    177      }
    178    }
    179  }
    180 
    181  // Verify that we error out when requested or available is not an array.
    182  for (const [req, avail] in [
    183    [null, ["fr-FR"]],
    184    [undefined, ["fr-FR"]],
    185    [2, ["fr-FR"]],
    186    ["fr-FR", ["fr-FR"]],
    187    [["fr-FR"], null],
    188    [["fr-FR"], undefined],
    189    [["fr-FR"], 2],
    190    [["fr-FR"], "fr-FR"],
    191    [[null], []],
    192    [[undefined], []],
    193    [[undefined], [null]],
    194    [[undefined], [undefined]],
    195    [[null], [null]],
    196    [[[]], [[2]]],
    197  ]) {
    198    Assert.throws(
    199      () => {
    200        nl(req, avail);
    201      },
    202      err => err.result == Cr.NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY
    203    );
    204  }
    205 }