tor-browser

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

test_parsePseudoClassesAndAttributes.js (5013B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const {
      7  parsePseudoClassesAndAttributes,
      8  SELECTOR_ATTRIBUTE,
      9  SELECTOR_ELEMENT,
     10  SELECTOR_PSEUDO_CLASS,
     11 } = require("resource://devtools/shared/css/parsing-utils.js");
     12 
     13 const TEST_DATA = [
     14  // Test that a null input throws an exception
     15  {
     16    input: null,
     17    throws: true,
     18  },
     19  // Test that a undefined input throws an exception
     20  {
     21    input: undefined,
     22    throws: true,
     23  },
     24  {
     25    input: ":root",
     26    expected: [{ value: ":root", type: SELECTOR_PSEUDO_CLASS }],
     27  },
     28  {
     29    input: ".testclass",
     30    expected: [{ value: ".testclass", type: SELECTOR_ELEMENT }],
     31  },
     32  {
     33    input: "div p",
     34    expected: [{ value: "div p", type: SELECTOR_ELEMENT }],
     35  },
     36  {
     37    input: "div > p",
     38    expected: [{ value: "div > p", type: SELECTOR_ELEMENT }],
     39  },
     40  {
     41    input: "a[hidden]",
     42    expected: [
     43      { value: "a", type: SELECTOR_ELEMENT },
     44      { value: "[hidden]", type: SELECTOR_ATTRIBUTE },
     45    ],
     46  },
     47  {
     48    input: "a[hidden=true]",
     49    expected: [
     50      { value: "a", type: SELECTOR_ELEMENT },
     51      { value: "[hidden=true]", type: SELECTOR_ATTRIBUTE },
     52    ],
     53  },
     54  {
     55    input: "a[hidden=true] p:hover",
     56    expected: [
     57      { value: "a", type: SELECTOR_ELEMENT },
     58      { value: "[hidden=true]", type: SELECTOR_ATTRIBUTE },
     59      { value: " p", type: SELECTOR_ELEMENT },
     60      { value: ":hover", type: SELECTOR_PSEUDO_CLASS },
     61    ],
     62  },
     63  {
     64    input: 'a[checked="true"]',
     65    expected: [
     66      { value: "a", type: SELECTOR_ELEMENT },
     67      { value: '[checked="true"]', type: SELECTOR_ATTRIBUTE },
     68    ],
     69  },
     70  {
     71    input: "a[title~=test]",
     72    expected: [
     73      { value: "a", type: SELECTOR_ELEMENT },
     74      { value: "[title~=test]", type: SELECTOR_ATTRIBUTE },
     75    ],
     76  },
     77  {
     78    input: 'h1[hidden="true"][title^="Important"]',
     79    expected: [
     80      { value: "h1", type: SELECTOR_ELEMENT },
     81      { value: '[hidden="true"]', type: SELECTOR_ATTRIBUTE },
     82      { value: '[title^="Important"]', type: SELECTOR_ATTRIBUTE },
     83    ],
     84  },
     85  {
     86    input: "p:hover",
     87    expected: [
     88      { value: "p", type: SELECTOR_ELEMENT },
     89      { value: ":hover", type: SELECTOR_PSEUDO_CLASS },
     90    ],
     91  },
     92  {
     93    input: "p + .testclass:hover",
     94    expected: [
     95      { value: "p + .testclass", type: SELECTOR_ELEMENT },
     96      { value: ":hover", type: SELECTOR_PSEUDO_CLASS },
     97    ],
     98  },
     99  {
    100    input: "p::before",
    101    expected: [
    102      { value: "p", type: SELECTOR_ELEMENT },
    103      { value: "::before", type: SELECTOR_PSEUDO_CLASS },
    104    ],
    105  },
    106  {
    107    input: "p:nth-child(2)",
    108    expected: [
    109      { value: "p", type: SELECTOR_ELEMENT },
    110      { value: ":nth-child(2)", type: SELECTOR_PSEUDO_CLASS },
    111    ],
    112  },
    113  {
    114    input: 'p:not([title="test"]) .testclass',
    115    expected: [
    116      { value: "p", type: SELECTOR_ELEMENT },
    117      { value: ':not([title="test"])', type: SELECTOR_PSEUDO_CLASS },
    118      { value: " .testclass", type: SELECTOR_ELEMENT },
    119    ],
    120  },
    121  {
    122    input: "a\\:hover",
    123    expected: [{ value: "a\\:hover", type: SELECTOR_ELEMENT }],
    124  },
    125  {
    126    input: ":not(:lang(it))",
    127    expected: [{ value: ":not(:lang(it))", type: SELECTOR_PSEUDO_CLASS }],
    128  },
    129  {
    130    input: "p:not(:lang(it))",
    131    expected: [
    132      { value: "p", type: SELECTOR_ELEMENT },
    133      { value: ":not(:lang(it))", type: SELECTOR_PSEUDO_CLASS },
    134    ],
    135  },
    136  {
    137    input: "p:not(p:lang(it))",
    138    expected: [
    139      { value: "p", type: SELECTOR_ELEMENT },
    140      { value: ":not(p:lang(it))", type: SELECTOR_PSEUDO_CLASS },
    141    ],
    142  },
    143  {
    144    input: ":not(:lang(it)",
    145    expected: [{ value: ":not(:lang(it)", type: SELECTOR_ELEMENT }],
    146  },
    147  {
    148    input: ":not(:lang(it)))",
    149    expected: [
    150      { value: ":not(:lang(it))", type: SELECTOR_PSEUDO_CLASS },
    151      { value: ")", type: SELECTOR_ELEMENT },
    152    ],
    153  },
    154 ];
    155 
    156 function run_test() {
    157  for (const test of TEST_DATA) {
    158    dump("Test input string " + test.input + "\n");
    159    let output;
    160 
    161    try {
    162      output = parsePseudoClassesAndAttributes(test.input);
    163    } catch (e) {
    164      dump(
    165        "parsePseudoClassesAndAttributes threw an exception with the " +
    166          "given input string\n"
    167      );
    168      if (test.throws) {
    169        ok(true, "Exception expected");
    170      } else {
    171        dump();
    172        ok(false, "Exception unexpected\n" + e);
    173      }
    174    }
    175 
    176    if (output) {
    177      assertOutput(output, test.expected);
    178    }
    179  }
    180 }
    181 
    182 function assertOutput(actual, expected) {
    183  if (actual.length === expected.length) {
    184    for (let i = 0; i < expected.length; i++) {
    185      dump("Check that the output item has the expected value and type\n");
    186      ok(!!actual[i]);
    187      equal(expected[i].value, actual[i].value);
    188      equal(expected[i].type, actual[i].type);
    189    }
    190  } else {
    191    for (const prop of actual) {
    192      dump(
    193        "Actual output contained: {value: " +
    194          prop.value +
    195          ", type: " +
    196          prop.type +
    197          "}\n"
    198      );
    199    }
    200    equal(actual.length, expected.length);
    201  }
    202 }