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] = jasmine.undefined; 22 }; 23 24 self.clearInterval = function(timeoutKey) { 25 self.scheduledFunctions[timeoutKey] = jasmine.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 != jasmine.undefined && 49 scheduledFunc.runAtMillis >= oldMillis && 50 scheduledFunc.runAtMillis <= nowMillis) { 51 funcsToRun.push(scheduledFunc); 52 this.scheduledFunctions[timeoutKey] = jasmine.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 if (!jasmine.Clock.isInstalled()) { 114 var spec = jasmine.getEnv().currentSpec; 115 spec.after(jasmine.Clock.uninstallMock); 116 117 jasmine.Clock.installMock(); 118 } 119 }, 120 121 installMock: function() { 122 jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; 123 }, 124 125 uninstallMock: function() { 126 jasmine.Clock.assertInstalled(); 127 jasmine.Clock.installed = jasmine.Clock.real; 128 }, 129 130 real: { 131 setTimeout: jasmine.getGlobal().setTimeout, 132 clearTimeout: jasmine.getGlobal().clearTimeout, 133 setInterval: jasmine.getGlobal().setInterval, 134 clearInterval: jasmine.getGlobal().clearInterval 135 }, 136 137 assertInstalled: function() { 138 if (!jasmine.Clock.isInstalled()) { 139 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); 140 } 141 }, 142 143 isInstalled: function() { 144 return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; 145 }, 146 147 installed: null 148 }; 149 jasmine.Clock.installed = jasmine.Clock.real; 150 151 //else for IE support 152 jasmine.getGlobal().setTimeout = function(funcToCall, millis) { 153 if (jasmine.Clock.installed.setTimeout.apply) { 154 return jasmine.Clock.installed.setTimeout.apply(this, arguments); 155 } else { 156 return jasmine.Clock.installed.setTimeout(funcToCall, millis); 157 } 158 }; 159 160 jasmine.getGlobal().setInterval = function(funcToCall, millis) { 161 if (jasmine.Clock.installed.setInterval.apply) { 162 return jasmine.Clock.installed.setInterval.apply(this, arguments); 163 } else { 164 return jasmine.Clock.installed.setInterval(funcToCall, millis); 165 } 166 }; 167 168 jasmine.getGlobal().clearTimeout = function(timeoutKey) { 169 if (jasmine.Clock.installed.clearTimeout.apply) { 170 return jasmine.Clock.installed.clearTimeout.apply(this, arguments); 171 } else { 172 return jasmine.Clock.installed.clearTimeout(timeoutKey); 173 } 174 }; 175 176 jasmine.getGlobal().clearInterval = function(timeoutKey) { 177 if (jasmine.Clock.installed.clearTimeout.apply) { 178 return jasmine.Clock.installed.clearInterval.apply(this, arguments); 179 } else { 180 return jasmine.Clock.installed.clearInterval(timeoutKey); 181 } 182 }; 183 184