From d5489a3e0d533d45506e7a2297a3bccd7e31e107 Mon Sep 17 00:00:00 2001 From: ragaskar Date: Sat, 1 Aug 2009 10:43:03 -0700 Subject: [PATCH] Start of before/after refactor. Yank defineGetter on nestedResults. rake build task now sorts sources to minimize jasmine.js changes post-build --- Rakefile | 5 +- lib/jasmine.js | 1224 ++++++++++++++++---------------- spec/suites/SpecRunningTest.js | 16 +- src/Spec.js | 14 +- src/Suite.js | 8 +- 5 files changed, 644 insertions(+), 623 deletions(-) diff --git a/Rakefile b/Rakefile index fcd5025d..63cc5c8b 100644 --- a/Rakefile +++ b/Rakefile @@ -4,11 +4,10 @@ task :build do # these files must be loaded first sources = ["src/base.js", "src/util.js", "src/Env.js", "src/ActionCollection.js", "src/Reporter.js", "src/Block.js"] - sources += Dir.glob('src/*.js').reject{|f| sources.include?(f)} + sources += Dir.glob('src/*.js').reject{|f| sources.include?(f)}.sort jasmine = File.new('lib/jasmine.js', 'w') sources.each do |source_filename| jasmine.puts(File.read(source_filename)) end -end - +end \ No newline at end of file diff --git a/lib/jasmine.js b/lib/jasmine.js index 63020c29..0b880547 100644 --- a/lib/jasmine.js +++ b/lib/jasmine.js @@ -649,7 +649,7 @@ jasmine.Env.prototype.it = function(description, func) { this.currentSpec = spec; if (func) { - spec.addToQueue(func); + spec.runs(func); } return spec; @@ -904,209 +904,6 @@ jasmine.Block.prototype.execute = function() { jasmine.Block.prototype.fail = function(e) { this.spec.results.addResult(new jasmine.ExpectationResult(false, jasmine.util.formatException(e), null)); }; -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - jasmine.ActionCollection.call(this, env); - - this.id = env.nextSuiteId_++; - this.description = description; - this.specs = this.actions; - this.parentSuite = parentSuite; - - this.beforeEachFunction = null; - this.afterEachFunction = null; -}; -jasmine.util.inherit(jasmine.Suite, jasmine.ActionCollection); - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finishCallback = function() { - this.env.reporter.reportSuiteResults(this); -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.beforeEachFunction = beforeEachFunction; -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.afterEachFunction = afterEachFunction; -}; - -jasmine.Suite.prototype.getResults = function() { - var results = new jasmine.NestedResults(); - results.description = this.description; - results.id = this.id; - - for (var i = 0; i < this.specs.length; i++) { - results.rollupCounts(this.specs[i].getResults()); - } - return results; -}; - -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - * @returns {String} - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - // return '(jasmine.pp nested too deeply!)'; - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value.navigator && value.frames && value.setTimeout) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__(property) != null); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); /** JavaScript API reporter. * * @constructor @@ -1165,372 +962,6 @@ jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { jasmine.JsApiReporter.prototype.log = function(str) { }; -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Tracks a result's message. - * @param message - */ -jasmine.NestedResults.prototype.log = function(message) { - this.items_.push(new jasmine.MessageResult(message)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'MessageResult') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.__defineGetter__('passed', function() { - return this.passedCount === this.totalCount; -}); -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - jasmine.ActionCollection.call(this, env); - - this.suites = this.actions; -}; -jasmine.util.inherit(jasmine.Runner, jasmine.ActionCollection); - -jasmine.Runner.prototype.execute = function() { - if (this.env.reporter.reportRunnerStarting) { - this.env.reporter.reportRunnerStarting(this); - } - jasmine.ActionCollection.prototype.execute.call(this); -}; - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.getResults = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.suites.length; i++) { - results.rollupCounts(this.suites[i].getResults()); - } - return results; -}; -/* 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) - */ -jasmine.Reporters = {}; - -jasmine.Reporters.reporter = function(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; -}; - -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function () { - var self = this; - self.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - self.env.setTimeout(function () { - self.next(); - }, self.timeout); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - this.id = env.nextSpecId_++; - this.env = env; - this.suite = suite; - this.description = description; - this.queue = []; - this.finished = false; - this.afterCallbacks = []; - this.spies_ = []; - - this.results = new jasmine.NestedResults(); - this.results.description = description; - this.runs = this.addToQueue; - this.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - -jasmine.Spec.prototype.getResults = function() { - return this.results; -}; - -jasmine.Spec.prototype.addToQueue = function(func) { - var block = new jasmine.Block(this.env, func, this); - - this.setNextOnLastInQueue(block); - - this.queue.push(block); - - return this; -}; - -/** - * @private - * @deprecated - */ -jasmine.Spec.prototype.expects_that = function(actual) { - return this.expect(actual); -}; - -/** -* @private - */ -jasmine.Spec.prototype.expect = function(actual) { - return new (this.getMatchersClass_())(this.env, actual, this.results); -}; - -/** - * @private - */ -jasmine.Spec.prototype.setNextOnLastInQueue = function (block) { - if (this.queue.length > 0) { - var previousBlock = this.queue[this.queue.length - 1]; - previousBlock.next = function() { - block.execute(); - }; - } -}; - -/** - * @private - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.setNextOnLastInQueue(waitsFunc); - this.queue.push(waitsFunc); - return this; -}; - -/** - * @private - */ -jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) { - var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this); - this.setNextOnLastInQueue(waitsForFunc); - this.queue.push(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.failWithException = function (e) { - this.results.addResult(new jasmine.ExpectationResult(false, jasmine.util.formatException(e), null)); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || jasmine.Matchers; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - for (var method in matchersPrototype) { - newMatchersClass.prototype[method] = matchersPrototype[method]; - } - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function() { - this.safeExecuteAfters(); - - this.removeAllSpies(); - this.finishCallback(); - this.finished = true; -}; - -jasmine.Spec.prototype.after = function(doAfter) { - this.afterCallbacks.unshift(doAfter); -}; - -jasmine.Spec.prototype.execute = function() { - if (!this.env.specFilter(this)) { - this.results.skipped = true; - this.finishCallback(); - this.finished = true; - return; - } - - this.env.currentSpec = this; - this.env.currentlyRunningTests = true; - - this.safeExecuteBefores(); - - if (this.queue[0]) { - this.queue[0].execute(); - } else { - this.finish(); - } - this.env.currentlyRunningTests = false; -}; - -jasmine.Spec.prototype.safeExecuteBefores = function() { - var befores = []; - for (var suite = this.suite; suite; suite = suite.parentSuite) { - if (suite.beforeEachFunction) befores.push(suite.beforeEachFunction); - } - - while (befores.length) { - this.safeExecuteBeforeOrAfter(befores.pop()); - } -}; - -jasmine.Spec.prototype.safeExecuteAfters = function() { - for (var suite = this.suite; suite; suite = suite.parentSuite) { - if (suite.afterEachFunction) this.safeExecuteBeforeOrAfter(suite.afterEachFunction); - } -}; - -jasmine.Spec.prototype.safeExecuteBeforeOrAfter = function(func) { - try { - func.apply(this); - } catch (e) { - this.results.addResult(new jasmine.ExpectationResult(false, func.typeName + '() fail: ' + jasmine.util.formatException(e), null)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - jasmine.Matchers = function(env, actual, results) { this.env = env; this.actual = actual; @@ -1803,6 +1234,621 @@ jasmine.Matchers.Any.prototype.toString = function() { return ''; }; +/** + * @constructor + */ +jasmine.MultiReporter = function() { + this.subReporters_ = []; +}; +jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); + +jasmine.MultiReporter.prototype.addReporter = function(reporter) { + this.subReporters_.push(reporter); +}; + +(function() { + var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"]; + for (var i = 0; i < functionNames.length; i++) { + var functionName = functionNames[i]; + jasmine.MultiReporter.prototype[functionName] = (function(functionName) { + return function() { + for (var j = 0; j < this.subReporters_.length; j++) { + var subReporter = this.subReporters_[j]; + if (subReporter[functionName]) { + subReporter[functionName].apply(subReporter, arguments); + } + } + }; + })(functionName); + } +})(); +/** + * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults + * + * @constructor + */ +jasmine.NestedResults = function() { + /** + * The total count of results + */ + this.totalCount = 0; + /** + * Number of passed results + */ + this.passedCount = 0; + /** + * Number of failed results + */ + this.failedCount = 0; + /** + * Was this suite/spec skipped? + */ + this.skipped = false; + /** + * @ignore + */ + this.items_ = []; +}; + +/** + * Roll up the result counts. + * + * @param result + */ +jasmine.NestedResults.prototype.rollupCounts = function(result) { + this.totalCount += result.totalCount; + this.passedCount += result.passedCount; + this.failedCount += result.failedCount; +}; + +/** + * Tracks a result's message. + * @param message + */ +jasmine.NestedResults.prototype.log = function(message) { + this.items_.push(new jasmine.MessageResult(message)); +}; + +/** + * Getter for the results: message & results. + */ +jasmine.NestedResults.prototype.getItems = function() { + return this.items_; +}; + +/** + * Adds a result, tracking counts (total, passed, & failed) + * @param {jasmine.ExpectationResult|jasmine.NestedResults} result + */ +jasmine.NestedResults.prototype.addResult = function(result) { + if (result.type != 'MessageResult') { + if (result.items_) { + this.rollupCounts(result); + } else { + this.totalCount++; + if (result.passed) { + this.passedCount++; + } else { + this.failedCount++; + } + } + } + this.items_.push(result); +}; + +/** + * @returns {Boolean} True if everything below passed + */ +jasmine.NestedResults.prototype.__defineGetter__('passed', function() { + return this.passedCount === this.totalCount; +}); +/** + * Base class for pretty printing for expectation results. + */ +jasmine.PrettyPrinter = function() { + this.ppNestLevel_ = 0; +}; + +/** + * Formats a value in a nice, human-readable string. + * + * @param value + * @returns {String} + */ +jasmine.PrettyPrinter.prototype.format = function(value) { + if (this.ppNestLevel_ > 40) { + // return '(jasmine.pp nested too deeply!)'; + throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); + } + + this.ppNestLevel_++; + try { + if (value === undefined) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value.navigator && value.frames && value.setTimeout) { + this.emitScalar(''); + } else if (value instanceof jasmine.Matchers.Any) { + this.emitScalar(value.toString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.__Jasmine_been_here_before__) { + this.emitScalar(''); + } else if (jasmine.isArray_(value) || typeof value == 'object') { + value.__Jasmine_been_here_before__ = true; + if (jasmine.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + delete value.__Jasmine_been_here_before__; + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } +}; + +jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (property == '__Jasmine_been_here_before__') continue; + fn(property, obj.__lookupGetter__(property) != null); + } +}; + +jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; + +jasmine.StringPrettyPrinter = function() { + jasmine.PrettyPrinter.call(this); + + this.string = ''; +}; +jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); + +jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); +}; + +jasmine.StringPrettyPrinter.prototype.emitString = function(value) { + this.append("'" + value + "'"); +}; + +jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { + this.append('[ '); + for (var i = 0; i < array.length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + this.append(' ]'); +}; + +jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { + var self = this; + this.append('{ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(' : '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' }'); +}; + +jasmine.StringPrettyPrinter.prototype.append = function(value) { + this.string += value; +}; +/* 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) + */ +jasmine.Reporters = {}; + +jasmine.Reporters.reporter = function(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 + * + * @constructor + * @param {jasmine.Env} env + */ +jasmine.Runner = function(env) { + jasmine.ActionCollection.call(this, env); + + this.suites = this.actions; +}; +jasmine.util.inherit(jasmine.Runner, jasmine.ActionCollection); + +jasmine.Runner.prototype.execute = function() { + if (this.env.reporter.reportRunnerStarting) { + this.env.reporter.reportRunnerStarting(this); + } + jasmine.ActionCollection.prototype.execute.call(this); +}; + +jasmine.Runner.prototype.finishCallback = function() { + this.env.reporter.reportRunnerResults(this); +}; + +jasmine.Runner.prototype.getResults = function() { + var results = new jasmine.NestedResults(); + for (var i = 0; i < this.suites.length; i++) { + results.rollupCounts(this.suites[i].getResults()); + } + return results; +}; +/** + * Internal representation of a Jasmine specification, or test. + * + * @constructor + * @param {jasmine.Env} env + * @param {jasmine.Suite} suite + * @param {String} description + */ +jasmine.Spec = function(env, suite, description) { + this.id = env.nextSpecId_++; + this.env = env; + this.suite = suite; + this.description = description; + this.queue = []; + this.finished = false; + this.afterCallbacks = []; + this.spies_ = []; + + this.results = new jasmine.NestedResults(); + this.results.description = description; + this.matchersClass = null; +}; + +jasmine.Spec.prototype.getFullName = function() { + return this.suite.getFullName() + ' ' + this.description + '.'; +}; + +jasmine.Spec.prototype.getResults = function() { + return this.results; +}; + +jasmine.Spec.prototype.runs = function (func) { + var block = new jasmine.Block(this.env, func, this); + this.addToQueue(block); + return this; +}; + +jasmine.Spec.prototype.addToQueue = function(block) { + this.setNextOnLastInQueue(block); + this.queue.push(block); +}; + +/** + * @private + * @deprecated + */ +jasmine.Spec.prototype.expects_that = function(actual) { + return this.expect(actual); +}; + +/** +* @private + */ +jasmine.Spec.prototype.expect = function(actual) { + return new (this.getMatchersClass_())(this.env, actual, this.results); +}; + +/** + * @private + */ +jasmine.Spec.prototype.setNextOnLastInQueue = function (block) { + if (this.queue.length > 0) { + var previousBlock = this.queue[this.queue.length - 1]; + previousBlock.next = function() { + block.execute(); + }; + } +}; + +/** + * @private + */ +jasmine.Spec.prototype.waits = function(timeout) { + var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); + this.addToQueue(waitsFunc); + return this; +}; + +/** + * @private + */ +jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) { + var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this); + this.addToQueue(waitsForFunc); + return this; +}; + +jasmine.Spec.prototype.failWithException = function (e) { + this.results.addResult(new jasmine.ExpectationResult(false, jasmine.util.formatException(e), null)); +}; + +jasmine.Spec.prototype.getMatchersClass_ = function() { + return this.matchersClass || jasmine.Matchers; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + for (var method in matchersPrototype) { + newMatchersClass.prototype[method] = matchersPrototype[method]; + } + this.matchersClass = newMatchersClass; +}; + +jasmine.Spec.prototype.finishCallback = function() { + this.env.reporter.reportSpecResults(this); +}; + +jasmine.Spec.prototype.finish = function() { + this.safeExecuteAfters(); + + this.removeAllSpies(); + this.finishCallback(); + this.finished = true; +}; + +jasmine.Spec.prototype.after = function(doAfter) { + this.afterCallbacks.unshift(doAfter); +}; + +jasmine.Spec.prototype.execute = function() { + if (!this.env.specFilter(this)) { + this.results.skipped = true; + this.finishCallback(); + this.finished = true; + return; + } + + this.env.currentSpec = this; + this.env.currentlyRunningTests = true; + + this.safeExecuteBefores(); + + if (this.queue[0]) { + this.queue[0].execute(); + } else { + this.finish(); + } + this.env.currentlyRunningTests = false; +}; + +jasmine.Spec.prototype.safeExecuteBefores = function() { + var befores = []; + for (var suite = this.suite; suite; suite = suite.parentSuite) { + if (suite.beforeQueue) { + for (var i = 0; i < suite.beforeQueue.length; i++) + befores.push(suite.beforeQueue[i]); + } + } + + while (befores.length) { + this.safeExecuteBeforeOrAfter(befores.pop()); + } +}; + +jasmine.Spec.prototype.safeExecuteAfters = function() { + var afters = []; + for (var suite = this.suite; suite; suite = suite.parentSuite) { + if (suite.afterQueue) { + for (var i = 0; i < suite.afterQueue.length; i++) + afters.unshift(suite.afterQueue[i]); + } + } + while (afters.length) { + this.safeExecuteBeforeOrAfter(afters.pop()); + } +}; + +jasmine.Spec.prototype.safeExecuteBeforeOrAfter = function(func) { + try { + func.apply(this); + } catch (e) { + this.results.addResult(new jasmine.ExpectationResult(false, func.typeName + '() fail: ' + jasmine.util.formatException(e), null)); + } +}; + +jasmine.Spec.prototype.explodes = function() { + throw 'explodes function should not have been called'; +}; + +jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { + if (obj == undefined) { + throw "spyOn could not find an object to spy upon for " + methodName + "()"; + } + + if (!ignoreMethodDoesntExist && obj[methodName] === undefined) { + throw methodName + '() method does not exist'; + } + + if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { + throw new Error(methodName + ' has already been spied upon'); + } + + var spyObj = jasmine.createSpy(methodName); + + this.spies_.push(spyObj); + spyObj.baseObj = obj; + spyObj.methodName = methodName; + spyObj.originalValue = obj[methodName]; + + obj[methodName] = spyObj; + + return spyObj; +}; + +jasmine.Spec.prototype.removeAllSpies = function() { + for (var i = 0; i < this.spies_.length; i++) { + var spy = this.spies_[i]; + spy.baseObj[spy.methodName] = spy.originalValue; + } + this.spies_ = []; +}; + +/** + * Internal representation of a Jasmine suite. + * + * @constructor + * @param {jasmine.Env} env + * @param {String} description + * @param {Function} specDefinitions + * @param {jasmine.Suite} parentSuite + */ +jasmine.Suite = function(env, description, specDefinitions, parentSuite) { + jasmine.ActionCollection.call(this, env); + + this.id = env.nextSuiteId_++; + this.description = description; + this.specs = this.actions; + this.parentSuite = parentSuite; + + this.beforeQueue = []; + this.afterQueue = []; +}; +jasmine.util.inherit(jasmine.Suite, jasmine.ActionCollection); + +jasmine.Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + return fullName; +}; + +jasmine.Suite.prototype.finishCallback = function() { + this.env.reporter.reportSuiteResults(this); +}; + +jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.beforeQueue.push(beforeEachFunction); +}; + +jasmine.Suite.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.afterQueue.push(afterEachFunction); +}; + +jasmine.Suite.prototype.getResults = function() { + var results = new jasmine.NestedResults(); + results.description = this.description; + results.id = this.id; + + for (var i = 0; i < this.specs.length; i++) { + results.rollupCounts(this.specs[i].getResults()); + } + return results; +}; + +jasmine.WaitsBlock = function(env, timeout, spec) { + this.timeout = timeout; + jasmine.Block.call(this, env, null, spec); +}; + +jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); + +jasmine.WaitsBlock.prototype.execute = function () { + var self = this; + self.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); + self.env.setTimeout(function () { + self.next(); + }, self.timeout); +}; +jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { + this.timeout = timeout; + 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.prototype.execute = function () { + var self = this; + self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen')); + var latchFunctionResult; + try { + latchFunctionResult = self.latchFunction.apply(self.spec); + } catch (e) { + self.fail(e); + self.next(); + return; + } + + if (latchFunctionResult) { + self.next(); + } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) { + var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen'); + self.fail({ + name: 'timeout', + message: message + }); + self.spec.next(); + } else { + self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; + self.env.setTimeout(function () { self.execute(); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); + } +}; // Mock setTimeout, clearTimeout // Contributed by Pivotal Computer Systems, www.pivotalsf.com @@ -1961,41 +2007,3 @@ window.clearInterval = function(timeoutKey) { return jasmine.Clock.installed.clearInterval.apply(this, arguments); }; -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout; - 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.prototype.execute = function () { - var self = this; - self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen')); - var latchFunctionResult; - try { - latchFunctionResult = self.latchFunction.apply(self.spec); - } catch (e) { - self.fail(e); - self.next(); - return; - } - - if (latchFunctionResult) { - self.next(); - } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) { - var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen'); - self.fail({ - name: 'timeout', - message: message - }); - self.spec.next(); - } else { - self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - self.env.setTimeout(function () { self.execute(); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; diff --git a/spec/suites/SpecRunningTest.js b/spec/suites/SpecRunningTest.js index 68f295ba..d0b7a386 100644 --- a/spec/suites/SpecRunningTest.js +++ b/spec/suites/SpecRunningTest.js @@ -587,7 +587,6 @@ describe("jasmine spec running", function () { }); xit("#beforeEach should be able to eval runs and waits blocks", function () { - var foo = 0; var bar = 0; var suiteWithBefore = env.describe('one suite with a before', function () { @@ -609,17 +608,20 @@ describe("jasmine spec running", function () { }); - //expect(foo).toEqual(0); + expect(foo).toEqual(0); expect(bar).toEqual(0); suiteWithBefore.execute(); + + expect(bar).toEqual(0); - //expect(foo).toEqual(1); + expect(foo).toEqual(1); fakeTimer.tick(500); + expect(bar).toEqual(0); - //expect(foo).toEqual(2); + expect(foo).toEqual(2); fakeTimer.tick(500); expect(bar).toEqual(1); - //expect(foo).toEqual(3); + expect(foo).toEqual(3); }); it("testBeforeExecutesSafely", function() { @@ -773,7 +775,9 @@ describe("jasmine spec running", function () { "inner 2 afterEach", "outer afterEach" ]; - expect(env.equals_(actions, expected)).toEqual(true); // "nested describes order failed:
" + jasmine.pp(actions) + "
wanted
" + jasmine.pp(expected) + "