| Index: test/elemHide.js |
| =================================================================== |
| --- a/test/elemHide.js |
| +++ b/test/elemHide.js |
| @@ -12,337 +12,340 @@ |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| "use strict"; |
| +const assert = require("assert"); |
| const {createSandbox} = require("./_common"); |
| let ElemHide = null; |
| let createStyleSheet = null; |
| let rulesFromStyleSheet = null; |
| let ElemHideExceptions = null; |
| let Filter = null; |
| let filtersByDomain = null; |
| let selectorGroupSize = null; |
| -exports.setUp = function(callback) |
| -{ |
| - let sandboxedRequire = createSandbox({ |
| - extraExports: { |
| - elemHide: ["filtersByDomain", "selectorGroupSize"] |
| - } |
| - }); |
| - ( |
| - {ElemHide, createStyleSheet, rulesFromStyleSheet, |
| - filtersByDomain, selectorGroupSize} = sandboxedRequire("../lib/elemHide"), |
| - {ElemHideExceptions} = sandboxedRequire("../lib/elemHideExceptions"), |
| - {Filter} = sandboxedRequire("../lib/filterClasses") |
| - ); |
| - |
| - callback(); |
| -}; |
| - |
| -function normalizeSelectors(selectors) |
| +describe("ElemHide", () => |
| { |
| - // generateStyleSheetForDomain is currently allowed to return duplicate |
| - // selectors for performance reasons, so we need to remove duplicates here. |
| - return selectors.slice().sort().filter((selector, index, sortedSelectors) => |
| + beforeEach(() => |
| + { |
| + let sandboxedRequire = createSandbox({ |
| + extraExports: { |
| + elemHide: ["filtersByDomain", "selectorGroupSize"] |
| + } |
| + }); |
| + ( |
| + {ElemHide, createStyleSheet, rulesFromStyleSheet, |
| + filtersByDomain, selectorGroupSize} = sandboxedRequire("../lib/elemHide"), |
| + {ElemHideExceptions} = sandboxedRequire("../lib/elemHideExceptions"), |
| + {Filter} = sandboxedRequire("../lib/filterClasses") |
| + ); |
| + }); |
| + |
| + function normalizeSelectors(selectors) |
| + { |
| + // generateStyleSheetForDomain is currently allowed to return duplicate |
| + // selectors for performance reasons, so we need to remove duplicates here. |
| + return selectors.slice().sort().filter((selector, index, sortedSelectors) => |
| + { |
| + return index == 0 || selector != sortedSelectors[index - 1]; |
| + }); |
| + } |
| + |
| + function testResult(domain, expectedSelectors, |
| + {specificOnly = false, expectedExceptions = []} = {}) |
| + { |
| + let normalizedExpectedSelectors = normalizeSelectors(expectedSelectors); |
| + |
| + let {code, selectors, exceptions} = |
| + ElemHide.generateStyleSheetForDomain(domain, specificOnly, true, true); |
| + |
| + assert.deepEqual(normalizeSelectors(selectors), normalizedExpectedSelectors); |
| + |
| + // Test for consistency in exception free case. |
| + assert.deepEqual(ElemHide.generateStyleSheetForDomain( |
| + domain, specificOnly, true, false), { |
| + code, |
| + selectors, |
| + exceptions: null |
| + }); |
| + |
| + assert.deepEqual(exceptions.map(({text}) => text), expectedExceptions); |
| + |
| + // Make sure each expected selector is in the actual CSS code. |
| + for (let selector of normalizedExpectedSelectors) |
| + { |
| + assert.ok(code.includes(selector + ", ") || |
| + code.includes(selector + " {display: none !important;}\n")); |
| + } |
| + } |
| + |
| + it("Generating Style Sheet", () => |
| { |
| - return index == 0 || selector != sortedSelectors[index - 1]; |
| - }); |
| -} |
| + let addFilter = filterText => ElemHide.add(Filter.fromText(filterText)); |
| + let removeFilter = |
| + filterText => ElemHide.remove(Filter.fromText(filterText)); |
| + let addException = |
| + filterText => ElemHideExceptions.add(Filter.fromText(filterText)); |
| + let removeException = |
| + filterText => ElemHideExceptions.remove(Filter.fromText(filterText)); |
| + |
| + testResult("", []); |
| + |
| + addFilter("~foo.example.com,example.com##foo"); |
| + testResult("barfoo.example.com", ["foo"]); |
| + testResult("bar.foo.example.com", []); |
| + testResult("foo.example.com", []); |
| + testResult("example.com", ["foo"]); |
| + testResult("com", []); |
| + testResult("", []); |
| + |
| + addFilter("foo.example.com##turnip"); |
| + testResult("foo.example.com", ["turnip"]); |
| + testResult("example.com", ["foo"]); |
| + testResult("com", []); |
| + testResult("", []); |
| + |
| + addException("example.com#@#foo"); |
| + testResult("foo.example.com", ["turnip"]); |
| + testResult("example.com", [], { |
| + expectedExceptions: ["example.com#@#foo"] |
| + }); |
| + testResult("com", []); |
| + testResult("", []); |
| + |
| + addFilter("com##bar"); |
| + testResult("foo.example.com", ["turnip", "bar"]); |
| + testResult("example.com", ["bar"], { |
| + expectedExceptions: ["example.com#@#foo"] |
| + }); |
| + testResult("com", ["bar"]); |
| + testResult("", []); |
| + |
| + addException("example.com#@#bar"); |
| + testResult("foo.example.com", ["turnip"], { |
| + expectedExceptions: ["example.com#@#bar"] |
| + }); |
| + testResult("example.com", [], { |
| + expectedExceptions: ["example.com#@#foo", "example.com#@#bar"] |
| + }); |
| + testResult("com", ["bar"]); |
| + testResult("", []); |
| + |
| + removeException("example.com#@#foo"); |
| + testResult("foo.example.com", ["turnip"], { |
| + expectedExceptions: ["example.com#@#bar"] |
| + }); |
| + testResult("example.com", ["foo"], { |
| + expectedExceptions: ["example.com#@#bar"] |
| + }); |
| + testResult("com", ["bar"]); |
| + testResult("", []); |
| + |
| + removeException("example.com#@#bar"); |
| + testResult("foo.example.com", ["turnip", "bar"]); |
| + testResult("example.com", ["foo", "bar"]); |
| + testResult("com", ["bar"]); |
| + testResult("", []); |
| + |
| + addFilter("##generic"); |
| + testResult("foo.example.com", ["turnip", "bar", "generic"]); |
| + testResult("example.com", ["foo", "bar", "generic"]); |
| + testResult("com", ["bar", "generic"]); |
| + testResult("", ["generic"]); |
| + testResult("foo.example.com", ["turnip", "bar"], {specificOnly: true}); |
| + testResult("example.com", ["foo", "bar"], {specificOnly: true}); |
| + testResult("com", ["bar"], {specificOnly: true}); |
| + testResult("", [], {specificOnly: true}); |
| + removeFilter("##generic"); |
| + |
| + addFilter("~adblockplus.org##example"); |
| + testResult("adblockplus.org", []); |
| + testResult("", ["example"]); |
| + testResult("foo.example.com", ["turnip", "bar", "example"]); |
| + testResult("foo.example.com", ["turnip", "bar"], {specificOnly: true}); |
| + removeFilter("~adblockplus.org##example"); |
| -function testResult(test, domain, expectedSelectors, |
| - {specificOnly = false, expectedExceptions = []} = {}) |
| -{ |
| - let normalizedExpectedSelectors = normalizeSelectors(expectedSelectors); |
| + removeFilter("~foo.example.com,example.com##foo"); |
| + testResult("foo.example.com", ["turnip", "bar"]); |
| + testResult("example.com", ["bar"]); |
| + testResult("com", ["bar"]); |
| + testResult("", []); |
| + |
| + removeFilter("com##bar"); |
| + testResult("foo.example.com", ["turnip"]); |
| + testResult("example.com", []); |
| + testResult("com", []); |
| + testResult("", []); |
| + |
| + removeFilter("foo.example.com##turnip"); |
| + testResult("foo.example.com", []); |
| + testResult("example.com", []); |
| + testResult("com", []); |
| + testResult("", []); |
| + |
| + addFilter("example.com##dupe"); |
| + addFilter("example.com##dupe"); |
| + testResult("example.com", ["dupe"]); |
| + removeFilter("example.com##dupe"); |
| + testResult("example.com", []); |
| + removeFilter("example.com##dupe"); |
| + |
| + addFilter("~foo.example.com,example.com##foo"); |
| - let {code, selectors, exceptions} = |
| - ElemHide.generateStyleSheetForDomain(domain, specificOnly, true, true); |
| + addFilter("##foo"); |
| + testResult("foo.example.com", ["foo"]); |
| + testResult("example.com", ["foo"]); |
| + testResult("com", ["foo"]); |
| + testResult("", ["foo"]); |
| + removeFilter("##foo"); |
| + |
| + addFilter("example.org##foo"); |
| + testResult("foo.example.com", []); |
| + testResult("example.com", ["foo"]); |
| + testResult("com", []); |
| + testResult("", []); |
| + removeFilter("example.org##foo"); |
| + |
| + addFilter("~example.com##foo"); |
| + testResult("foo.example.com", []); |
| + testResult("example.com", ["foo"]); |
| + testResult("com", ["foo"]); |
| + testResult("", ["foo"]); |
| + removeFilter("~example.com##foo"); |
| + |
| + removeFilter("~foo.example.com,example.com##foo"); |
| + |
| + // Test criteria |
| + addFilter("##hello"); |
| + addFilter("~example.com##world"); |
| + addFilter("foo.com##specific"); |
| + testResult("foo.com", ["specific"], {specificOnly: true}); |
| + testResult("foo.com", ["hello", "specific", "world"]); |
| + testResult("example.com", [], {specificOnly: true}); |
| + removeFilter("foo.com##specific"); |
| + removeFilter("~example.com##world"); |
| + removeFilter("##hello"); |
| + testResult("foo.com", []); |
| - test.deepEqual(normalizeSelectors(selectors), normalizedExpectedSelectors); |
| + addFilter("##hello"); |
| + testResult("foo.com", [], {specificOnly: true}); |
| + testResult("foo.com", ["hello"]); |
| + testResult("bar.com", [], {specificOnly: true}); |
| + testResult("bar.com", ["hello"]); |
| + addException("foo.com#@#hello"); |
| + testResult("foo.com", [], {specificOnly: true}); |
| + testResult("foo.com", [], {expectedExceptions: ["foo.com#@#hello"]}); |
| + testResult("bar.com", [], {specificOnly: true}); |
| + testResult("bar.com", ["hello"]); |
| + removeException("foo.com#@#hello"); |
| + testResult("foo.com", [], {specificOnly: true}); |
| + // Note: We don't take care to track conditional selectors which became |
| + // unconditional when a filter was removed. This was too expensive. |
| + testResult("foo.com", ["hello"]); |
| + testResult("bar.com", [], {specificOnly: true}); |
| + testResult("bar.com", ["hello"]); |
| + removeFilter("##hello"); |
| + testResult("foo.com", []); |
| + testResult("bar.com", []); |
| + |
| + addFilter("##hello"); |
| + addFilter("foo.com##hello"); |
| + testResult("foo.com", ["hello"]); |
| + removeFilter("foo.com##hello"); |
| + testResult("foo.com", ["hello"]); |
| + removeFilter("##hello"); |
| + testResult("foo.com", []); |
| + |
| + addFilter("##hello"); |
| + addFilter("foo.com##hello"); |
| + testResult("foo.com", ["hello"]); |
| + removeFilter("##hello"); |
| + testResult("foo.com", ["hello"]); |
| + removeFilter("foo.com##hello"); |
| + testResult("foo.com", []); |
| + }); |
| - // Test for consistency in exception free case. |
| - test.deepEqual(ElemHide.generateStyleSheetForDomain( |
| - domain, specificOnly, true, false), { |
| - code, |
| - selectors, |
| - exceptions: null |
| + it("Zero filter key", () => |
| + { |
| + ElemHide.add(Filter.fromText("##test")); |
| + ElemHideExceptions.add(Filter.fromText("foo.com#@#test")); |
| + testResult("foo.com", [], {expectedExceptions: ["foo.com#@#test"]}); |
| + testResult("bar.com", ["test"]); |
| + }); |
| + |
| + it("Filters by Domain", () => |
| + { |
| + assert.equal(filtersByDomain.size, 0); |
| + |
| + ElemHide.add(Filter.fromText("##test")); |
| + assert.equal(filtersByDomain.size, 0); |
| + |
| + ElemHide.add(Filter.fromText("example.com##test")); |
| + assert.equal(filtersByDomain.size, 1); |
| + |
| + ElemHide.add(Filter.fromText("example.com,~www.example.com##test")); |
| + assert.equal(filtersByDomain.size, 2); |
| + |
| + ElemHide.remove(Filter.fromText("example.com##test")); |
| + assert.equal(filtersByDomain.size, 2); |
| + |
| + ElemHide.remove(Filter.fromText("example.com,~www.example.com##test")); |
| + assert.equal(filtersByDomain.size, 0); |
| + }); |
| + |
| + describe("Creating Stylesheet", () => |
| + { |
| + it("Basic creation", () => |
| + { |
| + assert.equal( |
| + createStyleSheet([ |
| + "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
| + "#foo[data-bar='bar']" |
| + ]), |
| + "html, #foo, .bar, #foo .bar, #foo > .bar, #foo[data-bar='bar'] " + |
| + "{display: none !important;}\n", |
| + "Style sheet creation should work" |
| + ); |
| }); |
| - test.deepEqual(exceptions.map(({text}) => text), expectedExceptions); |
| - |
| - // Make sure each expected selector is in the actual CSS code. |
| - for (let selector of normalizedExpectedSelectors) |
| - { |
| - test.ok(code.includes(selector + ", ") || |
| - code.includes(selector + " {display: none !important;}\n")); |
| - } |
| -} |
| - |
| -exports.testGenerateStyleSheetForDomain = function(test) |
| -{ |
| - let addFilter = filterText => ElemHide.add(Filter.fromText(filterText)); |
| - let removeFilter = filterText => ElemHide.remove(Filter.fromText(filterText)); |
| - let addException = |
| - filterText => ElemHideExceptions.add(Filter.fromText(filterText)); |
| - let removeException = |
| - filterText => ElemHideExceptions.remove(Filter.fromText(filterText)); |
| - |
| - testResult(test, "", []); |
| - |
| - addFilter("~foo.example.com,example.com##foo"); |
| - testResult(test, "barfoo.example.com", ["foo"]); |
| - testResult(test, "bar.foo.example.com", []); |
| - testResult(test, "foo.example.com", []); |
| - testResult(test, "example.com", ["foo"]); |
| - testResult(test, "com", []); |
| - testResult(test, "", []); |
| - |
| - addFilter("foo.example.com##turnip"); |
| - testResult(test, "foo.example.com", ["turnip"]); |
| - testResult(test, "example.com", ["foo"]); |
| - testResult(test, "com", []); |
| - testResult(test, "", []); |
| - |
| - addException("example.com#@#foo"); |
| - testResult(test, "foo.example.com", ["turnip"]); |
| - testResult(test, "example.com", [], { |
| - expectedExceptions: ["example.com#@#foo"] |
| - }); |
| - testResult(test, "com", []); |
| - testResult(test, "", []); |
| - |
| - addFilter("com##bar"); |
| - testResult(test, "foo.example.com", ["turnip", "bar"]); |
| - testResult(test, "example.com", ["bar"], { |
| - expectedExceptions: ["example.com#@#foo"] |
| - }); |
| - testResult(test, "com", ["bar"]); |
| - testResult(test, "", []); |
| - |
| - addException("example.com#@#bar"); |
| - testResult(test, "foo.example.com", ["turnip"], { |
| - expectedExceptions: ["example.com#@#bar"] |
| - }); |
| - testResult(test, "example.com", [], { |
| - expectedExceptions: ["example.com#@#foo", "example.com#@#bar"] |
| - }); |
| - testResult(test, "com", ["bar"]); |
| - testResult(test, "", []); |
| + it("Splitting", () => |
| + { |
| + let selectors = new Array(50000).fill().map((element, index) => ".s" + index); |
| - removeException("example.com#@#foo"); |
| - testResult(test, "foo.example.com", ["turnip"], { |
| - expectedExceptions: ["example.com#@#bar"] |
| - }); |
| - testResult(test, "example.com", ["foo"], { |
| - expectedExceptions: ["example.com#@#bar"] |
| - }); |
| - testResult(test, "com", ["bar"]); |
| - testResult(test, "", []); |
| - |
| - removeException("example.com#@#bar"); |
| - testResult(test, "foo.example.com", ["turnip", "bar"]); |
| - testResult(test, "example.com", ["foo", "bar"]); |
| - testResult(test, "com", ["bar"]); |
| - testResult(test, "", []); |
| - |
| - addFilter("##generic"); |
| - testResult(test, "foo.example.com", ["turnip", "bar", "generic"]); |
| - testResult(test, "example.com", ["foo", "bar", "generic"]); |
| - testResult(test, "com", ["bar", "generic"]); |
| - testResult(test, "", ["generic"]); |
| - testResult(test, "foo.example.com", ["turnip", "bar"], {specificOnly: true}); |
| - testResult(test, "example.com", ["foo", "bar"], {specificOnly: true}); |
| - testResult(test, "com", ["bar"], {specificOnly: true}); |
| - testResult(test, "", [], {specificOnly: true}); |
| - removeFilter("##generic"); |
| - |
| - addFilter("~adblockplus.org##example"); |
| - testResult(test, "adblockplus.org", []); |
| - testResult(test, "", ["example"]); |
| - testResult(test, "foo.example.com", ["turnip", "bar", "example"]); |
| - testResult(test, "foo.example.com", ["turnip", "bar"], {specificOnly: true}); |
| - removeFilter("~adblockplus.org##example"); |
| - |
| - removeFilter("~foo.example.com,example.com##foo"); |
| - testResult(test, "foo.example.com", ["turnip", "bar"]); |
| - testResult(test, "example.com", ["bar"]); |
| - testResult(test, "com", ["bar"]); |
| - testResult(test, "", []); |
| - |
| - removeFilter("com##bar"); |
| - testResult(test, "foo.example.com", ["turnip"]); |
| - testResult(test, "example.com", []); |
| - testResult(test, "com", []); |
| - testResult(test, "", []); |
| - |
| - removeFilter("foo.example.com##turnip"); |
| - testResult(test, "foo.example.com", []); |
| - testResult(test, "example.com", []); |
| - testResult(test, "com", []); |
| - testResult(test, "", []); |
| - |
| - addFilter("example.com##dupe"); |
| - addFilter("example.com##dupe"); |
| - testResult(test, "example.com", ["dupe"]); |
| - removeFilter("example.com##dupe"); |
| - testResult(test, "example.com", []); |
| - removeFilter("example.com##dupe"); |
| - |
| - addFilter("~foo.example.com,example.com##foo"); |
| - |
| - addFilter("##foo"); |
| - testResult(test, "foo.example.com", ["foo"]); |
| - testResult(test, "example.com", ["foo"]); |
| - testResult(test, "com", ["foo"]); |
| - testResult(test, "", ["foo"]); |
| - removeFilter("##foo"); |
| - |
| - addFilter("example.org##foo"); |
| - testResult(test, "foo.example.com", []); |
| - testResult(test, "example.com", ["foo"]); |
| - testResult(test, "com", []); |
| - testResult(test, "", []); |
| - removeFilter("example.org##foo"); |
| + assert.equal((createStyleSheet(selectors).match(/\n/g) || []).length, |
| + Math.ceil(50000 / selectorGroupSize), |
| + "Style sheet should be split up into rules with at most " + |
| + selectorGroupSize + " selectors each"); |
| + }); |
| - addFilter("~example.com##foo"); |
| - testResult(test, "foo.example.com", []); |
| - testResult(test, "example.com", ["foo"]); |
| - testResult(test, "com", ["foo"]); |
| - testResult(test, "", ["foo"]); |
| - removeFilter("~example.com##foo"); |
| - |
| - removeFilter("~foo.example.com,example.com##foo"); |
| - |
| - // Test criteria |
| - addFilter("##hello"); |
| - addFilter("~example.com##world"); |
| - addFilter("foo.com##specific"); |
| - testResult(test, "foo.com", ["specific"], {specificOnly: true}); |
| - testResult(test, "foo.com", ["hello", "specific", "world"]); |
| - testResult(test, "example.com", [], {specificOnly: true}); |
| - removeFilter("foo.com##specific"); |
| - removeFilter("~example.com##world"); |
| - removeFilter("##hello"); |
| - testResult(test, "foo.com", []); |
| - |
| - addFilter("##hello"); |
| - testResult(test, "foo.com", [], {specificOnly: true}); |
| - testResult(test, "foo.com", ["hello"]); |
| - testResult(test, "bar.com", [], {specificOnly: true}); |
| - testResult(test, "bar.com", ["hello"]); |
| - addException("foo.com#@#hello"); |
| - testResult(test, "foo.com", [], {specificOnly: true}); |
| - testResult(test, "foo.com", [], {expectedExceptions: ["foo.com#@#hello"]}); |
| - testResult(test, "bar.com", [], {specificOnly: true}); |
| - testResult(test, "bar.com", ["hello"]); |
| - removeException("foo.com#@#hello"); |
| - testResult(test, "foo.com", [], {specificOnly: true}); |
| - // Note: We don't take care to track conditional selectors which became |
| - // unconditional when a filter was removed. This was too expensive. |
| - testResult(test, "foo.com", ["hello"]); |
| - testResult(test, "bar.com", [], {specificOnly: true}); |
| - testResult(test, "bar.com", ["hello"]); |
| - removeFilter("##hello"); |
| - testResult(test, "foo.com", []); |
| - testResult(test, "bar.com", []); |
| - |
| - addFilter("##hello"); |
| - addFilter("foo.com##hello"); |
| - testResult(test, "foo.com", ["hello"]); |
| - removeFilter("foo.com##hello"); |
| - testResult(test, "foo.com", ["hello"]); |
| - removeFilter("##hello"); |
| - testResult(test, "foo.com", []); |
| - |
| - addFilter("##hello"); |
| - addFilter("foo.com##hello"); |
| - testResult(test, "foo.com", ["hello"]); |
| - removeFilter("##hello"); |
| - testResult(test, "foo.com", ["hello"]); |
| - removeFilter("foo.com##hello"); |
| - testResult(test, "foo.com", []); |
| - |
| - test.done(); |
| -}; |
| + it("Escaping", () => |
| + { |
| + assert.equal( |
| + createStyleSheet([ |
| + "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
| + "#foo[data-bar='{foo: 1}']" |
| + ]), |
| + "html, #foo, .bar, #foo .bar, #foo > .bar, " + |
| + "#foo[data-bar='\\7B foo: 1\\7D '] {display: none !important;}\n", |
| + "Braces should be escaped" |
| + ); |
| + }); |
| + }); |
| -exports.testZeroFilterKey = function(test) |
| -{ |
| - ElemHide.add(Filter.fromText("##test")); |
| - ElemHideExceptions.add(Filter.fromText("foo.com#@#test")); |
| - testResult(test, "foo.com", [], {expectedExceptions: ["foo.com#@#test"]}); |
| - testResult(test, "bar.com", ["test"]); |
| - test.done(); |
| -}; |
| - |
| -exports.testFiltersByDomain = function(test) |
| -{ |
| - test.equal(filtersByDomain.size, 0); |
| - |
| - ElemHide.add(Filter.fromText("##test")); |
| - test.equal(filtersByDomain.size, 0); |
| - |
| - ElemHide.add(Filter.fromText("example.com##test")); |
| - test.equal(filtersByDomain.size, 1); |
| - |
| - ElemHide.add(Filter.fromText("example.com,~www.example.com##test")); |
| - test.equal(filtersByDomain.size, 2); |
| - |
| - ElemHide.remove(Filter.fromText("example.com##test")); |
| - test.equal(filtersByDomain.size, 2); |
| - |
| - ElemHide.remove(Filter.fromText("example.com,~www.example.com##test")); |
| - test.equal(filtersByDomain.size, 0); |
| - |
| - test.done(); |
| -}; |
| + it("Rules from StyleSheet", () => |
| + { |
| + // Note: The rulesFromStyleSheet function assumes that each rule will be |
| + // terminated with a newline character, including the last rule. If this is |
| + // not the case, the function goes into an infinite loop. It should only be |
| + // used with the return value of the createStyleSheet function. |
| -exports.testCreateStyleSheet = function(test) |
| -{ |
| - test.equal( |
| - createStyleSheet([ |
| - "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
| - "#foo[data-bar='bar']" |
| - ]), |
| - "html, #foo, .bar, #foo .bar, #foo > .bar, #foo[data-bar='bar'] " + |
| - "{display: none !important;}\n", |
| - "Style sheet creation should work" |
| - ); |
| - |
| - let selectors = new Array(50000).fill().map((element, index) => ".s" + index); |
| - |
| - test.equal((createStyleSheet(selectors).match(/\n/g) || []).length, |
| - Math.ceil(50000 / selectorGroupSize), |
| - "Style sheet should be split up into rules with at most " + |
| - selectorGroupSize + " selectors each"); |
| - |
| - test.equal( |
| - createStyleSheet([ |
| - "html", "#foo", ".bar", "#foo .bar", "#foo > .bar", |
| - "#foo[data-bar='{foo: 1}']" |
| - ]), |
| - "html, #foo, .bar, #foo .bar, #foo > .bar, " + |
| - "#foo[data-bar='\\7B foo: 1\\7D '] {display: none !important;}\n", |
| - "Braces should be escaped" |
| - ); |
| - |
| - test.done(); |
| -}; |
| - |
| -exports.testRulesFromStyleSheet = function(test) |
| -{ |
| - // Note: The rulesFromStyleSheet function assumes that each rule will be |
| - // terminated with a newline character, including the last rule. If this is |
| - // not the case, the function goes into an infinite loop. It should only be |
| - // used with the return value of the createStyleSheet function. |
| - |
| - test.deepEqual([...rulesFromStyleSheet("")], []); |
| - test.deepEqual([...rulesFromStyleSheet("#foo {}\n")], ["#foo {}"]); |
| - test.deepEqual([...rulesFromStyleSheet("#foo {}\n#bar {}\n")], |
| - ["#foo {}", "#bar {}"]); |
| - |
| - test.done(); |
| -}; |
| + assert.deepEqual([...rulesFromStyleSheet("")], []); |
| + assert.deepEqual([...rulesFromStyleSheet("#foo {}\n")], ["#foo {}"]); |
| + assert.deepEqual([...rulesFromStyleSheet("#foo {}\n#bar {}\n")], |
| + ["#foo {}", "#bar {}"]); |
| + }); |
| +}); |