tor-browser

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

test_natural-sort.js (24778B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const l10n = new Localization(["devtools/client/storage.ftl"], true);
      7 const sessionString = l10n.formatValueSync("storage-expires-session");
      8 const {
      9  naturalSortCaseSensitive,
     10  naturalSortCaseInsensitive,
     11 } = require("resource://devtools/shared/natural-sort.js");
     12 
     13 function run_test() {
     14  test("different values types", function () {
     15    runTest(["a", 1], [1, "a"], "number always comes first");
     16    runTest(
     17      ["1", 1],
     18      ["1", 1],
     19      "number vs numeric string - should remain unchanged (error in chrome)"
     20    );
     21    runTest(
     22      ["02", 3, 2, "01"],
     23      ["01", "02", 2, 3],
     24      "padding numeric string vs number"
     25    );
     26  });
     27 
     28  test("datetime", function () {
     29    runTest(
     30      ["10/12/2008", "10/11/2008", "10/11/2007", "10/12/2007"],
     31      ["10/11/2007", "10/12/2007", "10/11/2008", "10/12/2008"],
     32      "similar dates"
     33    );
     34    runTest(
     35      ["01/01/2008", "01/10/2008", "01/01/1992", "01/01/1991"],
     36      ["01/01/1991", "01/01/1992", "01/01/2008", "01/10/2008"],
     37      "similar dates"
     38    );
     39    // Years should expand to 0100, 2001, 2010
     40    runTest(
     41      ["1/1/100", "1/1/1", "1/1/10"],
     42      ["1/1/100", "1/1/1", "1/1/10"],
     43      "dates with short year formatting"
     44    );
     45    runTest(
     46      [
     47        "Wed Jan 01 2010 00:00:00 GMT-0800 (Pacific Standard Time)",
     48        "Thu Dec 31 2009 00:00:00 GMT-0800 (Pacific Standard Time)",
     49        "Wed Jan 01 2010 00:00:00 GMT-0500 (Eastern Standard Time)",
     50      ],
     51      [
     52        "Thu Dec 31 2009 00:00:00 GMT-0800 (Pacific Standard Time)",
     53        "Wed Jan 01 2010 00:00:00 GMT-0500 (Eastern Standard Time)",
     54        "Wed Jan 01 2010 00:00:00 GMT-0800 (Pacific Standard Time)",
     55      ],
     56      "javascript toString(), different timezones"
     57    );
     58    runTest(
     59      [
     60        "Saturday, July 3, 2010",
     61        "Monday, August 2, 2010",
     62        "Monday, May 3, 2010",
     63      ],
     64      [
     65        "Monday, May 3, 2010",
     66        "Saturday, July 3, 2010",
     67        "Monday, August 2, 2010",
     68      ],
     69      "Date.toString(), Date.toLocaleString()"
     70    );
     71    runTest(
     72      [
     73        "Mon, 15 Jun 2009 20:45:30 GMT",
     74        "Mon, 3 May 2010 17:45:30 GMT",
     75        "Mon, 15 Jun 2009 17:45:30 GMT",
     76      ],
     77      [
     78        "Mon, 15 Jun 2009 17:45:30 GMT",
     79        "Mon, 15 Jun 2009 20:45:30 GMT",
     80        "Mon, 3 May 2010 17:45:30 GMT",
     81      ],
     82      "Date.toUTCString()"
     83    );
     84    runTest(
     85      [
     86        "Saturday, July 3, 2010 1:45 PM",
     87        "Saturday, July 3, 2010 1:45 AM",
     88        "Monday, August 2, 2010 1:45 PM",
     89        "Monday, May 3, 2010 1:45 PM",
     90      ],
     91      [
     92        "Monday, May 3, 2010 1:45 PM",
     93        "Saturday, July 3, 2010 1:45 AM",
     94        "Saturday, July 3, 2010 1:45 PM",
     95        "Monday, August 2, 2010 1:45 PM",
     96      ],
     97      ""
     98    );
     99    runTest(
    100      [
    101        "Saturday, July 3, 2010 1:45:30 PM",
    102        "Saturday, July 3, 2010 1:45:29 PM",
    103        "Monday, August 2, 2010 1:45:01 PM",
    104        "Monday, May 3, 2010 1:45:00 PM",
    105      ],
    106      [
    107        "Monday, May 3, 2010 1:45:00 PM",
    108        "Saturday, July 3, 2010 1:45:29 PM",
    109        "Saturday, July 3, 2010 1:45:30 PM",
    110        "Monday, August 2, 2010 1:45:01 PM",
    111      ],
    112      ""
    113    );
    114    runTest(
    115      ["2/15/2009 1:45 PM", "1/15/2009 1:45 PM", "2/15/2009 1:45 AM"],
    116      ["1/15/2009 1:45 PM", "2/15/2009 1:45 AM", "2/15/2009 1:45 PM"],
    117      ""
    118    );
    119    runTest(
    120      [
    121        "2010-06-15T13:45:30",
    122        "2009-06-15T13:45:30",
    123        "2009-06-15T01:45:30.2",
    124        "2009-01-15T01:45:30",
    125      ],
    126      [
    127        "2009-01-15T01:45:30",
    128        "2009-06-15T01:45:30.2",
    129        "2009-06-15T13:45:30",
    130        "2010-06-15T13:45:30",
    131      ],
    132      "ISO8601 Dates"
    133    );
    134    runTest(
    135      ["2010-06-15 13:45:30", "2009-06-15 13:45:30", "2009-01-15 01:45:30"],
    136      ["2009-01-15 01:45:30", "2009-06-15 13:45:30", "2010-06-15 13:45:30"],
    137      "ISO8601-ish YYYY-MM-DDThh:mm:ss - which does not parse into a Date instance"
    138    );
    139    runTest(
    140      [
    141        "Mon, 15 Jun 2009 20:45:30 GMT",
    142        "Mon, 15 Jun 2009 20:45:30 PDT",
    143        "Mon, 15 Jun 2009 20:45:30 EST",
    144      ],
    145      [
    146        "Mon, 15 Jun 2009 20:45:30 GMT",
    147        "Mon, 15 Jun 2009 20:45:30 EST",
    148        "Mon, 15 Jun 2009 20:45:30 PDT",
    149      ],
    150      "RFC1123 testing different timezones"
    151    );
    152    runTest(
    153      ["1245098730000", "14330728000", "1245098728000"],
    154      ["14330728000", "1245098728000", "1245098730000"],
    155      "unix epoch, Date.getTime()"
    156    );
    157    runTest(
    158      [
    159        new Date("2001-01-10"),
    160        "2015-01-01",
    161        new Date("2001-01-01"),
    162        "1998-01-01",
    163      ],
    164      [
    165        "1998-01-01",
    166        new Date("2001-01-01"),
    167        new Date("2001-01-10"),
    168        "2015-01-01",
    169      ],
    170      "mixed Date types"
    171    );
    172    runTest(
    173      [
    174        "Tue, 29 Jun 2021 11:31:17 GMT",
    175        "Sun, 14 Jun 2009 11:11:15 GMT",
    176        sessionString,
    177        "Mon, 15 Jun 2009 20:45:30 GMT",
    178      ],
    179      [
    180        sessionString,
    181        "Sun, 14 Jun 2009 11:11:15 GMT",
    182        "Mon, 15 Jun 2009 20:45:30 GMT",
    183        "Tue, 29 Jun 2021 11:31:17 GMT",
    184      ],
    185      `"${sessionString}" amongst date strings`
    186    );
    187    runTest(
    188      [
    189        "Wed, 04 Sep 2024 09:11:44 GMT",
    190        sessionString,
    191        "Tue, 06 Sep 2022 09:11:44 GMT",
    192        sessionString,
    193        "Mon, 05 Sep 2022 09:12:41 GMT",
    194      ],
    195      [
    196        sessionString,
    197        sessionString,
    198        "Mon, 05 Sep 2022 09:12:41 GMT",
    199        "Tue, 06 Sep 2022 09:11:44 GMT",
    200        "Wed, 04 Sep 2024 09:11:44 GMT",
    201      ],
    202      `"${sessionString}" amongst date strings (complex)`
    203    );
    204 
    205    runTest(
    206      [
    207        "Madras",
    208        "Jalfrezi",
    209        "Rogan Josh",
    210        "Vindaloo",
    211        "Tikka Masala",
    212        sessionString,
    213        "Masala",
    214        "Korma",
    215      ],
    216      [
    217        "Jalfrezi",
    218        "Korma",
    219        "Madras",
    220        "Masala",
    221        "Rogan Josh",
    222        sessionString,
    223        "Tikka Masala",
    224        "Vindaloo",
    225      ],
    226      `"${sessionString}" amongst strings`
    227    );
    228  });
    229 
    230  test("version number strings", function () {
    231    runTest(
    232      ["1.0.2", "1.0.1", "1.0.0", "1.0.9"],
    233      ["1.0.0", "1.0.1", "1.0.2", "1.0.9"],
    234      "close version numbers"
    235    );
    236    runTest(
    237      ["1.1.100", "1.1.1", "1.1.10", "1.1.54"],
    238      ["1.1.1", "1.1.10", "1.1.54", "1.1.100"],
    239      "more version numbers"
    240    );
    241    runTest(
    242      ["1.0.03", "1.0.003", "1.0.002", "1.0.0001"],
    243      ["1.0.0001", "1.0.002", "1.0.003", "1.0.03"],
    244      "multi-digit branch release"
    245    );
    246    runTest(
    247      [
    248        "1.1beta",
    249        "1.1.2alpha3",
    250        "1.0.2alpha3",
    251        "1.0.2alpha1",
    252        "1.0.1alpha4",
    253        "2.1.2",
    254        "2.1.1",
    255      ],
    256      [
    257        "1.0.1alpha4",
    258        "1.0.2alpha1",
    259        "1.0.2alpha3",
    260        "1.1.2alpha3",
    261        "1.1beta",
    262        "2.1.1",
    263        "2.1.2",
    264      ],
    265      "close version numbers"
    266    );
    267    runTest(
    268      [
    269        "myrelease-1.1.3",
    270        "myrelease-1.2.3",
    271        "myrelease-1.1.4",
    272        "myrelease-1.1.1",
    273        "myrelease-1.0.5",
    274      ],
    275      [
    276        "myrelease-1.0.5",
    277        "myrelease-1.1.1",
    278        "myrelease-1.1.3",
    279        "myrelease-1.1.4",
    280        "myrelease-1.2.3",
    281      ],
    282      "string first"
    283    );
    284    runTest(
    285      [
    286        "1.1.3",
    287        "a-release-1.1.3",
    288        "b-release-1.1.3",
    289        "1.2.3",
    290        "a-release-1.2.3",
    291        "b-release-1.2.3",
    292        "1.1.4",
    293        "a-release-1.1.4",
    294        "b-release-1.1.4",
    295        "1.1.1",
    296        "a-release-1.1.1",
    297        "b-release-1.1.1",
    298        "1.0.5",
    299        "a-release-1.0.5",
    300        "b-release-1.0.5",
    301      ],
    302      [
    303        "1.0.5",
    304        "1.1.1",
    305        "1.1.3",
    306        "1.1.4",
    307        "1.2.3",
    308        "a-release-1.0.5",
    309        "a-release-1.1.1",
    310        "a-release-1.1.3",
    311        "a-release-1.1.4",
    312        "a-release-1.2.3",
    313        "b-release-1.0.5",
    314        "b-release-1.1.1",
    315        "b-release-1.1.3",
    316        "b-release-1.1.4",
    317        "b-release-1.2.3",
    318      ],
    319      "string first, different names"
    320    );
    321    runTest(
    322      ["zstring", "astring", "release-1.1.3"],
    323      ["astring", "release-1.1.3", "zstring"],
    324      "string first, mixed with regular strings"
    325    );
    326  });
    327 
    328  test("numerics", function () {
    329    runTest(["10", 9, 2, "1", "4"], ["1", 2, "4", 9, "10"], "string vs number");
    330    runTest(
    331      ["0001", "002", "001"],
    332      ["0001", "001", "002"],
    333      "0 left-padded numbers"
    334    );
    335    runTest(
    336      [2, 1, "1", "0001", "002", "02", "001"],
    337      [1, "1", "0001", "001", 2, "002", "02"],
    338      "0 left-padded numbers and regular numbers"
    339    );
    340    runTest(
    341      ["10.0401", 10.022, 10.042, "10.021999"],
    342      ["10.021999", 10.022, "10.0401", 10.042],
    343      "decimal string vs decimal, different precision"
    344    );
    345    runTest(
    346      ["10.04", 10.02, 10.03, "10.01"],
    347      ["10.01", 10.02, 10.03, "10.04"],
    348      "decimal string vs decimal, same precision"
    349    );
    350    runTest(
    351      ["10.04f", "10.039F", "10.038d", "10.037D"],
    352      ["10.037D", "10.038d", "10.039F", "10.04f"],
    353      "float/decimal with 'F' or 'D' notation"
    354    );
    355    runTest(
    356      ["10.004Z", "10.039T", "10.038ooo", "10.037g"],
    357      ["10.004Z", "10.037g", "10.038ooo", "10.039T"],
    358      "not foat/decimal notation"
    359    );
    360    runTest(
    361      ["1.528535047e5", "1.528535047e7", "1.52e15", "1.528535047e3", "1.59e-3"],
    362      ["1.59e-3", "1.528535047e3", "1.528535047e5", "1.528535047e7", "1.52e15"],
    363      "scientific notation"
    364    );
    365    runTest(
    366      ["-1", "-2", "4", "-3", "0", "-5"],
    367      ["-5", "-3", "-2", "-1", "0", "4"],
    368      "negative numbers as strings"
    369    );
    370    runTest(
    371      [-1, "-2", 4, -3, "0", "-5"],
    372      ["-5", -3, "-2", -1, "0", 4],
    373      "negative numbers as strings - mixed input type, string + numeric"
    374    );
    375    runTest(
    376      [-2.01, -2.1, 4.144, 4.1, -2.001, -5],
    377      [-5, -2.1, -2.01, -2.001, 4.1, 4.144],
    378      "negative floats - all numeric"
    379    );
    380  });
    381 
    382  test("IP addresses", function () {
    383    runTest(
    384      [
    385        "192.168.0.100",
    386        "192.168.0.1",
    387        "192.168.1.1",
    388        "192.168.0.250",
    389        "192.168.1.123",
    390        "10.0.0.2",
    391        "10.0.0.1",
    392      ],
    393      [
    394        "10.0.0.1",
    395        "10.0.0.2",
    396        "192.168.0.1",
    397        "192.168.0.100",
    398        "192.168.0.250",
    399        "192.168.1.1",
    400        "192.168.1.123",
    401      ]
    402    );
    403  });
    404 
    405  test("filenames", function () {
    406    runTest(
    407      ["img12.png", "img10.png", "img2.png", "img1.png"],
    408      ["img1.png", "img2.png", "img10.png", "img12.png"],
    409      "simple image filenames"
    410    );
    411    runTest(
    412      [
    413        "car.mov",
    414        "01alpha.sgi",
    415        "001alpha.sgi",
    416        "my.string_41299.tif",
    417        "organic2.0001.sgi",
    418      ],
    419      [
    420        "001alpha.sgi",
    421        "01alpha.sgi",
    422        "car.mov",
    423        "my.string_41299.tif",
    424        "organic2.0001.sgi",
    425      ],
    426      "complex filenames"
    427    );
    428    runTest(
    429      [
    430        "./system/kernel/js/01_ui.core.js",
    431        "./system/kernel/js/00_jquery-1.3.2.js",
    432        "./system/kernel/js/02_my.desktop.js",
    433      ],
    434      [
    435        "./system/kernel/js/00_jquery-1.3.2.js",
    436        "./system/kernel/js/01_ui.core.js",
    437        "./system/kernel/js/02_my.desktop.js",
    438      ],
    439      "unix filenames"
    440    );
    441  });
    442 
    443  test("space(s) as first character(s)", function () {
    444    runTest(["alpha", " 1", "  3", " 2", 0], [0, " 1", " 2", "  3", "alpha"]);
    445  });
    446 
    447  test("empty strings and space character", function () {
    448    runTest(
    449      ["10023", "999", "", 2, 5.663, 5.6629],
    450      ["", 2, 5.6629, 5.663, "999", "10023"]
    451    );
    452    runTest([0, "0", ""], [0, "0", ""]);
    453  });
    454 
    455  test("hex", function () {
    456    runTest(["0xA", "0x9", "0x99"], ["0x9", "0xA", "0x99"], "real hex numbers");
    457    runTest(
    458      ["0xZZ", "0xVVV", "0xVEV", "0xUU"],
    459      ["0xUU", "0xVEV", "0xVVV", "0xZZ"],
    460      "fake hex numbers"
    461    );
    462  });
    463 
    464  test("unicode", function () {
    465    runTest(
    466      ["\u0044", "\u0055", "\u0054", "\u0043"],
    467      ["\u0043", "\u0044", "\u0054", "\u0055"],
    468      "basic latin"
    469    );
    470  });
    471 
    472  test("sparse array sort", function () {
    473    const sarray = [3, 2];
    474    const sarrayOutput = [1, 2, 3];
    475 
    476    sarray[10] = 1;
    477    for (let i = 0; i < 8; i++) {
    478      sarrayOutput.push(undefined);
    479    }
    480    runTest(sarray, sarrayOutput, "simple sparse array");
    481  });
    482 
    483  test("case insensitive support", function () {
    484    runTest(
    485      ["A", "b", "C", "d", "E", "f"],
    486      ["A", "b", "C", "d", "E", "f"],
    487      "case sensitive pre-sorted array",
    488      true
    489    );
    490    runTest(
    491      ["A", "C", "E", "b", "d", "f"],
    492      ["A", "b", "C", "d", "E", "f"],
    493      "case sensitive un-sorted array",
    494      true
    495    );
    496    runTest(
    497      ["A", "C", "E", "b", "d", "f"],
    498      ["A", "C", "E", "b", "d", "f"],
    499      "case sensitive pre-sorted array"
    500    );
    501    runTest(
    502      ["A", "b", "C", "d", "E", "f"],
    503      ["A", "C", "E", "b", "d", "f"],
    504      "case sensitive un-sorted array"
    505    );
    506  });
    507 
    508  test("rosetta code natural sort small test set", function () {
    509    runTest(
    510      [
    511        "ignore leading spaces: 2-2",
    512        " ignore leading spaces: 2-1",
    513        "  ignore leading spaces: 2+0",
    514        "   ignore leading spaces: 2+1",
    515      ],
    516      [
    517        "  ignore leading spaces: 2+0",
    518        "   ignore leading spaces: 2+1",
    519        " ignore leading spaces: 2-1",
    520        "ignore leading spaces: 2-2",
    521      ],
    522      "Ignoring leading spaces"
    523    );
    524    runTest(
    525      [
    526        "ignore m.a.s spaces: 2-2",
    527        "ignore m.a.s  spaces: 2-1",
    528        "ignore m.a.s   spaces: 2+0",
    529        "ignore m.a.s    spaces: 2+1",
    530      ],
    531      [
    532        "ignore m.a.s   spaces: 2+0",
    533        "ignore m.a.s    spaces: 2+1",
    534        "ignore m.a.s  spaces: 2-1",
    535        "ignore m.a.s spaces: 2-2",
    536      ],
    537      "Ignoring multiple adjacent spaces (m.a.s)"
    538    );
    539    runTest(
    540      [
    541        "Equiv. spaces: 3-3",
    542        "Equiv.\rspaces: 3-2",
    543        "Equiv.\x0cspaces: 3-1",
    544        "Equiv.\x0bspaces: 3+0",
    545        "Equiv.\nspaces: 3+1",
    546        "Equiv.\tspaces: 3+2",
    547      ],
    548      [
    549        "Equiv.\x0bspaces: 3+0",
    550        "Equiv.\nspaces: 3+1",
    551        "Equiv.\tspaces: 3+2",
    552        "Equiv.\x0cspaces: 3-1",
    553        "Equiv.\rspaces: 3-2",
    554        "Equiv. spaces: 3-3",
    555      ],
    556      "Equivalent whitespace characters"
    557    );
    558    runTest(
    559      [
    560        "cASE INDEPENENT: 3-2",
    561        "caSE INDEPENENT: 3-1",
    562        "casE INDEPENENT: 3+0",
    563        "case INDEPENENT: 3+1",
    564      ],
    565      [
    566        "casE INDEPENENT: 3+0",
    567        "case INDEPENENT: 3+1",
    568        "caSE INDEPENENT: 3-1",
    569        "cASE INDEPENENT: 3-2",
    570      ],
    571      "Case Indepenent sort (naturalSort.insensitive = true)",
    572      true
    573    );
    574    runTest(
    575      [
    576        "foo100bar99baz0.txt",
    577        "foo100bar10baz0.txt",
    578        "foo1000bar99baz10.txt",
    579        "foo1000bar99baz9.txt",
    580      ],
    581      [
    582        "foo100bar10baz0.txt",
    583        "foo100bar99baz0.txt",
    584        "foo1000bar99baz9.txt",
    585        "foo1000bar99baz10.txt",
    586      ],
    587      "Numeric fields as numerics"
    588    );
    589    runTest(
    590      [
    591        "The Wind in the Willows",
    592        "The 40th step more",
    593        "The 39 steps",
    594        "Wanda",
    595      ],
    596      [
    597        "The 39 steps",
    598        "The 40th step more",
    599        "The Wind in the Willows",
    600        "Wanda",
    601      ],
    602      "Title sorts"
    603    );
    604    runTest(
    605      [
    606        "Equiv. \xfd accents: 2-2",
    607        "Equiv. \xdd accents: 2-1",
    608        "Equiv. y accents: 2+0",
    609        "Equiv. Y accents: 2+1",
    610      ],
    611      [
    612        "Equiv. y accents: 2+0",
    613        "Equiv. Y accents: 2+1",
    614        "Equiv. \xfd accents: 2-2",
    615        "Equiv. \xdd accents: 2-1",
    616      ],
    617      "Equivalent accented characters (and case) (naturalSort.insensitive = true)",
    618      true
    619    );
    620    // This is not a valuable unicode ordering test
    621    // runTest(
    622    //   ['Start with an \u0292: 2-2', 'Start with an \u017f: 2-1', 'Start with an \xdf: 2+0', 'Start with an s: 2+1'],
    623    //   ['Start with an s: 2+1', 'Start with an \xdf: 2+0', 'Start with an \u017f: 2-1', 'Start with an \u0292: 2-2'],
    624    //   'Character replacements');
    625  });
    626 
    627  test("contributed tests", function () {
    628    runTest(
    629      [
    630        "T78",
    631        "U17",
    632        "U10",
    633        "U12",
    634        "U14",
    635        "745",
    636        "U7",
    637        "485",
    638        "S16",
    639        "S2",
    640        "S22",
    641        "1081",
    642        "S25",
    643        "1055",
    644        "779",
    645        "776",
    646        "771",
    647        "44",
    648        "4",
    649        "87",
    650        "1091",
    651        "42",
    652        "480",
    653        "952",
    654        "951",
    655        "756",
    656        "1000",
    657        "824",
    658        "770",
    659        "666",
    660        "633",
    661        "619",
    662        "1",
    663        "991",
    664        "77H",
    665        "PIER-7",
    666        "47",
    667        "29",
    668        "9",
    669        "77L",
    670        "433",
    671      ],
    672      [
    673        "1",
    674        "4",
    675        "9",
    676        "29",
    677        "42",
    678        "44",
    679        "47",
    680        "77H",
    681        "77L",
    682        "87",
    683        "433",
    684        "480",
    685        "485",
    686        "619",
    687        "633",
    688        "666",
    689        "745",
    690        "756",
    691        "770",
    692        "771",
    693        "776",
    694        "779",
    695        "824",
    696        "951",
    697        "952",
    698        "991",
    699        "1000",
    700        "1055",
    701        "1081",
    702        "1091",
    703        "PIER-7",
    704        "S2",
    705        "S16",
    706        "S22",
    707        "S25",
    708        "T78",
    709        "U7",
    710        "U10",
    711        "U12",
    712        "U14",
    713        "U17",
    714      ],
    715      "contributed by Bob Zeiner (Chrome not stable sort)"
    716    );
    717    runTest(
    718      [
    719        "FSI stop, Position: 5",
    720        "Mail Group stop, Position: 5",
    721        "Mail Group stop, Position: 5",
    722        "FSI stop, Position: 6",
    723        "FSI stop, Position: 6",
    724        "Newsstand stop, Position: 4",
    725        "Newsstand stop, Position: 4",
    726        "FSI stop, Position: 5",
    727      ],
    728      [
    729        "FSI stop, Position: 5",
    730        "FSI stop, Position: 5",
    731        "FSI stop, Position: 6",
    732        "FSI stop, Position: 6",
    733        "Mail Group stop, Position: 5",
    734        "Mail Group stop, Position: 5",
    735        "Newsstand stop, Position: 4",
    736        "Newsstand stop, Position: 4",
    737      ],
    738      "contributed by Scott"
    739    );
    740    runTest(
    741      [2, 10, 1, "azd", undefined, "asd"],
    742      [1, 2, 10, "asd", "azd", undefined],
    743      "issue #2 - undefined support - jarvinen pekka"
    744    );
    745    runTest(
    746      [undefined, undefined, undefined, 1, undefined],
    747      [1, undefined, undefined, undefined],
    748      "issue #2 - undefined support - jarvinen pekka"
    749    );
    750    runTest(
    751      ["-1", "-2", "4", "-3", "0", "-5"],
    752      ["-5", "-3", "-2", "-1", "0", "4"],
    753      "issue #3 - invalid numeric string sorting - guilermo.dev"
    754    );
    755    // native sort implementations are not guaranteed to be stable (i.e. Chrome)
    756    // runTest(
    757    //  ['9','11','22','99','A','aaaa','bbbb','Aaaa','aAaa','aa','AA','Aa','aA','BB','bB','aaA','AaA','aaa'],
    758    //  ['9', '11', '22', '99', 'A', 'aa', 'AA', 'Aa', 'aA', 'aaA', 'AaA', 'aaa', 'aaaa', 'Aaaa', 'aAaa', 'BB', 'bB', 'bbbb'],
    759    //  'issue #5 - invalid sort order - Howie Schecter (naturalSort.insensitive = true)'m true);
    760    runTest(
    761      [
    762        "9",
    763        "11",
    764        "22",
    765        "99",
    766        "A",
    767        "aaaa",
    768        "bbbb",
    769        "Aaaa",
    770        "aAaa",
    771        "aa",
    772        "AA",
    773        "Aa",
    774        "aA",
    775        "BB",
    776        "bB",
    777        "aaA",
    778        "AaA",
    779        "aaa",
    780      ],
    781      [
    782        "9",
    783        "11",
    784        "22",
    785        "99",
    786        "A",
    787        "AA",
    788        "Aa",
    789        "AaA",
    790        "Aaaa",
    791        "BB",
    792        "aA",
    793        "aAaa",
    794        "aa",
    795        "aaA",
    796        "aaa",
    797        "aaaa",
    798        "bB",
    799        "bbbb",
    800      ],
    801      "issue #5 - invalid sort order - Howie Schecter (naturalSort.insensitive = false)"
    802    );
    803    runTest(
    804      [
    805        "5D",
    806        "1A",
    807        "2D",
    808        "33A",
    809        "5E",
    810        "33K",
    811        "33D",
    812        "5S",
    813        "2C",
    814        "5C",
    815        "5F",
    816        "1D",
    817        "2M",
    818      ],
    819      [
    820        "1A",
    821        "1D",
    822        "2C",
    823        "2D",
    824        "2M",
    825        "5C",
    826        "5D",
    827        "5E",
    828        "5F",
    829        "5S",
    830        "33A",
    831        "33D",
    832        "33K",
    833      ],
    834      "alphanumeric - number first"
    835    );
    836    runTest(
    837      ["img 99", "img199", "imga99", "imgz99"],
    838      ["img 99", "img199", "imga99", "imgz99"],
    839      "issue #16 - Sorting incorrect when there is a space - adrien-be"
    840    );
    841    runTest(
    842      ["img199", "img 99", "imga99", "imgz 99", "imgb99", "imgz199"],
    843      ["img 99", "img199", "imga99", "imgb99", "imgz 99", "imgz199"],
    844      "issue #16 - expanded test"
    845    );
    846    runTest(
    847      ["1", "02", "3"],
    848      ["1", "02", "3"],
    849      "issue #18 - Any zeros that precede a number messes up the sorting - menixator"
    850    );
    851    // strings are coerced as floats/ints if possible and sorted accordingly - e.g. they are not chunked
    852    runTest(
    853      ["1.100", "1.1", "1.10", "1.54"],
    854      ["1.100", "1.1", "1.10", "1.54"],
    855      "issue #13 - ['1.100', '1.10', '1.1', '1.54'] etc do not sort properly... - rubenstolk"
    856    );
    857    runTest(
    858      ["v1.100", "v1.1", "v1.10", "v1.54"],
    859      ["v1.1", "v1.10", "v1.54", "v1.100"],
    860      "issue #13 - ['v1.100', 'v1.10', 'v1.1', 'v1.54'] etc do not sort properly... - rubenstolk (bypass float coercion)"
    861    );
    862    runTest(
    863      [
    864        "MySnmp 1234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    865        "MySnmp 4234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    866        "MySnmp 2234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    867        "MySnmp 3234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    868      ],
    869      [
    870        "MySnmp 1234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    871        "MySnmp 2234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    872        "MySnmp 3234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    873        "MySnmp 4234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567",
    874      ],
    875      "issue #14 - Very large numbers make sorting very slow - Mottie"
    876    );
    877    runTest(
    878      ["bar.1-2", "bar.1"],
    879      ["bar.1", "bar.1-2"],
    880      "issue #21 - javascript error"
    881    );
    882    runTest(
    883      ["SomeString", "SomeString 1"],
    884      ["SomeString", "SomeString 1"],
    885      "PR #19 - ['SomeString', 'SomeString 1'] bombing on 'undefined is not an object' - dannycochran"
    886    );
    887    runTest(
    888      [
    889        "Udet",
    890        "\xDCbelacker",
    891        "Uell",
    892        "\xDClle",
    893        "Ueve",
    894        "\xDCxk\xFCll",
    895        "Uffenbach",
    896      ],
    897      [
    898        "\xDCbelacker",
    899        "Udet",
    900        "Uell",
    901        "Ueve",
    902        "Uffenbach",
    903        "\xDClle",
    904        "\xDCxk\xFCll",
    905      ],
    906      "issue #9 - Sorting umlauts characters \xC4, \xD6, \xDC - diogoalves"
    907    );
    908    runTest(
    909      ["2.2 sec", "1.9 sec", "1.53 sec"],
    910      ["1.53 sec", "1.9 sec", "2.2 sec"],
    911      "https://github.com/overset/javascript-natural-sort/issues/13 - ['2.2 sec','1.9 sec','1.53 sec'] - padded by spaces - harisb"
    912    );
    913    runTest(
    914      ["2.2sec", "1.9sec", "1.53sec"],
    915      ["1.53sec", "1.9sec", "2.2sec"],
    916      "https://github.com/overset/javascript-natural-sort/issues/13 - ['2.2sec','1.9sec','1.53sec'] - no padding - harisb"
    917    );
    918  });
    919 }
    920 
    921 function test(description, testFunc) {
    922  info(description);
    923  testFunc();
    924 }
    925 
    926 function runTest(testArray, expected, description, caseInsensitive = false) {
    927  let actual = null;
    928 
    929  if (caseInsensitive) {
    930    actual = testArray.sort((a, b) =>
    931      naturalSortCaseInsensitive(a, b, sessionString)
    932    );
    933  } else {
    934    actual = testArray.sort((a, b) =>
    935      naturalSortCaseSensitive(a, b, sessionString)
    936    );
    937  }
    938 
    939  compareOptions(actual, expected, description);
    940 }
    941 
    942 // deepEqual() doesn't work well for testing arrays containing `undefined` so
    943 // we need to use a custom method.
    944 function compareOptions(actual, expected, description) {
    945  let match = true;
    946  for (let i = 0; i < actual.length; i++) {
    947    if (actual[i] + "" !== expected[i] + "") {
    948      ok(
    949        false,
    950        `${description}\nElement ${i} does not match:\n[${i}] ${actual[i]}\n[${i}] ${expected[i]}`
    951      );
    952      match = false;
    953      break;
    954    }
    955  }
    956  if (match) {
    957    ok(true, description);
    958  }
    959 }