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.log("uninstall") 127 jasmine.Clock.assertInstalled(); 128 jasmine.Clock.installed = jasmine.Clock.real; 129 }, 130 131 real: { 132 setTimeout: jasmine.getGlobal().setTimeout, 133 clearTimeout: jasmine.getGlobal().clearTimeout, 134 setInterval: jasmine.getGlobal().setInterval, 135 clearInterval: jasmine.getGlobal().clearInterval 136 }, 137 138 assertInstalled: function() { 139 if (!jasmine.Clock.isInstalled()) { 140 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); 141 } 142 }, 143 144 isInstalled: function() { 145 return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; 146 }, 147 148 installed: null 149 }; 150 jasmine.Clock.installed = jasmine.Clock.real; 151 152 //else for IE support 153 jasmine.getGlobal().setTimeout = function(funcToCall, millis) { 154 if (jasmine.Clock.installed.setTimeout.apply) { 155 return jasmine.Clock.installed.setTimeout.apply(this, arguments); 156 } else { 157 return jasmine.Clock.installed.setTimeout(funcToCall, millis); 158 } 159 }; 160 161 jasmine.getGlobal().setInterval = function(funcToCall, millis) { 162 if (jasmine.Clock.installed.setInterval.apply) { 163 return jasmine.Clock.installed.setInterval.apply(this, arguments); 164 } else { 165 return jasmine.Clock.installed.setInterval(funcToCall, millis); 166 } 167 }; 168 169 jasmine.getGlobal().clearTimeout = function(timeoutKey) { 170 if (jasmine.Clock.installed.clearTimeout.apply) { 171 return jasmine.Clock.installed.clearTimeout.apply(this, arguments); 172 } else { 173 return jasmine.Clock.installed.clearTimeout(timeoutKey); 174 } 175 }; 176 177 jasmine.getGlobal().clearInterval = function(timeoutKey) { 178 if (jasmine.Clock.installed.clearTimeout.apply) { 179 return jasmine.Clock.installed.clearInterval.apply(this, arguments); 180 } else { 181 return jasmine.Clock.installed.clearInterval(timeoutKey); 182 } 183 }; 184 185