1 /** 2 * Environment for Jasmine 3 * 4 * @constructor 5 */ 6 jasmine.Env = function() { 7 this.currentSpec = null; 8 this.currentSuite = null; 9 this.currentRunner_ = new jasmine.Runner(this); 10 11 this.reporter = new jasmine.MultiReporter(); 12 13 this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; 14 this.lastUpdate = 0; 15 this.specFilter = function() { 16 return true; 17 }; 18 19 this.nextSpecId_ = 0; 20 this.nextSuiteId_ = 0; 21 this.equalityTesters_ = []; 22 23 // wrap matchers 24 this.matchersClass = function() { 25 jasmine.Matchers.apply(this, arguments); 26 }; 27 jasmine.util.inherit(this.matchersClass, jasmine.Matchers); 28 29 for (var methodName in jasmine.Matchers.prototype) { 30 var orig = jasmine.Matchers.prototype[methodName]; 31 this.matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); 32 } 33 }; 34 35 36 jasmine.Env.prototype.setTimeout = jasmine.setTimeout; 37 jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; 38 jasmine.Env.prototype.setInterval = jasmine.setInterval; 39 jasmine.Env.prototype.clearInterval = jasmine.clearInterval; 40 41 /** 42 * @returns an object containing jasmine version build info, if set. 43 */ 44 jasmine.Env.prototype.version = function () { 45 if (jasmine.version_) { 46 return jasmine.version_; 47 } else { 48 throw new Error('Version not set'); 49 } 50 }; 51 52 /** 53 * @returns a sequential integer starting at 0 54 */ 55 jasmine.Env.prototype.nextSpecId = function () { 56 return this.nextSpecId_++; 57 }; 58 59 /** 60 * @returns a sequential integer starting at 0 61 */ 62 jasmine.Env.prototype.nextSuiteId = function () { 63 return this.nextSuiteId_++; 64 }; 65 66 /** 67 * Register a reporter to receive status updates from Jasmine. 68 * @param {jasmine.Reporter} reporter An object which will receive status updates. 69 */ 70 jasmine.Env.prototype.addReporter = function(reporter) { 71 this.reporter.addReporter(reporter); 72 }; 73 74 jasmine.Env.prototype.execute = function() { 75 this.currentRunner_.execute(); 76 }; 77 78 jasmine.Env.prototype.describe = function(description, specDefinitions) { 79 var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); 80 81 var parentSuite = this.currentSuite; 82 if (parentSuite) { 83 parentSuite.add(suite); 84 } else { 85 this.currentRunner_.add(suite); 86 } 87 88 this.currentSuite = suite; 89 90 specDefinitions.call(suite); 91 92 this.currentSuite = parentSuite; 93 94 return suite; 95 }; 96 97 jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { 98 if (this.currentSuite) { 99 this.currentSuite.beforeEach(beforeEachFunction); 100 } else { 101 this.currentRunner_.beforeEach(beforeEachFunction); 102 } 103 }; 104 105 jasmine.Env.prototype.currentRunner = function () { 106 return this.currentRunner_; 107 }; 108 109 jasmine.Env.prototype.afterEach = function(afterEachFunction) { 110 if (this.currentSuite) { 111 this.currentSuite.afterEach(afterEachFunction); 112 } else { 113 this.currentRunner_.afterEach(afterEachFunction); 114 } 115 116 }; 117 118 jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { 119 return { 120 execute: function() { 121 } 122 }; 123 }; 124 125 jasmine.Env.prototype.it = function(description, func) { 126 var spec = new jasmine.Spec(this, this.currentSuite, description); 127 this.currentSuite.add(spec); 128 this.currentSpec = spec; 129 spec.pending = false; 130 131 if (func) { 132 spec.runs(func); 133 } else { 134 spec.pending = true; 135 } 136 137 return spec; 138 }; 139 140 jasmine.Env.prototype.xit = function(description, func) { 141 var spec = this.it(description, func); 142 spec.pending = -1; 143 return spec; 144 }; 145 146 jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { 147 if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { 148 return true; 149 } 150 151 a.__Jasmine_been_here_before__ = b; 152 b.__Jasmine_been_here_before__ = a; 153 154 var hasKey = function(obj, keyName) { 155 return obj != null && obj[keyName] !== undefined; 156 }; 157 158 for (var property in b) { 159 if (!hasKey(a, property) && hasKey(b, property)) { 160 mismatchKeys.push("expected has key '" + property + "', but missing from actual."); 161 } 162 } 163 for (property in a) { 164 if (!hasKey(b, property) && hasKey(a, property)) { 165 mismatchKeys.push("expected missing key '" + property + "', but present in actual."); 166 } 167 } 168 for (property in b) { 169 if (property == '__Jasmine_been_here_before__') continue; 170 if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { 171 mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); 172 } 173 } 174 175 if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { 176 mismatchValues.push("arrays were not the same length"); 177 } 178 179 delete a.__Jasmine_been_here_before__; 180 delete b.__Jasmine_been_here_before__; 181 return (mismatchKeys.length == 0 && mismatchValues.length == 0); 182 }; 183 184 jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { 185 mismatchKeys = mismatchKeys || []; 186 mismatchValues = mismatchValues || []; 187 188 if (a === b) return true; 189 190 if (a === undefined || a === null || b === undefined || b === null) { 191 return (a == undefined && b == undefined); 192 } 193 194 if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { 195 return a === b; 196 } 197 198 if (a instanceof Date && b instanceof Date) { 199 return a.getTime() == b.getTime(); 200 } 201 202 if (a instanceof jasmine.Matchers.Any) { 203 return a.matches(b); 204 } 205 206 if (b instanceof jasmine.Matchers.Any) { 207 return b.matches(a); 208 } 209 210 if (typeof a === "object" && typeof b === "object") { 211 return this.compareObjects_(a, b, mismatchKeys, mismatchValues); 212 } 213 214 for (var i = 0; i < this.equalityTesters_.length; i++) { 215 var equalityTester = this.equalityTesters_[i]; 216 var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); 217 if (result !== undefined) return result; 218 } 219 220 //Straight check 221 return (a === b); 222 }; 223 224 jasmine.Env.prototype.contains_ = function(haystack, needle) { 225 if (jasmine.isArray_(haystack)) { 226 for (var i = 0; i < haystack.length; i++) { 227 if (this.equals_(haystack[i], needle)) return true; 228 } 229 return false; 230 } 231 return haystack.indexOf(needle) >= 0; 232 }; 233 234 jasmine.Env.prototype.addEqualityTester = function(equalityTester) { 235 this.equalityTesters_.push(equalityTester); 236 }; 237