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