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.

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

mercurial