diff --git a/.gitignore b/.gitignore index 723ef36..ba72ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.idea \ No newline at end of file +.idea/ +.idea/inspectionProfiles/ \ No newline at end of file diff --git a/Rakefile b/Rakefile index 364d2da..bcadfe1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,20 +1,14 @@ desc 'Builds lib/jasmine from source' task :build do - sources = [ "src/base.js", - "src/util.js", - "src/Env.js", - "src/ActionCollection.js", - "src/Matchers.js", - "src/NestedResults.js", - "src/PrettyPrinter.js", - "src/QueuedFunction.js", - "src/Reporters.js", - "src/Runner.js", - "src/Spec.js", - "src/Suite.js"] + + # these files must be better + sources = ["src/base.js", "src/util.js", "src/Env.js"] + + sources += Dir.glob('src/*.js').reject{|f| sources.include?(f)} jasmine = File.new('lib/jasmine.js', 'w') sources.each do |source_filename| jasmine.puts(File.read(source_filename)) end -end \ No newline at end of file +end + diff --git a/lib/jasmine.js b/lib/jasmine.js index a82930f..8db9054 100644 --- a/lib/jasmine.js +++ b/lib/jasmine.js @@ -721,6 +721,164 @@ jasmine.Matchers.Any.prototype.toString = function() { return ''; }; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com + +jasmine.FakeTimer = function() { + this.reset(); + + var self = this; + self.setTimeout = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); + return self.timeoutsMade; + }; + + self.setInterval = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); + return self.timeoutsMade; + }; + + self.clearTimeout = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = undefined; + }; + +}; + +jasmine.FakeTimer.prototype.reset = function() { + this.timeoutsMade = 0; + this.scheduledFunctions = {}; + this.nowMillis = 0; +}; + +jasmine.FakeTimer.prototype.tick = function(millis) { + var oldMillis = this.nowMillis; + var newMillis = oldMillis + millis; + this.runFunctionsWithinRange(oldMillis, newMillis); + this.nowMillis = newMillis; +}; + +jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { + var scheduledFunc; + var funcsToRun = []; + for (var timeoutKey in this.scheduledFunctions) { + scheduledFunc = this.scheduledFunctions[timeoutKey]; + if (scheduledFunc != undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = undefined; + } + } + + if (funcsToRun.length > 0) { + funcsToRun.sort(function(a, b) { + return a.runAtMillis - b.runAtMillis; + }); + for (var i = 0; i < funcsToRun.length; ++i) { + try { + var funcToRun = funcsToRun[i]; + this.nowMillis = funcToRun.runAtMillis; + funcToRun.funcToCall(); + if (funcToRun.recurring) { + this.scheduleFunction(funcToRun.timeoutKey, + funcToRun.funcToCall, + funcToRun.millis, + true); + } + } catch(e) { + } + } + this.runFunctionsWithinRange(oldMillis, nowMillis); + } +}; + +jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { + this.scheduledFunctions[timeoutKey] = { + runAtMillis: this.nowMillis + millis, + funcToCall: funcToCall, + recurring: recurring, + timeoutKey: timeoutKey, + millis: millis + }; +}; + + +jasmine.Clock = { + defaultFakeTimer: new jasmine.FakeTimer(), + + reset: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.reset(); + }, + + tick: function(millis) { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.tick(millis); + }, + + runFunctionsWithinRange: function(oldMillis, nowMillis) { + jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); + }, + + scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { + jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); + }, + + useMock: function() { + var spec = jasmine.getEnv().currentSpec; + spec.after(jasmine.Clock.uninstallMock); + + jasmine.Clock.installMock(); + }, + + installMock: function() { + jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; + }, + + uninstallMock: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.installed = jasmine.Clock.real; + }, + + real: { + setTimeout: window.setTimeout, + clearTimeout: window.clearTimeout, + setInterval: window.setInterval, + clearInterval: window.clearInterval + }, + + assertInstalled: function() { + if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +window.setTimeout = function(funcToCall, millis) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); +}; + +window.setInterval = function(funcToCall, millis) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); +}; + +window.clearTimeout = function(timeoutKey) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); +}; + +window.clearInterval = function(timeoutKey) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); +}; + /** * Holds results; allows for the results array to hold another jasmine.NestedResults * diff --git a/spec/runner.html b/spec/runner.html index 0ae2cbf..fe4bbd8 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -18,11 +18,11 @@ + -