From 40a5d95c57bf56b4ce537aa1e3d5e9058b3fc012 Mon Sep 17 00:00:00 2001 From: Matthew DuVall Date: Wed, 18 Sep 2013 16:59:53 -0700 Subject: [PATCH] Add support for floating point seconds as a duration --- lib/countdown.js | 30 +++++++++++++++++++++++------- test/test.js | 26 +++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/lib/countdown.js b/lib/countdown.js index 49467f0..717fc5f 100644 --- a/lib/countdown.js +++ b/lib/countdown.js @@ -4,29 +4,45 @@ var root = this; var Countdown = function(duration, onTick, onComplete) { - var secondsLeft = duration + var secondsLeft = parseFloat(duration) , tick = function() { if (secondsLeft > 0) { onTick(secondsLeft); - secondsLeft -= 1; + + if (secondsLeft >= 1.0) { + secondsLeft -= 1.0; + } else { + clearInterval(interval); + + // Assign a new timeout here so we can abort still if < 1 second + setTimeout(function() { + onComplete(); + }, secondsLeft * 1000); + } } else { - clearInterval(interval); - onComplete(); + clearInterval(interval); + onComplete(); } } - // Setting the interval, by call tick and passing through this via a self-calling function wrap. + // Setting the interval, by calling tick() and passing through this via a self-calling function wrap. , interval = setInterval( (function(self){ return function() { tick.call(self); }; })(this), 1000 - ); + ) + , timeout; // First tick. tick.call(this); return { abort: function() { - clearInterval(interval); + // We set the timeout and are definitely < 1 second here + if (typeof timeout !== "undefined") { + clearTimeout(timeout); + } else { + clearInterval(interval); + } } , getRemainingTime: function() { diff --git a/test/test.js b/test/test.js index 4db93ec..4391386 100644 --- a/test/test.js +++ b/test/test.js @@ -33,13 +33,30 @@ describe("countdown.js", function() { assert(tickFunction.callCount == 5); }); - it("executes onComplete", function() { + it("executes onTick while countdown is running for floats on integer boundaries", function() { + new Countdown(1.5, tickFunction, callbackFunction); + assert(tickFunction.callCount == 1); + clock.tick(1000); + assert(tickFunction.callCount == 2); + clock.tick(1000); + assert(tickFunction.callCount == 2); + }); + + it("executes onComplete for integers", function() { new Countdown(5, tickFunction, callbackFunction); clock.tick(4000); assert(callbackFunction.callCount == 0); clock.tick(5000); assert(callbackFunction.callCount == 1); }); + + it("executes onComplete on for floats", function() { + new Countdown(1.5, tickFunction, callbackFunction); + clock.tick(1000); + assert(callbackFunction.callCount == 0); + clock.tick(1000); + assert(callbackFunction.callCount == 1); + }); }); describe("aborting countdown", function() { @@ -63,6 +80,13 @@ describe("countdown.js", function() { clock.tick(5000); assert(callbackFunction.callCount == 0); }); + + it("does not call onComplete when aborted with < 1 second", function() { + clock.tick(4000); + countdown.abort(); + clock.tick(1000); + assert(callbackFunction.callCount == 0); + }); }); describe("getRemainingTime", function() {