diff --git a/async-kicker.js b/async-kicker.js new file mode 100644 index 0000000..107e128 --- /dev/null +++ b/async-kicker.js @@ -0,0 +1,42 @@ +module.exports = Kicker; + +/* +Some of the tests in this project rely on the event loop being instant while the +reality is quite different. This helper tries to fix that discrepancy. Usage is as follows: + +var kicker = new Kicker(10) // kicks things to the next possible 10 ms + +setTimeout(() => kicker.add(), 2) // About +0 +setTimeout(() => kicker.add(), 13) // About +10 +setTimeout(() => kicker.add(), 25) // About +10 +setTimeout(() => kicker.add(), 38) // About +10 +setTimeout(() => kicker.add(), 41) // About +0 + +setTimeout(() => console.log(kicker.kick()), 50) // [0, 10, 20, 30, 30] + +*/ + +function Kicker(snap) { + if (!(this instanceof Kicker)) return new Kicker(snap); + this.snap = snap + this.times = [] + this.start = new Date() +} + +Kicker.prototype.add = function add() { + this.times.push(new Date() - this.start); +} + +Kicker.prototype.kicked = function kick() { + var kickedTimes = [] + var time = 0; + var offset = 0; + for (var i = 0; i < this.times.length; i++) { + var time = this.times[i] - offset; + var kicked = Math.floor(time / this.snap) * this.snap; + offset += time - kicked; + time = kicked; + kickedTimes.push(time) + } + return kickedTimes +} diff --git a/throttle/test.js b/throttle/test.js index fa91434..1eefb95 100644 --- a/throttle/test.js +++ b/throttle/test.js @@ -1,13 +1,8 @@ var assert = require('assert'); -var sinon = require('sinon'); +var Kicker = require('../async-kicker'); var throttle = require('./'); describe('throttle', function() { - var clock; - - beforeEach(function () { clock = sinon.useFakeTimers(); }); - afterEach(function () { clock.restore(); }); - it('executes right away', function() { var passed = false; var throttled = throttle(function() { @@ -15,7 +10,6 @@ describe('throttle', function() { }, 10); throttled(); assert(passed); - clock.tick(100); }); it("won't execute more than once within the threshold", function(done) { @@ -30,7 +24,6 @@ describe('throttle', function() { assert.equal(called, 1); done(); }, 5); - clock.tick(100); }); it("will execute at least once more to make up for swallowed calls", function(done) { @@ -44,25 +37,21 @@ describe('throttle', function() { assert.equal(called, 2); done(); }, 15); - clock.tick(100); }); - it('will execute every threshold ms', function(done) { - var startTime = new Date(); - var calledTimes = []; + it('will execute every ${threshold} ms', function(done) { + var kicker = new Kicker(10) var throttled = throttle(function() { - calledTimes.push(new Date() - startTime); + kicker.add(); }, 10); throttled(); //start now - var interval = setInterval(throttled, 1); + var interval = setInterval(throttled, 5); setTimeout(function() { clearInterval(interval); - - assert.deepEqual(calledTimes, [0, 11, 22, 33, 44, 55]); + assert.deepEqual(kicker.kicked(), [0, 10, 20, 30, 40, 50]); done(); - }, 59); - clock.tick(100); + }, 69); }); @@ -96,7 +85,6 @@ describe('throttle', function() { assert.deepEqual(args, [33, 44, 55]); done(); }, 15) - clock.tick(100); });