diff options
Diffstat (limited to 'lib/jasmine')
| -rw-r--r-- | lib/jasmine/.DS_Store | bin | 0 -> 6148 bytes | |||
| -rw-r--r-- | lib/jasmine/jasmine-1.0.1.js (renamed from lib/jasmine/jasmine-0.10.3.js) | 806 |
2 files changed, 448 insertions, 358 deletions
diff --git a/lib/jasmine/.DS_Store b/lib/jasmine/.DS_Store Binary files differnew file mode 100644 index 00000000..5008ddfc --- /dev/null +++ b/lib/jasmine/.DS_Store diff --git a/lib/jasmine/jasmine-0.10.3.js b/lib/jasmine/jasmine-1.0.1.js index f309493f..964f99ed 100644 --- a/lib/jasmine/jasmine-0.10.3.js +++ b/lib/jasmine/jasmine-1.0.1.js @@ -21,12 +21,25 @@ jasmine.unimplementedMethod_ = function() { jasmine.undefined = jasmine.___undefined___; /** - * Default interval for event loop yields. Small values here may result in slow test running. Zero means no updates until all tests have completed. + * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * */ jasmine.DEFAULT_UPDATE_INTERVAL = 250; /** + * Default timeout interval in milliseconds for waitsFor() blocks. + */ +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + +jasmine.getGlobal = function() { + function getGlobal() { + return this; + } + + return getGlobal(); +}; + +/** * Allows for bound functions to be compared. Internal use only. * * @ignore @@ -42,35 +55,49 @@ jasmine.bindOriginal_ = function(base, name) { }; } else { // IE support - return window[name]; + return jasmine.getGlobal()[name]; } }; -jasmine.setTimeout = jasmine.bindOriginal_(window, 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(window, 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(window, 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(window, 'clearInterval'); +jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); +jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); +jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); +jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); -jasmine.MessageResult = function(text) { - this.type = 'MessageResult'; - this.text = text; +jasmine.MessageResult = function(values) { + this.type = 'log'; + this.values = values; this.trace = new Error(); // todo: test better }; +jasmine.MessageResult.prototype.toString = function() { + var text = ""; + for(var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; +}; + jasmine.ExpectationResult = function(params) { - this.type = 'ExpectationResult'; + this.type = 'expect'; this.matcherName = params.matcherName; this.passed_ = params.passed; this.expected = params.expected; this.actual = params.actual; - /** @deprecated */ - this.details = params.details; - this.message = this.passed_ ? 'Passed.' : params.message; this.trace = this.passed_ ? '' : new Error(this.message); }; +jasmine.ExpectationResult.prototype.toString = function () { + return this.message; +}; + jasmine.ExpectationResult.prototype.passed = function () { return this.passed_; }; @@ -150,7 +177,7 @@ jasmine.isDomNode = function(obj) { * * @example * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).wasCalledWith(jasmine.any(Function)); + * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); * * @param {Class} clazz * @returns matchable object of the type clazz @@ -165,7 +192,8 @@ jasmine.any = function(clazz) { * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine * expectation syntax. Spies can be checked if they were called or not and what the calling params were. * - * A Spy has the following mehtod: wasCalled, callCount, mostRecentCall, and argsForCall (see docs) + * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). + * * Spies are torn down at the end of every spec. * * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. @@ -195,8 +223,8 @@ jasmine.any = function(clazz) { * * // mock example * foo.not(7 == 7); - * expect(foo.not).wasCalled(); - * expect(foo.not).wasCalledWith(true); + * expect(foo.not).toHaveBeenCalled(); + * expect(foo.not).toHaveBeenCalledWith(true); * * @constructor * @see spyOn, jasmine.createSpy, jasmine.createSpyObj @@ -387,8 +415,14 @@ jasmine.createSpyObj = function(baseName, methodNames) { return obj; }; -jasmine.log = function(message) { - jasmine.getEnv().currentSpec.log(message); +/** + * All parameters are pretty-printed and concatenated together, then written to the current spec's output. + * + * Be careful not to leave calls to <code>jasmine.log</code> in production code. + */ +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); }; /** @@ -461,22 +495,24 @@ var runs = function(func) { }; /** - * Waits for a timeout before moving to the next runs()-defined block. - * @param {Number} timeout + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait */ var waits = function(timeout) { jasmine.getEnv().currentSpec.waits(timeout); }; /** - * Waits for the latchFunction to return true before proceeding to the next runs()-defined block. + * Waits for the latchFunction to return true before proceeding to the next block. * - * @param {Number} timeout * @param {Function} latchFunction - * @param {String} message + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout */ -var waitsFor = function(timeout, latchFunction, message) { - jasmine.getEnv().currentSpec.waitsFor(timeout, latchFunction, message); +var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); }; /** @@ -551,31 +587,6 @@ jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { } throw new Error("This browser does not support XMLHttpRequest."); } : XMLHttpRequest; - -/** - * Adds suite files to an HTML document so that they are executed, thus adding them to the current - * Jasmine environment. - * - * @param {String} url path to the file to include - * @param {Boolean} opt_global - * @deprecated We suggest you use a different method of including JS source files. <code>jasmine.include</code> will be removed soon. - */ -jasmine.include = function(url, opt_global) { - if (opt_global) { - document.write('<script type="text/javascript" src="' + url + '"></' + 'script>'); - } else { - var xhr; - try { - xhr = new jasmine.XmlHttpRequest(); - xhr.open("GET", url, false); - xhr.send(null); - } catch(e) { - throw new Error("couldn't fetch " + url + ": " + e); - } - - return eval(xhr.responseText); - } -}; /** * @namespace */ @@ -656,6 +667,7 @@ jasmine.Env = function() { this.reporter = new jasmine.MultiReporter(); this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; + this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; this.lastUpdate = 0; this.specFilter = function() { return true; @@ -741,10 +753,21 @@ jasmine.Env.prototype.describe = function(description, specDefinitions) { this.currentSuite = suite; - specDefinitions.call(suite); + var declarationError = null; + try { + specDefinitions.call(suite); + } catch(e) { + declarationError = e; + } this.currentSuite = parentSuite; + if (declarationError) { + this.it("encountered a declaration exception", function() { + throw declarationError; + }); + } + return suite; }; @@ -915,6 +938,10 @@ jasmine.Reporter.prototype.reportSuiteResults = function(suite) { }; //noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecStarting = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.reportSpecResults = function(spec) { }; @@ -957,7 +984,7 @@ jasmine.JsApiReporter = function() { jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { this.started = true; - var suites = runner.suites(); + var suites = runner.topLevelSuites(); for (var i = 0; i < suites.length; i++) { var suite = suites[i]; this.suites_.push(this.summarize_(suite)); @@ -976,10 +1003,11 @@ jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { type: isSuite ? 'suite' : 'spec', children: [] }; + if (isSuite) { - var specs = suiteOrSpec.specs(); - for (var i = 0; i < specs.length; i++) { - summary.children.push(this.summarize_(specs[i])); + var children = suiteOrSpec.children(); + for (var i = 0; i < children.length; i++) { + summary.children.push(this.summarize_(children[i])); } } return summary; @@ -1025,11 +1053,11 @@ jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ var summaryMessages = []; - var messagesLength = result.messages.length + var messagesLength = result.messages.length; for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { var resultMessage = result.messages[messageIndex]; summaryMessages.push({ - text: resultMessage.text, + text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, passed: resultMessage.passed ? resultMessage.passed() : true, type: resultMessage.type, message: resultMessage.message, @@ -1037,14 +1065,12 @@ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined } }); - }; + } - var summaryResult = { + return { result : result.result, messages : summaryMessages }; - - return summaryResult; }; /** @@ -1064,25 +1090,11 @@ jasmine.Matchers = function(env, actual, spec, opt_isNot) { // todo: @deprecated as of Jasmine 0.11, remove soon [xw] jasmine.Matchers.pp = function(str) { throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); - this.report(); }; -/** @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. */ +// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] jasmine.Matchers.prototype.report = function(result, failing_message, details) { - // todo: report a deprecation warning [xw] - - if (this.isNot) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); - } - - this.reportWasCalled_ = true; - var expectationResult = new jasmine.ExpectationResult({ - passed: result, - message: failing_message, - details: details - }); - this.spec.addMatcherResult(expectationResult); - return result; + throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); }; jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { @@ -1131,7 +1143,7 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { message: message }); this.spec.addMatcherResult(expectationResult); - return result; + return jasmine.undefined; }; }; @@ -1149,6 +1161,7 @@ jasmine.Matchers.prototype.toBe = function(expected) { /** * toNotBe: compares the actual to the expected using !== * @param expected + * @deprecated as of 1.0. Use not.toBe() instead. */ jasmine.Matchers.prototype.toNotBe = function(expected) { return this.actual !== expected; @@ -1166,6 +1179,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) { /** * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual * @param expected + * @deprecated as of 1.0. Use not.toNotEqual() instead. */ jasmine.Matchers.prototype.toNotEqual = function(expected) { return !this.env.equals_(this.actual, expected); @@ -1184,6 +1198,7 @@ jasmine.Matchers.prototype.toMatch = function(expected) { /** * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch * @param expected + * @deprecated as of 1.0. Use not.toMatch() instead. */ jasmine.Matchers.prototype.toNotMatch = function(expected) { return !(new RegExp(expected).test(this.actual)); @@ -1225,12 +1240,13 @@ jasmine.Matchers.prototype.toBeFalsy = function() { return !this.actual; }; + /** * Matcher that checks to see if the actual, a Jasmine spy, was called. */ -jasmine.Matchers.prototype.wasCalled = function() { +jasmine.Matchers.prototype.toHaveBeenCalled = function() { if (arguments.length > 0) { - throw new Error('wasCalled does not take arguments, use wasCalledWith'); + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); } if (!jasmine.isSpy(this.actual)) { @@ -1238,14 +1254,22 @@ jasmine.Matchers.prototype.wasCalled = function() { } this.message = function() { - return "Expected spy " + this.actual.identity + " to have been called."; + return [ + "Expected spy " + this.actual.identity + " to have been called.", + "Expected spy " + this.actual.identity + " not to have been called." + ]; }; return this.actual.wasCalled; }; +/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ +jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; + /** * Matcher that checks to see if the actual, a Jasmine spy, was not called. + * + * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead */ jasmine.Matchers.prototype.wasNotCalled = function() { if (arguments.length > 0) { @@ -1257,7 +1281,10 @@ jasmine.Matchers.prototype.wasNotCalled = function() { } this.message = function() { - return "Expected spy " + this.actual.identity + " to not have been called."; + return [ + "Expected spy " + this.actual.identity + " to not have been called.", + "Expected spy " + this.actual.identity + " to have been called." + ]; }; return !this.actual.wasCalled; @@ -1269,22 +1296,33 @@ jasmine.Matchers.prototype.wasNotCalled = function() { * @example * */ -jasmine.Matchers.prototype.wasCalledWith = function() { +jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { var expectedArgs = jasmine.util.argsToArray(arguments); if (!jasmine.isSpy(this.actual)) { throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); } this.message = function() { if (this.actual.callCount == 0) { - return "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called."; + // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] + return [ + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was." + ]; } else { - return "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall); + return [ + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) + ]; } }; return this.env.contains_(this.actual.argsForCall, expectedArgs); }; +/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; + +/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ jasmine.Matchers.prototype.wasNotCalledWith = function() { var expectedArgs = jasmine.util.argsToArray(arguments); if (!jasmine.isSpy(this.actual)) { @@ -1292,7 +1330,10 @@ jasmine.Matchers.prototype.wasNotCalledWith = function() { } this.message = function() { - return "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was"; + return [ + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" + ] }; return !this.env.contains_(this.actual.argsForCall, expectedArgs); @@ -1311,6 +1352,7 @@ jasmine.Matchers.prototype.toContain = function(expected) { * Matcher that checks that the expected item is NOT an element in the actual Array. * * @param {Object} expected + * @deprecated as of 1.0. Use not.toNotContain() instead. */ jasmine.Matchers.prototype.toNotContain = function(expected) { return !this.env.contains_(this.actual, expected); @@ -1344,9 +1386,11 @@ jasmine.Matchers.prototype.toThrow = function(expected) { result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); } + var not = this.isNot ? "not " : ""; + this.message = function() { if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function to throw", expected.message || expected, ", but it threw", exception.message || exception].join(' '); + return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' '); } else { return "Expected function to throw an exception."; } @@ -1396,7 +1440,14 @@ jasmine.MultiReporter.prototype.addReporter = function(reporter) { }; (function() { - var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"]; + var functionNames = [ + "reportRunnerStarting", + "reportRunnerResults", + "reportSuiteResults", + "reportSpecStarting", + "reportSpecResults", + "log" + ]; for (var i = 0; i < functionNames.length; i++) { var functionName = functionNames[i]; jasmine.MultiReporter.prototype[functionName] = (function(functionName) { @@ -1451,11 +1502,11 @@ jasmine.NestedResults.prototype.rollupCounts = function(result) { }; /** - * Tracks a result's message. - * @param message + * Adds a log message. + * @param values Array of message parts which will be concatenated later. */ -jasmine.NestedResults.prototype.log = function(message) { - this.items_.push(new jasmine.MessageResult(message)); +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); }; /** @@ -1470,7 +1521,7 @@ jasmine.NestedResults.prototype.getItems = function() { * @param {jasmine.ExpectationResult|jasmine.NestedResults} result */ jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'MessageResult') { + if (result.type != 'log') { if (result.items_) { this.rollupCounts(result); } else { @@ -1514,8 +1565,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) { this.emitScalar('undefined'); } else if (value === null) { this.emitScalar('null'); - } else if (value.navigator && value.frames && value.setTimeout) { - this.emitScalar('<window>'); + } else if (value === jasmine.getGlobal()) { + this.emitScalar('<global>'); } else if (value instanceof jasmine.Matchers.Any) { this.emitScalar(value.toString()); } else if (typeof value === 'string') { @@ -1619,6 +1670,7 @@ jasmine.Queue = function(env) { this.running = false; this.index = 0; this.offset = 0; + this.abort = false; }; jasmine.Queue.prototype.addBefore = function(block) { @@ -1653,7 +1705,7 @@ jasmine.Queue.prototype.next_ = function() { while (goAgain) { goAgain = false; - if (self.index < self.blocks.length) { + if (self.index < self.blocks.length && !this.abort) { var calledSynchronously = true; var completedSynchronously = false; @@ -1663,6 +1715,10 @@ jasmine.Queue.prototype.next_ = function() { return; } + if (self.blocks[self.index].abort) { + self.abort = true; + } + self.offset = 0; self.index++; @@ -1707,49 +1763,6 @@ jasmine.Queue.prototype.results = function() { }; -/** JasmineReporters.reporter - * Base object that will get called whenever a Spec, Suite, or Runner is done. It is up to - * descendants of this object to do something with the results (see json_reporter.js) - * - * @deprecated - */ -jasmine.Reporters = {}; - -/** - * @deprecated - * @param callbacks - */ -jasmine.Reporters.reporter = function(callbacks) { - /** - * @deprecated - * @param callbacks - */ - var that = { - callbacks: callbacks || {}, - - doCallback: function(callback, results) { - if (callback) { - callback(results); - } - }, - - reportRunnerResults: function(runner) { - that.doCallback(that.callbacks.runnerCallback, runner); - }, - reportSuiteResults: function(suite) { - that.doCallback(that.callbacks.suiteCallback, suite); - }, - reportSpecResults: function(spec) { - that.doCallback(that.callbacks.specCallback, spec); - }, - log: function (str) { - if (console && console.log) console.log(str); - } - }; - - return that; -}; - /** * Runner * @@ -1777,12 +1790,12 @@ jasmine.Runner.prototype.execute = function() { jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { beforeEachFunction.typeName = 'beforeEach'; - this.before_.push(beforeEachFunction); + this.before_.splice(0,0,beforeEachFunction); }; jasmine.Runner.prototype.afterEach = function(afterEachFunction) { afterEachFunction.typeName = 'afterEach'; - this.after_.push(afterEachFunction); + this.after_.splice(0,0,afterEachFunction); }; @@ -1810,11 +1823,20 @@ jasmine.Runner.prototype.specs = function () { return specs; }; - jasmine.Runner.prototype.suites = function() { return this.suites_; }; +jasmine.Runner.prototype.topLevelSuites = function() { + var topLevelSuites = []; + for (var i = 0; i < this.suites_.length; i++) { + if (!this.suites_[i].parentSuite) { + topLevelSuites.push(this.suites_[i]); + } + } + return topLevelSuites; +}; + jasmine.Runner.prototype.results = function() { return this.queue.results(); }; @@ -1857,13 +1879,13 @@ jasmine.Spec.prototype.results = function() { return this.results_; }; -jasmine.Spec.prototype.log = function(message) { - return this.results_.log(message); -}; - -/** @deprecated */ -jasmine.Spec.prototype.getResults = function() { - return this.results_; +/** + * All parameters are pretty-printed and concatenated together, then written to the spec's output. + * + * Be careful not to leave calls to <code>jasmine.log</code> in production code. + */ +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); }; jasmine.Spec.prototype.runs = function (func) { @@ -1880,6 +1902,9 @@ jasmine.Spec.prototype.addToQueue = function (block) { } }; +/** + * @param {jasmine.ExpectationResult} result + */ jasmine.Spec.prototype.addMatcherResult = function(result) { this.results_.addResult(result); }; @@ -1890,14 +1915,46 @@ jasmine.Spec.prototype.expect = function(actual) { return positive; }; +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ jasmine.Spec.prototype.waits = function(timeout) { var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); this.addToQueue(waitsFunc); return this; }; -jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) { - var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this); +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + var latchFunction_ = null; + var optional_timeoutMessage_ = null; + var optional_timeout_ = null; + + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + switch (typeof arg) { + case 'function': + latchFunction_ = arg; + break; + case 'string': + optional_timeoutMessage_ = arg; + break; + case 'number': + optional_timeout_ = arg; + break; + } + } + + var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); this.addToQueue(waitsForFunc); return this; }; @@ -1951,7 +2008,8 @@ jasmine.Spec.prototype.execute = function(onComplete) { spec.finish(onComplete); return; } - this.env.reporter.log('>> Jasmine Running ' + this.suite.description + ' ' + this.description + '...'); + + this.env.reporter.reportSpecStarting(this); spec.env.currentSpec = spec; @@ -2042,6 +2100,8 @@ jasmine.Suite = function(env, description, specDefinitions, parentSuite) { self.env = env; self.before_ = []; self.after_ = []; + self.children_ = []; + self.suites_ = []; self.specs_ = []; }; @@ -2063,31 +2123,41 @@ jasmine.Suite.prototype.finish = function(onComplete) { jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { beforeEachFunction.typeName = 'beforeEach'; - this.before_.push(beforeEachFunction); + this.before_.unshift(beforeEachFunction); }; jasmine.Suite.prototype.afterEach = function(afterEachFunction) { afterEachFunction.typeName = 'afterEach'; - this.after_.push(afterEachFunction); + this.after_.unshift(afterEachFunction); }; jasmine.Suite.prototype.results = function() { return this.queue.results(); }; -jasmine.Suite.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.env.currentRunner().addSuite(block); +jasmine.Suite.prototype.add = function(suiteOrSpec) { + this.children_.push(suiteOrSpec); + if (suiteOrSpec instanceof jasmine.Suite) { + this.suites_.push(suiteOrSpec); + this.env.currentRunner().addSuite(suiteOrSpec); } else { - this.specs_.push(block); + this.specs_.push(suiteOrSpec); } - this.queue.add(block); + this.queue.add(suiteOrSpec); }; jasmine.Suite.prototype.specs = function() { return this.specs_; }; +jasmine.Suite.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Suite.prototype.children = function() { + return this.children_; +}; + jasmine.Suite.prototype.execute = function(onComplete) { var self = this; this.queue.start(function () { @@ -2107,225 +2177,245 @@ jasmine.WaitsBlock.prototype.execute = function (onComplete) { onComplete(); }, this.timeout); }; +/** + * A block which waits for some condition to become true, with timeout. + * + * @constructor + * @extends jasmine.Block + * @param {jasmine.Env} env The Jasmine environment. + * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. + * @param {Function} latchFunction A function which returns true when the desired condition has been met. + * @param {String} message The message to display if the desired condition hasn't been met within the given time period. + * @param {jasmine.Spec} spec The Jasmine spec. + */ jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout; + this.timeout = timeout || env.defaultTimeoutInterval; this.latchFunction = latchFunction; this.message = message; this.totalTimeSpentWaitingForLatch = 0; jasmine.Block.call(this, env, null, spec); }; - jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100; +jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; -jasmine.WaitsForBlock.prototype.execute = function (onComplete) { - var self = this; - self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen')); +jasmine.WaitsForBlock.prototype.execute = function(onComplete) { + this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); var latchFunctionResult; try { - latchFunctionResult = self.latchFunction.apply(self.spec); + latchFunctionResult = this.latchFunction.apply(this.spec); } catch (e) { - self.spec.fail(e); + this.spec.fail(e); onComplete(); return; } if (latchFunctionResult) { onComplete(); - } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) { - var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen'); - self.spec.fail({ + } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { + var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); + this.spec.fail({ name: 'timeout', message: message }); - self.spec._next(); + + this.abort = true; + onComplete(); } else { - self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// 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] = jasmine.undefined;
- };
-
- self.clearInterval = function(timeoutKey) {
- self.scheduledFunctions[timeoutKey] = jasmine.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 != jasmine.undefined &&
- scheduledFunc.runAtMillis >= oldMillis &&
- scheduledFunc.runAtMillis <= nowMillis) {
- funcsToRun.push(scheduledFunc);
- this.scheduledFunctions[timeoutKey] = jasmine.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
- };
-};
-
-/**
- * @namespace
- */
-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;
-
-//else for IE support
-window.setTimeout = function(funcToCall, millis) {
- if (jasmine.Clock.installed.setTimeout.apply) {
- return jasmine.Clock.installed.setTimeout.apply(this, arguments);
- } else {
- return jasmine.Clock.installed.setTimeout(funcToCall, millis);
- }
-};
-
-window.setInterval = function(funcToCall, millis) {
- if (jasmine.Clock.installed.setInterval.apply) {
- return jasmine.Clock.installed.setInterval.apply(this, arguments);
- } else {
- return jasmine.Clock.installed.setInterval(funcToCall, millis);
- }
-};
-
-window.clearTimeout = function(timeoutKey) {
- if (jasmine.Clock.installed.clearTimeout.apply) {
- return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
- } else {
- return jasmine.Clock.installed.clearTimeout(timeoutKey);
- }
-};
-
-window.clearInterval = function(timeoutKey) {
- if (jasmine.Clock.installed.clearTimeout.apply) {
- return jasmine.Clock.installed.clearInterval.apply(this, arguments);
- } else {
- return jasmine.Clock.installed.clearInterval(timeoutKey);
- }
-};
-
+ this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; + var self = this; + this.env.setTimeout(function() { + self.execute(onComplete); + }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); + } +}; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com -jasmine.version_= { - "major": 0, - "minor": 10, - "build": 3, - "revision": 1270162784 +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] = jasmine.undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.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 != jasmine.undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = jasmine.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 }; +}; + +/** + * @namespace + */ +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() { + if (!jasmine.Clock.isInstalled()) { + 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: jasmine.getGlobal().setTimeout, + clearTimeout: jasmine.getGlobal().clearTimeout, + setInterval: jasmine.getGlobal().setInterval, + clearInterval: jasmine.getGlobal().clearInterval + }, + + assertInstalled: function() { + if (!jasmine.Clock.isInstalled()) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + isInstalled: function() { + return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +//else for IE support +jasmine.getGlobal().setTimeout = function(funcToCall, millis) { + if (jasmine.Clock.installed.setTimeout.apply) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.setTimeout(funcToCall, millis); + } +}; + +jasmine.getGlobal().setInterval = function(funcToCall, millis) { + if (jasmine.Clock.installed.setInterval.apply) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.setInterval(funcToCall, millis); + } +}; + +jasmine.getGlobal().clearTimeout = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearTimeout(timeoutKey); + } +}; + +jasmine.getGlobal().clearInterval = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearInterval(timeoutKey); + } +}; + + +jasmine.version_= { + "major": 1, + "minor": 0, + "build": 1, + "revision": 1286311016 +}; |
