1 // Mock setTimeout, clearTimeout 2 // Contributed by Pivotal Computer Systems, www.pivotalsf.com 3 4 jasmine.FakeTimer = function() { 5 this.reset(); 6 7 var self = this; 8 self.setTimeout = function(funcToCall, millis) { 9 self.timeoutsMade++; 10 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); 11 return self.timeoutsMade; 12 }; 13 14 self.setInterval = function(funcToCall, millis) { 15 self.timeoutsMade++; 16 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); 17 return self.timeoutsMade; 18 }; 19 20 self.clearTimeout = function(timeoutKey) { 21 self.scheduledFunctions[timeoutKey] = undefined; 22 }; 23 24 self.clearInterval = function(timeoutKey) { 25 self.scheduledFunctions[timeoutKey] = undefined; 26 }; 27 28 }; 29 30 jasmine.FakeTimer.prototype.reset = function() { 31 this.timeoutsMade = 0; 32 this.scheduledFunctions = {}; 33 this.nowMillis = 0; 34 }; 35 36 jasmine.FakeTimer.prototype.tick = function(millis) { 37 var oldMillis = this.nowMillis; 38 var newMillis = oldMillis + millis; 39 this.runFunctionsWithinRange(oldMillis, newMillis); 40 this.nowMillis = newMillis; 41 }; 42 43 jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { 44 var scheduledFunc; 45 var funcsToRun = []; 46 for (var timeoutKey in this.scheduledFunctions) { 47 scheduledFunc = this.scheduledFunctions[timeoutKey]; 48 if (scheduledFunc != undefined && 49 scheduledFunc.runAtMillis >= oldMillis && 50 scheduledFunc.runAtMillis <= nowMillis) { 51 funcsToRun.push(scheduledFunc); 52 this.scheduledFunctions[timeoutKey] = undefined; 53 } 54 } 55 56 if (funcsToRun.length > 0) { 57 funcsToRun.sort(function(a, b) { 58 return a.runAtMillis - b.runAtMillis; 59 }); 60 for (var i = 0; i < funcsToRun.length; ++i) { 61 try { 62 var funcToRun = funcsToRun[i]; 63 this.nowMillis = funcToRun.runAtMillis; 64 funcToRun.funcToCall(); 65 if (funcToRun.recurring) { 66 this.scheduleFunction(funcToRun.timeoutKey, 67 funcToRun.funcToCall, 68 funcToRun.millis, 69 true); 70 } 71 } catch(e) { 72 } 73 } 74 this.runFunctionsWithinRange(oldMillis, nowMillis); 75 } 76 }; 77 78 jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { 79 this.scheduledFunctions[timeoutKey] = { 80 runAtMillis: this.nowMillis + millis, 81 funcToCall: funcToCall, 82 recurring: recurring, 83 timeoutKey: timeoutKey, 84 millis: millis 85 }; 86 }; 87 88 /** 89 * @namespace 90 */ 91 jasmine.Clock = { 92 defaultFakeTimer: new jasmine.FakeTimer(), 93 94 reset: function() { 95 jasmine.Clock.assertInstalled(); 96 jasmine.Clock.defaultFakeTimer.reset(); 97 }, 98 99 tick: function(millis) { 100 jasmine.Clock.assertInstalled(); 101 jasmine.Clock.defaultFakeTimer.tick(millis); 102 }, 103 104 runFunctionsWithinRange: function(oldMillis, nowMillis) { 105 jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); 106 }, 107 108 scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { 109 jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); 110 }, 111 112 useMock: function() { 113 var spec = jasmine.getEnv().currentSpec; 114 spec.after(jasmine.Clock.uninstallMock); 115 116 jasmine.Clock.installMock(); 117 }, 118 119 installMock: function() { 120 jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; 121 }, 122 123 uninstallMock: function() { 124 jasmine.Clock.assertInstalled(); 125 jasmine.Clock.installed = jasmine.Clock.real; 126 }, 127 128 real: { 129 setTimeout: window.setTimeout, 130 clearTimeout: window.clearTimeout, 131 setInterval: window.setInterval, 132 clearInterval: window.clearInterval 133 }, 134 135 assertInstalled: function() { 136 if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) { 137 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); 138 } 139 }, 140 141 installed: null 142 }; 143 jasmine.Clock.installed = jasmine.Clock.real; 144 145 //else for IE support 146 window.setTimeout = function(funcToCall, millis) { 147 if (jasmine.Clock.installed.setTimeout.apply) { 148 return jasmine.Clock.installed.setTimeout.apply(this, arguments); 149 } else { 150 return jasmine.Clock.installed.setTimeout(funcToCall, millis); 151 } 152 }; 153 154 window.setInterval = function(funcToCall, millis) { 155 if (jasmine.Clock.installed.setInterval.apply) { 156 return jasmine.Clock.installed.setInterval.apply(this, arguments); 157 } else { 158 return jasmine.Clock.installed.setInterval(funcToCall, millis); 159 } 160 }; 161 162 window.clearTimeout = function(timeoutKey) { 163 if (jasmine.Clock.installed.clearTimeout.apply) { 164 return jasmine.Clock.installed.clearTimeout.apply(this, arguments); 165 } else { 166 return jasmine.Clock.installed.clearTimeout(timeoutKey); 167 } 168 }; 169 170 window.clearInterval = function(timeoutKey) { 171 if (jasmine.Clock.installed.clearTimeout.apply) { 172 return jasmine.Clock.installed.clearInterval.apply(this, arguments); 173 } else { 174 return jasmine.Clock.installed.clearInterval(timeoutKey); 175 } 176 }; 177 178