| Index: test/abp2blocklist.js | 
| =================================================================== | 
| --- a/test/abp2blocklist.js | 
| +++ b/test/abp2blocklist.js | 
| @@ -15,23 +15,24 @@ | 
| * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| */ | 
|  | 
| "use strict"; | 
|  | 
| let Filter = require("filterClasses").Filter; | 
| let ContentBlockerList = require("../lib/abp2blocklist.js").ContentBlockerList; | 
|  | 
| -function testRules(test, filters, expected, transformFunction) | 
| +function testRules(test, filters, expected, transformFunction, | 
| +                   {merge = false, advancedMerge = false} = {}) | 
| { | 
| let blockerList = new ContentBlockerList(); | 
| for (let filter of filters) | 
| blockerList.addFilter(Filter.fromText(filter)); | 
|  | 
| -  let rules = blockerList.generateRules(); | 
| +  let rules = blockerList.generateRules({merge, advancedMerge}); | 
| if (transformFunction) | 
| rules = transformFunction(rules); | 
|  | 
| test.deepEqual(rules, expected); | 
| } | 
|  | 
| exports.generateRules = { | 
| testElementHiding: function(test) | 
| @@ -226,10 +227,115 @@ | 
| testUnicode: function(test) | 
| { | 
| testRules(test, ["$domain=🐈.cat"], ["xn--zn8h.cat", "www.xn--zn8h.cat"], | 
| rules => rules[0]["trigger"]["if-domain"]); | 
| testRules(test, ["🐈$domain=🐈.cat"], []); | 
| testRules(test, ["###🐈"], []); | 
|  | 
| test.done(); | 
| +  }, | 
| + | 
| +  testMerging: function(test) | 
| +  { | 
| +    testRules(test, ["/ads", "/adv"], ["^https?://.*/ad[sv]"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads", "/adv", "/ad"], ["^https?://.*/ad[sv]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ad", "/ads", "/adv"], ["^https?://.*/ad[sv]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/a", "/ad", "/ads", "/adv"], | 
| +              ["^https?://.*/a", "^https?://.*/ad[sv]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ad", "/a", "/ads", "/adv"], | 
| +              ["^https?://.*/a", "^https?://.*/ad[sv]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads", "/adv", "/ad", "/a"], | 
| +              ["^https?://.*/ad[sv]?", "^https?://.*/a"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads", "/adv", "/a", "/ad"], | 
| +              ["^https?://.*/ad[sv]?", "^https?://.*/a"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ad", "/a", "/ads", "/adv", "/adx"], | 
| +              ["^https?://.*/a", "^https?://.*/ad[svx]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads", "/a", "/ad", "/adv", "/adx"], | 
| +              ["^https?://.*/ad[svx]?", "^https?://.*/a"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads", "/a", "/ad", "/adv", "/adx", "/adxs"], | 
| +              ["^https?://.*/ad[svx]?", "^https?://.*/a", "^https?://.*/adxs"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/adxs", "/a", "/ad", "/ads", "/adv", "/adx"], | 
| +              ["^https?://.*/adxs", "^https?://.*/a", "^https?://.*/ad[svx]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/adxs", "/a", "/ads", "/ad", "/adv", "/adx"], | 
| +              ["^https?://.*/adxs", "^https?://.*/a", "^https?://.*/ad[svx]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/adxs", "/a", "/ads", "/adv", "/ad", "/adx"], | 
| +              ["^https?://.*/adxs", "^https?://.*/a", "^https?://.*/ad[svx]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/adsxi", "/adxs", "/a", "/ads", "/adv", "/ad", "/adx"], | 
| +              ["^https?://.*/adsxi", "^https?://.*/adxs", "^https?://.*/a", | 
| +               "^https?://.*/ad[svx]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/adxsi", "/adsxi", "/adxs", "/a", "/ads", "/adv", "/ad", | 
| +                     "/adx"], | 
| +              ["^https?://.*/adxsi?", "^https?://.*/adsxi", "^https?://.*/a", | 
| +               "^https?://.*/ad[svx]?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| + | 
| +    // Given "ads", "bds", "adv", "bdv", "adx", and "bdx", we want "ad[svx]" | 
| +    // and "bd[svx]" (2 rules), not "[ab]ds", "[ab]dv", and "[ab]dx" (3 rules). | 
| +    testRules(test, ["/ads", "/bds", "/adv", "/bdv", "/adx", "/bdx"], | 
| +              ["^https?://.*/ad[svx]", "^https?://.*/bd[svx]"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads", "/bds", "/adv", "/bdv", "/bdx"], | 
| +              ["^https?://.*/ad[sv]", "^https?://.*/bd[svx]"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| + | 
| +    // Make sure it ignores special characters. | 
| +    testRules(test, ["/ads?", "/ads"], | 
| +              ["^https?://.*/ads\\?", "^https?://.*/ads"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads?", "/ads-"], | 
| +              ["^https?://.*/ads\\?", "^https?://.*/ads-"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| +    testRules(test, ["/ads?-", "/ads-"], | 
| +              ["^https?://.*/ads\\?-", "^https?://.*/ads-"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true}); | 
| + | 
| +    // Test advanced merge. | 
| +    testRules(test, ["/ad", "/adxsi"], | 
| +              ["^https?://.*/ad(xsi)?"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true, advancedMerge: true}); | 
| +    testRules(test, ["/adxsi", "/xsi"], | 
| +              ["^https?://.*/(ad)?xsi"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true, advancedMerge: true}); | 
| +    testRules(test, ["/ad", "/adxsi", "/xsi", "/axsi", "/bxsi"], | 
| +              ["^https?://.*/ad(xsi)?", "^https?://.*/[ab]?xsi"], | 
| +              rules => rules.map(rule => rule.trigger["url-filter"]), | 
| +              {merge: true, advancedMerge: true}); | 
| + | 
| +    test.done(); | 
| } | 
| }; | 
|  |