Wed, 31 Dec 2014 06:09:35 +0100
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 }