Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial version for stopwatch. Based on similar implementations made on

  • Loading branch information...
commit d9420b4f32077a7a2a351ec126a4806b36706774 1 parent f436047
@emerleite authored
Showing with 207 additions and 0 deletions.
  1. +62 −0 lib/stopwatch.js
  2. +31 −0 test/manager.test.js
  3. +114 −0 test/stopwatch.test.js
View
62 lib/stopwatch.js
@@ -0,0 +1,62 @@
+var util = require('util');
+var EventEmitter = require('events').EventEmitter;
+var stopwatches = {};
+
+function Stopwatch(id, options) {
+ EventEmitter.call(this);
+
+ this.id = id;
+ this.seconds = options.seconds || 10;
+ this.interval = (options.interval || options.interval == 0) ? options.interval : 1000;
+ this.timer = null;
+}
+
+util.inherits(Stopwatch, EventEmitter);
+
+Stopwatch.prototype.stop = function() {
+ clearInterval(this.timer);
+ this.timer = null;
+};
+
+Stopwatch.prototype.start = function() {
+ if (this.started()) { return false; }
+
+ var self = this;
+ var currentSeconds = self.seconds;
+
+ self.timer = setInterval(function () {
+ self.emit('tick', currentSeconds);
+
+ if (--currentSeconds < 0) {
+ self.stop();
+ self.emit('end');
+ }
+ }, self.interval);
+
+ return true;
+};
+
+Stopwatch.prototype.started = function() {
+ return !!this.timer;
+};
+
+Stopwatch.prototype.restart = function() {
+ this.stop();
+ this.removeAllListeners('tick');
+ this.removeAllListeners('end');
+ this.start();
+};
+
+module.exports = {
+ Stopwatch : Stopwatch,
+ get: function(id, options) {
+ if (!stopwatches[id]) {
+ stopwatches[id] = new Stopwatch(id, options);
+ stopwatches[id].on('end', function() {
+ stopwatches[id] = null;
+ delete stopwatches[id];
+ });
+ }
+ return stopwatches[id];
+ }
+};
View
31 test/manager.test.js
@@ -0,0 +1,31 @@
+var should = require('should');
+var StopwatchManager = require('../lib/stopwatch');
+
+describe('StopwatchManager', function() {
+ var stopwatch = StopwatchManager.get(1, {seconds: 1, interval: 0});
+
+ describe('getting an instance', function() {
+ var subject = StopwatchManager.get(1);
+
+ it('should have the same seconds', function() {
+ subject.seconds.should.equal(stopwatch.seconds);
+ });
+
+ it('should have the same interval', function() {
+ subject.interval.should.equal(stopwatch.interval);
+ });
+ });
+
+ describe('when the time ends', function() {
+ it('should create a new instance', function(done) {
+ stopwatch.start();
+ stopwatch.on('end', function() {
+ var subject = StopwatchManager.get(1, { seconds: 10, interval: 2000 });
+ subject.seconds.should.equal(10);
+ subject.interval.should.equal(2000);
+ done();
+ });
+ });
+
+ });
+});
View
114 test/stopwatch.test.js
@@ -0,0 +1,114 @@
+var should = require('should');
+var Stopwatch = require('../lib/stopwatch').Stopwatch;
+
+describe('Stopwatch', function() {
+ var stopwatch = null;
+
+ beforeEach(function() {
+ stopwatch = new Stopwatch(1, { interval:0 });
+ });
+
+ describe('events', function() {
+ describe('tick and end', function() {
+ beforeEach(function() {
+ stopwatch.start();
+ });
+
+ it('should emit tick N times based on', function(done) {
+ var left = 10;
+ stopwatch.on('tick', function(secondsLeft) {
+ secondsLeft.should.equal(left--);
+ if (left < 0) { done(); }
+ });
+ });
+
+ it('should emit an end event', function(done) {
+ stopwatch.on('end', done);
+ });
+ });
+ });
+
+ describe('#start', function() {
+ it('should return true when first time', function() {
+ stopwatch.start().should.be.true;
+ });
+
+ it('should return false when sencod time', function() {
+ stopwatch.start();
+ stopwatch.start().should.be.false;
+ });
+ });
+
+ describe('#stop', function() {
+ it('should not be started', function() {
+ stopwatch.start();
+ stopwatch.stop();
+ stopwatch.started().should.be.false
+ });
+
+ it('should allow a new start', function() {
+ stopwatch.stop();
+ stopwatch.start().should.be.true;
+ });
+ });
+
+ describe('#restart', function() {
+ describe('when already started', function() {
+ beforeEach(function() {
+ stopwatch.start();
+ });
+
+ it('should be started', function() {
+ stopwatch.restart();
+ stopwatch.started().should.be.true;
+ });
+
+ describe('when has listeners', function() {
+ beforeEach(function() {
+ stopwatch.on('tick', function() {});
+ stopwatch.on('end', function() {});
+ stopwatch.restart();
+ });
+
+ it('should remove all tick listeners', function() {
+ stopwatch.listeners('tick').length.should.equal(0);
+ });
+
+ it('should remove all end listeners', function() {
+ stopwatch.listeners('end').length.should.equal(0);
+ });
+ });
+ });
+
+ describe('when stopped', function() {
+ beforeEach(function() {
+ stopwatch.start();
+ stopwatch.stop();
+ });
+
+ it('should be started', function() {
+ stopwatch.restart();
+ stopwatch.started().should.be.true;
+ });
+ });
+ });
+
+ describe('#started', function() {
+ it('should not be started without calling #start', function() {
+ stopwatch.started().should.be.false;
+ });
+
+ it('should be started after calling #start', function() {
+ stopwatch.start();
+ stopwatch.started().should.be.true;
+ });
+
+ it('should not be started when end', function(done) {
+ stopwatch.start();
+ stopwatch.on('end', function() {
+ stopwatch.started().should.be.false;
+ done();
+ });
+ });
+ });
+});
Please sign in to comment.
Something went wrong with that request. Please try again.