Skip to content

Commit

Permalink
Prepare for new release
Browse files Browse the repository at this point in the history
Includes a fix for a minor linting issue
  • Loading branch information
fatso83 committed Jul 18, 2017
1 parent 8e89bb8 commit 4de9790
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 32 deletions.
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ Mark Wubben <mark@novemberborn.net>
Duncan Beevers <duncan@dweebd.com>
Soutaro Matsumoto <matsumoto@soutaro.com>
Rogier Schouten <github@workingcode.ninja>
Benjamin Gruenbaum <inglor@gmail.com>
Karl O'Keeffe <karl@geckoboard.com>
Clark Tomlinson <fallen013@gmail.com>
Josh Goldberg <joshuakgoldberg@outlook.com>
Andy Edwards <jedwards@fastmail.com>
Benjamin Gruenbaum <inglor@gmail.com>
Curtis M. Humphrey, Ph.D <curtis@createdwithflair.com>
Elad Nachmias <theman@elad.im>
Kyle Fleming <kyle@kylefleming.net>
Mark Banner <standard8@mozilla.com>
Nando <fdanko@ekumenlabs.com>
Expand Down
8 changes: 8 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@

v2.0.1 / 2017-07-18
==================

* Throw error on incorrect install use (#112)
* Add support for process.nextTick
* lolex can now attach itself to the system timers and automatically ad… (#102)
* update hrtime when an interval ticks

v2.0.0 / 2017-07-13
==================

Expand Down
110 changes: 81 additions & 29 deletions lolex.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var NOOP = function () { return undefined; };
var timeoutResult = setTimeout(NOOP, 0);
var addTimerReturnsObject = typeof timeoutResult === "object";
var hrtimePresent = (global.process && typeof global.process.hrtime === "function");
var nextTickPresent = (global.process && typeof global.process.nextTick === "function");
var performancePresent = (global.performance && typeof global.performance.now === "function");

clearTimeout(timeoutResult);
Expand Down Expand Up @@ -165,6 +166,27 @@ function createDate() {
return mirrorDateProperties(ClockDate, NativeDate);
}


function enqueueJob(clock, job) {
// enqueues a microtick-deferred task - ecma262/#sec-enqueuejob
if (!clock.jobs) {
clock.jobs = [];
}
clock.jobs.push(job);
}

function runJobs(clock) {
// runs all microtick-deferred tasks - ecma262/#sec-runjobs
if (!clock.jobs) {
return;
}
for (var i = 0; i < clock.jobs.length; i++) {
var job = clock.jobs[i];
job.func.apply(null, job.func.args);
}
clock.jobs = [];
}

function addTimer(clock, timer) {
if (timer.func === undefined) {
throw new Error("Callback must be provided to timer calls");
Expand Down Expand Up @@ -288,26 +310,11 @@ function callTimer(clock, timer) {
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;
}

if (exception) {
throw exception;
if (typeof timer.func === "function") {
timer.func.apply(null, timer.args);
} else {
/* eslint no-eval: "off" */
eval(timer.func);
}
}

Expand Down Expand Up @@ -350,19 +357,25 @@ function clearTimer(clock, timerId, ttype) {
}
}

function uninstall(clock, target) {
function uninstall(clock, target, config) {
var method,
i,
l;
var installedHrTime = "_hrtime";
var installedNextTick = "_nextTick";

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 (method === "nextTick" && target.process) {
target.process.nextTick = clock[installedNextTick];
} else {
if (target[method] && target[method].hadOwnProperty) {
target[method] = clock["_" + method];
if (method === "clearInterval" && config.shouldAdvanceTime === true) {
target[method](clock.attachedInterval);
}
} else {
try {
delete target[method];
Expand All @@ -377,7 +390,6 @@ function uninstall(clock, target) {

function hijackMethod(target, method, clock) {
var prop;

clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
clock["_" + method] = target[method];

Expand All @@ -399,6 +411,10 @@ function hijackMethod(target, method, clock) {
target[method].clock = clock;
}

function doIntervalTick(clock, advanceTimeDelta) {
clock.tick(advanceTimeDelta);
}

var timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
Expand All @@ -413,6 +429,10 @@ if (hrtimePresent) {
timers.hrtime = global.process.hrtime;
}

if (nextTickPresent) {
timers.nextTick = global.process.nextTick;
}

if (performancePresent) {
timers.performance = global.performance;
}
Expand Down Expand Up @@ -460,7 +480,12 @@ function createClock(now, loopLimit) {
clock.clearTimeout = function clearTimeout(timerId) {
return clearTimer(clock, timerId, "Timeout");
};

clock.nextTick = function nextTick(func) {
return enqueueJob(clock, {
func: func,
args: Array.prototype.slice.call(1)
});
};
clock.setInterval = function setInterval(func, timeout) {
return addTimer(clock, {
func: func,
Expand All @@ -486,6 +511,10 @@ function createClock(now, loopLimit) {
return clearTimer(clock, timerId, "Immediate");
};

function updateHrTime(newNow) {
clock.hrNow += (newNow - clock.now);
}

clock.tick = function tick(ms) {
ms = typeof ms === "number" ? ms : parseTime(ms);
var tickFrom = clock.now;
Expand All @@ -495,17 +524,15 @@ function createClock(now, loopLimit) {
var oldNow, firstException;

clock.duringTick = true;

function updateHrTime(newNow) {
clock.hrNow += (newNow - clock.now);
}
runJobs(clock);

while (timer && tickFrom <= tickTo) {
if (clock.timers[timer.id]) {
updateHrTime(timer.callAt);
tickFrom = timer.callAt;
clock.now = timer.callAt;
try {
runJobs(clock);
oldNow = clock.now;
callTimer(clock, timer);
} catch (e) {
Expand All @@ -524,6 +551,7 @@ function createClock(now, loopLimit) {
previous = tickFrom;
}

runJobs(clock);
clock.duringTick = false;
updateHrTime(tickTo);
clock.now = tickTo;
Expand All @@ -536,15 +564,18 @@ function createClock(now, loopLimit) {
};

clock.next = function next() {
runJobs(clock);
var timer = firstTimer(clock);
if (!timer) {
return clock.now;
}

clock.duringTick = true;
try {
updateHrTime(timer.callAt);
clock.now = timer.callAt;
callTimer(clock, timer);
runJobs(clock);
return clock.now;
} finally {
clock.duringTick = false;
Expand All @@ -553,12 +584,13 @@ function createClock(now, loopLimit) {

clock.runAll = function runAll() {
var numTimers, i;
runJobs(clock);
for (i = 0; i < clock.loopLimit; i++) {
if (!clock.timers) {
return clock.now;
}

numTimers = Object.keys(clock.timers).length;
numTimers = keys(clock.timers).length;
if (numTimers === 0) {
return clock.now;
}
Expand All @@ -572,6 +604,7 @@ function createClock(now, loopLimit) {
clock.runToLast = function runToLast() {
var timer = lastTimer(clock);
if (!timer) {
runJobs(clock);
return clock.now;
}

Expand Down Expand Up @@ -637,16 +670,24 @@ exports.createClock = createClock;
* @param config.now {number|Date} a number (in milliseconds) or a Date object (default epoch)
* @param config.toFake {string[]} names of the methods that should be faked.
* @param config.loopLimit {number} the maximum number of timers that will be run when calling runAll()
* @param config.shouldAdvanceTime {Boolean} tells lolex to increment mocked time automatically (default false)
* @param config.advanceTimeDelta {Number} increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
*/
exports.install = function install(config) {
if ( arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number") {
throw new TypeError("lolex.install called with " + String(config) +
" lolex 2.0+ requires an object parameter - see https://github.com/sinonjs/lolex");
}
config = typeof config !== "undefined" ? config : {};
config.shouldAdvanceTime = config.shouldAdvanceTime || false;
config.advanceTimeDelta = config.advanceTimeDelta || 20;

var i, l;
var target = config.target || global;
var clock = createClock(config.now, config.loopLimit);

clock.uninstall = function () {
uninstall(clock, target);
uninstall(clock, target, config);
};

clock.methods = config.toFake || [];
Expand All @@ -660,7 +701,18 @@ exports.install = function install(config) {
if (target.process && typeof target.process.hrtime === "function") {
hijackMethod(target.process, clock.methods[i], clock);
}
} else if (clock.methods[i] === "nextTick") {
if (target.process && typeof target.process.nextTick === "function") {
hijackMethod(target.process, clock.methods[i], clock);
}
} else {
if (clock.methods[i] === "setInterval" && config.shouldAdvanceTime === true) {
var intervalTick = doIntervalTick.bind(null, clock, config.advanceTimeDelta);
var intervalId = target[clock.methods[i]](
intervalTick,
config.advanceTimeDelta);
clock.attachedInterval = intervalId;
}
hijackMethod(target, clock.methods[i], clock);
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/lolex-src.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,6 @@ function lastTimer(clock) {
}

function callTimer(clock, timer) {
var exception;

if (typeof timer.interval === "number") {
clock.timers[timer.id].callAt += timer.interval;
} else {
Expand Down

0 comments on commit 4de9790

Please sign in to comment.