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

Unified Diff: test/_common.js

Issue 29356001: Issue 4223 - Adapt notification tests to work in adblockpluscore repository (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Addressed comments Created Oct. 5, 2016, 12:50 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
« no previous file with comments | « no previous file | test/notification.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/_common.js
===================================================================
--- a/test/_common.js
+++ b/test/_common.js
@@ -16,16 +16,27 @@
*/
"use strict";
let fs = require("fs");
let path = require("path");
let SandboxedModule = require("sandboxed-module");
+const Cr = exports.Cr = {
+ NS_OK: 0,
+ NS_BINDING_ABORTED: 0x804B0002,
+ NS_ERROR_FAILURE: 0x80004005
+};
+
+const MILLIS_IN_SECOND = exports.MILLIS_IN_SECOND = 1000;
+const MILLIS_IN_MINUTE = exports.MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND;
+const MILLIS_IN_HOUR = exports.MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
+const MILLIS_IN_DAY = exports.MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
+
let globals = {
atob: data => new Buffer(data, "base64").toString("binary"),
btoa: data => new Buffer(data, "binary").toString("base64"),
Ci: {
},
Cu: {
import: () => {},
reportError: e => undefined
@@ -41,22 +52,52 @@ let globals = {
{
}
},
Services: {
obs: {
addObserver: () =>
{
}
+ },
+ vc: {
+ compare: (v1, v2) =>
+ {
+ function comparePart(p1, p2)
+ {
+ if (p1 != "*" && p2 == "*")
+ return -1;
+ else if (p1 == "*" && p2 != "*")
+ return 1;
+ else if (p1 == p2)
+ return 0;
+ else
+ return parseInt(p1, 10) - parseInt(p2, 10);
+ }
+
+ let parts1 = v1.split(".");
+ let parts2 = v2.split(".");
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++)
+ {
+ let result = comparePart(parts1[i] || "0", parts2[i] || "0");
+ if (result != 0)
+ return result;
+ }
+ return 0;
+ }
}
},
XPCOMUtils: {
generateQI: () =>
{
}
+ },
+ URL: function(urlString)
+ {
+ return require("url").parse(urlString);
}
};
let knownModules = new Map();
for (let dir of [path.join(__dirname, "stub-modules"),
path.join(__dirname, "..", "lib")])
for (let file of fs.readdirSync(path.resolve(dir)))
if (path.extname(file) == ".js")
@@ -103,8 +144,291 @@ exports.createSandbox = function(options
// function which can be used to load further modules into the sandbox.
return SandboxedModule.require("./_common", {
globals: Object.assign({}, globals, options.globals),
sourceTransformers: sourceTransformers
}).require;
};
exports.require = require;
+
+exports.setupTimerAndXMLHttp = function()
+{
+ let currentTime = 100000 * MILLIS_IN_HOUR;
+ let startTime = currentTime;
+
+ let fakeTimer = {
+ callback: null,
+ delay: -1,
+ nextExecution: 0,
+
+ initWithCallback: function(callback, delay, type)
+ {
+ if (this.callback)
+ throw new Error("Only one timer instance supported");
+ if (type != 1)
+ throw new Error("Only TYPE_REPEATING_SLACK timers supported");
+
+ this.callback = callback;
+ this.delay = delay;
+ this.nextExecution = currentTime + delay;
+ },
+
+ trigger: function()
+ {
+ if (currentTime < this.nextExecution)
+ currentTime = this.nextExecution;
+ try
+ {
+ this.callback();
+ }
+ finally
+ {
+ this.nextExecution = currentTime + this.delay;
+ }
+ },
+
+ cancel: function()
+ {
+ this.nextExecution = -1;
+ }
+ };
+
+ let requests = [];
+ function XMLHttpRequest()
+ {
+ this._host = "http://example.com";
+ this._loadHandlers = [];
+ this._errorHandlers = [];
+ };
+ XMLHttpRequest.prototype =
+ {
+ _path: null,
+ _data: null,
+ _queryString: null,
+ _loadHandlers: null,
+ _errorHandlers: null,
+ status: 0,
+ readyState: 0,
+ responseText: null,
+
+ addEventListener: function(eventName, handler, capture)
+ {
+ let list;
+ if (eventName == "load")
+ list = this._loadHandlers;
+ else if (eventName == "error")
+ list = this._errorHandlers;
+ else
+ throw new Error("Event type " + eventName + " not supported");
+
+ if (list.indexOf(handler) < 0)
+ list.push(handler);
+ },
+
+ removeEventListener: function(eventName, handler, capture)
+ {
+ let list;
+ if (eventName == "load")
+ list = this._loadHandlers;
+ else if (eventName == "error")
+ list = this._errorHandlers;
+ else
+ throw new Error("Event type " + eventName + " not supported");
+
+ let index = list.indexOf(handler);
+ if (index >= 0)
+ list.splice(index, 1);
+ },
+
+ open: function(method, url, async, user, password)
+ {
+ if (method != "GET")
+ throw new Error("Only GET requests are supported");
+ if (typeof async != "undefined" && !async)
+ throw new Error("Sync requests are not supported");
+ if (typeof user != "undefined" || typeof password != "undefined")
+ throw new Error("User authentification is not supported");
+
+ let match = /^data:[^,]+,/.exec(url);
+ if (match)
+ {
+ this._data = decodeURIComponent(url.substr(match[0].length));
+ return;
+ }
+
+ if (url.substr(0, this._host.length + 1) != this._host + "/")
+ throw new Error("Unexpected URL: " + url + " (URL starting with " + this._host + "expected)");
+
+ this._path = url.substr(this._host.length);
+
+ let queryIndex = this._path.indexOf("?");
+ this._queryString = "";
+ if (queryIndex >= 0)
+ {
+ this._queryString = this._path.substr(queryIndex + 1);
+ this._path = this._path.substr(0, queryIndex);
+ }
+ },
+
+ send: function(data)
+ {
+ if (!this._data && !this._path)
+ throw new Error("No request path set");
+ if (typeof data != "undefined" && data)
+ throw new Error("Sending data to server is not supported");
+
+ requests.push(Promise.resolve().then(() =>
+ {
+ let result = [Cr.NS_OK, 404, ""];
+ if (this._data)
+ result = [Cr.NS_OK, 0, this._data];
+ else if (this._path in XMLHttpRequest.requestHandlers)
+ {
+ result = XMLHttpRequest.requestHandlers[this._path]({
+ method: "GET",
+ path: this._path,
+ queryString: this._queryString
+ });
+ }
+
+ [this.channel.status, this.channel.responseStatus, this.responseText] = result;
+ this.status = this.channel.responseStatus;
+
+ let eventName = (this.channel.status == Cr.NS_OK ? "load" : "error");
+ let event = {type: eventName};
+ for (let handler of this["_" + eventName + "Handlers"])
+ handler.call(this, event);
+ }));
+ },
+
+ overrideMimeType: function(mime)
+ {
+ },
+
+ channel:
+ {
+ status: -1,
+ responseStatus: 0,
+ loadFlags: 0,
+ INHIBIT_CACHING: 0,
+ VALIDATE_ALWAYS: 0,
+ QueryInterface: () => this
+ }
+ };
+
+ XMLHttpRequest.requestHandlers = {};
+ this.registerHandler = (path, handler) =>
+ {
+ XMLHttpRequest.requestHandlers[path] = handler;
+ };
+
+ function waitForRequests()
+ {
+ if (requests.length)
+ {
+ let result = Promise.all(requests);
+ requests = [];
+ return result.catch(e =>
+ {
+ console.error(e);
+ }).then(() => waitForRequests());
+ }
+ else
+ return Promise.resolve();
+ }
+
+ function runScheduledTasks(maxMillis)
+ {
+ let endTime = currentTime + maxMillis;
+ if (fakeTimer.nextExecution < 0 || fakeTimer.nextExecution > endTime)
+ {
+ currentTime = endTime;
+ return Promise.resolve();
+ }
+ else
+ {
+ fakeTimer.trigger();
+ return waitForRequests().then(() => runScheduledTasks(endTime - currentTime));
+ }
+
+ currentTime = endTime;
+ }
+
+ this.runScheduledTasks = (maxHours, initial, skip) =>
+ {
+ if (typeof maxHours != "number")
+ throw new Error("Numerical parameter expected");
+ if (typeof initial != "number")
+ initial = 0;
+ if (typeof skip != "number")
+ skip = 0;
+
+ startTime = currentTime;
+ return Promise.resolve().then(() =>
+ {
+ if (initial >= 0)
+ {
+ maxHours -= initial;
+ return runScheduledTasks(initial * MILLIS_IN_HOUR);
+ }
+ }).then(() =>
+ {
+ if (skip >= 0)
+ {
+ maxHours -= skip;
+ currentTime += skip * MILLIS_IN_HOUR;
+ }
+ return runScheduledTasks(maxHours * MILLIS_IN_HOUR);
+ });
+ };
+
+ this.getTimeOffset = () => (currentTime - startTime) / MILLIS_IN_HOUR;
+ Object.defineProperty(this, "currentTime", {
+ get: () => currentTime
+ });
+
+ return {
+ Cc: {
+ "@mozilla.org/timer;1": {
+ createInstance: () => fakeTimer
+ }
+ },
+ Ci: {
+ nsITimer:
+ {
+ TYPE_ONE_SHOT: 0,
+ TYPE_REPEATING_SLACK: 1,
+ TYPE_REPEATING_PRECISE: 2
+ },
+ nsIHttpChannel: () => null,
+ },
+ Cr,
+ XMLHttpRequest,
+ Date: {
+ now: () => currentTime
+ }
+ };
+};
+
+exports.setupRandomResult = function()
+{
+ let randomResult = 0.5;
+ Object.defineProperty(this, "randomResult", {
+ get: () => randomResult,
+ set: value => randomResult = value
+ });
+
+ return {
+ Math: {
+ random: () => randomResult,
+ min: Math.min,
+ max: Math.max,
+ round: Math.round
+ }
+ };
+};
+
+exports.unexpectedError = function(error)
+{
+ console.error(error);
+ this.ok(false, "Unexpected error: " + error);
+};
« no previous file with comments | « no previous file | test/notification.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld