From fce5e18d6ccb3f4833e26f29a1cb90d121ed8d12 Mon Sep 17 00:00:00 2001 From: Maximilian Antoni Date: Sat, 25 Feb 2017 17:31:26 +0100 Subject: [PATCH] Remove wrapper function Browserify already adds a wrapper function if the use of `global` is detected. --- lolex.js | 1037 +++++++++++++++++++++++----------------------- src/lolex-src.js | 1037 +++++++++++++++++++++++----------------------- 2 files changed, 1034 insertions(+), 1040 deletions(-) diff --git a/lolex.js b/lolex.js index 16eb0b03..21430579 100644 --- a/lolex.js +++ b/lolex.js @@ -1,657 +1,654 @@ (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 -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; - } - - // 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; - } - - var strings = str.split(":"); - var l = strings.length, i = l; - var ms = 0, parsed; +"use strict"; + +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; +} + +// 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; + } - 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 strings = str.split(":"); + var l = strings.length, i = l; + var ms = 0, parsed; - while (i--) { - parsed = parseInt(strings[i], 10); + 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"); + } - if (parsed >= 60) { - throw new Error("Invalid time " + str); - } + while (i--) { + parsed = parseInt(strings[i], 10); - ms += parsed * Math.pow(60, (l - i - 1)); + if (parsed >= 60) { + throw new Error("Invalid time " + str); } - return ms * 1000; + ms += parsed * Math.pow(60, (l - i - 1)); } - /** - * Floor function that also works for negative numbers - */ - function fixedFloor(n) { - return (n >= 0 ? Math.floor(n) : Math.ceil(n)); + return ms * 1000; +} + +/** + * Floor function that also works for negative numbers + */ +function fixedFloor(n) { + return (n >= 0 ? Math.floor(n) : Math.ceil(n)); +} + +/** + * % operator that also works for negative numbers + */ +function fixedModulo(n, m) { + return ((n % m) + m) % m; +} + +/** + * 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"); +} + +function inRange(from, to, timer) { + return timer && timer.callAt >= from && timer.callAt <= to; +} + +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; + + return target; +} + +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 now implementation - if (source.now) { - target.now = function now() { - return target.clock.now; - }; - } else { - delete target.now; - } + return mirrorDateProperties(ClockDate, NativeDate); +} - // set special toSource implementation - if (source.toSource) { - target.toSource = function toSource() { - return source.toSource(); - }; - } else { - delete target.toSource; - } +function addTimer(clock, timer) { + if (timer.func === undefined) { + throw new Error("Callback must be provided to timer calls"); + } - // set special toString implementation - target.toString = function toString() { - return source.toString(); - }; + if (!clock.timers) { + clock.timers = {}; + } - target.prototype = source.prototype; - target.parse = source.parse; - target.UTC = source.UTC; - target.prototype.toUTCString = source.prototype.toUTCString; - - return target; - } - - 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; - function addTimer(clock, timer) { - if (timer.func === undefined) { - throw new Error("Callback must be provided to timer calls"); - } + if (addTimerReturnsObject) { + return { + id: timer.id, + ref: NOOP, + unref: NOOP + }; + } - if (!clock.timers) { - clock.timers = {}; - } + return timer.id; +} - timer.id = uniqueTimerId++; - timer.createdAt = clock.now; - timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); - clock.timers[timer.id] = timer; +/* 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; + } - if (addTimerReturnsObject) { - return { - id: timer.id, - ref: NOOP, - unref: NOOP - }; - } + // Sort next by immediate, immediate timers take precedence + if (a.immediate && !b.immediate) { + return -1; + } + if (!a.immediate && b.immediate) { + return 1; + } - return timer.id; + // Sort next by creation time, earlier-created timers take precedence + if (a.createdAt < b.createdAt) { + return -1; + } + 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; + } - /* 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; - } + // As timer ids are unique, no fallback `0` is necessary +} - // Sort next by immediate, immediate timers take precedence - if (a.immediate && !b.immediate) { - return -1; - } - if (!a.immediate && b.immediate) { - return 1; - } +function firstTimerInRange(clock, from, to) { + var timers = clock.timers, + timer = null, + id, + isInRange; - // Sort next by creation time, earlier-created timers take precedence - if (a.createdAt < b.createdAt) { - return -1; - } - if (a.createdAt > b.createdAt) { - return 1; - } + for (id in timers) { + if (timers.hasOwnProperty(id)) { + isInRange = inRange(from, to, timers[id]); - // Sort next by id, lower-id timers take precedence - if (a.id < b.id) { - return -1; - } - if (a.id > b.id) { - return 1; + if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) { + timer = timers[id]; + } } - - // 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, + timer = null, + 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, + timer = null, + 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]; - } - - 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; + /* eslint no-eval: "off" */ + eval(timer.func); } + } catch (e) { + exception = e; + } + 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"; +} + +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; + } - if (!clock.timers) { - clock.timers = []; - } + if (!clock.timers) { + clock.timers = []; + } - // 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; - } + // 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 + "()"); - } + 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"; - - for (i = 0, l = clock.methods.length; i < l; i++) { - method = clock.methods[i]; - if (method === "hrtime" && target.process) { - target.process.hrtime = clock[installedHrTime]; +} + +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]; + } 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 = [], + 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, tickTo = clock.now + ms, previous = clock.now; + var timer = firstTimerInRange(clock, tickFrom, tickTo); + var oldNow; - 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; + 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; } - - 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.duringTick = true; + try { + clock.now = timer.callAt; + callTimer(clock, timer); + return clock.now; + } finally { + clock.duringTick = false; + } + }; - clock.next = function next() { - var timer = firstTimer(clock); - if (!timer) { + 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; - } - numTimers = Object.keys(clock.timers).length; - if (numTimers === 0) { - return clock.now; - } - - clock.next(); - } + clock.next(); + } - throw new Error("Aborting after running " + clock.loopLimit + "timers, assuming an infinite loop!"); - }; + throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!"); + }; - clock.runToLast = function runToLast() { - var timer = lastTimer(clock); - if (!timer) { - return clock.now; - } + clock.runToLast = function runToLast() { + var timer = lastTimer(clock); + if (!timer) { + return clock.now; + } - return clock.tick(timer.callAt); - }; + return clock.tick(timer.callAt); + }; - clock.reset = function reset() { - clock.timers = {}; - }; + clock.reset = function reset() { + clock.timers = {}; + }; - 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; - } + 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; } - }; + } + }; - 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 clock; + } + return [ + fixedFloor(clock.hrNow / 1000), + fixedModulo(clock.hrNow * 1e6, 1e9) + ]; + }; } - exports.createClock = createClock; - exports.install = function install(target, now, toFake, loopLimit) { - var i, - l; + return clock; +} +exports.createClock = createClock; - if (typeof target === "number") { - toFake = now; - now = target; - target = null; - } +exports.install = function install(target, now, toFake, loopLimit) { + var i, + l; - if (!target) { - target = global; - } + if (typeof target === "number") { + toFake = now; + now = target; + target = null; + } - var clock = createClock(now, loopLimit); + if (!target) { + target = global; + } - clock.uninstall = function () { - uninstall(clock, target); - }; + var clock = createClock(now, loopLimit); - clock.methods = toFake || []; + clock.uninstall = function () { + uninstall(clock, target); + }; - if (clock.methods.length === 0) { - clock.methods = keys(timers); - } + clock.methods = toFake || []; - 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); + 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); } + } - return clock; - }; - -}(global || this)); + return clock; +}; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}]},{},[1])(1) diff --git a/src/lolex-src.js b/src/lolex-src.js index 6399d21a..93c0a51a 100644 --- a/src/lolex-src.js +++ b/src/lolex-src.js @@ -1,652 +1,649 @@ -(function (global) { - "use strict"; - - 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; - } - - // 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; - } - - var strings = str.split(":"); - var l = strings.length, i = l; - var ms = 0, parsed; +"use strict"; + +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; +} + +// 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; + } - 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 strings = str.split(":"); + var l = strings.length, i = l; + var ms = 0, parsed; - while (i--) { - parsed = parseInt(strings[i], 10); + 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"); + } - if (parsed >= 60) { - throw new Error("Invalid time " + str); - } + while (i--) { + parsed = parseInt(strings[i], 10); - ms += parsed * Math.pow(60, (l - i - 1)); + if (parsed >= 60) { + throw new Error("Invalid time " + str); } - return ms * 1000; + ms += parsed * Math.pow(60, (l - i - 1)); } - /** - * Floor function that also works for negative numbers - */ - function fixedFloor(n) { - return (n >= 0 ? Math.floor(n) : Math.ceil(n)); + return ms * 1000; +} + +/** + * Floor function that also works for negative numbers + */ +function fixedFloor(n) { + return (n >= 0 ? Math.floor(n) : Math.ceil(n)); +} + +/** + * % operator that also works for negative numbers + */ +function fixedModulo(n, m) { + return ((n % m) + m) % m; +} + +/** + * 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"); +} + +function inRange(from, to, timer) { + return timer && timer.callAt >= from && timer.callAt <= to; +} + +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; + + return target; +} + +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 now implementation - if (source.now) { - target.now = function now() { - return target.clock.now; - }; - } else { - delete target.now; - } + return mirrorDateProperties(ClockDate, NativeDate); +} - // set special toSource implementation - if (source.toSource) { - target.toSource = function toSource() { - return source.toSource(); - }; - } else { - delete target.toSource; - } +function addTimer(clock, timer) { + if (timer.func === undefined) { + throw new Error("Callback must be provided to timer calls"); + } - // set special toString implementation - target.toString = function toString() { - return source.toString(); - }; + if (!clock.timers) { + clock.timers = {}; + } - target.prototype = source.prototype; - target.parse = source.parse; - target.UTC = source.UTC; - target.prototype.toUTCString = source.prototype.toUTCString; - - return target; - } - - 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; - function addTimer(clock, timer) { - if (timer.func === undefined) { - throw new Error("Callback must be provided to timer calls"); - } + if (addTimerReturnsObject) { + return { + id: timer.id, + ref: NOOP, + unref: NOOP + }; + } - if (!clock.timers) { - clock.timers = {}; - } + return timer.id; +} - timer.id = uniqueTimerId++; - timer.createdAt = clock.now; - timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); - clock.timers[timer.id] = timer; +/* 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; + } - if (addTimerReturnsObject) { - return { - id: timer.id, - ref: NOOP, - unref: NOOP - }; - } + // Sort next by immediate, immediate timers take precedence + if (a.immediate && !b.immediate) { + return -1; + } + if (!a.immediate && b.immediate) { + return 1; + } - return timer.id; + // Sort next by creation time, earlier-created timers take precedence + if (a.createdAt < b.createdAt) { + return -1; + } + 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; + } - /* 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; - } + // As timer ids are unique, no fallback `0` is necessary +} - // Sort next by immediate, immediate timers take precedence - if (a.immediate && !b.immediate) { - return -1; - } - if (!a.immediate && b.immediate) { - return 1; - } +function firstTimerInRange(clock, from, to) { + var timers = clock.timers, + timer = null, + id, + isInRange; - // Sort next by creation time, earlier-created timers take precedence - if (a.createdAt < b.createdAt) { - return -1; - } - if (a.createdAt > b.createdAt) { - return 1; - } + for (id in timers) { + if (timers.hasOwnProperty(id)) { + isInRange = inRange(from, to, timers[id]); - // Sort next by id, lower-id timers take precedence - if (a.id < b.id) { - return -1; - } - if (a.id > b.id) { - return 1; + if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) { + timer = timers[id]; + } } - - // 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, + timer = null, + 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, + timer = null, + 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]; - } - - 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; + /* eslint no-eval: "off" */ + eval(timer.func); } + } catch (e) { + exception = e; + } + 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"; +} + +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; + } - if (!clock.timers) { - clock.timers = []; - } + if (!clock.timers) { + clock.timers = []; + } - // 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; - } + // 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 + "()"); - } + 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"; - - for (i = 0, l = clock.methods.length; i < l; i++) { - method = clock.methods[i]; - if (method === "hrtime" && target.process) { - target.process.hrtime = clock[installedHrTime]; +} + +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]; + } 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 = [], + 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, tickTo = clock.now + ms, previous = clock.now; + var timer = firstTimerInRange(clock, tickFrom, tickTo); + var oldNow; - 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; + 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; } - - 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.duringTick = true; + try { + clock.now = timer.callAt; + callTimer(clock, timer); + return clock.now; + } finally { + clock.duringTick = false; + } + }; - clock.next = function next() { - var timer = firstTimer(clock); - if (!timer) { + 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; - } - numTimers = Object.keys(clock.timers).length; - if (numTimers === 0) { - return clock.now; - } - - clock.next(); - } + clock.next(); + } - throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!"); - }; + throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!"); + }; - clock.runToLast = function runToLast() { - var timer = lastTimer(clock); - if (!timer) { - return clock.now; - } + clock.runToLast = function runToLast() { + var timer = lastTimer(clock); + if (!timer) { + return clock.now; + } - return clock.tick(timer.callAt); - }; + return clock.tick(timer.callAt); + }; - clock.reset = function reset() { - clock.timers = {}; - }; + clock.reset = function reset() { + clock.timers = {}; + }; - 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; - } + 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; } - }; + } + }; - 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 clock; + } + return [ + fixedFloor(clock.hrNow / 1000), + fixedModulo(clock.hrNow * 1e6, 1e9) + ]; + }; } - exports.createClock = createClock; - exports.install = function install(target, now, toFake, loopLimit) { - var i, - l; + return clock; +} +exports.createClock = createClock; - if (typeof target === "number") { - toFake = now; - now = target; - target = null; - } +exports.install = function install(target, now, toFake, loopLimit) { + var i, + l; - if (!target) { - target = global; - } + if (typeof target === "number") { + toFake = now; + now = target; + target = null; + } - var clock = createClock(now, loopLimit); + if (!target) { + target = global; + } - clock.uninstall = function () { - uninstall(clock, target); - }; + var clock = createClock(now, loopLimit); - clock.methods = toFake || []; + clock.uninstall = function () { + uninstall(clock, target); + }; - if (clock.methods.length === 0) { - clock.methods = keys(timers); - } + clock.methods = toFake || []; - 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); + 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); } + } - return clock; - }; - -}(global || this)); + return clock; +};