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 jasmine.Clock = { 90 defaultFakeTimer: new jasmine.FakeTimer(), 91 92 reset: function() { 93 jasmine.Clock.assertInstalled(); 94 jasmine.Clock.defaultFakeTimer.reset(); 95 }, 96 97 tick: function(millis) { 98 jasmine.Clock.assertInstalled(); 99 jasmine.Clock.defaultFakeTimer.tick(millis); 100 }, 101 102 runFunctionsWithinRange: function(oldMillis, nowMillis) { 103 jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); 104 }, 105 106 scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { 107 jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); 108 }, 109 110 useMock: function() { 111 var spec = jasmine.getEnv().currentSpec; 112 spec.after(jasmine.Clock.uninstallMock); 113 114 jasmine.Clock.installMock(); 115 }, 116 117 installMock: function() { 118 jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; 119 }, 120 121 uninstallMock: function() { 122 jasmine.Clock.assertInstalled(); 123 jasmine.Clock.installed = jasmine.Clock.real; 124 }, 125 126 real: { 127 setTimeout: window.setTimeout, 128 clearTimeout: window.clearTimeout, 129 setInterval: window.setInterval, 130 clearInterval: window.clearInterval 131 }, 132 133 assertInstalled: function() { 134 if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) { 135 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); 136 } 137 }, 138 139 installed: null 140 }; 141 jasmine.Clock.installed = jasmine.Clock.real; 142 143 //else for IE support 144 window.setTimeout = function(funcToCall, millis) { 145 if (jasmine.Clock.installed.setTimeout.apply) { 146 return jasmine.Clock.installed.setTimeout.apply(this, arguments); 147 } else { 148 return jasmine.Clock.installed.setTimeout(funcToCall, millis); 149 } 150 }; 151 152 window.setInterval = function(funcToCall, millis) { 153 if (jasmine.Clock.installed.setInterval.apply) { 154 return jasmine.Clock.installed.setInterval.apply(this, arguments); 155 } else { 156 return jasmine.Clock.installed.setInterval(funcToCall, millis); 157 } 158 }; 159 160 window.clearTimeout = function(timeoutKey) { 161 if (jasmine.Clock.installed.clearTimeout.apply) { 162 return jasmine.Clock.installed.clearTimeout.apply(this, arguments); 163 } else { 164 return jasmine.Clock.installed.clearTimeout(timeoutKey); 165 } 166 }; 167 168 window.clearInterval = function(timeoutKey) { 169 if (jasmine.Clock.installed.clearTimeout.apply) { 170 return jasmine.Clock.installed.clearInterval.apply(this, arguments); 171 } else { 172 return jasmine.Clock.installed.clearInterval(timeoutKey); 173 } 174 }; 175 176