OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 "use strict"; | 18 "use strict"; |
19 | 19 |
| 20 const assert = require("assert"); |
20 const {createSandbox} = require("./_common"); | 21 const {createSandbox} = require("./_common"); |
21 | 22 |
22 let ElemHide = null; | 23 let ElemHide = null; |
23 let createStyleSheet = null; | 24 let createStyleSheet = null; |
24 let rulesFromStyleSheet = null; | 25 let rulesFromStyleSheet = null; |
25 let ElemHideExceptions = null; | 26 let ElemHideExceptions = null; |
26 let Filter = null; | 27 let Filter = null; |
27 let filtersByDomain = null; | 28 let filtersByDomain = null; |
28 let selectorGroupSize = null; | 29 let selectorGroupSize = null; |
29 | 30 |
30 exports.setUp = function(callback) | 31 describe("ElemHide", () => |
31 { | 32 { |
32 let sandboxedRequire = createSandbox({ | 33 beforeEach(() => |
33 extraExports: { | 34 { |
34 elemHide: ["filtersByDomain", "selectorGroupSize"] | 35 let sandboxedRequire = createSandbox({ |
| 36 extraExports: { |
| 37 elemHide: ["filtersByDomain", "selectorGroupSize"] |
| 38 } |
| 39 }); |
| 40 ( |
| 41 {ElemHide, createStyleSheet, rulesFromStyleSheet, |
| 42 filtersByDomain, selectorGroupSize} = sandboxedRequire("../lib/elemHide")
, |
| 43 {ElemHideExceptions} = sandboxedRequire("../lib/elemHideExceptions"), |
| 44 {Filter} = sandboxedRequire("../lib/filterClasses") |
| 45 ); |
| 46 }); |
| 47 |
| 48 function normalizeSelectors(selectors) |
| 49 { |
| 50 // generateStyleSheetForDomain is currently allowed to return duplicate |
| 51 // selectors for performance reasons, so we need to remove duplicates here. |
| 52 return selectors.slice().sort().filter((selector, index, sortedSelectors) => |
| 53 { |
| 54 return index == 0 || selector != sortedSelectors[index - 1]; |
| 55 }); |
| 56 } |
| 57 |
| 58 function testResult(domain, expectedSelectors, specificOnly) |
| 59 { |
| 60 let normalizedExpectedSelectors = normalizeSelectors(expectedSelectors); |
| 61 |
| 62 let {code, selectors} = |
| 63 ElemHide.generateStyleSheetForDomain(domain, specificOnly, true); |
| 64 |
| 65 assert.deepEqual(normalizeSelectors(selectors), normalizedExpectedSelectors)
; |
| 66 |
| 67 // Make sure each expected selector is in the actual CSS code. |
| 68 for (let selector of normalizedExpectedSelectors) |
| 69 { |
| 70 assert.ok(code.includes(selector + ", ") || |
| 71 code.includes(selector + " {display: none !important;}\n")); |
35 } | 72 } |
36 }); | |
37 ( | |
38 {ElemHide, createStyleSheet, rulesFromStyleSheet, | |
39 filtersByDomain, selectorGroupSize} = sandboxedRequire("../lib/elemHide"), | |
40 {ElemHideExceptions} = sandboxedRequire("../lib/elemHideExceptions"), | |
41 {Filter} = sandboxedRequire("../lib/filterClasses") | |
42 ); | |
43 | |
44 callback(); | |
45 }; | |
46 | |
47 function normalizeSelectors(selectors) | |
48 { | |
49 // generateStyleSheetForDomain is currently allowed to return duplicate | |
50 // selectors for performance reasons, so we need to remove duplicates here. | |
51 return selectors.slice().sort().filter((selector, index, sortedSelectors) => | |
52 { | |
53 return index == 0 || selector != sortedSelectors[index - 1]; | |
54 }); | |
55 } | |
56 | |
57 function testResult(test, domain, expectedSelectors, specificOnly) | |
58 { | |
59 let normalizedExpectedSelectors = normalizeSelectors(expectedSelectors); | |
60 | |
61 let {code, selectors} = | |
62 ElemHide.generateStyleSheetForDomain(domain, specificOnly, true); | |
63 | |
64 test.deepEqual(normalizeSelectors(selectors), normalizedExpectedSelectors); | |
65 | |
66 // Make sure each expected selector is in the actual CSS code. | |
67 for (let selector of normalizedExpectedSelectors) | |
68 { | |
69 test.ok(code.includes(selector + ", ") || | |
70 code.includes(selector + " {display: none !important;}\n")); | |
71 } | 73 } |
72 } | 74 |
73 | 75 it("Generating Style Sheet", () => |
74 exports.testGenerateStyleSheetForDomain = function(test) | 76 { |
75 { | 77 let addFilter = filterText => ElemHide.add(Filter.fromText(filterText)); |
76 let addFilter = filterText => ElemHide.add(Filter.fromText(filterText)); | 78 let removeFilter = |
77 let removeFilter = filterText => ElemHide.remove(Filter.fromText(filterText)); | 79 filterText => ElemHide.remove(Filter.fromText(filterText)); |
78 let addException = | 80 let addException = |
79 filterText => ElemHideExceptions.add(Filter.fromText(filterText)); | 81 filterText => ElemHideExceptions.add(Filter.fromText(filterText)); |
80 let removeException = | 82 let removeException = |
81 filterText => ElemHideExceptions.remove(Filter.fromText(filterText)); | 83 filterText => ElemHideExceptions.remove(Filter.fromText(filterText)); |
82 | 84 |
83 testResult(test, "", []); | 85 testResult("", []); |
84 | 86 |
85 addFilter("~foo.example.com,example.com##foo"); | 87 addFilter("~foo.example.com,example.com##foo"); |
86 testResult(test, "barfoo.example.com", ["foo"]); | 88 testResult("barfoo.example.com", ["foo"]); |
87 testResult(test, "bar.foo.example.com", []); | 89 testResult("bar.foo.example.com", []); |
88 testResult(test, "foo.example.com", []); | 90 testResult("foo.example.com", []); |
89 testResult(test, "example.com", ["foo"]); | 91 testResult("example.com", ["foo"]); |
90 testResult(test, "com", []); | 92 testResult("com", []); |
91 testResult(test, "", []); | 93 testResult("", []); |
92 | 94 |
93 addFilter("foo.example.com##turnip"); | 95 addFilter("foo.example.com##turnip"); |
94 testResult(test, "foo.example.com", ["turnip"]); | 96 testResult("foo.example.com", ["turnip"]); |
95 testResult(test, "example.com", ["foo"]); | 97 testResult("example.com", ["foo"]); |
96 testResult(test, "com", []); | 98 testResult("com", []); |
97 testResult(test, "", []); | 99 testResult("", []); |
98 | 100 |
99 addException("example.com#@#foo"); | 101 addException("example.com#@#foo"); |
100 testResult(test, "foo.example.com", ["turnip"]); | 102 testResult("foo.example.com", ["turnip"]); |
101 testResult(test, "example.com", []); | 103 testResult("example.com", []); |
102 testResult(test, "com", []); | 104 testResult("com", []); |
103 testResult(test, "", []); | 105 testResult("", []); |
104 | 106 |
105 addFilter("com##bar"); | 107 addFilter("com##bar"); |
106 testResult(test, "foo.example.com", ["turnip", "bar"]); | 108 testResult("foo.example.com", ["turnip", "bar"]); |
107 testResult(test, "example.com", ["bar"]); | 109 testResult("example.com", ["bar"]); |
108 testResult(test, "com", ["bar"]); | 110 testResult("com", ["bar"]); |
109 testResult(test, "", []); | 111 testResult("", []); |
110 | 112 |
111 addException("example.com#@#bar"); | 113 addException("example.com#@#bar"); |
112 testResult(test, "foo.example.com", ["turnip"]); | 114 testResult("foo.example.com", ["turnip"]); |
113 testResult(test, "example.com", []); | 115 testResult("example.com", []); |
114 testResult(test, "com", ["bar"]); | 116 testResult("com", ["bar"]); |
115 testResult(test, "", []); | 117 testResult("", []); |
116 | 118 |
117 removeException("example.com#@#foo"); | 119 removeException("example.com#@#foo"); |
118 testResult(test, "foo.example.com", ["turnip"]); | 120 testResult("foo.example.com", ["turnip"]); |
119 testResult(test, "example.com", ["foo"]); | 121 testResult("example.com", ["foo"]); |
120 testResult(test, "com", ["bar"]); | 122 testResult("com", ["bar"]); |
121 testResult(test, "", []); | 123 testResult("", []); |
122 | 124 |
123 removeException("example.com#@#bar"); | 125 removeException("example.com#@#bar"); |
124 testResult(test, "foo.example.com", ["turnip", "bar"]); | 126 testResult("foo.example.com", ["turnip", "bar"]); |
125 testResult(test, "example.com", ["foo", "bar"]); | 127 testResult("example.com", ["foo", "bar"]); |
126 testResult(test, "com", ["bar"]); | 128 testResult("com", ["bar"]); |
127 testResult(test, "", []); | 129 testResult("", []); |
128 | 130 |
129 addFilter("##generic"); | 131 addFilter("##generic"); |
130 testResult(test, "foo.example.com", ["turnip", "bar", "generic"]); | 132 testResult("foo.example.com", ["turnip", "bar", "generic"]); |
131 testResult(test, "example.com", ["foo", "bar", "generic"]); | 133 testResult("example.com", ["foo", "bar", "generic"]); |
132 testResult(test, "com", ["bar", "generic"]); | 134 testResult("com", ["bar", "generic"]); |
133 testResult(test, "", ["generic"]); | 135 testResult("", ["generic"]); |
134 testResult(test, "foo.example.com", ["turnip", "bar"], true); | 136 testResult("foo.example.com", ["turnip", "bar"], true); |
135 testResult(test, "example.com", ["foo", "bar"], true); | 137 testResult("example.com", ["foo", "bar"], true); |
136 testResult(test, "com", ["bar"], true); | 138 testResult("com", ["bar"], true); |
137 testResult(test, "", [], true); | 139 testResult("", [], true); |
138 removeFilter("##generic"); | 140 removeFilter("##generic"); |
139 | 141 |
140 addFilter("~adblockplus.org##example"); | 142 addFilter("~adblockplus.org##example"); |
141 testResult(test, "adblockplus.org", []); | 143 testResult("adblockplus.org", []); |
142 testResult(test, "", ["example"]); | 144 testResult("", ["example"]); |
143 testResult(test, "foo.example.com", ["turnip", "bar", "example"]); | 145 testResult("foo.example.com", ["turnip", "bar", "example"]); |
144 testResult(test, "foo.example.com", ["turnip", "bar"], true); | 146 testResult("foo.example.com", ["turnip", "bar"], true); |
145 removeFilter("~adblockplus.org##example"); | 147 removeFilter("~adblockplus.org##example"); |
146 | 148 |
147 removeFilter("~foo.example.com,example.com##foo"); | 149 removeFilter("~foo.example.com,example.com##foo"); |
148 testResult(test, "foo.example.com", ["turnip", "bar"]); | 150 testResult("foo.example.com", ["turnip", "bar"]); |
149 testResult(test, "example.com", ["bar"]); | 151 testResult("example.com", ["bar"]); |
150 testResult(test, "com", ["bar"]); | 152 testResult("com", ["bar"]); |
151 testResult(test, "", []); | 153 testResult("", []); |
152 | 154 |
153 removeFilter("com##bar"); | 155 removeFilter("com##bar"); |
154 testResult(test, "foo.example.com", ["turnip"]); | 156 testResult("foo.example.com", ["turnip"]); |
155 testResult(test, "example.com", []); | 157 testResult("example.com", []); |
156 testResult(test, "com", []); | 158 testResult("com", []); |
157 testResult(test, "", []); | 159 testResult("", []); |
158 | 160 |
159 removeFilter("foo.example.com##turnip"); | 161 removeFilter("foo.example.com##turnip"); |
160 testResult(test, "foo.example.com", []); | 162 testResult("foo.example.com", []); |
161 testResult(test, "example.com", []); | 163 testResult("example.com", []); |
162 testResult(test, "com", []); | 164 testResult("com", []); |
163 testResult(test, "", []); | 165 testResult("", []); |
164 | 166 |
165 addFilter("example.com##dupe"); | 167 addFilter("example.com##dupe"); |
166 addFilter("example.com##dupe"); | 168 addFilter("example.com##dupe"); |
167 testResult(test, "example.com", ["dupe"]); | 169 testResult("example.com", ["dupe"]); |
168 removeFilter("example.com##dupe"); | 170 removeFilter("example.com##dupe"); |
169 testResult(test, "example.com", []); | 171 testResult("example.com", []); |
170 removeFilter("example.com##dupe"); | 172 removeFilter("example.com##dupe"); |
171 | 173 |
172 addFilter("~foo.example.com,example.com##foo"); | 174 addFilter("~foo.example.com,example.com##foo"); |
173 | 175 |
174 addFilter("##foo"); | 176 addFilter("##foo"); |
175 testResult(test, "foo.example.com", ["foo"]); | 177 testResult("foo.example.com", ["foo"]); |
176 testResult(test, "example.com", ["foo"]); | 178 testResult("example.com", ["foo"]); |
177 testResult(test, "com", ["foo"]); | 179 testResult("com", ["foo"]); |
178 testResult(test, "", ["foo"]); | 180 testResult("", ["foo"]); |
179 removeFilter("##foo"); | 181 removeFilter("##foo"); |
180 | 182 |
181 addFilter("example.org##foo"); | 183 addFilter("example.org##foo"); |
182 testResult(test, "foo.example.com", []); | 184 testResult("foo.example.com", []); |
183 testResult(test, "example.com", ["foo"]); | 185 testResult("example.com", ["foo"]); |
184 testResult(test, "com", []); | 186 testResult("com", []); |
185 testResult(test, "", []); | 187 testResult("", []); |
186 removeFilter("example.org##foo"); | 188 removeFilter("example.org##foo"); |
187 | 189 |
188 addFilter("~example.com##foo"); | 190 addFilter("~example.com##foo"); |
189 testResult(test, "foo.example.com", []); | 191 testResult("foo.example.com", []); |
190 testResult(test, "example.com", ["foo"]); | 192 testResult("example.com", ["foo"]); |
191 testResult(test, "com", ["foo"]); | 193 testResult("com", ["foo"]); |
192 testResult(test, "", ["foo"]); | 194 testResult("", ["foo"]); |
193 removeFilter("~example.com##foo"); | 195 removeFilter("~example.com##foo"); |
194 | 196 |
195 removeFilter("~foo.example.com,example.com##foo"); | 197 removeFilter("~foo.example.com,example.com##foo"); |
196 | 198 |
197 // Test criteria | 199 // Test criteria |
198 addFilter("##hello"); | 200 addFilter("##hello"); |
199 addFilter("~example.com##world"); | 201 addFilter("~example.com##world"); |
200 addFilter("foo.com##specific"); | 202 addFilter("foo.com##specific"); |
201 testResult(test, "foo.com", ["specific"], true); | 203 testResult("foo.com", ["specific"], true); |
202 testResult(test, "foo.com", ["hello", "specific", "world"], false); | 204 testResult("foo.com", ["hello", "specific", "world"], false); |
203 testResult(test, "foo.com", ["hello", "specific", "world"]); | 205 testResult("foo.com", ["hello", "specific", "world"]); |
204 testResult(test, "foo.com.", ["hello", "specific", "world"]); | 206 testResult("foo.com.", ["hello", "specific", "world"]); |
205 testResult(test, "example.com", [], true); | 207 testResult("example.com", [], true); |
206 removeFilter("foo.com##specific"); | 208 removeFilter("foo.com##specific"); |
207 removeFilter("~example.com##world"); | 209 removeFilter("~example.com##world"); |
208 removeFilter("##hello"); | 210 removeFilter("##hello"); |
209 testResult(test, "foo.com", []); | 211 testResult("foo.com", []); |
210 | 212 |
211 addFilter("##hello"); | 213 addFilter("##hello"); |
212 testResult(test, "foo.com", [], true); | 214 testResult("foo.com", [], true); |
213 testResult(test, "foo.com", ["hello"], false); | 215 testResult("foo.com", ["hello"], false); |
214 testResult(test, "foo.com", ["hello"]); | 216 testResult("foo.com", ["hello"]); |
215 testResult(test, "bar.com", [], true); | 217 testResult("bar.com", [], true); |
216 testResult(test, "bar.com", ["hello"], false); | 218 testResult("bar.com", ["hello"], false); |
217 testResult(test, "bar.com", ["hello"]); | 219 testResult("bar.com", ["hello"]); |
218 addException("foo.com#@#hello"); | 220 addException("foo.com#@#hello"); |
219 testResult(test, "foo.com", [], true); | 221 testResult("foo.com", [], true); |
220 testResult(test, "foo.com", [], false); | 222 testResult("foo.com", [], false); |
221 testResult(test, "foo.com", []); | 223 testResult("foo.com", []); |
222 testResult(test, "bar.com", [], true); | 224 testResult("bar.com", [], true); |
223 testResult(test, "bar.com", ["hello"], false); | 225 testResult("bar.com", ["hello"], false); |
224 testResult(test, "bar.com", ["hello"]); | 226 testResult("bar.com", ["hello"]); |
225 removeException("foo.com#@#hello"); | 227 removeException("foo.com#@#hello"); |
226 testResult(test, "foo.com", [], true); | 228 testResult("foo.com", [], true); |
227 // Note: We don't take care to track conditional selectors which became | 229 // Note: We don't take care to track conditional selectors which became |
228 // unconditional when a filter was removed. This was too expensive. | 230 // unconditional when a filter was removed. This was too expensive. |
229 testResult(test, "foo.com", ["hello"], false); | 231 testResult("foo.com", ["hello"], false); |
230 testResult(test, "foo.com", ["hello"]); | 232 testResult("foo.com", ["hello"]); |
231 testResult(test, "bar.com", [], true); | 233 testResult("bar.com", [], true); |
232 testResult(test, "bar.com", ["hello"], false); | 234 testResult("bar.com", ["hello"], false); |
233 testResult(test, "bar.com", ["hello"]); | 235 testResult("bar.com", ["hello"]); |
234 removeFilter("##hello"); | 236 removeFilter("##hello"); |
235 testResult(test, "foo.com", []); | 237 testResult("foo.com", []); |
236 testResult(test, "bar.com", []); | 238 testResult("bar.com", []); |
237 | 239 |
238 addFilter("##hello"); | 240 addFilter("##hello"); |
239 addFilter("foo.com##hello"); | 241 addFilter("foo.com##hello"); |
240 testResult(test, "foo.com", ["hello"]); | 242 testResult("foo.com", ["hello"]); |
241 removeFilter("foo.com##hello"); | 243 removeFilter("foo.com##hello"); |
242 testResult(test, "foo.com", ["hello"]); | 244 testResult("foo.com", ["hello"]); |
243 removeFilter("##hello"); | 245 removeFilter("##hello"); |
244 testResult(test, "foo.com", []); | 246 testResult("foo.com", []); |
245 | 247 |
246 addFilter("##hello"); | 248 addFilter("##hello"); |
247 addFilter("foo.com##hello"); | 249 addFilter("foo.com##hello"); |
248 testResult(test, "foo.com", ["hello"]); | 250 testResult("foo.com", ["hello"]); |
249 removeFilter("##hello"); | 251 removeFilter("##hello"); |
250 testResult(test, "foo.com", ["hello"]); | 252 testResult("foo.com", ["hello"]); |
251 removeFilter("foo.com##hello"); | 253 removeFilter("foo.com##hello"); |
252 testResult(test, "foo.com", []); | 254 testResult("foo.com", []); |
253 | 255 }); |
254 test.done(); | 256 |
255 }; | 257 it("Zero filter key", () => |
256 | 258 { |
257 exports.testZeroFilterKey = function(test) | 259 ElemHide.add(Filter.fromText("##test")); |
258 { | 260 ElemHideExceptions.add(Filter.fromText("foo.com#@#test")); |
259 ElemHide.add(Filter.fromText("##test")); | 261 testResult("foo.com", []); |
260 ElemHideExceptions.add(Filter.fromText("foo.com#@#test")); | 262 testResult("bar.com", ["test"]); |
261 testResult(test, "foo.com", []); | 263 }); |
262 testResult(test, "bar.com", ["test"]); | 264 |
263 test.done(); | 265 it("Filters by Domain", () => |
264 }; | 266 { |
265 | 267 assert.equal(filtersByDomain.size, 0); |
266 exports.testFiltersByDomain = function(test) | 268 |
267 { | 269 ElemHide.add(Filter.fromText("##test")); |
268 test.equal(filtersByDomain.size, 0); | 270 assert.equal(filtersByDomain.size, 0); |
269 | 271 |
270 ElemHide.add(Filter.fromText("##test")); | 272 ElemHide.add(Filter.fromText("example.com##test")); |
271 test.equal(filtersByDomain.size, 0); | 273 assert.equal(filtersByDomain.size, 1); |
272 | 274 |
273 ElemHide.add(Filter.fromText("example.com##test")); | 275 ElemHide.add(Filter.fromText("example.com,~www.example.com##test")); |
274 test.equal(filtersByDomain.size, 1); | 276 assert.equal(filtersByDomain.size, 2); |
275 | 277 |
276 ElemHide.add(Filter.fromText("example.com,~www.example.com##test")); | 278 ElemHide.remove(Filter.fromText("example.com##test")); |
277 test.equal(filtersByDomain.size, 2); | 279 assert.equal(filtersByDomain.size, 2); |
278 | 280 |
279 ElemHide.remove(Filter.fromText("example.com##test")); | 281 ElemHide.remove(Filter.fromText("example.com,~www.example.com##test")); |
280 test.equal(filtersByDomain.size, 2); | 282 assert.equal(filtersByDomain.size, 0); |
281 | 283 }); |
282 ElemHide.remove(Filter.fromText("example.com,~www.example.com##test")); | 284 |
283 test.equal(filtersByDomain.size, 0); | 285 describe("Creating Stylesheet", () => |
284 | 286 { |
285 test.done(); | 287 it("Basic creation", () => |
286 }; | 288 { |
287 | 289 assert.equal( |
288 exports.testCreateStyleSheet = function(test) | 290 createStyleSheet([ |
289 { | 291 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
290 test.equal( | 292 "#foo[data-bar='bar']" |
291 createStyleSheet([ | 293 ]), |
292 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", | 294 "html, #foo, .bar, #foo .bar, #foo > .bar, #foo[data-bar='bar'] " + |
293 "#foo[data-bar='bar']" | 295 "{display: none !important;}\n", |
294 ]), | 296 "Style sheet creation should work" |
295 "html, #foo, .bar, #foo .bar, #foo > .bar, #foo[data-bar='bar'] " + | 297 ); |
296 "{display: none !important;}\n", | 298 }); |
297 "Style sheet creation should work" | 299 |
298 ); | 300 it("Splitting", () => |
299 | 301 { |
300 let selectors = new Array(50000).fill().map((element, index) => ".s" + index); | 302 let selectors = new Array(50000).fill().map((element, index) => ".s" + ind
ex); |
301 | 303 |
302 test.equal((createStyleSheet(selectors).match(/\n/g) || []).length, | 304 assert.equal((createStyleSheet(selectors).match(/\n/g) || []).length, |
303 Math.ceil(50000 / selectorGroupSize), | 305 Math.ceil(50000 / selectorGroupSize), |
304 "Style sheet should be split up into rules with at most " + | 306 "Style sheet should be split up into rules with at most " + |
305 selectorGroupSize + " selectors each"); | 307 selectorGroupSize + " selectors each"); |
306 | 308 }); |
307 test.equal( | 309 |
308 createStyleSheet([ | 310 it("Escaping", () => |
309 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", | 311 { |
310 "#foo[data-bar='{foo: 1}']" | 312 assert.equal( |
311 ]), | 313 createStyleSheet([ |
312 "html, #foo, .bar, #foo .bar, #foo > .bar, " + | 314 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
313 "#foo[data-bar='\\7B foo: 1\\7D '] {display: none !important;}\n", | 315 "#foo[data-bar='{foo: 1}']" |
314 "Braces should be escaped" | 316 ]), |
315 ); | 317 "html, #foo, .bar, #foo .bar, #foo > .bar, " + |
316 | 318 "#foo[data-bar='\\7B foo: 1\\7D '] {display: none !important;}\n", |
317 test.done(); | 319 "Braces should be escaped" |
318 }; | 320 ); |
319 | 321 }); |
320 exports.testRulesFromStyleSheet = function(test) | 322 }); |
321 { | 323 |
322 // Note: The rulesFromStyleSheet function assumes that each rule will be | 324 it("Rules from StyleSheet", () => |
323 // terminated with a newline character, including the last rule. If this is | 325 { |
324 // not the case, the function goes into an infinite loop. It should only be | 326 // Note: The rulesFromStyleSheet function assumes that each rule will be |
325 // used with the return value of the createStyleSheet function. | 327 // terminated with a newline character, including the last rule. If this is |
326 | 328 // not the case, the function goes into an infinite loop. It should only be |
327 test.deepEqual([...rulesFromStyleSheet("")], []); | 329 // used with the return value of the createStyleSheet function. |
328 test.deepEqual([...rulesFromStyleSheet("#foo {}\n")], ["#foo {}"]); | 330 |
329 test.deepEqual([...rulesFromStyleSheet("#foo {}\n#bar {}\n")], | 331 assert.deepEqual([...rulesFromStyleSheet("")], []); |
330 ["#foo {}", "#bar {}"]); | 332 assert.deepEqual([...rulesFromStyleSheet("#foo {}\n")], ["#foo {}"]); |
331 | 333 assert.deepEqual([...rulesFromStyleSheet("#foo {}\n#bar {}\n")], |
332 test.done(); | 334 ["#foo {}", "#bar {}"]); |
333 }; | 335 }); |
| 336 }); |
OLD | NEW |