lib/jspec.timers.js in jspec-4.3.2 vs lib/jspec.timers.js in jspec-4.3.3
- old
+ new
@@ -1,90 +1,154 @@
-// JSpec - Mock Timers - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
+// Mock Timers - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
;(function(){
/**
- * Version.
- */
-
- mockTimersVersion = '1.0.2'
-
- /**
* Localized timer stack.
*/
+ var timers = [];
- var timers = []
+ // nodejs, rhino don't have a window object
+ var global = this;
- /**
- * Set mock timeout with _callback_ and timeout of _ms_.
- *
- * @param {function} callback
- * @param {int} ms
- * @return {int}
- * @api public
- */
+ // if they where mocked before this library is loaded - bad luck
+ var savedGlobals = {
+ setTimeout: global.setTimeout,
+ setInterval: global.setInterval,
+ clearInterval: global.clearInterval,
+ clearTimeout: global.clearTimeout,
+
+ // those should not be globals, but are mocked none the less, so we save them
+ resetTimers: global.resetTimers,
+ tick: global.tick
+ };
+ var hadResetTimers = 'resetTimers' in global;
+ var hadTick = 'tick' in global;
- setTimeout = function(callback, ms) {
- var id
- return id = setInterval(function(){
- callback()
- clearInterval(id)
- }, ms)
+ function forEachProperty(anObject, aClosure) {
+ for (var key in anObject) {
+ if ( ! anObject.hasOwnProperty(key))
+ continue;
+
+ aClosure(key, anObject[key]);
+ }
}
- /**
- * Set mock interval with _callback_ and interval of _ms_.
- *
- * @param {function} callback
- * @param {int} ms
- * @return {int}
- * @api public
- */
-
- setInterval = function(callback, ms) {
- callback.step = ms, callback.current = callback.last = 0
- return timers[timers.length] = callback, timers.length
+ global.MockTimers = {
+
+ mockTimersVersion: '2.0.0',
+
+ mockGlobalTimerFunctions: function() {
+ forEachProperty(this.mocks, function(aName, aFunction) {
+ global[aName] = aFunction;
+ });
+ },
+
+ unmockGlobalTimerFunctions: function() {
+ forEachProperty(this.savedGlobals, function(aName, aFunction) {
+ global[aName] = aFunction;
+ });
+
+ if ( ! hadResetTimers)
+ delete global['resetTimers'];
+ if ( ! hadTick)
+ delete global['tick'];
+
+ }
+ };
+
+ function clearTimer(id) {
+ return delete timers[--id];
}
- /**
- * Destroy timer with _id_.
- *
- * @param {int} id
- * @return {bool}
- * @api public
- */
+ var mocks = {
+
+ /**
+ * Set mock timeout with _callback_ and timeout of _ms_.
+ *
+ * @param {function} callback
+ * @param {int} ms
+ * @return {int}
+ * @api public
+ */
+ setTimeout: function(callback, ms) {
+ var id;
+ return id = setInterval(function(){
+ callback();
+ clearInterval(id);
+ }, ms);
+ },
- clearInterval = clearTimeout = function(id) {
- return delete timers[--id]
- }
+
+ /**
+ * Set mock interval with _callback_ and interval of _ms_.
+ *
+ * @param {function} callback
+ * @param {int} ms
+ * @return {int}
+ * @api public
+ */
+ setInterval: function(callback, ms) {
+ // REFACT: use wrapper object so callback is not changed -> state leak
+ callback.step = ms;
+ callback.current = callback.last = 0;
+ timers[timers.length] = callback;
+ return timers.length;
+ },
+
+ /**
+ * Destroy timer with _id_.
+ *
+ * @param {int} id
+ * @return {bool}
+ * @api public
+ */
+ clearInterval: clearTimer,
+ clearTimeout: clearTimer
+ };
+ // additional functions that are not originally in the global namespace
/**
* Reset timers.
*
* @return {array}
* @api public
*/
+ mocks.resetTimers = function() {
+ return timers = [];
+ };
- resetTimers = function() {
- return timers = []
- }
-
/**
* Increment each timers internal clock by _ms_.
*
* @param {int} ms
* @api public
*/
+ mocks.tick = function(ms) {
+ for (var i = 0, len = timers.length; i < len; ++i) {
+ if ( ! timers[i] || ! (timers[i].current += ms))
+ continue;
+
+ if (timers[i].current - timers[i].last < timers[i].step)
+ continue;
+
+ var times = Math.floor((timers[i].current - timers[i].last) / timers[i].step);
+ var remainder = (timers[i].current - timers[i].last) % timers[i].step;
+ timers[i].last = timers[i].current - remainder;
+ while (times-- && timers[i])
+ timers[i]();
+ }
+ };
- tick = function(ms) {
- for (var i = 0, len = timers.length; i < len; ++i)
- if (timers[i] && (timers[i].current += ms))
- if (timers[i].current - timers[i].last >= timers[i].step) {
- var times = Math.floor((timers[i].current - timers[i].last) / timers[i].step)
- var remainder = (timers[i].current - timers[i].last) % timers[i].step
- timers[i].last = timers[i].current - remainder
- while (times-- && timers[i]) timers[i]()
- }
- }
+ // make them available publicly
+ MockTimers.mocks = mocks;
-})()
+ JSpec.include({
+ beforeSpec: function(){
+ MockTimers.mockGlobalTimerFunctions();
+ },
+ afterSpec : function() {
+ MockTimers.unmockGlobalTimerFunctions();
+ }
+ });
+})();
\ No newline at end of file