UNPKG

d2-ui

Version:
1,261 lines (952 loc) 38.6 kB
/*global describe, beforeEach, afterEach, it, assert */ /** * @author Christian Johansen (christian@cjohansen.no) * @license BSD * * Copyright (c) 2010-2014 Christian Johansen */ "use strict"; if (typeof require === "function" && typeof module === "object") { var referee = require("referee"); var lolex = require("../src/lolex"); var sinon = require("sinon"); global.lolex = lolex; // For testing eval } var assert = referee.assert; var refute = referee.refute; var GlobalDate = Date; var NOOP = function NOOP() { return undefined; }; describe("lolex", function () { describe("setTimeout", function () { beforeEach(function () { this.clock = lolex.createClock(); lolex.evalCalled = false; }); afterEach(function () { delete lolex.evalCalled; }); it("throws if no arguments", function () { var clock = this.clock; assert.exception(function () { clock.setTimeout(); }); }); it("returns numeric id or object with numeric id", function () { var result = this.clock.setTimeout(""); if (typeof result === 'object') { assert.isNumber(result.id); } else { assert.isNumber(result); } }); it("returns unique id", function () { var id1 = this.clock.setTimeout(""); var id2 = this.clock.setTimeout(""); refute.equals(id2, id1); }); it("sets timers on instance", function () { var clock1 = lolex.createClock(); var clock2 = lolex.createClock(); var stubs = [sinon.stub(), sinon.stub()]; clock1.setTimeout(stubs[0], 100); clock2.setTimeout(stubs[1], 100); clock2.tick(200); assert.isFalse(stubs[0].called); assert(stubs[1].called); }); it("evals non-function callbacks", function () { this.clock.setTimeout("lolex.evalCalled = true", 10); this.clock.tick(10); assert(lolex.evalCalled); }); it("passes setTimeout parameters", function () { var clock = lolex.createClock(); var stub = sinon.stub(); clock.setTimeout(stub, 2, "the first", "the second"); clock.tick(3); assert.isTrue(stub.calledWithExactly("the first", "the second")); }); it("calls correct timeout on recursive tick", function () { var clock = lolex.createClock(); var stub = sinon.stub(); var recurseCallback = function () { clock.tick(100); }; clock.setTimeout(recurseCallback, 50); clock.setTimeout(stub, 100); clock.tick(50); assert(stub.called); }); it("does not depend on this", function () { var clock = lolex.createClock(); var stub = sinon.stub(); var setTimeout = clock.setTimeout; setTimeout(stub, 100); clock.tick(100); assert(stub.called); }); it("is not influenced by forward system clock changes", function () { var stub = sinon.stub(); this.clock.setTimeout(stub, 5000); this.clock.tick(1000); this.clock.setSystemTime((new this.clock.Date()).getTime() + 1000); this.clock.tick(3990); assert.equals(stub.callCount, 0); this.clock.tick(20); assert.equals(stub.callCount, 1); }); it("is not influenced by backward system clock changes", function () { var stub = sinon.stub(); this.clock.setTimeout(stub, 5000); this.clock.tick(1000); this.clock.setSystemTime((new this.clock.Date()).getTime() - 1000); this.clock.tick(3990); assert.equals(stub.callCount, 0); this.clock.tick(20); assert.equals(stub.callCount, 1); }); }); describe("setImmediate", function () { beforeEach(function () { this.clock = lolex.createClock(); }); it("returns numeric id or object with numeric id", function () { var result = this.clock.setImmediate(NOOP); if (typeof result === 'object') { assert.isNumber(result.id); } else { assert.isNumber(result); } }); it("calls the given callback immediately", function () { var stub = sinon.stub(); this.clock.setImmediate(stub); this.clock.tick(0); assert(stub.called); }); it("throws if no arguments", function () { var clock = this.clock; assert.exception(function () { clock.setImmediate(); }); }); it("manages separate timers per clock instance", function () { var clock1 = lolex.createClock(); var clock2 = lolex.createClock(); var stubs = [sinon.stub(), sinon.stub()]; clock1.setImmediate(stubs[0]); clock2.setImmediate(stubs[1]); clock2.tick(0); assert.isFalse(stubs[0].called); assert(stubs[1].called); }); it("passes extra parameters through to the callback", function () { var stub = sinon.stub(); this.clock.setImmediate(stub, 'value1', 2); this.clock.tick(1); assert(stub.calledWithExactly('value1', 2)); }); it("calls the given callback before setTimeout", function () { var stub1 = sinon.stub.create(); var stub2 = sinon.stub.create(); this.clock.setTimeout(stub1, 0); this.clock.setImmediate(stub2); this.clock.tick(0); assert(stub1.calledOnce); assert(stub2.calledOnce); assert(stub2.calledBefore(stub1)); }); it("does not stuck next tick even if nested", function () { var clock = this.clock; clock.setImmediate(function f() { clock.setImmediate(f); }); clock.tick(0); }); }); describe("clearImmediate", function () { beforeEach(function () { this.clock = lolex.createClock(); }); it("removes immediate callbacks", function () { var callback = sinon.stub(); var id = this.clock.setImmediate(callback); this.clock.clearImmediate(id); this.clock.tick(1); assert.isFalse(callback.called); }); it("does not remove timeout", function () { var callback = sinon.stub(); var id = this.clock.setTimeout(callback, 50); assert.exception(function() { this.clock.clearImmediate(id); }); this.clock.tick(55); assert.isTrue(callback.called); }); it("does not remove interval", function () { var callback = sinon.stub(); var id = this.clock.setInterval(callback, 50); assert.exception(function() { this.clock.clearImmediate(id); }); this.clock.tick(55); assert.isTrue(callback.called); }); }); describe("tick", function () { beforeEach(function () { this.clock = lolex.install(0); }); afterEach(function () { this.clock.uninstall(); }); it("triggers immediately without specified delay", function () { var stub = sinon.stub(); this.clock.setTimeout(stub); this.clock.tick(0); assert(stub.called); }); it("does not trigger without sufficient delay", function () { var stub = sinon.stub(); this.clock.setTimeout(stub, 100); this.clock.tick(10); assert.isFalse(stub.called); }); it("triggers after sufficient delay", function () { var stub = sinon.stub(); this.clock.setTimeout(stub, 100); this.clock.tick(100); assert(stub.called); }); it("triggers simultaneous timers", function () { var spies = [sinon.spy(), sinon.spy()]; this.clock.setTimeout(spies[0], 100); this.clock.setTimeout(spies[1], 100); this.clock.tick(100); assert(spies[0].called); assert(spies[1].called); }); it("triggers multiple simultaneous timers", function () { var spies = [sinon.spy(), sinon.spy(), sinon.spy(), sinon.spy()]; this.clock.setTimeout(spies[0], 100); this.clock.setTimeout(spies[1], 100); this.clock.setTimeout(spies[2], 99); this.clock.setTimeout(spies[3], 100); this.clock.tick(100); assert(spies[0].called); assert(spies[1].called); assert(spies[2].called); assert(spies[3].called); }); it("triggers multiple simultaneous timers with zero callAt", function () { var test = this; var spies = [ sinon.spy(function () { test.clock.setTimeout(spies[1], 0); }), sinon.spy(), sinon.spy() ]; // First spy calls another setTimeout with delay=0 this.clock.setTimeout(spies[0], 0); this.clock.setTimeout(spies[2], 10); this.clock.tick(10); assert(spies[0].called); assert(spies[1].called); assert(spies[2].called); }); it("waits after setTimeout was called", function () { this.clock.tick(100); var stub = sinon.stub(); this.clock.setTimeout(stub, 150); this.clock.tick(50); assert.isFalse(stub.called); this.clock.tick(100); assert(stub.called); }); it("mini integration test", function () { var stubs = [sinon.stub(), sinon.stub(), sinon.stub()]; this.clock.setTimeout(stubs[0], 100); this.clock.setTimeout(stubs[1], 120); this.clock.tick(10); this.clock.tick(89); assert.isFalse(stubs[0].called); assert.isFalse(stubs[1].called); this.clock.setTimeout(stubs[2], 20); this.clock.tick(1); assert(stubs[0].called); assert.isFalse(stubs[1].called); assert.isFalse(stubs[2].called); this.clock.tick(19); assert.isFalse(stubs[1].called); assert(stubs[2].called); this.clock.tick(1); assert(stubs[1].called); }); it("triggers even when some throw", function () { var clock = this.clock; var stubs = [sinon.stub().throws(), sinon.stub()]; clock.setTimeout(stubs[0], 100); clock.setTimeout(stubs[1], 120); assert.exception(function () { clock.tick(120); }); assert(stubs[0].called); assert(stubs[1].called); }); it("calls function with global object or null (strict mode) as this", function () { var clock = this.clock; var stub = sinon.stub().throws(); clock.setTimeout(stub, 100); assert.exception(function () { clock.tick(100); }); assert(stub.calledOn(global) || stub.calledOn(null)); }); it("triggers in the order scheduled", function () { var spies = [sinon.spy(), sinon.spy()]; this.clock.setTimeout(spies[0], 13); this.clock.setTimeout(spies[1], 11); this.clock.tick(15); assert(spies[1].calledBefore(spies[0])); }); it("creates updated Date while ticking", function () { var spy = sinon.spy(); this.clock.setInterval(function () { spy(new Date().getTime()); }, 10); this.clock.tick(100); assert.equals(spy.callCount, 10); assert(spy.calledWith(10)); assert(spy.calledWith(20)); assert(spy.calledWith(30)); assert(spy.calledWith(40)); assert(spy.calledWith(50)); assert(spy.calledWith(60)); assert(spy.calledWith(70)); assert(spy.calledWith(80)); assert(spy.calledWith(90)); assert(spy.calledWith(100)); }); it("fires timer in intervals of 13", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 13); this.clock.tick(500); assert.equals(spy.callCount, 38); }); it("fires timers in correct order", function () { var spy13 = sinon.spy(); var spy10 = sinon.spy(); this.clock.setInterval(function () { spy13(new Date().getTime()); }, 13); this.clock.setInterval(function () { spy10(new Date().getTime()); }, 10); this.clock.tick(500); assert.equals(spy13.callCount, 38); assert.equals(spy10.callCount, 50); assert(spy13.calledWith(416)); assert(spy10.calledWith(320)); assert(spy10.getCall(0).calledBefore(spy13.getCall(0))); assert(spy10.getCall(4).calledBefore(spy13.getCall(3))); }); it("triggers timeouts and intervals in the order scheduled", function () { var spies = [sinon.spy(), sinon.spy()]; this.clock.setInterval(spies[0], 10); this.clock.setTimeout(spies[1], 50); this.clock.tick(100); assert(spies[0].calledBefore(spies[1])); assert.equals(spies[0].callCount, 10); assert.equals(spies[1].callCount, 1); }); it("does not fire canceled intervals", function () { var id; var callback = sinon.spy(function () { if (callback.callCount === 3) { clearInterval(id); } }); id = this.clock.setInterval(callback, 10); this.clock.tick(100); assert.equals(callback.callCount, 3); }); it("passes 6 seconds", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 4000); this.clock.tick("08"); assert.equals(spy.callCount, 2); }); it("passes 1 minute", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 6000); this.clock.tick("01:00"); assert.equals(spy.callCount, 10); }); it("passes 2 hours, 34 minutes and 12 seconds", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 10000); this.clock.tick("02:34:10"); assert.equals(spy.callCount, 925); }); it("throws for invalid format", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 10000); var test = this; assert.exception(function () { test.clock.tick("12:02:34:10"); }); assert.equals(spy.callCount, 0); }); it("throws for invalid minutes", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 10000); var test = this; assert.exception(function () { test.clock.tick("67:10"); }); assert.equals(spy.callCount, 0); }); it("throws for negative minutes", function () { var spy = sinon.spy(); this.clock.setInterval(spy, 10000); var test = this; assert.exception(function () { test.clock.tick("-7:10"); }); assert.equals(spy.callCount, 0); }); it("treats missing argument as 0", function () { this.clock.tick(); assert.equals(this.clock.now, 0); }); it("fires nested setTimeout calls properly", function () { var i = 0; var clock = this.clock; var callback = function () { ++i; clock.setTimeout(function () { callback(); }, 100); }; callback(); clock.tick(1000); assert.equals(i, 11); }); it("does not silently catch errors", function () { var clock = this.clock; clock.setTimeout(function () { throw new Error("oh no!"); }, 1000); assert.exception(function () { clock.tick(1000); }); }); it("returns the current now value", function () { var clock = this.clock; var value = clock.tick(200); assert.equals(clock.now, value); }); }); describe("clearTimeout", function () { beforeEach(function () { this.clock = lolex.createClock(); }); it("removes timeout", function () { var stub = sinon.stub(); var id = this.clock.setTimeout(stub, 50); this.clock.clearTimeout(id); this.clock.tick(50); assert.isFalse(stub.called); }); it("does not remove interval", function () { var stub = sinon.stub(); var id = this.clock.setInterval(stub, 50); assert.exception(function() { this.clock.clearTimeout(id); }); this.clock.tick(50); assert.isTrue(stub.called); }); it("does not remove immediate", function () { var stub = sinon.stub(); var id = this.clock.setImmediate(stub); assert.exception(function() { this.clock.clearTimeout(id); }); this.clock.tick(50); assert.isTrue(stub.called); }); it("ignores null argument", function () { this.clock.clearTimeout(null); assert(true); // doesn't fail }); }); describe("reset", function () { beforeEach(function () { this.clock = lolex.createClock(); }); it("empties timeouts queue", function () { var stub = sinon.stub(); this.clock.setTimeout(stub); this.clock.reset(); this.clock.tick(0); assert.isFalse(stub.called); }); }); describe("setInterval", function () { beforeEach(function () { this.clock = lolex.createClock(); }); it("throws if no arguments", function () { var clock = this.clock; assert.exception(function () { clock.setInterval(); }); }); it("returns numeric id or object with numeric id", function () { var result = this.clock.setInterval(""); if (typeof result === 'object') { assert.isNumber(result.id); } else { assert.isNumber(result); } }); it("returns unique id", function () { var id1 = this.clock.setInterval(""); var id2 = this.clock.setInterval(""); refute.equals(id2, id1); }); it("schedules recurring timeout", function () { var stub = sinon.stub(); this.clock.setInterval(stub, 10); this.clock.tick(99); assert.equals(stub.callCount, 9); }); it("is not influenced by forward system clock changes", function () { var stub = sinon.stub(); this.clock.setInterval(stub, 10); this.clock.tick(11); assert.equals(stub.callCount, 1); this.clock.setSystemTime((new this.clock.Date()).getTime() + 1000); this.clock.tick(8); assert.equals(stub.callCount, 1); this.clock.tick(3); assert.equals(stub.callCount, 2); }); it("is not influenced by backward system clock changes", function () { var stub = sinon.stub(); this.clock.setInterval(stub, 10); this.clock.tick(5); this.clock.setSystemTime((new this.clock.Date()).getTime() - 1000); this.clock.tick(6); assert.equals(stub.callCount, 1); this.clock.tick(10); assert.equals(stub.callCount, 2); }); it("does not schedule recurring timeout when cleared", function () { var clock = this.clock; var id; var stub = sinon.spy(function () { if (stub.callCount === 3) { clock.clearInterval(id); } }); id = this.clock.setInterval(stub, 10); this.clock.tick(100); assert.equals(stub.callCount, 3); }); it("passes setTimeout parameters", function () { var clock = lolex.createClock(); var stub = sinon.stub(); clock.setInterval(stub, 2, "the first", "the second"); clock.tick(3); assert.isTrue(stub.calledWithExactly("the first", "the second")); }); }); describe("clearInterval", function () { beforeEach(function () { this.clock = lolex.createClock(); }); it("removes interval", function () { var stub = sinon.stub(); var id = this.clock.setInterval(stub, 50); this.clock.clearInterval(id); this.clock.tick(50); assert.isFalse(stub.called); }); it("does not remove timeout", function () { var stub = sinon.stub(); var id = this.clock.setTimeout(stub, 50); assert.exception(function() { this.clock.clearInterval(id); }); this.clock.tick(50); assert.isTrue(stub.called); }); it("does not remove immediate", function () { var stub = sinon.stub(); var id = this.clock.setImmediate(stub); assert.exception(function() { this.clock.clearInterval(id); }); this.clock.tick(50); assert.isTrue(stub.called); }); it("ignores null argument", function () { this.clock.clearInterval(null); assert(true); // doesn't fail }); }); describe("date", function () { beforeEach(function () { this.now = new GlobalDate().getTime() - 3000; this.clock = lolex.createClock(this.now); this.Date = global.Date; }); afterEach(function () { global.Date = this.Date; }); it("provides date constructor", function () { assert.isFunction(this.clock.Date); }); it("creates real Date objects", function () { var date = new this.clock.Date(); assert(Date.prototype.isPrototypeOf(date)); }); it("creates real Date objects when called as function", function () { var date = this.clock.Date(); assert(Date.prototype.isPrototypeOf(date)); }); it("creates real Date objects when Date constructor is gone", function () { var realDate = new Date(); Date = NOOP; global.Date = NOOP; var date = new this.clock.Date(); assert.same(date.constructor.prototype, realDate.constructor.prototype); }); it("creates Date objects representing clock time", function () { var date = new this.clock.Date(); assert.equals(date.getTime(), new Date(this.now).getTime()); }); it("returns Date object representing clock time", function () { var date = this.clock.Date(); assert.equals(date.getTime(), new Date(this.now).getTime()); }); it("listens to ticking clock", function () { var date1 = new this.clock.Date(); this.clock.tick(3); var date2 = new this.clock.Date(); assert.equals(date2.getTime() - date1.getTime(), 3); }); it("listens to system clock changes", function () { var date1 = new this.clock.Date(); this.clock.setSystemTime(date1.getTime() + 1000); var date2 = new this.clock.Date(); assert.equals(date2.getTime() - date1.getTime(), 1000); }); it("creates regular date when passing timestamp", function () { var date = new Date(); var fakeDate = new this.clock.Date(date.getTime()); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with timestamp", function () { var date = new Date(); var fakeDate = this.clock.Date(date.getTime()); assert.equals(fakeDate.getTime(), date.getTime()); }); it("creates regular date when passing year, month", function () { var date = new Date(2010, 4); var fakeDate = new this.clock.Date(2010, 4); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with year, month", function () { var date = new Date(2010, 4); var fakeDate = this.clock.Date(2010, 4); assert.equals(fakeDate.getTime(), date.getTime()); }); it("creates regular date when passing y, m, d", function () { var date = new Date(2010, 4, 2); var fakeDate = new this.clock.Date(2010, 4, 2); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with y, m, d", function () { var date = new Date(2010, 4, 2); var fakeDate = this.clock.Date(2010, 4, 2); assert.equals(fakeDate.getTime(), date.getTime()); }); it("creates regular date when passing y, m, d, h", function () { var date = new Date(2010, 4, 2, 12); var fakeDate = new this.clock.Date(2010, 4, 2, 12); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with y, m, d, h", function () { var date = new Date(2010, 4, 2, 12); var fakeDate = this.clock.Date(2010, 4, 2, 12); assert.equals(fakeDate.getTime(), date.getTime()); }); it("creates regular date when passing y, m, d, h, m", function () { var date = new Date(2010, 4, 2, 12, 42); var fakeDate = new this.clock.Date(2010, 4, 2, 12, 42); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with y, m, d, h, m", function () { var date = new Date(2010, 4, 2, 12, 42); var fakeDate = this.clock.Date(2010, 4, 2, 12, 42); assert.equals(fakeDate.getTime(), date.getTime()); }); it("creates regular date when passing y, m, d, h, m, s", function () { var date = new Date(2010, 4, 2, 12, 42, 53); var fakeDate = new this.clock.Date(2010, 4, 2, 12, 42, 53); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with y, m, d, h, m, s", function () { var date = new Date(2010, 4, 2, 12, 42, 53); var fakeDate = this.clock.Date(2010, 4, 2, 12, 42, 53); assert.equals(fakeDate.getTime(), date.getTime()); }); it("creates regular date when passing y, m, d, h, m, s, ms", function () { var date = new Date(2010, 4, 2, 12, 42, 53, 498); var fakeDate = new this.clock.Date(2010, 4, 2, 12, 42, 53, 498); assert.equals(fakeDate.getTime(), date.getTime()); }); it("returns regular date when calling with y, m, d, h, m, s, ms", function () { var date = new Date(2010, 4, 2, 12, 42, 53, 498); var fakeDate = this.clock.Date(2010, 4, 2, 12, 42, 53, 498); assert.equals(fakeDate.getTime(), date.getTime()); }); it("mirrors native Date.prototype", function () { assert.same(this.clock.Date.prototype, Date.prototype); }); it("supports now method if present", function () { assert.same(typeof this.clock.Date.now, typeof Date.now); }); if (Date.now) { describe("now", function () { it("returns clock.now", function () { var clock_now = this.clock.Date.now(); var global_now = GlobalDate.now(); assert(this.now <= clock_now && clock_now <= global_now); }); }); } else { describe("unsupported now", function () { it("is undefined", function () { refute.defined(this.clock.Date.now); }); }); } it("mirrors parse method", function () { assert.same(this.clock.Date.parse, Date.parse); }); it("mirrors UTC method", function () { assert.same(this.clock.Date.UTC, Date.UTC); }); it("mirrors toUTCString method", function () { assert.same(this.clock.Date.prototype.toUTCString, Date.prototype.toUTCString); }); if (Date.toSource) { describe("toSource", function () { it("is mirrored", function () { assert.same(this.clock.Date.toSource(), Date.toSource()); }); }); } else { describe("unsupported toSource", function () { it("is undefined", function () { refute.defined(this.clock.Date.toSource); }); }); } it("mirrors toString", function () { assert.same(this.clock.Date.toString(), Date.toString()); }); }); describe("stubTimers", function () { beforeEach(function () { this.dateNow = global.Date.now; }); afterEach(function () { if (this.clock) { this.clock.uninstall(); } clearTimeout(this.timer); if (this.dateNow === undefined) { delete global.Date.now; } else { global.Date.now = this.dateNow; } }); it("returns clock object", function () { this.clock = lolex.install(); assert.isObject(this.clock); assert.isFunction(this.clock.tick); }); it("has clock property", function () { this.clock = lolex.install(); assert.same(setTimeout.clock, this.clock); assert.same(clearTimeout.clock, this.clock); assert.same(setInterval.clock, this.clock); assert.same(clearInterval.clock, this.clock); assert.same(Date.clock, this.clock); }); it("sets initial timestamp", function () { this.clock = lolex.install(1400); assert.equals(this.clock.now, 1400); }); it("replaces global setTimeout", function () { this.clock = lolex.install(); var stub = sinon.stub(); setTimeout(stub, 1000); this.clock.tick(1000); assert(stub.called); }); it("global fake setTimeout should return id", function () { this.clock = lolex.install(); var stub = sinon.stub(); var to = setTimeout(stub, 1000); if (typeof (setTimeout(NOOP, 0)) === 'object') { assert.isNumber(to.id); assert.isFunction(to.ref); assert.isFunction(to.unref); } else { assert.isNumber(to); } }); it("replaces global clearTimeout", function () { this.clock = lolex.install(); var stub = sinon.stub(); clearTimeout(setTimeout(stub, 1000)); this.clock.tick(1000); assert.isFalse(stub.called); }); it("uninstalls global setTimeout", function () { this.clock = lolex.install(); var stub = sinon.stub(); this.clock.uninstall(); this.timer = setTimeout(stub, 1000); this.clock.tick(1000); assert.isFalse(stub.called); assert.same(setTimeout, lolex.timers.setTimeout); }); it("uninstalls global clearTimeout", function () { this.clock = lolex.install(); sinon.stub(); this.clock.uninstall(); assert.same(clearTimeout, lolex.timers.clearTimeout); }); it("replaces global setInterval", function () { this.clock = lolex.install(); var stub = sinon.stub(); setInterval(stub, 500); this.clock.tick(1000); assert(stub.calledTwice); }); it("replaces global clearInterval", function () { this.clock = lolex.install(); var stub = sinon.stub(); clearInterval(setInterval(stub, 500)); this.clock.tick(1000); assert.isFalse(stub.called); }); it("uninstalls global setInterval", function () { this.clock = lolex.install(); var stub = sinon.stub(); this.clock.uninstall(); this.timer = setInterval(stub, 1000); this.clock.tick(1000); assert.isFalse(stub.called); assert.same(setInterval, lolex.timers.setInterval); }); it("uninstalls global clearInterval", function () { this.clock = lolex.install(); sinon.stub(); this.clock.uninstall(); assert.same(clearInterval, lolex.timers.clearInterval); }); if (global.__proto__) { delete global.hasOwnPropertyTest; global.__proto__.hasOwnPropertyTest = function() {}; if (!global.hasOwnProperty("hasOwnPropertyTest")) { it("deletes global property on uninstall if it was inherited onto the global object", function () { // Give the global object an inherited 'tick' method delete global.tick; global.__proto__.tick = function() { }; this.clock = lolex.install(0, ['tick']); assert.isTrue(global.hasOwnProperty("tick")); this.clock.uninstall(); assert.isFalse(global.hasOwnProperty("tick")); delete global.__proto__.tick; }); } delete global.__proto__.hasOwnPropertyTest; } it("uninstalls global property on uninstall if it is present on the global object itself", function () { // Directly give the global object a tick method global.tick = NOOP; this.clock = lolex.install(0, ['tick']); assert.isTrue(global.hasOwnProperty("tick")); this.clock.uninstall(); assert.isTrue(global.hasOwnProperty("tick")); delete global.tick; }); it("fakes Date constructor", function () { this.clock = lolex.install(0); var now = new Date(); refute.same(Date, lolex.timers.Date); assert.equals(now.getTime(), 0); }); it("fake Date constructor should mirror Date's properties", function () { this.clock = lolex.install(0); assert(!!Date.parse); assert(!!Date.UTC); }); it("decide on Date.now support at call-time when supported", function () { global.Date.now = NOOP; this.clock = lolex.install(0); assert.equals(typeof Date.now, "function"); }); it("decide on Date.now support at call-time when unsupported", function () { global.Date.now = undefined; this.clock = lolex.install(0); refute.defined(Date.now); }); // TODO: The following tests causes test suite instability it("mirrors custom Date properties", function () { var f = function () { }; global.Date.format = f; this.clock = lolex.install(); assert.equals(Date.format, f); }); it("uninstalls Date constructor", function () { this.clock = lolex.install(0); this.clock.uninstall(); assert.same(GlobalDate, lolex.timers.Date); }); it("fakes provided methods", function () { this.clock = lolex.install(0, ["setTimeout", "Date", "setImmediate"]); refute.same(setTimeout, lolex.timers.setTimeout); refute.same(Date, lolex.timers.Date); }); it("resets faked methods", function () { this.clock = lolex.install(0, ["setTimeout", "Date", "setImmediate"]); this.clock.uninstall(); assert.same(setTimeout, lolex.timers.setTimeout); assert.same(Date, lolex.timers.Date); }); it("does not fake methods not provided", function () { this.clock = lolex.install(0, ["setTimeout", "Date", "setImmediate"]); assert.same(clearTimeout, lolex.timers.clearTimeout); assert.same(setInterval, lolex.timers.setInterval); assert.same(clearInterval, lolex.timers.clearInterval); }); it("does not be able to use date object for now", function () { assert.exception(function () { lolex.install(new Date(2011, 9, 1)); }); }); }); });