| 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; |