This repository has been archived by the owner on Jun 16, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
305 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
describe('poller', function () { | ||
"use strict"; | ||
|
||
var ngFactories = factory('factories/ng-factories'); | ||
var module = factory('factories/poller', { | ||
'factories/ng-factories': ngFactories | ||
}); | ||
|
||
var Poller; | ||
var $interval; | ||
var poller; | ||
var callback; | ||
var INTERVAL = 1000; | ||
|
||
beforeEach(function () { | ||
angular.mock.module(module.name); | ||
angular.mock.inject(["Poller", "$interval", function (_Poller_, _$interval_) { | ||
Poller = _Poller_; | ||
$interval = _$interval_; | ||
callback = jasmine.createSpy("callback"); | ||
poller = new Poller(INTERVAL, callback); | ||
}]); | ||
|
||
}); | ||
|
||
describe('constructor', function () { | ||
it('should not start poller', function () { | ||
$interval.flush(1001); | ||
expect(callback).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
describe('start', function () { | ||
it('should be started when someone is interested', function () { | ||
poller.start(); | ||
$interval.flush(INTERVAL + 1); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should keep running when someone is interested', function () { | ||
poller.start(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(2); | ||
}); | ||
}); | ||
|
||
describe('stop', function () { | ||
it('should stop when no-one is interested, case 1', function () { | ||
poller.start(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
poller.stop(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should stop when no-one is interested, case 2', function () { | ||
poller.start(); | ||
poller.start(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
poller.stop(); | ||
poller.stop(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should not stop when at least one user is interested', function () { | ||
poller.start(); | ||
poller.start(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
poller.stop(); | ||
$interval.flush(INTERVAL); | ||
expect(callback).toHaveBeenCalledTimes(2); | ||
}); | ||
it('should throw when stopping more then starting', function () { | ||
poller.start(); | ||
poller.stop(); | ||
expect(function () { | ||
poller.stop(); | ||
}).toThrowError(); | ||
}) | ||
}); | ||
|
||
describe('reset', function () { | ||
it('should not start timer when no-one interested', function () { | ||
$interval.flush(INTERVAL / 2); | ||
poller.reset(); | ||
$interval.flush(2 * INTERVAL); | ||
expect(callback).not.toHaveBeenCalled(); | ||
}); | ||
it('should restart timer when someone interested', function () { | ||
poller.start(); | ||
$interval.flush(INTERVAL / 2); | ||
expect(callback).not.toHaveBeenCalled(); | ||
poller.reset(); | ||
$interval.flush(INTERVAL / 2); | ||
expect(callback).not.toHaveBeenCalled(); | ||
$interval.flush(INTERVAL / 2); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
define('factories/ng-factories', ['angular'], function () { | ||
return angular.module('factories', []); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/** | ||
* Variant of $interval() which only starts the interval | ||
* when at least one user is interested. | ||
*/ | ||
define('factories/poller', [ | ||
'factories/ng-factories', | ||
], function (module) { | ||
"use strict"; | ||
|
||
return module.factory('Poller', [ | ||
'$interval', | ||
function($interval) { | ||
|
||
/** | ||
* Ref-counted $interval. | ||
* Starts calling `callback` every `interval` milliseconds when | ||
* number of calls to `start()` is bigger than number of calls to `stop()`. | ||
* | ||
* Usage example: | ||
* const p = new Poller(10000, () => { console.log("tick"); }); | ||
* // when instantiating controller: | ||
* p.start(); | ||
* // when destroying controller: | ||
* p.stop(); | ||
*/ | ||
function Poller(interval, callback) { | ||
this._interval = interval; | ||
this._callback = callback; | ||
this._refs = 0; | ||
this._handle = undefined; // $interval handle | ||
} | ||
|
||
/** | ||
* Enable polling. | ||
* Multiple calls to start() can be made. As long as the number of | ||
* stop() calls is smaller than the number of start() calls, the | ||
* poller keeps running. | ||
*/ | ||
Poller.prototype.start = function () { | ||
this._refs++; | ||
this.reset(); | ||
}; | ||
|
||
/** | ||
* Disable polling when the number of stop calls is equal to | ||
* the number of start calls. | ||
* It is an error to call stop more often than start. | ||
*/ | ||
Poller.prototype.stop = function () { | ||
if (this._refs <= 0) { | ||
throw new Error("start/stop calls mismatched"); | ||
} | ||
this._refs--; | ||
if (this._refs === 0) { | ||
// Keep timer running if others are still interested | ||
this.reset(); | ||
} | ||
}; | ||
|
||
/** | ||
* Restart poller, if it is currently running. | ||
*/ | ||
Poller.prototype.reset = function() { | ||
var self = this; | ||
if (this._handle !== undefined) { | ||
$interval.cancel(this._handle); | ||
this._handle = undefined; | ||
} | ||
if (this._refs > 0) { | ||
this._handle = $interval(function () { | ||
self._callback(); | ||
}, this._interval); | ||
} | ||
}; | ||
|
||
return Poller; | ||
} | ||
]); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.