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, |
| 59 {specificOnly = false, expectedExceptions = []} = {}) |
| 60 { |
| 61 let normalizedExpectedSelectors = normalizeSelectors(expectedSelectors); |
| 62 |
| 63 let {code, selectors, exceptions} = |
| 64 ElemHide.generateStyleSheetForDomain(domain, specificOnly, true, true); |
| 65 |
| 66 assert.deepEqual(normalizeSelectors(selectors), normalizedExpectedSelectors)
; |
| 67 |
| 68 // Test for consistency in exception free case. |
| 69 assert.deepEqual(ElemHide.generateStyleSheetForDomain( |
| 70 domain, specificOnly, true, false), { |
| 71 code, |
| 72 selectors, |
| 73 exceptions: null |
| 74 }); |
| 75 |
| 76 assert.deepEqual(exceptions.map(({text}) => text), expectedExceptions); |
| 77 |
| 78 // Make sure each expected selector is in the actual CSS code. |
| 79 for (let selector of normalizedExpectedSelectors) |
| 80 { |
| 81 assert.ok(code.includes(selector + ", ") || |
| 82 code.includes(selector + " {display: none !important;}\n")); |
35 } | 83 } |
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, | |
58 {specificOnly = false, expectedExceptions = []} = {}) | |
59 { | |
60 let normalizedExpectedSelectors = normalizeSelectors(expectedSelectors); | |
61 | |
62 let {code, selectors, exceptions} = | |
63 ElemHide.generateStyleSheetForDomain(domain, specificOnly, true, true); | |
64 | |
65 test.deepEqual(normalizeSelectors(selectors), normalizedExpectedSelectors); | |
66 | |
67 // Test for consistency in exception free case. | |
68 test.deepEqual(ElemHide.generateStyleSheetForDomain( | |
69 domain, specificOnly, true, false), { | |
70 code, | |
71 selectors, | |
72 exceptions: null | |
73 }); | |
74 | |
75 test.deepEqual(exceptions.map(({text}) => text), expectedExceptions); | |
76 | |
77 // Make sure each expected selector is in the actual CSS code. | |
78 for (let selector of normalizedExpectedSelectors) | |
79 { | |
80 test.ok(code.includes(selector + ", ") || | |
81 code.includes(selector + " {display: none !important;}\n")); | |
82 } | 84 } |
83 } | 85 |
84 | 86 it("Generating Style Sheet", () => |
85 exports.testGenerateStyleSheetForDomain = function(test) | 87 { |
86 { | 88 let addFilter = filterText => ElemHide.add(Filter.fromText(filterText)); |
87 let addFilter = filterText => ElemHide.add(Filter.fromText(filterText)); | 89 let removeFilter = |
88 let removeFilter = filterText => ElemHide.remove(Filter.fromText(filterText)); | 90 filterText => ElemHide.remove(Filter.fromText(filterText)); |
89 let addException = | 91 let addException = |
90 filterText => ElemHideExceptions.add(Filter.fromText(filterText)); | 92 filterText => ElemHideExceptions.add(Filter.fromText(filterText)); |
91 let removeException = | 93 let removeException = |
92 filterText => ElemHideExceptions.remove(Filter.fromText(filterText)); | 94 filterText => ElemHideExceptions.remove(Filter.fromText(filterText)); |
93 | 95 |
94 testResult(test, "", []); | 96 testResult("", []); |
95 | 97 |
96 addFilter("~foo.example.com,example.com##foo"); | 98 addFilter("~foo.example.com,example.com##foo"); |
97 testResult(test, "barfoo.example.com", ["foo"]); | 99 testResult("barfoo.example.com", ["foo"]); |
98 testResult(test, "bar.foo.example.com", []); | 100 testResult("bar.foo.example.com", []); |
99 testResult(test, "foo.example.com", []); | 101 testResult("foo.example.com", []); |
100 testResult(test, "example.com", ["foo"]); | 102 testResult("example.com", ["foo"]); |
101 testResult(test, "com", []); | 103 testResult("com", []); |
102 testResult(test, "", []); | 104 testResult("", []); |
103 | 105 |
104 addFilter("foo.example.com##turnip"); | 106 addFilter("foo.example.com##turnip"); |
105 testResult(test, "foo.example.com", ["turnip"]); | 107 testResult("foo.example.com", ["turnip"]); |
106 testResult(test, "example.com", ["foo"]); | 108 testResult("example.com", ["foo"]); |
107 testResult(test, "com", []); | 109 testResult("com", []); |
108 testResult(test, "", []); | 110 testResult("", []); |
109 | 111 |
110 addException("example.com#@#foo"); | 112 addException("example.com#@#foo"); |
111 testResult(test, "foo.example.com", ["turnip"]); | 113 testResult("foo.example.com", ["turnip"]); |
112 testResult(test, "example.com", [], { | 114 testResult("example.com", [], { |
113 expectedExceptions: ["example.com#@#foo"] | 115 expectedExceptions: ["example.com#@#foo"] |
114 }); | 116 }); |
115 testResult(test, "com", []); | 117 testResult("com", []); |
116 testResult(test, "", []); | 118 testResult("", []); |
117 | 119 |
118 addFilter("com##bar"); | 120 addFilter("com##bar"); |
119 testResult(test, "foo.example.com", ["turnip", "bar"]); | 121 testResult("foo.example.com", ["turnip", "bar"]); |
120 testResult(test, "example.com", ["bar"], { | 122 testResult("example.com", ["bar"], { |
121 expectedExceptions: ["example.com#@#foo"] | 123 expectedExceptions: ["example.com#@#foo"] |
122 }); | 124 }); |
123 testResult(test, "com", ["bar"]); | 125 testResult("com", ["bar"]); |
124 testResult(test, "", []); | 126 testResult("", []); |
125 | 127 |
126 addException("example.com#@#bar"); | 128 addException("example.com#@#bar"); |
127 testResult(test, "foo.example.com", ["turnip"], { | 129 testResult("foo.example.com", ["turnip"], { |
128 expectedExceptions: ["example.com#@#bar"] | 130 expectedExceptions: ["example.com#@#bar"] |
129 }); | 131 }); |
130 testResult(test, "example.com", [], { | 132 testResult("example.com", [], { |
131 expectedExceptions: ["example.com#@#foo", "example.com#@#bar"] | 133 expectedExceptions: ["example.com#@#foo", "example.com#@#bar"] |
132 }); | 134 }); |
133 testResult(test, "com", ["bar"]); | 135 testResult("com", ["bar"]); |
134 testResult(test, "", []); | 136 testResult("", []); |
135 | 137 |
136 removeException("example.com#@#foo"); | 138 removeException("example.com#@#foo"); |
137 testResult(test, "foo.example.com", ["turnip"], { | 139 testResult("foo.example.com", ["turnip"], { |
138 expectedExceptions: ["example.com#@#bar"] | 140 expectedExceptions: ["example.com#@#bar"] |
139 }); | 141 }); |
140 testResult(test, "example.com", ["foo"], { | 142 testResult("example.com", ["foo"], { |
141 expectedExceptions: ["example.com#@#bar"] | 143 expectedExceptions: ["example.com#@#bar"] |
142 }); | 144 }); |
143 testResult(test, "com", ["bar"]); | 145 testResult("com", ["bar"]); |
144 testResult(test, "", []); | 146 testResult("", []); |
145 | 147 |
146 removeException("example.com#@#bar"); | 148 removeException("example.com#@#bar"); |
147 testResult(test, "foo.example.com", ["turnip", "bar"]); | 149 testResult("foo.example.com", ["turnip", "bar"]); |
148 testResult(test, "example.com", ["foo", "bar"]); | 150 testResult("example.com", ["foo", "bar"]); |
149 testResult(test, "com", ["bar"]); | 151 testResult("com", ["bar"]); |
150 testResult(test, "", []); | 152 testResult("", []); |
151 | 153 |
152 addFilter("##generic"); | 154 addFilter("##generic"); |
153 testResult(test, "foo.example.com", ["turnip", "bar", "generic"]); | 155 testResult("foo.example.com", ["turnip", "bar", "generic"]); |
154 testResult(test, "example.com", ["foo", "bar", "generic"]); | 156 testResult("example.com", ["foo", "bar", "generic"]); |
155 testResult(test, "com", ["bar", "generic"]); | 157 testResult("com", ["bar", "generic"]); |
156 testResult(test, "", ["generic"]); | 158 testResult("", ["generic"]); |
157 testResult(test, "foo.example.com", ["turnip", "bar"], {specificOnly: true}); | 159 testResult("foo.example.com", ["turnip", "bar"], {specificOnly: true}); |
158 testResult(test, "example.com", ["foo", "bar"], {specificOnly: true}); | 160 testResult("example.com", ["foo", "bar"], {specificOnly: true}); |
159 testResult(test, "com", ["bar"], {specificOnly: true}); | 161 testResult("com", ["bar"], {specificOnly: true}); |
160 testResult(test, "", [], {specificOnly: true}); | 162 testResult("", [], {specificOnly: true}); |
161 removeFilter("##generic"); | 163 removeFilter("##generic"); |
162 | 164 |
163 addFilter("~adblockplus.org##example"); | 165 addFilter("~adblockplus.org##example"); |
164 testResult(test, "adblockplus.org", []); | 166 testResult("adblockplus.org", []); |
165 testResult(test, "", ["example"]); | 167 testResult("", ["example"]); |
166 testResult(test, "foo.example.com", ["turnip", "bar", "example"]); | 168 testResult("foo.example.com", ["turnip", "bar", "example"]); |
167 testResult(test, "foo.example.com", ["turnip", "bar"], {specificOnly: true}); | 169 testResult("foo.example.com", ["turnip", "bar"], {specificOnly: true}); |
168 removeFilter("~adblockplus.org##example"); | 170 removeFilter("~adblockplus.org##example"); |
169 | 171 |
170 removeFilter("~foo.example.com,example.com##foo"); | 172 removeFilter("~foo.example.com,example.com##foo"); |
171 testResult(test, "foo.example.com", ["turnip", "bar"]); | 173 testResult("foo.example.com", ["turnip", "bar"]); |
172 testResult(test, "example.com", ["bar"]); | 174 testResult("example.com", ["bar"]); |
173 testResult(test, "com", ["bar"]); | 175 testResult("com", ["bar"]); |
174 testResult(test, "", []); | 176 testResult("", []); |
175 | 177 |
176 removeFilter("com##bar"); | 178 removeFilter("com##bar"); |
177 testResult(test, "foo.example.com", ["turnip"]); | 179 testResult("foo.example.com", ["turnip"]); |
178 testResult(test, "example.com", []); | 180 testResult("example.com", []); |
179 testResult(test, "com", []); | 181 testResult("com", []); |
180 testResult(test, "", []); | 182 testResult("", []); |
181 | 183 |
182 removeFilter("foo.example.com##turnip"); | 184 removeFilter("foo.example.com##turnip"); |
183 testResult(test, "foo.example.com", []); | 185 testResult("foo.example.com", []); |
184 testResult(test, "example.com", []); | 186 testResult("example.com", []); |
185 testResult(test, "com", []); | 187 testResult("com", []); |
186 testResult(test, "", []); | 188 testResult("", []); |
187 | 189 |
188 addFilter("example.com##dupe"); | 190 addFilter("example.com##dupe"); |
189 addFilter("example.com##dupe"); | 191 addFilter("example.com##dupe"); |
190 testResult(test, "example.com", ["dupe"]); | 192 testResult("example.com", ["dupe"]); |
191 removeFilter("example.com##dupe"); | 193 removeFilter("example.com##dupe"); |
192 testResult(test, "example.com", []); | 194 testResult("example.com", []); |
193 removeFilter("example.com##dupe"); | 195 removeFilter("example.com##dupe"); |
194 | 196 |
195 addFilter("~foo.example.com,example.com##foo"); | 197 addFilter("~foo.example.com,example.com##foo"); |
196 | 198 |
197 addFilter("##foo"); | 199 addFilter("##foo"); |
198 testResult(test, "foo.example.com", ["foo"]); | 200 testResult("foo.example.com", ["foo"]); |
199 testResult(test, "example.com", ["foo"]); | 201 testResult("example.com", ["foo"]); |
200 testResult(test, "com", ["foo"]); | 202 testResult("com", ["foo"]); |
201 testResult(test, "", ["foo"]); | 203 testResult("", ["foo"]); |
202 removeFilter("##foo"); | 204 removeFilter("##foo"); |
203 | 205 |
204 addFilter("example.org##foo"); | 206 addFilter("example.org##foo"); |
205 testResult(test, "foo.example.com", []); | 207 testResult("foo.example.com", []); |
206 testResult(test, "example.com", ["foo"]); | 208 testResult("example.com", ["foo"]); |
207 testResult(test, "com", []); | 209 testResult("com", []); |
208 testResult(test, "", []); | 210 testResult("", []); |
209 removeFilter("example.org##foo"); | 211 removeFilter("example.org##foo"); |
210 | 212 |
211 addFilter("~example.com##foo"); | 213 addFilter("~example.com##foo"); |
212 testResult(test, "foo.example.com", []); | 214 testResult("foo.example.com", []); |
213 testResult(test, "example.com", ["foo"]); | 215 testResult("example.com", ["foo"]); |
214 testResult(test, "com", ["foo"]); | 216 testResult("com", ["foo"]); |
215 testResult(test, "", ["foo"]); | 217 testResult("", ["foo"]); |
216 removeFilter("~example.com##foo"); | 218 removeFilter("~example.com##foo"); |
217 | 219 |
218 removeFilter("~foo.example.com,example.com##foo"); | 220 removeFilter("~foo.example.com,example.com##foo"); |
219 | 221 |
220 // Test criteria | 222 // Test criteria |
221 addFilter("##hello"); | 223 addFilter("##hello"); |
222 addFilter("~example.com##world"); | 224 addFilter("~example.com##world"); |
223 addFilter("foo.com##specific"); | 225 addFilter("foo.com##specific"); |
224 testResult(test, "foo.com", ["specific"], {specificOnly: true}); | 226 testResult("foo.com", ["specific"], {specificOnly: true}); |
225 testResult(test, "foo.com", ["hello", "specific", "world"]); | 227 testResult("foo.com", ["hello", "specific", "world"]); |
226 testResult(test, "example.com", [], {specificOnly: true}); | 228 testResult("example.com", [], {specificOnly: true}); |
227 removeFilter("foo.com##specific"); | 229 removeFilter("foo.com##specific"); |
228 removeFilter("~example.com##world"); | 230 removeFilter("~example.com##world"); |
229 removeFilter("##hello"); | 231 removeFilter("##hello"); |
230 testResult(test, "foo.com", []); | 232 testResult("foo.com", []); |
231 | 233 |
232 addFilter("##hello"); | 234 addFilter("##hello"); |
233 testResult(test, "foo.com", [], {specificOnly: true}); | 235 testResult("foo.com", [], {specificOnly: true}); |
234 testResult(test, "foo.com", ["hello"]); | 236 testResult("foo.com", ["hello"]); |
235 testResult(test, "bar.com", [], {specificOnly: true}); | 237 testResult("bar.com", [], {specificOnly: true}); |
236 testResult(test, "bar.com", ["hello"]); | 238 testResult("bar.com", ["hello"]); |
237 addException("foo.com#@#hello"); | 239 addException("foo.com#@#hello"); |
238 testResult(test, "foo.com", [], {specificOnly: true}); | 240 testResult("foo.com", [], {specificOnly: true}); |
239 testResult(test, "foo.com", [], {expectedExceptions: ["foo.com#@#hello"]}); | 241 testResult("foo.com", [], {expectedExceptions: ["foo.com#@#hello"]}); |
240 testResult(test, "bar.com", [], {specificOnly: true}); | 242 testResult("bar.com", [], {specificOnly: true}); |
241 testResult(test, "bar.com", ["hello"]); | 243 testResult("bar.com", ["hello"]); |
242 removeException("foo.com#@#hello"); | 244 removeException("foo.com#@#hello"); |
243 testResult(test, "foo.com", [], {specificOnly: true}); | 245 testResult("foo.com", [], {specificOnly: true}); |
244 // Note: We don't take care to track conditional selectors which became | 246 // Note: We don't take care to track conditional selectors which became |
245 // unconditional when a filter was removed. This was too expensive. | 247 // unconditional when a filter was removed. This was too expensive. |
246 testResult(test, "foo.com", ["hello"]); | 248 testResult("foo.com", ["hello"]); |
247 testResult(test, "bar.com", [], {specificOnly: true}); | 249 testResult("bar.com", [], {specificOnly: true}); |
248 testResult(test, "bar.com", ["hello"]); | 250 testResult("bar.com", ["hello"]); |
249 removeFilter("##hello"); | 251 removeFilter("##hello"); |
250 testResult(test, "foo.com", []); | 252 testResult("foo.com", []); |
251 testResult(test, "bar.com", []); | 253 testResult("bar.com", []); |
252 | 254 |
253 addFilter("##hello"); | 255 addFilter("##hello"); |
254 addFilter("foo.com##hello"); | 256 addFilter("foo.com##hello"); |
255 testResult(test, "foo.com", ["hello"]); | 257 testResult("foo.com", ["hello"]); |
256 removeFilter("foo.com##hello"); | 258 removeFilter("foo.com##hello"); |
257 testResult(test, "foo.com", ["hello"]); | 259 testResult("foo.com", ["hello"]); |
258 removeFilter("##hello"); | 260 removeFilter("##hello"); |
259 testResult(test, "foo.com", []); | 261 testResult("foo.com", []); |
260 | 262 |
261 addFilter("##hello"); | 263 addFilter("##hello"); |
262 addFilter("foo.com##hello"); | 264 addFilter("foo.com##hello"); |
263 testResult(test, "foo.com", ["hello"]); | 265 testResult("foo.com", ["hello"]); |
264 removeFilter("##hello"); | 266 removeFilter("##hello"); |
265 testResult(test, "foo.com", ["hello"]); | 267 testResult("foo.com", ["hello"]); |
266 removeFilter("foo.com##hello"); | 268 removeFilter("foo.com##hello"); |
267 testResult(test, "foo.com", []); | 269 testResult("foo.com", []); |
268 | 270 }); |
269 test.done(); | 271 |
270 }; | 272 it("Zero filter key", () => |
271 | 273 { |
272 exports.testZeroFilterKey = function(test) | 274 ElemHide.add(Filter.fromText("##test")); |
273 { | 275 ElemHideExceptions.add(Filter.fromText("foo.com#@#test")); |
274 ElemHide.add(Filter.fromText("##test")); | 276 testResult("foo.com", [], {expectedExceptions: ["foo.com#@#test"]}); |
275 ElemHideExceptions.add(Filter.fromText("foo.com#@#test")); | 277 testResult("bar.com", ["test"]); |
276 testResult(test, "foo.com", [], {expectedExceptions: ["foo.com#@#test"]}); | 278 }); |
277 testResult(test, "bar.com", ["test"]); | 279 |
278 test.done(); | 280 it("Filters by Domain", () => |
279 }; | 281 { |
280 | 282 assert.equal(filtersByDomain.size, 0); |
281 exports.testFiltersByDomain = function(test) | 283 |
282 { | 284 ElemHide.add(Filter.fromText("##test")); |
283 test.equal(filtersByDomain.size, 0); | 285 assert.equal(filtersByDomain.size, 0); |
284 | 286 |
285 ElemHide.add(Filter.fromText("##test")); | 287 ElemHide.add(Filter.fromText("example.com##test")); |
286 test.equal(filtersByDomain.size, 0); | 288 assert.equal(filtersByDomain.size, 1); |
287 | 289 |
288 ElemHide.add(Filter.fromText("example.com##test")); | 290 ElemHide.add(Filter.fromText("example.com,~www.example.com##test")); |
289 test.equal(filtersByDomain.size, 1); | 291 assert.equal(filtersByDomain.size, 2); |
290 | 292 |
291 ElemHide.add(Filter.fromText("example.com,~www.example.com##test")); | 293 ElemHide.remove(Filter.fromText("example.com##test")); |
292 test.equal(filtersByDomain.size, 2); | 294 assert.equal(filtersByDomain.size, 2); |
293 | 295 |
294 ElemHide.remove(Filter.fromText("example.com##test")); | 296 ElemHide.remove(Filter.fromText("example.com,~www.example.com##test")); |
295 test.equal(filtersByDomain.size, 2); | 297 assert.equal(filtersByDomain.size, 0); |
296 | 298 }); |
297 ElemHide.remove(Filter.fromText("example.com,~www.example.com##test")); | 299 |
298 test.equal(filtersByDomain.size, 0); | 300 describe("Creating Stylesheet", () => |
299 | 301 { |
300 test.done(); | 302 it("Basic creation", () => |
301 }; | 303 { |
302 | 304 assert.equal( |
303 exports.testCreateStyleSheet = function(test) | 305 createStyleSheet([ |
304 { | 306 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
305 test.equal( | 307 "#foo[data-bar='bar']" |
306 createStyleSheet([ | 308 ]), |
307 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", | 309 "html, #foo, .bar, #foo .bar, #foo > .bar, #foo[data-bar='bar'] " + |
308 "#foo[data-bar='bar']" | 310 "{display: none !important;}\n", |
309 ]), | 311 "Style sheet creation should work" |
310 "html, #foo, .bar, #foo .bar, #foo > .bar, #foo[data-bar='bar'] " + | 312 ); |
311 "{display: none !important;}\n", | 313 }); |
312 "Style sheet creation should work" | 314 |
313 ); | 315 it("Splitting", () => |
314 | 316 { |
315 let selectors = new Array(50000).fill().map((element, index) => ".s" + index); | 317 let selectors = new Array(50000).fill().map((element, index) => ".s" + ind
ex); |
316 | 318 |
317 test.equal((createStyleSheet(selectors).match(/\n/g) || []).length, | 319 assert.equal((createStyleSheet(selectors).match(/\n/g) || []).length, |
318 Math.ceil(50000 / selectorGroupSize), | 320 Math.ceil(50000 / selectorGroupSize), |
319 "Style sheet should be split up into rules with at most " + | 321 "Style sheet should be split up into rules with at most " + |
320 selectorGroupSize + " selectors each"); | 322 selectorGroupSize + " selectors each"); |
321 | 323 }); |
322 test.equal( | 324 |
323 createStyleSheet([ | 325 it("Escaping", () => |
324 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", | 326 { |
325 "#foo[data-bar='{foo: 1}']" | 327 assert.equal( |
326 ]), | 328 createStyleSheet([ |
327 "html, #foo, .bar, #foo .bar, #foo > .bar, " + | 329 "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
328 "#foo[data-bar='\\7B foo: 1\\7D '] {display: none !important;}\n", | 330 "#foo[data-bar='{foo: 1}']" |
329 "Braces should be escaped" | 331 ]), |
330 ); | 332 "html, #foo, .bar, #foo .bar, #foo > .bar, " + |
331 | 333 "#foo[data-bar='\\7B foo: 1\\7D '] {display: none !important;}\n", |
332 test.done(); | 334 "Braces should be escaped" |
333 }; | 335 ); |
334 | 336 }); |
335 exports.testRulesFromStyleSheet = function(test) | 337 }); |
336 { | 338 |
337 // Note: The rulesFromStyleSheet function assumes that each rule will be | 339 it("Rules from StyleSheet", () => |
338 // terminated with a newline character, including the last rule. If this is | 340 { |
339 // not the case, the function goes into an infinite loop. It should only be | 341 // Note: The rulesFromStyleSheet function assumes that each rule will be |
340 // used with the return value of the createStyleSheet function. | 342 // terminated with a newline character, including the last rule. If this is |
341 | 343 // not the case, the function goes into an infinite loop. It should only be |
342 test.deepEqual([...rulesFromStyleSheet("")], []); | 344 // used with the return value of the createStyleSheet function. |
343 test.deepEqual([...rulesFromStyleSheet("#foo {}\n")], ["#foo {}"]); | 345 |
344 test.deepEqual([...rulesFromStyleSheet("#foo {}\n#bar {}\n")], | 346 assert.deepEqual([...rulesFromStyleSheet("")], []); |
345 ["#foo {}", "#bar {}"]); | 347 assert.deepEqual([...rulesFromStyleSheet("#foo {}\n")], ["#foo {}"]); |
346 | 348 assert.deepEqual([...rulesFromStyleSheet("#foo {}\n#bar {}\n")], |
347 test.done(); | 349 ["#foo {}", "#bar {}"]); |
348 }; | 350 }); |
| 351 }); |
OLD | NEW |