diff --git a/lib/jasmine.js b/lib/jasmine.js index 612d9b6..bf1db30 100644 --- a/lib/jasmine.js +++ b/lib/jasmine.js @@ -1917,7 +1917,8 @@ jasmine.Spec = function(env, suite, description) { }; jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; + var description = (this.description.apply ? this.description.name : this.description); + return this.suite.getFullName() + ' ' + description + '.'; }; @@ -2153,7 +2154,7 @@ jasmine.Suite = function(env, description, specDefinitions, parentSuite) { }; jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; + var fullName = (this.description.apply ? this.description.name : this.description); for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { fullName = parentSuite.description + ' ' + fullName; } @@ -2468,5 +2469,5 @@ jasmine.version_= { "major": 1, "minor": 1, "build": 0, - "revision": 1307335480 + "revision": 1307455246 }; diff --git a/spec/suites/RunnerSpec.js b/spec/suites/RunnerSpec.js index 3f66aaa..d432602 100644 --- a/spec/suites/RunnerSpec.js +++ b/spec/suites/RunnerSpec.js @@ -107,7 +107,6 @@ describe('RunnerTest', function() { }); }); - it('should run child suites and specs and generate results when execute is called', function() { env.describe('one suite description', function () { env.it('should be a test', function() { @@ -264,4 +263,4 @@ describe('RunnerTest', function() { expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite3.getFullName()]); }); }); -}); \ No newline at end of file +}); diff --git a/spec/suites/SpecSpec.js b/spec/suites/SpecSpec.js index e222222..4321a7b 100644 --- a/spec/suites/SpecSpec.js +++ b/spec/suites/SpecSpec.js @@ -46,6 +46,7 @@ describe('Spec', function () { describe('with class name', function () { function MyClass() {} + it('getFullName returns suite & spec description', function () { var spec = new jasmine.Spec(env, suite, MyClass); expect(spec.getFullName()).toEqual('suite 1 MyClass.'); diff --git a/spec/suites/SuiteSpec.js b/spec/suites/SuiteSpec.js index d48ef39..3b33cf3 100644 --- a/spec/suites/SuiteSpec.js +++ b/spec/suites/SuiteSpec.js @@ -67,6 +67,22 @@ describe('Suite', function() { }); }); + describe('getFullName', function() { + describe('with class', function() { + function MyClass() {} + + it('should use the name of the class if provided as the description', function() { + suite = env.describe(MyClass, function() { + env.it('should be something', function() { + }); + }); + + expect(suite.getFullName()).toEqual("MyClass"); + expect(suite.children()[0].getFullName()).toEqual("MyClass should be something."); + }); + }); + }); + describe('SpecCount', function () { it('should keep a count of the number of specs that are run', function() { @@ -117,4 +133,4 @@ describe('Suite', function() { expect(suite.specs().length).toEqual(3); }); }); -}); \ No newline at end of file +}); diff --git a/src/Spec.js b/src/Spec.js new file mode 100644 index 0000000..56dc898 --- /dev/null +++ b/src/Spec.js @@ -0,0 +1,243 @@ +/** + * 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) { + if (!env) { + throw new Error('jasmine.Env() required'); + } + if (!suite) { + throw new Error('jasmine.Suite() required'); + } + var spec = this; + spec.id = env.nextSpecId ? env.nextSpecId() : null; + spec.env = env; + spec.suite = suite; + spec.description = description; + spec.queue = new jasmine.Queue(env); + + spec.afterCallbacks = []; + spec.spies_ = []; + + spec.results_ = new jasmine.NestedResults(); + spec.results_.description = description; + spec.matchersClass = null; +}; + +jasmine.Spec.prototype.getFullName = function() { + var description = (this.description.apply ? this.description.name : this.description); + return this.suite.getFullName() + ' ' + description + '.'; +}; + + +jasmine.Spec.prototype.results = 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 jasmine.log in production code. + */ +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); +}; + +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) { + if (this.queue.isRunning()) { + this.queue.insertNext(block); + } else { + this.queue.add(block); + } +}; + +/** + * @param {jasmine.ExpectationResult} result + */ +jasmine.Spec.prototype.addMatcherResult = function(result) { + this.results_.addResult(result); +}; + +jasmine.Spec.prototype.expect = function(actual) { + var positive = new (this.getMatchersClass_())(this.env, actual, this); + positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); + 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; +}; + +/** + * 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; +}; + +jasmine.Spec.prototype.fail = function (e) { + var expectationResult = new jasmine.ExpectationResult({ + passed: false, + message: e ? jasmine.util.formatException(e) : 'Exception' + }); + this.results_.addResult(expectationResult); +}; + +jasmine.Spec.prototype.getMatchersClass_ = function() { + return this.matchersClass || this.env.matchersClass; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); + this.matchersClass = newMatchersClass; +}; + +jasmine.Spec.prototype.finishCallback = function() { + this.env.reporter.reportSpecResults(this); +}; + +jasmine.Spec.prototype.finish = function(onComplete) { + this.removeAllSpies(); + this.finishCallback(); + if (onComplete) { + onComplete(); + } +}; + +jasmine.Spec.prototype.after = function(doAfter) { + if (this.queue.isRunning()) { + this.queue.add(new jasmine.Block(this.env, doAfter, this)); + } else { + this.afterCallbacks.unshift(doAfter); + } +}; + +jasmine.Spec.prototype.execute = function(onComplete) { + var spec = this; + if (!spec.env.specFilter(spec)) { + spec.results_.skipped = true; + spec.finish(onComplete); + return; + } + + this.env.reporter.reportSpecStarting(this); + + spec.env.currentSpec = spec; + + spec.addBeforesAndAftersToQueue(); + + spec.queue.start(function () { + spec.finish(onComplete); + }); +}; + +jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { + var runner = this.env.currentRunner(); + var i; + + for (var suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); + } + } + for (i = 0; i < runner.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); + } + for (i = 0; i < this.afterCallbacks.length; i++) { + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); + } + for (suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); + } + } + for (i = 0; i < runner.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + } +}; + +jasmine.Spec.prototype.explodes = function() { + throw 'explodes function should not have been called'; +}; + +jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { + if (obj == jasmine.undefined) { + throw "spyOn could not find an object to spy upon for " + methodName + "()"; + } + + if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.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_ = []; +}; + diff --git a/src/core/Suite.js b/src/core/Suite.js index 0b57352..a83593a 100644 --- a/src/core/Suite.js +++ b/src/core/Suite.js @@ -22,7 +22,7 @@ jasmine.Suite = function(env, description, specDefinitions, parentSuite) { }; jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; + var fullName = (this.description.apply ? this.description.name : this.description); for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { fullName = parentSuite.description + ' ' + fullName; } @@ -79,4 +79,4 @@ jasmine.Suite.prototype.execute = function(onComplete) { this.queue.start(function () { self.finish(onComplete); }); -}; \ No newline at end of file +};