Comparing version 1.5.2 to 1.6.0
1014
lolex.js
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.lolex = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
(function (global){ | ||
(function (global) { | ||
"use strict"; | ||
"use strict"; | ||
var userAgent = global.navigator && global.navigator.userAgent; | ||
var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1; | ||
var userAgent = global.navigator && global.navigator.userAgent; | ||
var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1; | ||
// Make properties writable in IE, as per | ||
// http://www.adequatelygood.com/Replacing-setTimeout-Globally.html | ||
if (isRunningInIE) { | ||
global.setTimeout = global.setTimeout; | ||
global.clearTimeout = global.clearTimeout; | ||
global.setInterval = global.setInterval; | ||
global.clearInterval = global.clearInterval; | ||
global.Date = global.Date; | ||
} | ||
// Make properties writable in IE, as per | ||
// http://www.adequatelygood.com/Replacing-setTimeout-Globally.html | ||
if (isRunningInIE) { | ||
global.setTimeout = global.setTimeout; | ||
global.clearTimeout = global.clearTimeout; | ||
global.setInterval = global.setInterval; | ||
global.clearInterval = global.clearInterval; | ||
global.Date = global.Date; | ||
} | ||
// setImmediate is not a standard function | ||
// avoid adding the prop to the window object if not present | ||
if (global.setImmediate !== undefined) { | ||
global.setImmediate = global.setImmediate; | ||
global.clearImmediate = global.clearImmediate; | ||
// setImmediate is not a standard function | ||
// avoid adding the prop to the window object if not present | ||
if (global.setImmediate !== undefined) { | ||
global.setImmediate = global.setImmediate; | ||
global.clearImmediate = global.clearImmediate; | ||
} | ||
// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref() | ||
// browsers, a number. | ||
// see https://github.com/cjohansen/Sinon.JS/pull/436 | ||
var NOOP = function () { return undefined; }; | ||
var timeoutResult = setTimeout(NOOP, 0); | ||
var addTimerReturnsObject = typeof timeoutResult === "object"; | ||
var hrtimePresent = (global.process && typeof global.process.hrtime === "function"); | ||
clearTimeout(timeoutResult); | ||
var NativeDate = Date; | ||
var uniqueTimerId = 1; | ||
/** | ||
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into | ||
* number of milliseconds. This is used to support human-readable strings passed | ||
* to clock.tick() | ||
*/ | ||
function parseTime(str) { | ||
if (!str) { | ||
return 0; | ||
} | ||
// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref() | ||
// browsers, a number. | ||
// see https://github.com/cjohansen/Sinon.JS/pull/436 | ||
var strings = str.split(":"); | ||
var l = strings.length; | ||
var i = l; | ||
var ms = 0; | ||
var parsed; | ||
var NOOP = function () { return undefined; }; | ||
var timeoutResult = setTimeout(NOOP, 0); | ||
var addTimerReturnsObject = typeof timeoutResult === "object"; | ||
var hrtimePresent = (global.process && typeof global.process.hrtime === "function"); | ||
clearTimeout(timeoutResult); | ||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { | ||
throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits"); | ||
} | ||
var NativeDate = Date; | ||
var uniqueTimerId = 1; | ||
while (i--) { | ||
parsed = parseInt(strings[i], 10); | ||
/** | ||
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into | ||
* number of milliseconds. This is used to support human-readable strings passed | ||
* to clock.tick() | ||
*/ | ||
function parseTime(str) { | ||
if (!str) { | ||
return 0; | ||
if (parsed >= 60) { | ||
throw new Error("Invalid time " + str); | ||
} | ||
var strings = str.split(":"); | ||
var l = strings.length, i = l; | ||
var ms = 0, parsed; | ||
ms += parsed * Math.pow(60, (l - i - 1)); | ||
} | ||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { | ||
throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits"); | ||
} | ||
return ms * 1000; | ||
} | ||
while (i--) { | ||
parsed = parseInt(strings[i], 10); | ||
/** | ||
* Floor function that also works for negative numbers | ||
*/ | ||
function fixedFloor(n) { | ||
return (n >= 0 ? Math.floor(n) : Math.ceil(n)); | ||
} | ||
if (parsed >= 60) { | ||
throw new Error("Invalid time " + str); | ||
} | ||
/** | ||
* % operator that also works for negative numbers | ||
*/ | ||
function fixedModulo(n, m) { | ||
return ((n % m) + m) % m; | ||
} | ||
ms += parsed * Math.pow(60, (l - i - 1)); | ||
} | ||
/** | ||
* Used to grok the `now` parameter to createClock. | ||
*/ | ||
function getEpoch(epoch) { | ||
if (!epoch) { return 0; } | ||
if (typeof epoch.getTime === "function") { return epoch.getTime(); } | ||
if (typeof epoch === "number") { return epoch; } | ||
throw new TypeError("now should be milliseconds since UNIX epoch"); | ||
} | ||
return ms * 1000; | ||
} | ||
function inRange(from, to, timer) { | ||
return timer && timer.callAt >= from && timer.callAt <= to; | ||
} | ||
/** | ||
* Floor function that also works for negative numbers | ||
*/ | ||
function fixedFloor(n) { | ||
return (n >= 0 ? Math.floor(n) : Math.ceil(n)); | ||
function mirrorDateProperties(target, source) { | ||
var prop; | ||
for (prop in source) { | ||
if (source.hasOwnProperty(prop)) { | ||
target[prop] = source[prop]; | ||
} | ||
} | ||
/** | ||
* % operator that also works for negative numbers | ||
*/ | ||
function fixedModulo(n, m) { | ||
return ((n % m) + m) % m; | ||
// set special now implementation | ||
if (source.now) { | ||
target.now = function now() { | ||
return target.clock.now; | ||
}; | ||
} else { | ||
delete target.now; | ||
} | ||
/** | ||
* Used to grok the `now` parameter to createClock. | ||
*/ | ||
function getEpoch(epoch) { | ||
if (!epoch) { return 0; } | ||
if (typeof epoch.getTime === "function") { return epoch.getTime(); } | ||
if (typeof epoch === "number") { return epoch; } | ||
throw new TypeError("now should be milliseconds since UNIX epoch"); | ||
// set special toSource implementation | ||
if (source.toSource) { | ||
target.toSource = function toSource() { | ||
return source.toSource(); | ||
}; | ||
} else { | ||
delete target.toSource; | ||
} | ||
function inRange(from, to, timer) { | ||
return timer && timer.callAt >= from && timer.callAt <= to; | ||
} | ||
// set special toString implementation | ||
target.toString = function toString() { | ||
return source.toString(); | ||
}; | ||
function mirrorDateProperties(target, source) { | ||
var prop; | ||
for (prop in source) { | ||
if (source.hasOwnProperty(prop)) { | ||
target[prop] = source[prop]; | ||
} | ||
} | ||
target.prototype = source.prototype; | ||
target.parse = source.parse; | ||
target.UTC = source.UTC; | ||
target.prototype.toUTCString = source.prototype.toUTCString; | ||
// set special now implementation | ||
if (source.now) { | ||
target.now = function now() { | ||
return target.clock.now; | ||
}; | ||
} else { | ||
delete target.now; | ||
} | ||
return target; | ||
} | ||
// set special toSource implementation | ||
if (source.toSource) { | ||
target.toSource = function toSource() { | ||
return source.toSource(); | ||
}; | ||
} else { | ||
delete target.toSource; | ||
function createDate() { | ||
function ClockDate(year, month, date, hour, minute, second, ms) { | ||
// Defensive and verbose to avoid potential harm in passing | ||
// explicit undefined when user does not pass argument | ||
switch (arguments.length) { | ||
case 0: | ||
return new NativeDate(ClockDate.clock.now); | ||
case 1: | ||
return new NativeDate(year); | ||
case 2: | ||
return new NativeDate(year, month); | ||
case 3: | ||
return new NativeDate(year, month, date); | ||
case 4: | ||
return new NativeDate(year, month, date, hour); | ||
case 5: | ||
return new NativeDate(year, month, date, hour, minute); | ||
case 6: | ||
return new NativeDate(year, month, date, hour, minute, second); | ||
default: | ||
return new NativeDate(year, month, date, hour, minute, second, ms); | ||
} | ||
} | ||
// set special toString implementation | ||
target.toString = function toString() { | ||
return source.toString(); | ||
}; | ||
return mirrorDateProperties(ClockDate, NativeDate); | ||
} | ||
target.prototype = source.prototype; | ||
target.parse = source.parse; | ||
target.UTC = source.UTC; | ||
target.prototype.toUTCString = source.prototype.toUTCString; | ||
function addTimer(clock, timer) { | ||
if (timer.func === undefined) { | ||
throw new Error("Callback must be provided to timer calls"); | ||
} | ||
return target; | ||
if (!clock.timers) { | ||
clock.timers = {}; | ||
} | ||
function createDate() { | ||
function ClockDate(year, month, date, hour, minute, second, ms) { | ||
// Defensive and verbose to avoid potential harm in passing | ||
// explicit undefined when user does not pass argument | ||
switch (arguments.length) { | ||
case 0: | ||
return new NativeDate(ClockDate.clock.now); | ||
case 1: | ||
return new NativeDate(year); | ||
case 2: | ||
return new NativeDate(year, month); | ||
case 3: | ||
return new NativeDate(year, month, date); | ||
case 4: | ||
return new NativeDate(year, month, date, hour); | ||
case 5: | ||
return new NativeDate(year, month, date, hour, minute); | ||
case 6: | ||
return new NativeDate(year, month, date, hour, minute, second); | ||
default: | ||
return new NativeDate(year, month, date, hour, minute, second, ms); | ||
} | ||
} | ||
timer.id = uniqueTimerId++; | ||
timer.createdAt = clock.now; | ||
timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); | ||
return mirrorDateProperties(ClockDate, NativeDate); | ||
clock.timers[timer.id] = timer; | ||
if (addTimerReturnsObject) { | ||
return { | ||
id: timer.id, | ||
ref: NOOP, | ||
unref: NOOP | ||
}; | ||
} | ||
function addTimer(clock, timer) { | ||
if (timer.func === undefined) { | ||
throw new Error("Callback must be provided to timer calls"); | ||
} | ||
return timer.id; | ||
} | ||
if (!clock.timers) { | ||
clock.timers = {}; | ||
} | ||
timer.id = uniqueTimerId++; | ||
timer.createdAt = clock.now; | ||
timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); | ||
/* eslint consistent-return: "off" */ | ||
function compareTimers(a, b) { | ||
// Sort first by absolute timing | ||
if (a.callAt < b.callAt) { | ||
return -1; | ||
} | ||
if (a.callAt > b.callAt) { | ||
return 1; | ||
} | ||
clock.timers[timer.id] = timer; | ||
// Sort next by immediate, immediate timers take precedence | ||
if (a.immediate && !b.immediate) { | ||
return -1; | ||
} | ||
if (!a.immediate && b.immediate) { | ||
return 1; | ||
} | ||
if (addTimerReturnsObject) { | ||
return { | ||
id: timer.id, | ||
ref: NOOP, | ||
unref: NOOP | ||
}; | ||
} | ||
// Sort next by creation time, earlier-created timers take precedence | ||
if (a.createdAt < b.createdAt) { | ||
return -1; | ||
} | ||
if (a.createdAt > b.createdAt) { | ||
return 1; | ||
} | ||
return timer.id; | ||
// Sort next by id, lower-id timers take precedence | ||
if (a.id < b.id) { | ||
return -1; | ||
} | ||
if (a.id > b.id) { | ||
return 1; | ||
} | ||
// As timer ids are unique, no fallback `0` is necessary | ||
} | ||
/* eslint consistent-return: "off" */ | ||
function compareTimers(a, b) { | ||
// Sort first by absolute timing | ||
if (a.callAt < b.callAt) { | ||
return -1; | ||
} | ||
if (a.callAt > b.callAt) { | ||
return 1; | ||
} | ||
function firstTimerInRange(clock, from, to) { | ||
var timers = clock.timers; | ||
var timer = null; | ||
var id, isInRange; | ||
// Sort next by immediate, immediate timers take precedence | ||
if (a.immediate && !b.immediate) { | ||
return -1; | ||
} | ||
if (!a.immediate && b.immediate) { | ||
return 1; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
isInRange = inRange(from, to, timers[id]); | ||
// Sort next by creation time, earlier-created timers take precedence | ||
if (a.createdAt < b.createdAt) { | ||
return -1; | ||
if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) { | ||
timer = timers[id]; | ||
} | ||
} | ||
if (a.createdAt > b.createdAt) { | ||
return 1; | ||
} | ||
// Sort next by id, lower-id timers take precedence | ||
if (a.id < b.id) { | ||
return -1; | ||
} | ||
if (a.id > b.id) { | ||
return 1; | ||
} | ||
// As timer ids are unique, no fallback `0` is necessary | ||
} | ||
function firstTimerInRange(clock, from, to) { | ||
var timers = clock.timers, | ||
timer = null, | ||
id, | ||
isInRange; | ||
return timer; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
isInRange = inRange(from, to, timers[id]); | ||
function firstTimer(clock) { | ||
var timers = clock.timers; | ||
var timer = null; | ||
var id; | ||
if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) { | ||
timer = timers[id]; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === 1) { | ||
timer = timers[id]; | ||
} | ||
} | ||
return timer; | ||
} | ||
function firstTimer(clock) { | ||
var timers = clock.timers, | ||
timer = null, | ||
id; | ||
return timer; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === 1) { | ||
timer = timers[id]; | ||
} | ||
function lastTimer(clock) { | ||
var timers = clock.timers; | ||
var timer = null; | ||
var id; | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === -1) { | ||
timer = timers[id]; | ||
} | ||
} | ||
return timer; | ||
} | ||
function lastTimer(clock) { | ||
var timers = clock.timers, | ||
timer = null, | ||
id; | ||
return timer; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === -1) { | ||
timer = timers[id]; | ||
} | ||
} | ||
} | ||
function callTimer(clock, timer) { | ||
var exception; | ||
return timer; | ||
if (typeof timer.interval === "number") { | ||
clock.timers[timer.id].callAt += timer.interval; | ||
} else { | ||
delete clock.timers[timer.id]; | ||
} | ||
function callTimer(clock, timer) { | ||
var exception; | ||
if (typeof timer.interval === "number") { | ||
clock.timers[timer.id].callAt += timer.interval; | ||
try { | ||
if (typeof timer.func === "function") { | ||
timer.func.apply(null, timer.args); | ||
} else { | ||
delete clock.timers[timer.id]; | ||
/* eslint no-eval: "off" */ | ||
eval(timer.func); | ||
} | ||
} catch (e) { | ||
exception = e; | ||
} | ||
try { | ||
if (typeof timer.func === "function") { | ||
timer.func.apply(null, timer.args); | ||
} else { | ||
/* eslint no-eval: "off" */ | ||
eval(timer.func); | ||
} | ||
} catch (e) { | ||
exception = e; | ||
} | ||
if (!clock.timers[timer.id]) { | ||
if (exception) { | ||
throw exception; | ||
} | ||
return; | ||
} | ||
if (!clock.timers[timer.id]) { | ||
if (exception) { | ||
throw exception; | ||
} | ||
return; | ||
} | ||
function timerType(timer) { | ||
if (timer.immediate) { | ||
return "Immediate"; | ||
} | ||
if (timer.interval !== undefined) { | ||
return "Interval"; | ||
} | ||
return "Timeout"; | ||
if (exception) { | ||
throw exception; | ||
} | ||
} | ||
function clearTimer(clock, timerId, ttype) { | ||
if (!timerId) { | ||
// null appears to be allowed in most browsers, and appears to be | ||
// relied upon by some libraries, like Bootstrap carousel | ||
return; | ||
} | ||
function timerType(timer) { | ||
if (timer.immediate) { | ||
return "Immediate"; | ||
} | ||
if (timer.interval !== undefined) { | ||
return "Interval"; | ||
} | ||
return "Timeout"; | ||
} | ||
if (!clock.timers) { | ||
clock.timers = []; | ||
} | ||
function clearTimer(clock, timerId, ttype) { | ||
if (!timerId) { | ||
// null appears to be allowed in most browsers, and appears to be | ||
// relied upon by some libraries, like Bootstrap carousel | ||
return; | ||
} | ||
// in Node, timerId is an object with .ref()/.unref(), and | ||
// its .id field is the actual timer id. | ||
if (typeof timerId === "object") { | ||
timerId = timerId.id; | ||
} | ||
if (!clock.timers) { | ||
clock.timers = []; | ||
} | ||
if (clock.timers.hasOwnProperty(timerId)) { | ||
// check that the ID matches a timer of the correct type | ||
var timer = clock.timers[timerId]; | ||
if (timerType(timer) === ttype) { | ||
delete clock.timers[timerId]; | ||
} else { | ||
throw new Error("Cannot clear timer: timer created with set" + timerType(timer) | ||
+ "() but cleared with clear" + ttype + "()"); | ||
} | ||
// in Node, timerId is an object with .ref()/.unref(), and | ||
// its .id field is the actual timer id. | ||
if (typeof timerId === "object") { | ||
timerId = timerId.id; | ||
} | ||
if (clock.timers.hasOwnProperty(timerId)) { | ||
// check that the ID matches a timer of the correct type | ||
var timer = clock.timers[timerId]; | ||
if (timerType(timer) === ttype) { | ||
delete clock.timers[timerId]; | ||
} else { | ||
throw new Error("Cannot clear timer: timer created with set" + timerType(timer) | ||
+ "() but cleared with clear" + ttype + "()"); | ||
} | ||
} | ||
} | ||
function uninstall(clock, target) { | ||
var method, | ||
i, | ||
l; | ||
var installedHrTime = "_hrtime"; | ||
function uninstall(clock, target) { | ||
var method, | ||
i, | ||
l; | ||
var installedHrTime = "_hrtime"; | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
method = clock.methods[i]; | ||
if (method === "hrtime" && target.process) { | ||
target.process.hrtime = clock[installedHrTime]; | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
method = clock.methods[i]; | ||
if (method === "hrtime" && target.process) { | ||
target.process.hrtime = clock[installedHrTime]; | ||
} else { | ||
if (target[method] && target[method].hadOwnProperty) { | ||
target[method] = clock["_" + method]; | ||
} else { | ||
if (target[method] && target[method].hadOwnProperty) { | ||
target[method] = clock["_" + method]; | ||
} else { | ||
try { | ||
delete target[method]; | ||
} catch (ignore) { /* eslint empty-block: "off" */ } | ||
} | ||
try { | ||
delete target[method]; | ||
} catch (ignore) { /* eslint empty-block: "off" */ } | ||
} | ||
} | ||
// Prevent multiple executions which will completely remove these props | ||
clock.methods = []; | ||
} | ||
function hijackMethod(target, method, clock) { | ||
var prop; | ||
// Prevent multiple executions which will completely remove these props | ||
clock.methods = []; | ||
} | ||
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method); | ||
clock["_" + method] = target[method]; | ||
function hijackMethod(target, method, clock) { | ||
var prop; | ||
if (method === "Date") { | ||
var date = mirrorDateProperties(clock[method], target[method]); | ||
target[method] = date; | ||
} else { | ||
target[method] = function () { | ||
return clock[method].apply(clock, arguments); | ||
}; | ||
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method); | ||
clock["_" + method] = target[method]; | ||
for (prop in clock[method]) { | ||
if (clock[method].hasOwnProperty(prop)) { | ||
target[method][prop] = clock[method][prop]; | ||
} | ||
if (method === "Date") { | ||
var date = mirrorDateProperties(clock[method], target[method]); | ||
target[method] = date; | ||
} else { | ||
target[method] = function () { | ||
return clock[method].apply(clock, arguments); | ||
}; | ||
for (prop in clock[method]) { | ||
if (clock[method].hasOwnProperty(prop)) { | ||
target[method][prop] = clock[method][prop]; | ||
} | ||
} | ||
target[method].clock = clock; | ||
} | ||
var timers = { | ||
setTimeout: setTimeout, | ||
clearTimeout: clearTimeout, | ||
setImmediate: global.setImmediate, | ||
clearImmediate: global.clearImmediate, | ||
setInterval: setInterval, | ||
clearInterval: clearInterval, | ||
Date: Date | ||
}; | ||
target[method].clock = clock; | ||
} | ||
if (hrtimePresent) { | ||
timers.hrtime = global.process.hrtime; | ||
} | ||
var timers = { | ||
setTimeout: setTimeout, | ||
clearTimeout: clearTimeout, | ||
setImmediate: global.setImmediate, | ||
clearImmediate: global.clearImmediate, | ||
setInterval: setInterval, | ||
clearInterval: clearInterval, | ||
Date: Date | ||
}; | ||
var keys = Object.keys || function (obj) { | ||
var ks = [], | ||
key; | ||
if (hrtimePresent) { | ||
timers.hrtime = global.process.hrtime; | ||
} | ||
for (key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
ks.push(key); | ||
} | ||
var keys = Object.keys || function (obj) { | ||
var ks = []; | ||
var key; | ||
for (key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
ks.push(key); | ||
} | ||
} | ||
return ks; | ||
}; | ||
return ks; | ||
}; | ||
exports.timers = timers; | ||
exports.timers = timers; | ||
function createClock(now, loopLimit) { | ||
loopLimit = loopLimit || 1000; | ||
function createClock(now, loopLimit) { | ||
loopLimit = loopLimit || 1000; | ||
var clock = { | ||
now: getEpoch(now), | ||
hrNow: 0, | ||
timeouts: {}, | ||
Date: createDate(), | ||
loopLimit: loopLimit | ||
}; | ||
var clock = { | ||
now: getEpoch(now), | ||
hrNow: 0, | ||
timeouts: {}, | ||
Date: createDate(), | ||
loopLimit: loopLimit | ||
}; | ||
clock.Date.clock = clock; | ||
clock.Date.clock = clock; | ||
clock.setTimeout = function setTimeout(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout | ||
}); | ||
}; | ||
clock.setTimeout = function setTimeout(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout | ||
}); | ||
}; | ||
clock.clearTimeout = function clearTimeout(timerId) { | ||
return clearTimer(clock, timerId, "Timeout"); | ||
}; | ||
clock.clearTimeout = function clearTimeout(timerId) { | ||
return clearTimer(clock, timerId, "Timeout"); | ||
}; | ||
clock.setInterval = function setInterval(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout, | ||
interval: timeout | ||
}); | ||
}; | ||
clock.setInterval = function setInterval(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout, | ||
interval: timeout | ||
}); | ||
}; | ||
clock.clearInterval = function clearInterval(timerId) { | ||
return clearTimer(clock, timerId, "Interval"); | ||
}; | ||
clock.clearInterval = function clearInterval(timerId) { | ||
return clearTimer(clock, timerId, "Interval"); | ||
}; | ||
clock.setImmediate = function setImmediate(func) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 1), | ||
immediate: true | ||
}); | ||
}; | ||
clock.setImmediate = function setImmediate(func) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 1), | ||
immediate: true | ||
}); | ||
}; | ||
clock.clearImmediate = function clearImmediate(timerId) { | ||
return clearTimer(clock, timerId, "Immediate"); | ||
}; | ||
clock.clearImmediate = function clearImmediate(timerId) { | ||
return clearTimer(clock, timerId, "Immediate"); | ||
}; | ||
clock.tick = function tick(ms) { | ||
ms = typeof ms === "number" ? ms : parseTime(ms); | ||
var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now; | ||
var timer = firstTimerInRange(clock, tickFrom, tickTo); | ||
var oldNow; | ||
clock.tick = function tick(ms) { | ||
ms = typeof ms === "number" ? ms : parseTime(ms); | ||
var tickFrom = clock.now; | ||
var tickTo = clock.now + ms; | ||
var previous = clock.now; | ||
var timer = firstTimerInRange(clock, tickFrom, tickTo); | ||
var oldNow, firstException; | ||
clock.duringTick = true; | ||
clock.duringTick = true; | ||
function updateHrTime(newNow) { | ||
clock.hrNow += (newNow - clock.now); | ||
} | ||
function updateHrTime(newNow) { | ||
clock.hrNow += (newNow - clock.now); | ||
} | ||
var firstException; | ||
while (timer && tickFrom <= tickTo) { | ||
if (clock.timers[timer.id]) { | ||
updateHrTime(timer.callAt); | ||
tickFrom = timer.callAt; | ||
clock.now = timer.callAt; | ||
try { | ||
oldNow = clock.now; | ||
callTimer(clock, timer); | ||
// compensate for any setSystemTime() call during timer callback | ||
if (oldNow !== clock.now) { | ||
tickFrom += clock.now - oldNow; | ||
tickTo += clock.now - oldNow; | ||
previous += clock.now - oldNow; | ||
} | ||
} catch (e) { | ||
firstException = firstException || e; | ||
while (timer && tickFrom <= tickTo) { | ||
if (clock.timers[timer.id]) { | ||
updateHrTime(timer.callAt); | ||
tickFrom = timer.callAt; | ||
clock.now = timer.callAt; | ||
try { | ||
oldNow = clock.now; | ||
callTimer(clock, timer); | ||
// compensate for any setSystemTime() call during timer callback | ||
if (oldNow !== clock.now) { | ||
tickFrom += clock.now - oldNow; | ||
tickTo += clock.now - oldNow; | ||
previous += clock.now - oldNow; | ||
} | ||
} catch (e) { | ||
firstException = firstException || e; | ||
} | ||
timer = firstTimerInRange(clock, previous, tickTo); | ||
previous = tickFrom; | ||
} | ||
clock.duringTick = false; | ||
updateHrTime(tickTo); | ||
clock.now = tickTo; | ||
timer = firstTimerInRange(clock, previous, tickTo); | ||
previous = tickFrom; | ||
} | ||
if (firstException) { | ||
throw firstException; | ||
} | ||
clock.duringTick = false; | ||
updateHrTime(tickTo); | ||
clock.now = tickTo; | ||
if (firstException) { | ||
throw firstException; | ||
} | ||
return clock.now; | ||
}; | ||
clock.next = function next() { | ||
var timer = firstTimer(clock); | ||
if (!timer) { | ||
return clock.now; | ||
}; | ||
} | ||
clock.next = function next() { | ||
var timer = firstTimer(clock); | ||
if (!timer) { | ||
clock.duringTick = true; | ||
try { | ||
clock.now = timer.callAt; | ||
callTimer(clock, timer); | ||
return clock.now; | ||
} finally { | ||
clock.duringTick = false; | ||
} | ||
}; | ||
clock.runAll = function runAll() { | ||
var numTimers, i; | ||
for (i = 0; i < clock.loopLimit; i++) { | ||
if (!clock.timers) { | ||
return clock.now; | ||
} | ||
clock.duringTick = true; | ||
try { | ||
clock.now = timer.callAt; | ||
callTimer(clock, timer); | ||
numTimers = Object.keys(clock.timers).length; | ||
if (numTimers === 0) { | ||
return clock.now; | ||
} finally { | ||
clock.duringTick = false; | ||
} | ||
}; | ||
clock.runAll = function runAll() { | ||
var numTimers, i; | ||
for (i = 0; i < clock.loopLimit; i++) { | ||
if (!clock.timers) { | ||
return clock.now; | ||
} | ||
clock.next(); | ||
} | ||
numTimers = Object.keys(clock.timers).length; | ||
if (numTimers === 0) { | ||
return clock.now; | ||
} | ||
throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!"); | ||
}; | ||
clock.next(); | ||
} | ||
clock.runToLast = function runToLast() { | ||
var timer = lastTimer(clock); | ||
if (!timer) { | ||
return clock.now; | ||
} | ||
throw new Error("Aborting after running " + clock.loopLimit + "timers, assuming an infinite loop!"); | ||
}; | ||
return clock.tick(timer.callAt); | ||
}; | ||
clock.runToLast = function runToLast() { | ||
var timer = lastTimer(clock); | ||
if (!timer) { | ||
return clock.now; | ||
} | ||
clock.reset = function reset() { | ||
clock.timers = {}; | ||
}; | ||
return clock.tick(timer.callAt); | ||
}; | ||
clock.setSystemTime = function setSystemTime(systemTime) { | ||
// determine time difference | ||
var newNow = getEpoch(systemTime); | ||
var difference = newNow - clock.now; | ||
var id, timer; | ||
clock.reset = function reset() { | ||
clock.timers = {}; | ||
}; | ||
// update 'system clock' | ||
clock.now = newNow; | ||
clock.setSystemTime = function setSystemTime(now) { | ||
// determine time difference | ||
var newNow = getEpoch(now); | ||
var difference = newNow - clock.now; | ||
var id, timer; | ||
// update 'system clock' | ||
clock.now = newNow; | ||
// update timers and intervals to keep them stable | ||
for (id in clock.timers) { | ||
if (clock.timers.hasOwnProperty(id)) { | ||
timer = clock.timers[id]; | ||
timer.createdAt += difference; | ||
timer.callAt += difference; | ||
} | ||
// update timers and intervals to keep them stable | ||
for (id in clock.timers) { | ||
if (clock.timers.hasOwnProperty(id)) { | ||
timer = clock.timers[id]; | ||
timer.createdAt += difference; | ||
timer.callAt += difference; | ||
} | ||
}; | ||
} | ||
}; | ||
if (hrtimePresent) { | ||
clock.hrtime = function (prev) { | ||
if (Array.isArray(prev)) { | ||
var oldSecs = (prev[0] + prev[1] / 1e9); | ||
var newSecs = (clock.hrNow / 1000); | ||
var difference = (newSecs - oldSecs); | ||
var secs = fixedFloor(difference); | ||
var nanosecs = fixedModulo(difference * 1e9, 1e9); | ||
return [ | ||
secs, | ||
nanosecs | ||
]; | ||
} | ||
if (hrtimePresent) { | ||
clock.hrtime = function (prev) { | ||
if (Array.isArray(prev)) { | ||
var oldSecs = (prev[0] + prev[1] / 1e9); | ||
var newSecs = (clock.hrNow / 1000); | ||
var difference = (newSecs - oldSecs); | ||
var secs = fixedFloor(difference); | ||
var nanosecs = fixedModulo(difference * 1e9, 1e9); | ||
return [ | ||
fixedFloor(clock.hrNow / 1000), | ||
fixedModulo(clock.hrNow * 1e6, 1e9) | ||
secs, | ||
nanosecs | ||
]; | ||
}; | ||
} | ||
} | ||
return [ | ||
fixedFloor(clock.hrNow / 1000), | ||
fixedModulo(clock.hrNow * 1e6, 1e9) | ||
]; | ||
}; | ||
} | ||
return clock; | ||
return clock; | ||
} | ||
exports.createClock = createClock; | ||
exports.install = function install(target, now, toFake, loopLimit) { | ||
var i, l; | ||
if (target instanceof Date) { | ||
toFake = now; | ||
now = target.getTime(); | ||
target = null; | ||
} | ||
exports.createClock = createClock; | ||
exports.install = function install(target, now, toFake, loopLimit) { | ||
var i, | ||
l; | ||
if (typeof target === "number") { | ||
toFake = now; | ||
now = target; | ||
target = null; | ||
} | ||
if (typeof target === "number") { | ||
toFake = now; | ||
now = target; | ||
target = null; | ||
} | ||
if (!target) { | ||
target = global; | ||
} | ||
if (!target) { | ||
target = global; | ||
} | ||
var clock = createClock(now, loopLimit); | ||
var clock = createClock(now, loopLimit); | ||
clock.uninstall = function () { | ||
uninstall(clock, target); | ||
}; | ||
clock.uninstall = function () { | ||
uninstall(clock, target); | ||
}; | ||
clock.methods = toFake || []; | ||
clock.methods = toFake || []; | ||
if (clock.methods.length === 0) { | ||
clock.methods = keys(timers); | ||
} | ||
if (clock.methods.length === 0) { | ||
clock.methods = keys(timers); | ||
} | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
if (clock.methods[i] === "hrtime") { | ||
if (target.process && typeof target.process.hrtime === "function") { | ||
hijackMethod(target.process, clock.methods[i], clock); | ||
} | ||
} else { | ||
hijackMethod(target, clock.methods[i], clock); | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
if (clock.methods[i] === "hrtime") { | ||
if (target.process && typeof target.process.hrtime === "function") { | ||
hijackMethod(target.process, clock.methods[i], clock); | ||
} | ||
} else { | ||
hijackMethod(target, clock.methods[i], clock); | ||
} | ||
} | ||
return clock; | ||
}; | ||
return clock; | ||
}; | ||
}(global || this)); | ||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | ||
},{}]},{},[1])(1) | ||
}); |
{ | ||
"name": "lolex", | ||
"description": "Fake JavaScript timers", | ||
"version": "1.5.2", | ||
"version": "1.6.0", | ||
"homepage": "http://github.com/sinonjs/lolex", | ||
@@ -26,10 +26,15 @@ "author": "Christian Johansen", | ||
"devDependencies": { | ||
"browserify": "^13.0.1", | ||
"eslint": "^3.0.1", | ||
"mocha": "^3.1.2", | ||
"mochify": "^2.18.0", | ||
"browserify": "^14.1.0", | ||
"eslint": "^3.16.1", | ||
"eslint-config-sinon": "^1.0.0", | ||
"eslint-plugin-mocha": "^4.8.0", | ||
"mocha": "^3.2.0", | ||
"mochify": "^3.0.0", | ||
"referee": "^1.2.0", | ||
"sinon": "^1.17.4" | ||
}, | ||
"eslintConfig": { | ||
"extends": "eslint-config-sinon" | ||
}, | ||
"main": "./src/lolex-src.js" | ||
} |
@@ -21,3 +21,3 @@ # Lolex [![Build Status](https://secure.travis-ci.org/sinonjs/lolex.png)](http://travis-ci.org/sinonjs/lolex) [![bitHound Overall Score](https://www.bithound.io/github/sinonjs/lolex/badges/score.svg)](https://www.bithound.io/github/sinonjs/lolex) | ||
If you want to use Lolex in a browser you can use [the pre-built | ||
version](https://github.com/sinonjs/lolex/edit/master/lolex.js) available in the repo | ||
version](https://github.com/sinonjs/lolex/blob/master/lolex.js) available in the repo | ||
and the npm package. Using npm you only need to reference `./node_modules/lolex/lolex.js` in your `<script>` tags. | ||
@@ -151,3 +151,3 @@ | ||
Schedules the callback, to be fired once `0` milliseconds have ticked by. Note | ||
Schedules the callback to be fired once `0` milliseconds have ticked by. Note | ||
that you'll still have to call `clock.tick()` for the callback to fire. If | ||
@@ -154,0 +154,0 @@ called during a tick the callback won't fire until `1` millisecond has ticked |
1014
src/lolex-src.js
@@ -1,652 +0,656 @@ | ||
(function (global) { | ||
"use strict"; | ||
"use strict"; | ||
var userAgent = global.navigator && global.navigator.userAgent; | ||
var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1; | ||
var userAgent = global.navigator && global.navigator.userAgent; | ||
var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1; | ||
// Make properties writable in IE, as per | ||
// http://www.adequatelygood.com/Replacing-setTimeout-Globally.html | ||
if (isRunningInIE) { | ||
global.setTimeout = global.setTimeout; | ||
global.clearTimeout = global.clearTimeout; | ||
global.setInterval = global.setInterval; | ||
global.clearInterval = global.clearInterval; | ||
global.Date = global.Date; | ||
} | ||
// Make properties writable in IE, as per | ||
// http://www.adequatelygood.com/Replacing-setTimeout-Globally.html | ||
if (isRunningInIE) { | ||
global.setTimeout = global.setTimeout; | ||
global.clearTimeout = global.clearTimeout; | ||
global.setInterval = global.setInterval; | ||
global.clearInterval = global.clearInterval; | ||
global.Date = global.Date; | ||
} | ||
// setImmediate is not a standard function | ||
// avoid adding the prop to the window object if not present | ||
if (global.setImmediate !== undefined) { | ||
global.setImmediate = global.setImmediate; | ||
global.clearImmediate = global.clearImmediate; | ||
// setImmediate is not a standard function | ||
// avoid adding the prop to the window object if not present | ||
if (global.setImmediate !== undefined) { | ||
global.setImmediate = global.setImmediate; | ||
global.clearImmediate = global.clearImmediate; | ||
} | ||
// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref() | ||
// browsers, a number. | ||
// see https://github.com/cjohansen/Sinon.JS/pull/436 | ||
var NOOP = function () { return undefined; }; | ||
var timeoutResult = setTimeout(NOOP, 0); | ||
var addTimerReturnsObject = typeof timeoutResult === "object"; | ||
var hrtimePresent = (global.process && typeof global.process.hrtime === "function"); | ||
clearTimeout(timeoutResult); | ||
var NativeDate = Date; | ||
var uniqueTimerId = 1; | ||
/** | ||
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into | ||
* number of milliseconds. This is used to support human-readable strings passed | ||
* to clock.tick() | ||
*/ | ||
function parseTime(str) { | ||
if (!str) { | ||
return 0; | ||
} | ||
// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref() | ||
// browsers, a number. | ||
// see https://github.com/cjohansen/Sinon.JS/pull/436 | ||
var strings = str.split(":"); | ||
var l = strings.length; | ||
var i = l; | ||
var ms = 0; | ||
var parsed; | ||
var NOOP = function () { return undefined; }; | ||
var timeoutResult = setTimeout(NOOP, 0); | ||
var addTimerReturnsObject = typeof timeoutResult === "object"; | ||
var hrtimePresent = (global.process && typeof global.process.hrtime === "function"); | ||
clearTimeout(timeoutResult); | ||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { | ||
throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits"); | ||
} | ||
var NativeDate = Date; | ||
var uniqueTimerId = 1; | ||
while (i--) { | ||
parsed = parseInt(strings[i], 10); | ||
/** | ||
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into | ||
* number of milliseconds. This is used to support human-readable strings passed | ||
* to clock.tick() | ||
*/ | ||
function parseTime(str) { | ||
if (!str) { | ||
return 0; | ||
if (parsed >= 60) { | ||
throw new Error("Invalid time " + str); | ||
} | ||
var strings = str.split(":"); | ||
var l = strings.length, i = l; | ||
var ms = 0, parsed; | ||
ms += parsed * Math.pow(60, (l - i - 1)); | ||
} | ||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { | ||
throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits"); | ||
} | ||
return ms * 1000; | ||
} | ||
while (i--) { | ||
parsed = parseInt(strings[i], 10); | ||
/** | ||
* Floor function that also works for negative numbers | ||
*/ | ||
function fixedFloor(n) { | ||
return (n >= 0 ? Math.floor(n) : Math.ceil(n)); | ||
} | ||
if (parsed >= 60) { | ||
throw new Error("Invalid time " + str); | ||
} | ||
/** | ||
* % operator that also works for negative numbers | ||
*/ | ||
function fixedModulo(n, m) { | ||
return ((n % m) + m) % m; | ||
} | ||
ms += parsed * Math.pow(60, (l - i - 1)); | ||
} | ||
/** | ||
* Used to grok the `now` parameter to createClock. | ||
*/ | ||
function getEpoch(epoch) { | ||
if (!epoch) { return 0; } | ||
if (typeof epoch.getTime === "function") { return epoch.getTime(); } | ||
if (typeof epoch === "number") { return epoch; } | ||
throw new TypeError("now should be milliseconds since UNIX epoch"); | ||
} | ||
return ms * 1000; | ||
} | ||
function inRange(from, to, timer) { | ||
return timer && timer.callAt >= from && timer.callAt <= to; | ||
} | ||
/** | ||
* Floor function that also works for negative numbers | ||
*/ | ||
function fixedFloor(n) { | ||
return (n >= 0 ? Math.floor(n) : Math.ceil(n)); | ||
function mirrorDateProperties(target, source) { | ||
var prop; | ||
for (prop in source) { | ||
if (source.hasOwnProperty(prop)) { | ||
target[prop] = source[prop]; | ||
} | ||
} | ||
/** | ||
* % operator that also works for negative numbers | ||
*/ | ||
function fixedModulo(n, m) { | ||
return ((n % m) + m) % m; | ||
// set special now implementation | ||
if (source.now) { | ||
target.now = function now() { | ||
return target.clock.now; | ||
}; | ||
} else { | ||
delete target.now; | ||
} | ||
/** | ||
* Used to grok the `now` parameter to createClock. | ||
*/ | ||
function getEpoch(epoch) { | ||
if (!epoch) { return 0; } | ||
if (typeof epoch.getTime === "function") { return epoch.getTime(); } | ||
if (typeof epoch === "number") { return epoch; } | ||
throw new TypeError("now should be milliseconds since UNIX epoch"); | ||
// set special toSource implementation | ||
if (source.toSource) { | ||
target.toSource = function toSource() { | ||
return source.toSource(); | ||
}; | ||
} else { | ||
delete target.toSource; | ||
} | ||
function inRange(from, to, timer) { | ||
return timer && timer.callAt >= from && timer.callAt <= to; | ||
} | ||
// set special toString implementation | ||
target.toString = function toString() { | ||
return source.toString(); | ||
}; | ||
function mirrorDateProperties(target, source) { | ||
var prop; | ||
for (prop in source) { | ||
if (source.hasOwnProperty(prop)) { | ||
target[prop] = source[prop]; | ||
} | ||
} | ||
target.prototype = source.prototype; | ||
target.parse = source.parse; | ||
target.UTC = source.UTC; | ||
target.prototype.toUTCString = source.prototype.toUTCString; | ||
// set special now implementation | ||
if (source.now) { | ||
target.now = function now() { | ||
return target.clock.now; | ||
}; | ||
} else { | ||
delete target.now; | ||
} | ||
return target; | ||
} | ||
// set special toSource implementation | ||
if (source.toSource) { | ||
target.toSource = function toSource() { | ||
return source.toSource(); | ||
}; | ||
} else { | ||
delete target.toSource; | ||
function createDate() { | ||
function ClockDate(year, month, date, hour, minute, second, ms) { | ||
// Defensive and verbose to avoid potential harm in passing | ||
// explicit undefined when user does not pass argument | ||
switch (arguments.length) { | ||
case 0: | ||
return new NativeDate(ClockDate.clock.now); | ||
case 1: | ||
return new NativeDate(year); | ||
case 2: | ||
return new NativeDate(year, month); | ||
case 3: | ||
return new NativeDate(year, month, date); | ||
case 4: | ||
return new NativeDate(year, month, date, hour); | ||
case 5: | ||
return new NativeDate(year, month, date, hour, minute); | ||
case 6: | ||
return new NativeDate(year, month, date, hour, minute, second); | ||
default: | ||
return new NativeDate(year, month, date, hour, minute, second, ms); | ||
} | ||
} | ||
// set special toString implementation | ||
target.toString = function toString() { | ||
return source.toString(); | ||
}; | ||
return mirrorDateProperties(ClockDate, NativeDate); | ||
} | ||
target.prototype = source.prototype; | ||
target.parse = source.parse; | ||
target.UTC = source.UTC; | ||
target.prototype.toUTCString = source.prototype.toUTCString; | ||
function addTimer(clock, timer) { | ||
if (timer.func === undefined) { | ||
throw new Error("Callback must be provided to timer calls"); | ||
} | ||
return target; | ||
if (!clock.timers) { | ||
clock.timers = {}; | ||
} | ||
function createDate() { | ||
function ClockDate(year, month, date, hour, minute, second, ms) { | ||
// Defensive and verbose to avoid potential harm in passing | ||
// explicit undefined when user does not pass argument | ||
switch (arguments.length) { | ||
case 0: | ||
return new NativeDate(ClockDate.clock.now); | ||
case 1: | ||
return new NativeDate(year); | ||
case 2: | ||
return new NativeDate(year, month); | ||
case 3: | ||
return new NativeDate(year, month, date); | ||
case 4: | ||
return new NativeDate(year, month, date, hour); | ||
case 5: | ||
return new NativeDate(year, month, date, hour, minute); | ||
case 6: | ||
return new NativeDate(year, month, date, hour, minute, second); | ||
default: | ||
return new NativeDate(year, month, date, hour, minute, second, ms); | ||
} | ||
} | ||
timer.id = uniqueTimerId++; | ||
timer.createdAt = clock.now; | ||
timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); | ||
return mirrorDateProperties(ClockDate, NativeDate); | ||
clock.timers[timer.id] = timer; | ||
if (addTimerReturnsObject) { | ||
return { | ||
id: timer.id, | ||
ref: NOOP, | ||
unref: NOOP | ||
}; | ||
} | ||
function addTimer(clock, timer) { | ||
if (timer.func === undefined) { | ||
throw new Error("Callback must be provided to timer calls"); | ||
} | ||
return timer.id; | ||
} | ||
if (!clock.timers) { | ||
clock.timers = {}; | ||
} | ||
timer.id = uniqueTimerId++; | ||
timer.createdAt = clock.now; | ||
timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); | ||
/* eslint consistent-return: "off" */ | ||
function compareTimers(a, b) { | ||
// Sort first by absolute timing | ||
if (a.callAt < b.callAt) { | ||
return -1; | ||
} | ||
if (a.callAt > b.callAt) { | ||
return 1; | ||
} | ||
clock.timers[timer.id] = timer; | ||
// Sort next by immediate, immediate timers take precedence | ||
if (a.immediate && !b.immediate) { | ||
return -1; | ||
} | ||
if (!a.immediate && b.immediate) { | ||
return 1; | ||
} | ||
if (addTimerReturnsObject) { | ||
return { | ||
id: timer.id, | ||
ref: NOOP, | ||
unref: NOOP | ||
}; | ||
} | ||
// Sort next by creation time, earlier-created timers take precedence | ||
if (a.createdAt < b.createdAt) { | ||
return -1; | ||
} | ||
if (a.createdAt > b.createdAt) { | ||
return 1; | ||
} | ||
return timer.id; | ||
// Sort next by id, lower-id timers take precedence | ||
if (a.id < b.id) { | ||
return -1; | ||
} | ||
if (a.id > b.id) { | ||
return 1; | ||
} | ||
// As timer ids are unique, no fallback `0` is necessary | ||
} | ||
/* eslint consistent-return: "off" */ | ||
function compareTimers(a, b) { | ||
// Sort first by absolute timing | ||
if (a.callAt < b.callAt) { | ||
return -1; | ||
} | ||
if (a.callAt > b.callAt) { | ||
return 1; | ||
} | ||
function firstTimerInRange(clock, from, to) { | ||
var timers = clock.timers; | ||
var timer = null; | ||
var id, isInRange; | ||
// Sort next by immediate, immediate timers take precedence | ||
if (a.immediate && !b.immediate) { | ||
return -1; | ||
} | ||
if (!a.immediate && b.immediate) { | ||
return 1; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
isInRange = inRange(from, to, timers[id]); | ||
// Sort next by creation time, earlier-created timers take precedence | ||
if (a.createdAt < b.createdAt) { | ||
return -1; | ||
if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) { | ||
timer = timers[id]; | ||
} | ||
} | ||
if (a.createdAt > b.createdAt) { | ||
return 1; | ||
} | ||
// Sort next by id, lower-id timers take precedence | ||
if (a.id < b.id) { | ||
return -1; | ||
} | ||
if (a.id > b.id) { | ||
return 1; | ||
} | ||
// As timer ids are unique, no fallback `0` is necessary | ||
} | ||
function firstTimerInRange(clock, from, to) { | ||
var timers = clock.timers, | ||
timer = null, | ||
id, | ||
isInRange; | ||
return timer; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
isInRange = inRange(from, to, timers[id]); | ||
function firstTimer(clock) { | ||
var timers = clock.timers; | ||
var timer = null; | ||
var id; | ||
if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) { | ||
timer = timers[id]; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === 1) { | ||
timer = timers[id]; | ||
} | ||
} | ||
return timer; | ||
} | ||
function firstTimer(clock) { | ||
var timers = clock.timers, | ||
timer = null, | ||
id; | ||
return timer; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === 1) { | ||
timer = timers[id]; | ||
} | ||
function lastTimer(clock) { | ||
var timers = clock.timers; | ||
var timer = null; | ||
var id; | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === -1) { | ||
timer = timers[id]; | ||
} | ||
} | ||
return timer; | ||
} | ||
function lastTimer(clock) { | ||
var timers = clock.timers, | ||
timer = null, | ||
id; | ||
return timer; | ||
} | ||
for (id in timers) { | ||
if (timers.hasOwnProperty(id)) { | ||
if (!timer || compareTimers(timer, timers[id]) === -1) { | ||
timer = timers[id]; | ||
} | ||
} | ||
} | ||
function callTimer(clock, timer) { | ||
var exception; | ||
return timer; | ||
if (typeof timer.interval === "number") { | ||
clock.timers[timer.id].callAt += timer.interval; | ||
} else { | ||
delete clock.timers[timer.id]; | ||
} | ||
function callTimer(clock, timer) { | ||
var exception; | ||
if (typeof timer.interval === "number") { | ||
clock.timers[timer.id].callAt += timer.interval; | ||
try { | ||
if (typeof timer.func === "function") { | ||
timer.func.apply(null, timer.args); | ||
} else { | ||
delete clock.timers[timer.id]; | ||
/* eslint no-eval: "off" */ | ||
eval(timer.func); | ||
} | ||
} catch (e) { | ||
exception = e; | ||
} | ||
try { | ||
if (typeof timer.func === "function") { | ||
timer.func.apply(null, timer.args); | ||
} else { | ||
/* eslint no-eval: "off" */ | ||
eval(timer.func); | ||
} | ||
} catch (e) { | ||
exception = e; | ||
} | ||
if (!clock.timers[timer.id]) { | ||
if (exception) { | ||
throw exception; | ||
} | ||
return; | ||
} | ||
if (!clock.timers[timer.id]) { | ||
if (exception) { | ||
throw exception; | ||
} | ||
return; | ||
} | ||
function timerType(timer) { | ||
if (timer.immediate) { | ||
return "Immediate"; | ||
} | ||
if (timer.interval !== undefined) { | ||
return "Interval"; | ||
} | ||
return "Timeout"; | ||
if (exception) { | ||
throw exception; | ||
} | ||
} | ||
function clearTimer(clock, timerId, ttype) { | ||
if (!timerId) { | ||
// null appears to be allowed in most browsers, and appears to be | ||
// relied upon by some libraries, like Bootstrap carousel | ||
return; | ||
} | ||
function timerType(timer) { | ||
if (timer.immediate) { | ||
return "Immediate"; | ||
} | ||
if (timer.interval !== undefined) { | ||
return "Interval"; | ||
} | ||
return "Timeout"; | ||
} | ||
if (!clock.timers) { | ||
clock.timers = []; | ||
} | ||
function clearTimer(clock, timerId, ttype) { | ||
if (!timerId) { | ||
// null appears to be allowed in most browsers, and appears to be | ||
// relied upon by some libraries, like Bootstrap carousel | ||
return; | ||
} | ||
// in Node, timerId is an object with .ref()/.unref(), and | ||
// its .id field is the actual timer id. | ||
if (typeof timerId === "object") { | ||
timerId = timerId.id; | ||
} | ||
if (!clock.timers) { | ||
clock.timers = []; | ||
} | ||
if (clock.timers.hasOwnProperty(timerId)) { | ||
// check that the ID matches a timer of the correct type | ||
var timer = clock.timers[timerId]; | ||
if (timerType(timer) === ttype) { | ||
delete clock.timers[timerId]; | ||
} else { | ||
throw new Error("Cannot clear timer: timer created with set" + timerType(timer) | ||
+ "() but cleared with clear" + ttype + "()"); | ||
} | ||
// in Node, timerId is an object with .ref()/.unref(), and | ||
// its .id field is the actual timer id. | ||
if (typeof timerId === "object") { | ||
timerId = timerId.id; | ||
} | ||
if (clock.timers.hasOwnProperty(timerId)) { | ||
// check that the ID matches a timer of the correct type | ||
var timer = clock.timers[timerId]; | ||
if (timerType(timer) === ttype) { | ||
delete clock.timers[timerId]; | ||
} else { | ||
throw new Error("Cannot clear timer: timer created with set" + timerType(timer) | ||
+ "() but cleared with clear" + ttype + "()"); | ||
} | ||
} | ||
} | ||
function uninstall(clock, target) { | ||
var method, | ||
i, | ||
l; | ||
var installedHrTime = "_hrtime"; | ||
function uninstall(clock, target) { | ||
var method, | ||
i, | ||
l; | ||
var installedHrTime = "_hrtime"; | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
method = clock.methods[i]; | ||
if (method === "hrtime" && target.process) { | ||
target.process.hrtime = clock[installedHrTime]; | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
method = clock.methods[i]; | ||
if (method === "hrtime" && target.process) { | ||
target.process.hrtime = clock[installedHrTime]; | ||
} else { | ||
if (target[method] && target[method].hadOwnProperty) { | ||
target[method] = clock["_" + method]; | ||
} else { | ||
if (target[method] && target[method].hadOwnProperty) { | ||
target[method] = clock["_" + method]; | ||
} else { | ||
try { | ||
delete target[method]; | ||
} catch (ignore) { /* eslint empty-block: "off" */ } | ||
} | ||
try { | ||
delete target[method]; | ||
} catch (ignore) { /* eslint empty-block: "off" */ } | ||
} | ||
} | ||
// Prevent multiple executions which will completely remove these props | ||
clock.methods = []; | ||
} | ||
function hijackMethod(target, method, clock) { | ||
var prop; | ||
// Prevent multiple executions which will completely remove these props | ||
clock.methods = []; | ||
} | ||
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method); | ||
clock["_" + method] = target[method]; | ||
function hijackMethod(target, method, clock) { | ||
var prop; | ||
if (method === "Date") { | ||
var date = mirrorDateProperties(clock[method], target[method]); | ||
target[method] = date; | ||
} else { | ||
target[method] = function () { | ||
return clock[method].apply(clock, arguments); | ||
}; | ||
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method); | ||
clock["_" + method] = target[method]; | ||
for (prop in clock[method]) { | ||
if (clock[method].hasOwnProperty(prop)) { | ||
target[method][prop] = clock[method][prop]; | ||
} | ||
if (method === "Date") { | ||
var date = mirrorDateProperties(clock[method], target[method]); | ||
target[method] = date; | ||
} else { | ||
target[method] = function () { | ||
return clock[method].apply(clock, arguments); | ||
}; | ||
for (prop in clock[method]) { | ||
if (clock[method].hasOwnProperty(prop)) { | ||
target[method][prop] = clock[method][prop]; | ||
} | ||
} | ||
target[method].clock = clock; | ||
} | ||
var timers = { | ||
setTimeout: setTimeout, | ||
clearTimeout: clearTimeout, | ||
setImmediate: global.setImmediate, | ||
clearImmediate: global.clearImmediate, | ||
setInterval: setInterval, | ||
clearInterval: clearInterval, | ||
Date: Date | ||
}; | ||
target[method].clock = clock; | ||
} | ||
if (hrtimePresent) { | ||
timers.hrtime = global.process.hrtime; | ||
} | ||
var timers = { | ||
setTimeout: setTimeout, | ||
clearTimeout: clearTimeout, | ||
setImmediate: global.setImmediate, | ||
clearImmediate: global.clearImmediate, | ||
setInterval: setInterval, | ||
clearInterval: clearInterval, | ||
Date: Date | ||
}; | ||
var keys = Object.keys || function (obj) { | ||
var ks = [], | ||
key; | ||
if (hrtimePresent) { | ||
timers.hrtime = global.process.hrtime; | ||
} | ||
for (key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
ks.push(key); | ||
} | ||
var keys = Object.keys || function (obj) { | ||
var ks = []; | ||
var key; | ||
for (key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
ks.push(key); | ||
} | ||
} | ||
return ks; | ||
}; | ||
return ks; | ||
}; | ||
exports.timers = timers; | ||
exports.timers = timers; | ||
function createClock(now, loopLimit) { | ||
loopLimit = loopLimit || 1000; | ||
function createClock(now, loopLimit) { | ||
loopLimit = loopLimit || 1000; | ||
var clock = { | ||
now: getEpoch(now), | ||
hrNow: 0, | ||
timeouts: {}, | ||
Date: createDate(), | ||
loopLimit: loopLimit | ||
}; | ||
var clock = { | ||
now: getEpoch(now), | ||
hrNow: 0, | ||
timeouts: {}, | ||
Date: createDate(), | ||
loopLimit: loopLimit | ||
}; | ||
clock.Date.clock = clock; | ||
clock.Date.clock = clock; | ||
clock.setTimeout = function setTimeout(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout | ||
}); | ||
}; | ||
clock.setTimeout = function setTimeout(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout | ||
}); | ||
}; | ||
clock.clearTimeout = function clearTimeout(timerId) { | ||
return clearTimer(clock, timerId, "Timeout"); | ||
}; | ||
clock.clearTimeout = function clearTimeout(timerId) { | ||
return clearTimer(clock, timerId, "Timeout"); | ||
}; | ||
clock.setInterval = function setInterval(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout, | ||
interval: timeout | ||
}); | ||
}; | ||
clock.setInterval = function setInterval(func, timeout) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 2), | ||
delay: timeout, | ||
interval: timeout | ||
}); | ||
}; | ||
clock.clearInterval = function clearInterval(timerId) { | ||
return clearTimer(clock, timerId, "Interval"); | ||
}; | ||
clock.clearInterval = function clearInterval(timerId) { | ||
return clearTimer(clock, timerId, "Interval"); | ||
}; | ||
clock.setImmediate = function setImmediate(func) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 1), | ||
immediate: true | ||
}); | ||
}; | ||
clock.setImmediate = function setImmediate(func) { | ||
return addTimer(clock, { | ||
func: func, | ||
args: Array.prototype.slice.call(arguments, 1), | ||
immediate: true | ||
}); | ||
}; | ||
clock.clearImmediate = function clearImmediate(timerId) { | ||
return clearTimer(clock, timerId, "Immediate"); | ||
}; | ||
clock.clearImmediate = function clearImmediate(timerId) { | ||
return clearTimer(clock, timerId, "Immediate"); | ||
}; | ||
clock.tick = function tick(ms) { | ||
ms = typeof ms === "number" ? ms : parseTime(ms); | ||
var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now; | ||
var timer = firstTimerInRange(clock, tickFrom, tickTo); | ||
var oldNow; | ||
clock.tick = function tick(ms) { | ||
ms = typeof ms === "number" ? ms : parseTime(ms); | ||
var tickFrom = clock.now; | ||
var tickTo = clock.now + ms; | ||
var previous = clock.now; | ||
var timer = firstTimerInRange(clock, tickFrom, tickTo); | ||
var oldNow, firstException; | ||
clock.duringTick = true; | ||
clock.duringTick = true; | ||
function updateHrTime(newNow) { | ||
clock.hrNow += (newNow - clock.now); | ||
} | ||
function updateHrTime(newNow) { | ||
clock.hrNow += (newNow - clock.now); | ||
} | ||
var firstException; | ||
while (timer && tickFrom <= tickTo) { | ||
if (clock.timers[timer.id]) { | ||
updateHrTime(timer.callAt); | ||
tickFrom = timer.callAt; | ||
clock.now = timer.callAt; | ||
try { | ||
oldNow = clock.now; | ||
callTimer(clock, timer); | ||
// compensate for any setSystemTime() call during timer callback | ||
if (oldNow !== clock.now) { | ||
tickFrom += clock.now - oldNow; | ||
tickTo += clock.now - oldNow; | ||
previous += clock.now - oldNow; | ||
} | ||
} catch (e) { | ||
firstException = firstException || e; | ||
while (timer && tickFrom <= tickTo) { | ||
if (clock.timers[timer.id]) { | ||
updateHrTime(timer.callAt); | ||
tickFrom = timer.callAt; | ||
clock.now = timer.callAt; | ||
try { | ||
oldNow = clock.now; | ||
callTimer(clock, timer); | ||
// compensate for any setSystemTime() call during timer callback | ||
if (oldNow !== clock.now) { | ||
tickFrom += clock.now - oldNow; | ||
tickTo += clock.now - oldNow; | ||
previous += clock.now - oldNow; | ||
} | ||
} catch (e) { | ||
firstException = firstException || e; | ||
} | ||
timer = firstTimerInRange(clock, previous, tickTo); | ||
previous = tickFrom; | ||
} | ||
clock.duringTick = false; | ||
updateHrTime(tickTo); | ||
clock.now = tickTo; | ||
timer = firstTimerInRange(clock, previous, tickTo); | ||
previous = tickFrom; | ||
} | ||
if (firstException) { | ||
throw firstException; | ||
} | ||
clock.duringTick = false; | ||
updateHrTime(tickTo); | ||
clock.now = tickTo; | ||
if (firstException) { | ||
throw firstException; | ||
} | ||
return clock.now; | ||
}; | ||
clock.next = function next() { | ||
var timer = firstTimer(clock); | ||
if (!timer) { | ||
return clock.now; | ||
}; | ||
} | ||
clock.next = function next() { | ||
var timer = firstTimer(clock); | ||
if (!timer) { | ||
clock.duringTick = true; | ||
try { | ||
clock.now = timer.callAt; | ||
callTimer(clock, timer); | ||
return clock.now; | ||
} finally { | ||
clock.duringTick = false; | ||
} | ||
}; | ||
clock.runAll = function runAll() { | ||
var numTimers, i; | ||
for (i = 0; i < clock.loopLimit; i++) { | ||
if (!clock.timers) { | ||
return clock.now; | ||
} | ||
clock.duringTick = true; | ||
try { | ||
clock.now = timer.callAt; | ||
callTimer(clock, timer); | ||
numTimers = Object.keys(clock.timers).length; | ||
if (numTimers === 0) { | ||
return clock.now; | ||
} finally { | ||
clock.duringTick = false; | ||
} | ||
}; | ||
clock.runAll = function runAll() { | ||
var numTimers, i; | ||
for (i = 0; i < clock.loopLimit; i++) { | ||
if (!clock.timers) { | ||
return clock.now; | ||
} | ||
clock.next(); | ||
} | ||
numTimers = Object.keys(clock.timers).length; | ||
if (numTimers === 0) { | ||
return clock.now; | ||
} | ||
throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!"); | ||
}; | ||
clock.next(); | ||
} | ||
clock.runToLast = function runToLast() { | ||
var timer = lastTimer(clock); | ||
if (!timer) { | ||
return clock.now; | ||
} | ||
throw new Error("Aborting after running " + clock.loopLimit + "timers, assuming an infinite loop!"); | ||
}; | ||
return clock.tick(timer.callAt); | ||
}; | ||
clock.runToLast = function runToLast() { | ||
var timer = lastTimer(clock); | ||
if (!timer) { | ||
return clock.now; | ||
} | ||
clock.reset = function reset() { | ||
clock.timers = {}; | ||
}; | ||
return clock.tick(timer.callAt); | ||
}; | ||
clock.setSystemTime = function setSystemTime(systemTime) { | ||
// determine time difference | ||
var newNow = getEpoch(systemTime); | ||
var difference = newNow - clock.now; | ||
var id, timer; | ||
clock.reset = function reset() { | ||
clock.timers = {}; | ||
}; | ||
// update 'system clock' | ||
clock.now = newNow; | ||
clock.setSystemTime = function setSystemTime(now) { | ||
// determine time difference | ||
var newNow = getEpoch(now); | ||
var difference = newNow - clock.now; | ||
var id, timer; | ||
// update 'system clock' | ||
clock.now = newNow; | ||
// update timers and intervals to keep them stable | ||
for (id in clock.timers) { | ||
if (clock.timers.hasOwnProperty(id)) { | ||
timer = clock.timers[id]; | ||
timer.createdAt += difference; | ||
timer.callAt += difference; | ||
} | ||
// update timers and intervals to keep them stable | ||
for (id in clock.timers) { | ||
if (clock.timers.hasOwnProperty(id)) { | ||
timer = clock.timers[id]; | ||
timer.createdAt += difference; | ||
timer.callAt += difference; | ||
} | ||
}; | ||
} | ||
}; | ||
if (hrtimePresent) { | ||
clock.hrtime = function (prev) { | ||
if (Array.isArray(prev)) { | ||
var oldSecs = (prev[0] + prev[1] / 1e9); | ||
var newSecs = (clock.hrNow / 1000); | ||
var difference = (newSecs - oldSecs); | ||
var secs = fixedFloor(difference); | ||
var nanosecs = fixedModulo(difference * 1e9, 1e9); | ||
return [ | ||
secs, | ||
nanosecs | ||
]; | ||
} | ||
if (hrtimePresent) { | ||
clock.hrtime = function (prev) { | ||
if (Array.isArray(prev)) { | ||
var oldSecs = (prev[0] + prev[1] / 1e9); | ||
var newSecs = (clock.hrNow / 1000); | ||
var difference = (newSecs - oldSecs); | ||
var secs = fixedFloor(difference); | ||
var nanosecs = fixedModulo(difference * 1e9, 1e9); | ||
return [ | ||
fixedFloor(clock.hrNow / 1000), | ||
fixedModulo(clock.hrNow * 1e6, 1e9) | ||
secs, | ||
nanosecs | ||
]; | ||
}; | ||
} | ||
} | ||
return [ | ||
fixedFloor(clock.hrNow / 1000), | ||
fixedModulo(clock.hrNow * 1e6, 1e9) | ||
]; | ||
}; | ||
} | ||
return clock; | ||
return clock; | ||
} | ||
exports.createClock = createClock; | ||
exports.install = function install(target, now, toFake, loopLimit) { | ||
var i, l; | ||
if (target instanceof Date) { | ||
toFake = now; | ||
now = target.getTime(); | ||
target = null; | ||
} | ||
exports.createClock = createClock; | ||
exports.install = function install(target, now, toFake, loopLimit) { | ||
var i, | ||
l; | ||
if (typeof target === "number") { | ||
toFake = now; | ||
now = target; | ||
target = null; | ||
} | ||
if (typeof target === "number") { | ||
toFake = now; | ||
now = target; | ||
target = null; | ||
} | ||
if (!target) { | ||
target = global; | ||
} | ||
if (!target) { | ||
target = global; | ||
} | ||
var clock = createClock(now, loopLimit); | ||
var clock = createClock(now, loopLimit); | ||
clock.uninstall = function () { | ||
uninstall(clock, target); | ||
}; | ||
clock.uninstall = function () { | ||
uninstall(clock, target); | ||
}; | ||
clock.methods = toFake || []; | ||
clock.methods = toFake || []; | ||
if (clock.methods.length === 0) { | ||
clock.methods = keys(timers); | ||
} | ||
if (clock.methods.length === 0) { | ||
clock.methods = keys(timers); | ||
} | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
if (clock.methods[i] === "hrtime") { | ||
if (target.process && typeof target.process.hrtime === "function") { | ||
hijackMethod(target.process, clock.methods[i], clock); | ||
} | ||
} else { | ||
hijackMethod(target, clock.methods[i], clock); | ||
for (i = 0, l = clock.methods.length; i < l; i++) { | ||
if (clock.methods[i] === "hrtime") { | ||
if (target.process && typeof target.process.hrtime === "function") { | ||
hijackMethod(target.process, clock.methods[i], clock); | ||
} | ||
} else { | ||
hijackMethod(target, clock.methods[i], clock); | ||
} | ||
} | ||
return clock; | ||
}; | ||
}(global || this)); | ||
return clock; | ||
}; |
@@ -44,2 +44,11 @@ /*global | ||
describe("issue #73", function () { | ||
it("should install with date object", function () { | ||
var date = new Date("2015-09-25"); | ||
var clock = lolex.install(date); | ||
assert.same(clock.now, 1443139200000); | ||
clock.uninstall(); | ||
}); | ||
}); | ||
describe("lolex", function () { | ||
@@ -1245,3 +1254,3 @@ | ||
var realDate = new Date(); | ||
Date = NOOP; | ||
Date = NOOP; // eslint-disable-line no-native-reassign | ||
global.Date = NOOP; | ||
@@ -1713,8 +1722,2 @@ | ||
}); | ||
it("does not be able to use date object for now", function () { | ||
assert.exception(function () { | ||
lolex.install(new Date(2011, 9, 1)); | ||
}); | ||
}); | ||
}); | ||
@@ -1721,0 +1724,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2447
108575
8
17