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 119 if (func) { 120 spec.runs(func); 121 } 122 123 return spec; 124 }; 125 126 jasmine.Env.prototype.xit = function(desc, func) { 127 return { 128 id: this.nextSpecId(), 129 runs: function() { 130 } 131 }; 132 }; 133 134 jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { 135 if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { 136 return true; 137 } 138 139 a.__Jasmine_been_here_before__ = b; 140 b.__Jasmine_been_here_before__ = a; 141 142 var hasKey = function(obj, keyName) { 143 return obj != null && obj[keyName] !== undefined; 144 }; 145 146 for (var property in b) { 147 if (!hasKey(a, property) && hasKey(b, property)) { 148 mismatchKeys.push("expected has key '" + property + "', but missing from actual."); 149 } 150 } 151 for (property in a) { 152 if (!hasKey(b, property) && hasKey(a, property)) { 153 mismatchKeys.push("expected missing key '" + property + "', but present in actual."); 154 } 155 } 156 for (property in b) { 157 if (property == '__Jasmine_been_here_before__') continue; 158 if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { 159 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."); 160 } 161 } 162 163 if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { 164 mismatchValues.push("arrays were not the same length"); 165 } 166 167 delete a.__Jasmine_been_here_before__; 168 delete b.__Jasmine_been_here_before__; 169 return (mismatchKeys.length == 0 && mismatchValues.length == 0); 170 }; 171 172 jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { 173 mismatchKeys = mismatchKeys || []; 174 mismatchValues = mismatchValues || []; 175 176 if (a === b) return true; 177 178 if (a === undefined || a === null || b === undefined || b === null) { 179 return (a == undefined && b == undefined); 180 } 181 182 if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { 183 return a === b; 184 } 185 186 if (a instanceof Date && b instanceof Date) { 187 return a.getTime() == b.getTime(); 188 } 189 190 if (a instanceof jasmine.Matchers.Any) { 191 return a.matches(b); 192 } 193 194 if (b instanceof jasmine.Matchers.Any) { 195 return b.matches(a); 196 } 197 198 if (typeof a === "object" && typeof b === "object") { 199 return this.compareObjects_(a, b, mismatchKeys, mismatchValues); 200 } 201 202 for (var i = 0; i < this.equalityTesters_.length; i++) { 203 var equalityTester = this.equalityTesters_[i]; 204 var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); 205 if (result !== undefined) return result; 206 } 207 208 //Straight check 209 return (a === b); 210 }; 211 212 jasmine.Env.prototype.contains_ = function(haystack, needle) { 213 if (jasmine.isArray_(haystack)) { 214 for (var i = 0; i < haystack.length; i++) { 215 if (this.equals_(haystack[i], needle)) return true; 216 } 217 return false; 218 } 219 return haystack.indexOf(needle) >= 0; 220 }; 221 222 jasmine.Env.prototype.addEqualityTester = function(equalityTester) { 223 this.equalityTesters_.push(equalityTester); 224 }; 225