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