browser/devtools/styleinspector/test/unit/test_parseDeclarations.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* Any copyright is dedicated to the Public Domain.
     4    http://creativecommons.org/publicdomain/zero/1.0/ */
     6 const Cu = Components.utils;
     7 Cu.import("resource://gre/modules/devtools/Loader.jsm");
     8 const {parseDeclarations} = devtools.require("devtools/styleinspector/css-parsing-utils");
    10 const TEST_DATA = [
    11   // Simple test
    12   {
    13     input: "p:v;",
    14     expected: [{name: "p", value: "v", priority: ""}]
    15   },
    16   // Simple test
    17   {
    18     input: "this:is;a:test;",
    19     expected: [
    20       {name: "this", value: "is", priority: ""},
    21       {name: "a", value: "test", priority: ""}
    22     ]
    23   },
    24   // Test a single declaration with semi-colon
    25   {
    26     input: "name:value;",
    27     expected: [{name: "name", value: "value", priority: ""}]
    28   },
    29   // Test a single declaration without semi-colon
    30   {
    31     input: "name:value",
    32     expected: [{name: "name", value: "value", priority: ""}]
    33   },
    34   // Test multiple declarations separated by whitespaces and carriage returns and tabs
    35   {
    36     input: "p1 : v1 ; \t\t  \n p2:v2;   \n\n\n\n\t  p3    :   v3;",
    37     expected: [
    38       {name: "p1", value: "v1", priority: ""},
    39       {name: "p2", value: "v2", priority: ""},
    40       {name: "p3", value: "v3", priority: ""},
    41     ]
    42   },
    43   // Test simple priority
    44   {
    45     input: "p1: v1; p2: v2 !important;",
    46     expected: [
    47       {name: "p1", value: "v1", priority: ""},
    48       {name: "p2", value: "v2", priority: "important"}
    49     ]
    50   },
    51   // Test simple priority
    52   {
    53     input: "p1: v1 !important; p2: v2",
    54     expected: [
    55       {name: "p1", value: "v1", priority: "important"},
    56       {name: "p2", value: "v2", priority: ""}
    57     ]
    58   },
    59   // Test simple priority
    60   {
    61     input: "p1: v1 !  important; p2: v2 ! important;",
    62     expected: [
    63       {name: "p1", value: "v1", priority: "important"},
    64       {name: "p2", value: "v2", priority: "important"}
    65     ]
    66   },
    67   // Test invalid priority
    68   {
    69     input: "p1: v1 important;",
    70     expected: [
    71       {name: "p1", value: "v1 important", priority: ""}
    72     ]
    73   },
    74   // Test various types of background-image urls
    75   {
    76     input: "background-image: url(../../relative/image.png)",
    77     expected: [{name: "background-image", value: "url(\"../../relative/image.png\")", priority: ""}]
    78   },
    79   {
    80     input: "background-image: url(http://site.com/test.png)",
    81     expected: [{name: "background-image", value: "url(\"http://site.com/test.png\")", priority: ""}]
    82   },
    83   {
    84     input: "background-image: url(wow.gif)",
    85     expected: [{name: "background-image", value: "url(\"wow.gif\")", priority: ""}]
    86   },
    87   // Test that urls with :;{} characters in them are parsed correctly
    88   {
    89     input: "background: red url(\"http://site.com/image{}:;.png?id=4#wat\") repeat top right",
    90     expected: [
    91       {name: "background", value: "red url(\"http://site.com/image{}:;.png?id=4#wat\") repeat top right", priority: ""}
    92     ]
    93   },
    94   // Test that an empty string results in an empty array
    95   {input: "", expected: []},
    96   // Test that a string comprised only of whitespaces results in an empty array
    97   {input: "       \n \n   \n   \n \t  \t\t\t  ", expected: []},
    98   // Test that a null input throws an exception
    99   {input: null, throws: true},
   100   // Test that a undefined input throws an exception
   101   {input: undefined, throws: true},
   102   // Test that :;{} characters in quoted content are not parsed as multiple declarations
   103   {
   104     input: "content: \";color:red;}selector{color:yellow;\"",
   105     expected: [
   106       {name: "content", value: "\";color:red;}selector{color:yellow;\"", priority: ""}
   107     ]
   108   },
   109   // Test that rules aren't parsed, just declarations. So { and } found after a
   110   // property name should be part of the property name, same for values.
   111   {
   112     input: "body {color:red;} p {color: blue;}",
   113     expected: [
   114       {name: "body {color", value: "red", priority: ""},
   115       {name: "} p {color", value: "blue", priority: ""},
   116       {name: "}", value: "", priority: ""}
   117     ]
   118   },
   119   // Test unbalanced : and ;
   120   {
   121     input: "color :red : font : arial;",
   122     expected : [
   123       {name: "color", value: "red : font : arial", priority: ""}
   124     ]
   125   },
   126   {input: "background: red;;;;;", expected: [{name: "background", value: "red", priority: ""}]},
   127   {input: "background:;", expected: [{name: "background", value: "", priority: ""}]},
   128   {input: ";;;;;", expected: []},
   129   {input: ":;:;", expected: []},
   130   // Test name only
   131   {input: "color", expected: [
   132     {name: "color", value: "", priority: ""}
   133   ]},
   134   // Test trailing name without :
   135   {input: "color:blue;font", expected: [
   136     {name: "color", value: "blue", priority: ""},
   137     {name: "font", value: "", priority: ""}
   138   ]},
   139   // Test trailing name with :
   140   {input: "color:blue;font:", expected: [
   141     {name: "color", value: "blue", priority: ""},
   142     {name: "font", value: "", priority: ""}
   143   ]},
   144   // Test leading value
   145   {input: "Arial;color:blue;", expected: [
   146     {name: "", value: "Arial", priority: ""},
   147     {name: "color", value: "blue", priority: ""}
   148   ]},
   149   // Test hex colors
   150   {input: "color: #333", expected: [{name: "color", value: "#333", priority: ""}]},
   151   {input: "color: #456789", expected: [{name: "color", value: "#456789", priority: ""}]},
   152   {input: "wat: #XYZ", expected: [{name: "wat", value: "#XYZ", priority: ""}]},
   153   // Test string/url quotes escaping
   154   {input: "content: \"this is a 'string'\"", expected: [{name: "content", value: "\"this is a 'string'\"", priority: ""}]},
   155   {input: 'content: "this is a \\"string\\""', expected: [{name: "content", value: '\'this is a "string"\'', priority: ""}]},
   156   {input: "content: 'this is a \"string\"'", expected: [{name: "content", value: '\'this is a "string"\'', priority: ""}]},
   157   {input: "content: 'this is a \\'string\\'", expected: [{name: "content", value: '"this is a \'string\'"', priority: ""}]},
   158   {input: "content: 'this \\' is a \" really strange string'", expected: [{name: "content", value: '"this \' is a \" really strange string"', priority: ""}]},
   159   {
   160     input: "content: \"a not s\\\
   161           o very long title\"",
   162     expected: [
   163       {name: "content", value: '"a not s\
   164           o very long title"', priority: ""}
   165     ]
   166   }
   167 ];
   169 function run_test() {
   170   for (let test of TEST_DATA) {
   171     do_print("Test input string " + test.input);
   172     let output;
   173     try {
   174       output = parseDeclarations(test.input);
   175     } catch (e) {
   176       do_print("parseDeclarations threw an exception with the given input string");
   177       if (test.throws) {
   178         do_print("Exception expected");
   179         do_check_true(true);
   180       } else {
   181         do_print("Exception unexpected\n" + e);
   182         do_check_true(false);
   183       }
   184     }
   185     if (output) {
   186       assertOutput(output, test.expected);
   187     }
   188   }
   189 }
   191 function assertOutput(actual, expected) {
   192   if (actual.length === expected.length) {
   193     for (let i = 0; i < expected.length; i ++) {
   194       do_check_true(!!actual[i]);
   195       do_print("Check that the output item has the expected name, value and priority");
   196       do_check_eq(expected[i].name, actual[i].name);
   197       do_check_eq(expected[i].value, actual[i].value);
   198       do_check_eq(expected[i].priority, actual[i].priority);
   199     }
   200   } else {
   201     for (let prop of actual) {
   202       do_print("Actual output contained: {name: "+prop.name+", value: "+prop.value+", priority: "+prop.priority+"}");
   203     }
   204     do_check_eq(actual.length, expected.length);
   205   }
   206 }

mercurial