1 /** 2 * Internal representation of a Jasmine specification, or test. 3 * 4 * @constructor 5 * @param {jasmine.Env} env 6 * @param {jasmine.Suite} suite 7 * @param {String} description 8 */ 9 jasmine.Spec = function(env, suite, description) { 10 if (!env) { 11 throw new Error('jasmine.Env() required'); 12 } 13 ; 14 if (!suite) { 15 throw new Error('jasmine.Suite() required'); 16 } 17 ; 18 var spec = this; 19 spec.id = env.nextSpecId ? env.nextSpecId() : null; 20 spec.env = env; 21 spec.suite = suite; 22 spec.description = description; 23 spec.queue = new jasmine.Queue(env); 24 25 spec.afterCallbacks = []; 26 spec.spies_ = []; 27 28 spec.results_ = new jasmine.NestedResults(); 29 spec.results_.description = description; 30 spec.matchersClass = null; 31 }; 32 33 jasmine.Spec.prototype.getFullName = function() { 34 return this.suite.getFullName() + ' ' + this.description + '.'; 35 }; 36 37 38 jasmine.Spec.prototype.results = function() { 39 return this.results_; 40 }; 41 42 jasmine.Spec.prototype.log = function(message) { 43 return this.results_.log(message); 44 }; 45 46 /** @deprecated */ 47 jasmine.Spec.prototype.getResults = function() { 48 return this.results_; 49 }; 50 51 jasmine.Spec.prototype.runs = function (func) { 52 var block = new jasmine.Block(this.env, func, this); 53 this.addToQueue(block); 54 return this; 55 }; 56 57 jasmine.Spec.prototype.addToQueue = function (block) { 58 if (this.queue.isRunning()) { 59 this.queue.insertNext(block); 60 } else { 61 this.queue.add(block); 62 } 63 }; 64 65 jasmine.Spec.prototype.stop = function(){ 66 this.queue._stop(); 67 } 68 69 jasmine.Spec.prototype.start = function(){ 70 this.queue._start(); 71 } 72 73 jasmine.Spec.prototype.anticipate = function(number){ 74 this._anticipate = number; 75 } 76 77 jasmine.Spec.prototype.addMatcherResult = function(result) { 78 this.results_.addResult(result); 79 }; 80 81 jasmine.Spec.prototype.expect = function(actual) { 82 return new (this.getMatchersClass_())(this.env, actual, this); 83 }; 84 85 jasmine.Spec.prototype.waits = function(timeout) { 86 var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); 87 this.addToQueue(waitsFunc); 88 return this; 89 }; 90 91 jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) { 92 var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this); 93 this.addToQueue(waitsForFunc); 94 return this; 95 }; 96 97 jasmine.Spec.prototype.fail = function (e) { 98 var expectationResult = new jasmine.ExpectationResult({ 99 passed: false, 100 message: e ? jasmine.util.formatException(e) : 'Exception', 101 exception: e 102 }); 103 this.results_.addResult(expectationResult); 104 }; 105 106 jasmine.Spec.prototype.getMatchersClass_ = function() { 107 return this.matchersClass || jasmine.Matchers; 108 }; 109 110 jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { 111 var parent = this.getMatchersClass_(); 112 var newMatchersClass = function() { 113 parent.apply(this, arguments); 114 }; 115 jasmine.util.inherit(newMatchersClass, parent); 116 for (var method in matchersPrototype) { 117 newMatchersClass.prototype[method] = matchersPrototype[method]; 118 } 119 this.matchersClass = newMatchersClass; 120 }; 121 122 jasmine.Spec.prototype.finishCallback = function() { 123 this.env.reporter.reportSpecResults(this); 124 }; 125 126 jasmine.Spec.prototype.finish = function(onComplete) { 127 this.removeAllSpies(); 128 this.finishCallback(); 129 if (onComplete) { 130 onComplete(); 131 } 132 }; 133 134 jasmine.Spec.prototype.after = function(doAfter, test) { 135 136 if (this.queue.isRunning()) { 137 this.queue.add(new jasmine.Block(this.env, doAfter, this)); 138 } else { 139 this.afterCallbacks.unshift(doAfter); 140 } 141 }; 142 143 jasmine.Spec.prototype.execute = function(onComplete) { 144 var spec = this; 145 if (!spec.env.specFilter(spec)) { 146 spec.results_.skipped = true; 147 spec.finish(onComplete); 148 return; 149 } 150 this.env.reporter.log('>> Jasmine Running ' + this.suite.description + ' ' + this.description + '...'); 151 152 spec.env.currentSpec = spec; 153 154 spec.addBeforesAndAftersToQueue(); 155 156 spec.queue.start(function () { 157 spec.finish(onComplete); 158 }); 159 }; 160 161 jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { 162 var runner = this.env.currentRunner(); 163 for (var suite = this.suite; suite; suite = suite.parentSuite) { 164 for (var i = 0; i < suite.before_.length; i++) { 165 this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); 166 } 167 } 168 for (var i = 0; i < runner.before_.length; i++) { 169 this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); 170 } 171 for (i = 0; i < this.afterCallbacks.length; i++) { 172 this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); 173 } 174 for (suite = this.suite; suite; suite = suite.parentSuite) { 175 for (var i = 0; i < suite.after_.length; i++) { 176 this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); 177 } 178 } 179 for (var i = 0; i < runner.after_.length; i++) { 180 this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); 181 } 182 }; 183 184 jasmine.Spec.prototype.explodes = function() { 185 throw 'explodes function should not have been called'; 186 }; 187 188 jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { 189 if (obj == undefined) { 190 throw "spyOn could not find an object to spy upon for " + methodName + "()"; 191 } 192 193 if (!ignoreMethodDoesntExist && obj[methodName] === undefined) { 194 throw methodName + '() method does not exist'; 195 } 196 197 if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { 198 throw new Error(methodName + ' has already been spied upon'); 199 } 200 201 var spyObj = jasmine.createSpy(methodName); 202 203 this.spies_.push(spyObj); 204 spyObj.baseObj = obj; 205 spyObj.methodName = methodName; 206 spyObj.originalValue = obj[methodName]; 207 208 obj[methodName] = spyObj; 209 210 return spyObj; 211 }; 212 213 jasmine.Spec.prototype.removeAllSpies = function() { 214 for (var i = 0; i < this.spies_.length; i++) { 215 var spy = this.spies_[i]; 216 spy.baseObj[spy.methodName] = spy.originalValue; 217 } 218 this.spies_ = []; 219 }; 220 221