Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: test/filterStorage_readwrite.js

Issue 29356024: Issue 4223 - Adapt filter storage read/write tests to work in adblockpluscore repository (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Created Oct. 5, 2016, 8:02 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« README.md ('K') | « README.md ('k') | test/stub-modules/io.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/filterStorage_readwrite.js
===================================================================
--- a/test/filterStorage_readwrite.js
+++ b/test/filterStorage_readwrite.js
@@ -1,358 +1,315 @@
-(function()
-{
- module("Filter storage read/write", {
- setup: function()
- {
- prepareFilterComponents.call(this);
- preparePrefs.call(this);
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2016 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ */
- FilterStorage.addSubscription(Subscription.fromURL("~fl~"));
- },
- teardown: function()
- {
- restoreFilterComponents.call(this);
- restorePrefs.call(this);
- }
+"use strict";
+
+let {createSandbox, unexpectedError} = require("./_common");
+
+let Filter = null;
+let FilterNotifier = null;
+let FilterStorage = null;
+let IO = null;
+let Prefs = null;
+let Subscription = null;
+let ExternalSubscription = null;
+
+exports.setUp = function(callback)
+{
+ let sandboxedRequire = createSandbox();
+ (
+ {Filter} = sandboxedRequire("../lib/filterClasses"),
+ {FilterNotifier} = sandboxedRequire("../lib/filterNotifier"),
+ {FilterStorage} = sandboxedRequire("../lib/filterStorage"),
+ {IO} = sandboxedRequire("./stub-modules/io"),
+ {Prefs} = sandboxedRequire("./stub-modules/prefs"),
+ {Subscription, ExternalSubscription} = sandboxedRequire("../lib/subscriptionClasses")
+ );
+
+ FilterStorage.addSubscription(Subscription.fromURL("~fl~"));
+ callback();
+}
+
+let testData = new Promise((resolve, reject) =>
+{
+ let fs = require("fs");
+ let path = require("path");
+ let datapath = path.resolve(__dirname, "data", "patterns.ini");
kzar 2016/10/06 05:13:38 Did you forget to add the data/patterns.ini file?
Wladimir Palant 2016/10/06 07:13:59 No, I copied the files in a separate commit - what
kzar 2016/10/06 08:06:47 Acknowledged.
+
+ fs.readFile(datapath, "utf-8", (error, data) =>
+ {
+ if (error)
+ reject(error);
+ else
+ resolve(data);
});
+});
- let {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", null);
- let {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", null);
-
- function loadFilters(file, callback)
+function loadFilters(file)
+{
+ return new Promise((resolve, reject) =>
{
let listener = function(action)
kzar 2016/10/06 05:13:38 Seems like this logic is nearly identical in saveF
Wladimir Palant 2016/10/06 07:13:59 Reusing isn't quite trivial but with the new Filte
{
if (action == "load")
{
FilterNotifier.removeListener(listener);
- callback();
+ resolve();
}
};
FilterNotifier.addListener(listener);
FilterStorage.loadFromDisk(file);
- }
+ });
+}
- function writeToFile(file, data)
- {
- let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
- converter.charset = "utf-8";
- data = converter.ConvertFromUnicode(data);
-
- let stream = FileUtils.openFileOutputStream(file);
- stream.write(data, data.length);
- stream.close();
- }
-
- function saveFilters(file, callback)
+function saveFilters(file, callback)
+{
+ return new Promise((resolve, reject) =>
{
let listener = function(action)
{
if (action == "save")
{
FilterNotifier.removeListener(listener);
- callback();
+ resolve();
}
};
FilterNotifier.addListener(listener);
FilterStorage.saveToDisk(file);
+ });
+}
+
+function testReadWrite(test, withExternal)
+{
+ let tempFile = IO.resolveFilePath("temp_patterns1.ini");
+ let tempFile2 = IO.resolveFilePath("temp_patterns2.ini");
+
+ function canonize(data)
+ {
+ let curSection = null;
+ let sections = [];
+ for (let line of (data + "\n[end]").split(/[\r\n]+/))
+ {
+ if (/^\[.*\]$/.test(line))
+ {
+ if (curSection)
+ sections.push(curSection);
+
+ curSection = {header: line, data: []};
+ }
+ else if (curSection && /\S/.test(line))
+ curSection.data.push(line);
+ }
+ for (let section of sections)
+ {
+ section.key = section.header + " " + section.data[0];
+ section.data.sort();
+ }
+ sections.sort(function(a, b)
+ {
+ if (a.key < b.key)
+ return -1;
+ else if (a.key > b.key)
+ return 1;
+ else
+ return 0;
+ });
+ return sections.map(function(section) {
+ return [section.header].concat(section.data).join("\n");
+ }).join("\n");
}
- function testReadWrite(withExternal)
+ return testData.then(data =>
{
- let tempFile = FileUtils.getFile("TmpD", ["temp_patterns1.ini"]);
- let tempFile2 = FileUtils.getFile("TmpD", ["temp_patterns2.ini"]);
- tempFile.createUnique(tempFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- createTempFile();
-
- function canonize(data)
- {
- let curSection = null;
- let sections = [];
- for (let line of (data + "\n[end]").split(/[\r\n]+/))
- {
- if (/^\[.*\]$/.test(line))
- {
- if (curSection)
- sections.push(curSection);
+ tempFile.contents = data;
+ return loadFilters(tempFile);
+ }).then(() =>
+ {
+ test.equal(FilterStorage.fileProperties.version, FilterStorage.formatVersion, "File format version");
- curSection = {header: line, data: []};
- }
- else if (curSection && /\S/.test(line))
- curSection.data.push(line);
- }
- for (let section of sections)
- {
- section.key = section.header + " " + section.data[0];
- section.data.sort();
- }
- sections.sort(function(a, b)
- {
- if (a.key < b.key)
- return -1;
- else if (a.key > b.key)
- return 1;
- else
- return 0;
- });
- return sections.map(function(section) {
- return [section.header].concat(section.data).join("\n");
- }).join("\n");
- }
-
- function createTempFile()
+ if (withExternal)
{
- let request = new XMLHttpRequest();
- request.open("GET", "data/patterns.ini");
- request.overrideMimeType("text/plain; charset=utf-8");
- request.addEventListener("load", function()
- {
- writeToFile(tempFile, request.responseText);
- loadFilters(tempFile, saveFile);
- }, false);
- request.send(null);
- }
-
- function saveFile()
- {
- equal(FilterStorage.fileProperties.version, FilterStorage.formatVersion, "File format version");
+ let subscription = new ExternalSubscription("~external~external subscription ID", "External subscription");
+ subscription.filters = [Filter.fromText("foo"), Filter.fromText("bar")];
+ FilterStorage.addSubscription(subscription);
Wladimir Palant 2016/10/05 20:10:22 This was calling our public API in the original te
kzar 2016/10/06 05:13:38 Acknowledged.
- if (withExternal)
- {
- let {AdblockPlus} = Cu.import(Cc["@adblockplus.org/abp/public;1"].getService(Ci.nsIURI).spec, null);
- AdblockPlus.updateExternalSubscription("~external~external subscription ID", "External subscription", ["foo", "bar"]);
-
- let externalSubscriptions = FilterStorage.subscriptions.filter(function (subscription) subscription instanceof ExternalSubscription);
- equal(externalSubscriptions.length, 1, "Number of external subscriptions after updateExternalSubscription");
+ let externalSubscriptions = FilterStorage.subscriptions.filter(subscription => subscription instanceof ExternalSubscription);
+ test.equal(externalSubscriptions.length, 1, "Number of external subscriptions after updateExternalSubscription");
- if (externalSubscriptions.length == 1)
- {
- equal(externalSubscriptions[0].url, "~external~external subscription ID", "ID of external subscription");
- equal(externalSubscriptions[0].filters.length, 2, "Number of filters in external subscription");
- }
- }
-
- saveFilters(tempFile2, compareFile);
+ test.equal(externalSubscriptions[0].url, "~external~external subscription ID", "ID of external subscription");
+ test.equal(externalSubscriptions[0].filters.length, 2, "Number of filters in external subscription");
}
- function compareFile()
- {
- let stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- stream.init(tempFile2, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, Ci.nsIFileInputStream.DEFER_OPEN);
-
- NetUtil.asyncFetch(stream, function(inputStream, nsresult)
- {
- let result = NetUtil.readInputStreamToString(inputStream, inputStream.available(), {charset: "utf-8"});
-
- let request = new XMLHttpRequest();
- request.open("GET", "data/patterns.ini");
- request.overrideMimeType("text/plain");
- request.addEventListener("load", function()
- {
- let expected = request.responseText;
- equal(canonize(result), canonize(expected), "Read/write result");
-
- tempFile.remove(false);
- tempFile2.remove(false);
- start();
- }, false);
- request.send(null);
- });
- }
- }
-
- asyncTest("Read and save to file", testReadWrite.bind(false));
- asyncTest("Read, add external subscription and save to file", testReadWrite.bind(true));
-
- let groupTests = [
- ["~wl~", "whitelist"],
- ["~fl~", "blocking"],
- ["~eh~", "elemhide"]
- ];
- for (let i = 0; i < groupTests.length; i++)
+ return saveFilters(tempFile2);
+ }).then(() => testData).then(expected =>
{
- let [url, defaults] = groupTests[i];
- asyncTest("Read empty legacy user-defined group (" + url + ")", function()
- {
- let data = "[Subscription]\nurl=" + url;
- let tempFile = FileUtils.getFile("TmpD", ["temp_patterns1.ini"]);
- writeToFile(tempFile, data);
-
- loadFilters(tempFile, function()
- {
- tempFile.remove(false);
- equal(FilterStorage.subscriptions.length, 0, "Number of filter subscriptions");
- start();
- });
- });
- asyncTest("Read non-empty legacy user-defined group (" + url + ")", function()
- {
- let data = "[Subscription]\nurl=" + url + "\n[Subscription filters]\nfoo";
- let tempFile = FileUtils.getFile("TmpD", ["temp_patterns1.ini"]);
- writeToFile(tempFile, data);
+ test.equal(canonize(tempFile2.contents), canonize(expected), "Read/write result");
+ }).catch(unexpectedError.bind(test)).then(() => test.done());
+}
- loadFilters(tempFile, function()
- {
- tempFile.remove(false);
- equal(FilterStorage.subscriptions.length, 1, "Number of filter subscriptions");
- if (FilterStorage.subscriptions.length == 1)
- {
- let subscription = FilterStorage.subscriptions[0];
- equal(subscription.url, url, "Subscription ID");
- equal(subscription.title, Utils.getString(defaults + "Group_title"), "Subscription title");
- deepEqual(subscription.defaults, [defaults], "Default types");
- equal(subscription.filters.length, 1, "Number of subscription filters");
- if (subscription.filters.length == 1)
- equal(subscription.filters[0].text, "foo", "First filter");
- }
- start();
- });
- });
- }
+exports.testReadAndSaveToFile = function(test)
+{
+ testReadWrite(test, false);
+};
- asyncTest("Read legacy user-defined filters", function()
+exports.testReadAndSaveToFileWithExternalSubscription = function(test)
+{
+ testReadWrite(test, true);
+};
+
+exports.testLegacyGroups = {};
+
+for (let url of ["~wl~", "~fl~", "~eh~"])
+{
+ exports.testLegacyGroups["read empty " + url] = function(test)
{
- let data = "[Subscription]\nurl=~user~1234\ntitle=Foo\n[Subscription filters]\n[User patterns]\nfoo\n\\[bar]\nfoo#bar";
- let tempFile = FileUtils.getFile("TmpD", ["temp_patterns1.ini"]);
- writeToFile(tempFile, data);
+ let data = "[Subscription]\nurl=" + url;
+ let tempFile = IO.resolveFilePath("temp_patterns1.ini");
+ tempFile.contents = data;
loadFilters(tempFile, function()
{
- tempFile.remove(false);
- equal(FilterStorage.subscriptions.length, 1, "Number of filter subscriptions");
+ test.equal(FilterStorage.subscriptions.length, 0, "Number of filter subscriptions");
+ }).catch(unexpectedError.bind(test)).then(() => test.done());
+ };
+
+ exports.testLegacyGroups["read non-empty " + url] = function(test)
+ {
+ let data = "[Subscription]\nurl=" + url + "\n[Subscription filters]\nfoo";
+ let tempFile = IO.resolveFilePath("temp_patterns1.ini");
+ tempFile.contents = data;
+
+ loadFilters(tempFile).then(() =>
+ {
+ test.equal(FilterStorage.subscriptions.length, 1, "Number of filter subscriptions");
if (FilterStorage.subscriptions.length == 1)
{
let subscription = FilterStorage.subscriptions[0];
- equal(subscription.filters.length, 3, "Number of subscription filters");
- if (subscription.filters.length == 3)
- {
- equal(subscription.filters[0].text, "foo", "First filter");
- equal(subscription.filters[1].text, "[bar]", "Second filter");
- equal(subscription.filters[2].text, "foo#bar", "Third filter");
- }
+ test.equal(subscription.url, url, "Subscription ID");
kzar 2016/10/06 05:13:37 Won't `url` always be "~eh~" by the time the test
Wladimir Palant 2016/10/06 07:13:59 Good question. I checked and this isn't the case -
kzar 2016/10/06 08:06:47 Ah of course.
+ test.equal(subscription.title, null, "Subscription title");
+ test.deepEqual(subscription.defaults, null, "Default types");
Wladimir Palant 2016/10/05 20:10:22 I had to modify this, the fallback for legacy grou
kzar 2016/10/06 05:13:37 Acknowledged.
+ test.equal(subscription.filters.length, 1, "Number of subscription filters");
+ if (subscription.filters.length == 1)
+ test.equal(subscription.filters[0].text, "foo", "First filter");
}
- start();
- });
- });
-
- asyncTest("Saving without backups", function()
- {
- Prefs.patternsbackups = 0;
- Prefs.patternsbackupinterval = 24;
-
- let tempFile = FileUtils.getFile("TmpD", ["temp_patterns.ini"]);
- tempFile.createUnique(tempFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- FilterStorage.__defineGetter__("sourceFile", () => tempFile.clone());
+ }).catch(unexpectedError.bind(test)).then(() => test.done());
+ };
+}
- saveFilters(null, function()
+exports.testReadLegacyFilters = function(test)
+{
+ let data = "[Subscription]\nurl=~user~1234\ntitle=Foo\n[Subscription filters]\n[User patterns]\nfoo\n\\[bar]\nfoo#bar";
+ let tempFile = IO.resolveFilePath("temp_patterns1.ini");
+ tempFile.contents = data;
+
+ loadFilters(tempFile).then(() =>
+ {
+ test.equal(FilterStorage.subscriptions.length, 1, "Number of filter subscriptions");
+ if (FilterStorage.subscriptions.length == 1)
{
- saveFilters(null, function()
+ let subscription = FilterStorage.subscriptions[0];
+ test.equal(subscription.filters.length, 3, "Number of subscription filters");
+ if (subscription.filters.length == 3)
{
- let backupFile = tempFile.clone();
- backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini");
- ok(!backupFile.exists(), "Backup shouldn't be created");
- start();
- });
- });
- });
+ test.equal(subscription.filters[0].text, "foo", "First filter");
+ test.equal(subscription.filters[1].text, "[bar]", "Second filter");
+ test.equal(subscription.filters[2].text, "foo#bar", "Third filter");
+ }
+ }
+ }).catch(unexpectedError.bind(test)).then(() => test.done());
+};
- asyncTest("Saving with backups", function()
+exports.testSavingWithoutBackups = function(test)
+{
+ Prefs.patternsbackups = 0;
+ Prefs.patternsbackupinterval = 24;
+
+ let tempFile = IO.resolveFilePath("temp_patterns.ini");
+ Object.defineProperty(FilterStorage, "sourceFile", {get: () => tempFile.clone()});
+
+ saveFilters(null).then(() =>
{
- Prefs.patternsbackups = 2;
- Prefs.patternsbackupinterval = 24;
-
- let tempFile = FileUtils.getFile("TmpD", ["temp_patterns.ini"]);
- tempFile.createUnique(tempFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- FilterStorage.__defineGetter__("sourceFile", () => tempFile.clone());
-
+ return saveFilters(null);
+ }).then(() =>
+ {
let backupFile = tempFile.clone();
backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini");
-
- let backupFile2 = tempFile.clone();
- backupFile2.leafName = backupFile2.leafName.replace(/\.ini$/, "-backup2.ini");
-
- let backupFile3 = tempFile.clone();
- backupFile3.leafName = backupFile3.leafName.replace(/\.ini$/, "-backup3.ini");
-
- let oldModifiedTime;
-
- saveFilters(null, callback1);
-
- function callback1()
- {
- // Save again immediately
- saveFilters(null, callback2);
- }
-
- function callback2()
- {
- backupFile = backupFile.clone(); // File parameters are cached, clone to prevent this
- ok(backupFile.exists(), "First backup created");
-
- backupFile.lastModifiedTime -= 10000;
- oldModifiedTime = backupFile.lastModifiedTime;
- saveFilters(null, callback3);
- }
-
- function callback3()
- {
- backupFile = backupFile.clone(); // File parameters are cached, clone to prevent this
- equal(backupFile.lastModifiedTime, oldModifiedTime, "Backup not overwritten if it is only 10 seconds old");
-
- backupFile.lastModifiedTime -= 40*60*60*1000;
- oldModifiedTime = backupFile.lastModifiedTime;
- saveFilters(null, callback4);
- }
-
- function callback4()
- {
- backupFile = backupFile.clone(); // File parameters are cached, clone to prevent this
- notEqual(backupFile.lastModifiedTime, oldModifiedTime, "Backup overwritten if it is 40 hours old");
+ test.ok(!backupFile.exists(), "Backup shouldn't be created");
+ }).catch(unexpectedError.bind(test)).then(() => test.done());
+};
- backupFile2 = backupFile2.clone(); // File parameters are cached, clone to prevent this
- ok(backupFile2.exists(), "Second backup created when first backup is overwritten");
-
- backupFile.lastModifiedTime -= 20000;
- oldModifiedTime = backupFile2.lastModifiedTime;
- saveFilters(null, callback5);
- }
-
- function callback5()
- {
- backupFile2 = backupFile2.clone(); // File parameters are cached, clone to prevent this
- equal(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup not overwritten if first one is only 20 seconds old");
-
- backupFile.lastModifiedTime -= 25*60*60*1000;
- oldModifiedTime = backupFile2.lastModifiedTime;
- saveFilters(null, callback6);
- }
-
- function callback6()
- {
- backupFile2 = backupFile2.clone(); // File parameters are cached, clone to prevent this
- notEqual(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup overwritten if first one is 25 hours old");
+exports.testSavingWithBackups = function(test)
+{
+ Prefs.patternsbackups = 2;
+ Prefs.patternsbackupinterval = 24;
- ok(!backupFile3.exists(), "Third backup not created with patternsbackups = 2");
+ let tempFile = IO.resolveFilePath("temp_patterns.ini");
+ Object.defineProperty(FilterStorage, "sourceFile", {get: () => tempFile.clone()});
- try
- {
- tempFile.remove(false);
- } catch (e) {}
- try
- {
- backupFile.remove(false);
- } catch (e) {}
- try
- {
- backupFile2.remove(false);
- } catch (e) {}
- try
- {
- backupFile3.remove(false);
- } catch (e) {}
+ let backupFile = tempFile.clone();
+ backupFile.leafName = backupFile.leafName.replace(/\.ini$/, "-backup1.ini");
- start();
- }
- });
-})();
+ let backupFile2 = tempFile.clone();
+ backupFile2.leafName = backupFile2.leafName.replace(/\.ini$/, "-backup2.ini");
+
+ let backupFile3 = tempFile.clone();
+ backupFile3.leafName = backupFile3.leafName.replace(/\.ini$/, "-backup3.ini");
+
+ let oldModifiedTime;
+
+ saveFilters(null).then(() =>
+ {
+ // Save again immediately
+ return saveFilters(null);
+ }).then(() =>
+ {
+ test.ok(backupFile.exists(), "First backup created");
+
+ backupFile.lastModifiedTime -= 10000;
+ oldModifiedTime = backupFile.lastModifiedTime;
+ return saveFilters(null);
+ }).then(() =>
+ {
+ test.equal(backupFile.lastModifiedTime, oldModifiedTime, "Backup not overwritten if it is only 10 seconds old");
+
+ backupFile.lastModifiedTime -= 40*60*60*1000;
+ oldModifiedTime = backupFile.lastModifiedTime;
+ return saveFilters(null);
+ }).then(() =>
+ {
+ test.notEqual(backupFile.lastModifiedTime, oldModifiedTime, "Backup overwritten if it is 40 hours old");
+
+ test.ok(backupFile2.exists(), "Second backup created when first backup is overwritten");
+
+ backupFile.lastModifiedTime -= 20000;
+ oldModifiedTime = backupFile2.lastModifiedTime;
+ return saveFilters(null);
+ }).then(() =>
+ {
+ test.equal(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup not overwritten if first one is only 20 seconds old");
+
+ backupFile.lastModifiedTime -= 25*60*60*1000;
+ oldModifiedTime = backupFile2.lastModifiedTime;
+ return saveFilters(null);
+ }).then(() =>
+ {
+ test.notEqual(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup overwritten if first one is 25 hours old");
+
+ test.ok(!backupFile3.exists(), "Third backup not created with patternsbackups = 2");
+ }).catch(unexpectedError.bind(test)).then(() => test.done());
+};
« README.md ('K') | « README.md ('k') | test/stub-modules/io.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld