Index: test/synchronizer.js |
=================================================================== |
--- a/test/synchronizer.js |
+++ b/test/synchronizer.js |
@@ -12,328 +12,44 @@ |
* 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"; |
-let {createSandbox} = require("./_common"); |
- |
-const MILLIS_IN_SECOND = 1000; |
-const MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND; |
-const MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE; |
-const MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR; |
- |
-const Cr = { |
- NS_OK: 0, |
- NS_BINDING_ABORTED: 0x804B0002, |
- NS_ERROR_FAILURE: 0x80004005 |
-} |
+let { |
+ createSandbox, setupTimerAndXMLHttp, setupRandomResult, unexpectedError, Cr, |
+ MILLIS_IN_SECOND, MILLIS_IN_HOUR |
+} = require("./_common"); |
let Filter = null; |
let FilterStorage = null; |
let Prefs = null; |
let Subscription = null; |
let Synchronizer = null; |
exports.setUp = function(callback) |
{ |
- 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"); |
+ let globals = Object.assign({}, setupTimerAndXMLHttp.call(this), |
+ setupRandomResult.call(this)); |
- 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 |
- }); |
- |
- let randomResult = 0.5; |
- Object.defineProperty(this, "randomResult", { |
- get: () => randomResult, |
- set: value => randomResult = value |
- }); |
- |
- let sandboxedRequire = createSandbox({ |
- globals: { |
- Cc: { |
- "@mozilla.org/timer;1": { |
- createInstance: () => fakeTimer |
- } |
- }, |
- Ci: { |
- nsITimer: |
- { |
- TYPE_ONE_SHOT: 0, |
- TYPE_REPEATING_SLACK: 1, |
- TYPE_REPEATING_PRECISE: 2 |
- }, |
- nsIHttpChannel: () => null, |
- }, |
- Cr: Cr, |
- XMLHttpRequest: XMLHttpRequest, |
- Date: { |
- now: () => currentTime |
- }, |
- Math: { |
- random: () => randomResult, |
- min: Math.min, |
- max: Math.max, |
- round: Math.round |
- }, |
- URL: function(urlString) |
- { |
- return require("url").parse(urlString); |
- } |
- } |
- }); |
- |
+ let sandboxedRequire = createSandbox({globals}); |
( |
{Filter} = sandboxedRequire("../lib/filterClasses"), |
{FilterStorage} = sandboxedRequire("../lib/filterStorage"), |
{Prefs} = sandboxedRequire("./stub-modules/prefs"), |
{Subscription} = sandboxedRequire("../lib/subscriptionClasses"), |
{Synchronizer} = sandboxedRequire("../lib/synchronizer") |
); |
callback(); |
}; |
-function unexpectedError(error) |
-{ |
- console.error(error); |
- this.ok(false, "Unexpected error: " + error); |
-} |
- |
function resetSubscription(subscription) |
{ |
FilterStorage.updateSubscriptionFilters(subscription, []); |
subscription.lastCheck = subscription.lastDownload = |
subscription.version = subscription.lastSuccess = |
subscription.expires = subscription.softExpiration = 0; |
subscription.title = ""; |
subscription.homepage = null; |