github.com/kvattikuti/drone@v0.2.1-0.20140603034306-d400229a327a/cmd/droned/assets/test/lib/jasmine-2.0.0/jasmine-html.js (about) 1 /* 2 Copyright (c) 2008-2013 Pivotal Labs 3 4 Permission is hereby granted, free of charge, to any person obtaining 5 a copy of this software and associated documentation files (the 6 "Software"), to deal in the Software without restriction, including 7 without limitation the rights to use, copy, modify, merge, publish, 8 distribute, sublicense, and/or sell copies of the Software, and to 9 permit persons to whom the Software is furnished to do so, subject to 10 the following conditions: 11 12 The above copyright notice and this permission notice shall be 13 included in all copies or substantial portions of the Software. 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 jasmineRequire.html = function(j$) { 24 j$.ResultsNode = jasmineRequire.ResultsNode(); 25 j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); 26 j$.QueryString = jasmineRequire.QueryString(); 27 j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); 28 }; 29 30 jasmineRequire.HtmlReporter = function(j$) { 31 32 var noopTimer = { 33 start: function() {}, 34 elapsed: function() { return 0; } 35 }; 36 37 function HtmlReporter(options) { 38 var env = options.env || {}, 39 getContainer = options.getContainer, 40 createElement = options.createElement, 41 createTextNode = options.createTextNode, 42 onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, 43 timer = options.timer || noopTimer, 44 results = [], 45 specsExecuted = 0, 46 failureCount = 0, 47 pendingSpecCount = 0, 48 htmlReporterMain, 49 symbols; 50 51 this.initialize = function() { 52 htmlReporterMain = createDom("div", {className: "html-reporter"}, 53 createDom("div", {className: "banner"}, 54 createDom("span", {className: "title"}, "Jasmine"), 55 createDom("span", {className: "version"}, j$.version) 56 ), 57 createDom("ul", {className: "symbol-summary"}), 58 createDom("div", {className: "alert"}), 59 createDom("div", {className: "results"}, 60 createDom("div", {className: "failures"}) 61 ) 62 ); 63 getContainer().appendChild(htmlReporterMain); 64 65 symbols = find(".symbol-summary"); 66 }; 67 68 var totalSpecsDefined; 69 this.jasmineStarted = function(options) { 70 totalSpecsDefined = options.totalSpecsDefined || 0; 71 timer.start(); 72 }; 73 74 var summary = createDom("div", {className: "summary"}); 75 76 var topResults = new j$.ResultsNode({}, "", null), 77 currentParent = topResults; 78 79 this.suiteStarted = function(result) { 80 currentParent.addChild(result, "suite"); 81 currentParent = currentParent.last(); 82 }; 83 84 this.suiteDone = function(result) { 85 if (currentParent == topResults) { 86 return; 87 } 88 89 currentParent = currentParent.parent; 90 }; 91 92 this.specStarted = function(result) { 93 currentParent.addChild(result, "spec"); 94 }; 95 96 var failures = []; 97 this.specDone = function(result) { 98 if (result.status != "disabled") { 99 specsExecuted++; 100 } 101 102 symbols.appendChild(createDom("li", { 103 className: result.status, 104 id: "spec_" + result.id, 105 title: result.fullName 106 } 107 )); 108 109 if (result.status == "failed") { 110 failureCount++; 111 112 var failure = 113 createDom("div", {className: "spec-detail failed"}, 114 createDom("div", {className: "description"}, 115 createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName) 116 ), 117 createDom("div", {className: "messages"}) 118 ); 119 var messages = failure.childNodes[1]; 120 121 for (var i = 0; i < result.failedExpectations.length; i++) { 122 var expectation = result.failedExpectations[i]; 123 messages.appendChild(createDom("div", {className: "result-message"}, expectation.message)); 124 messages.appendChild(createDom("div", {className: "stack-trace"}, expectation.stack)); 125 } 126 127 failures.push(failure); 128 } 129 130 if (result.status == "pending") { 131 pendingSpecCount++; 132 } 133 }; 134 135 this.jasmineDone = function() { 136 var banner = find(".banner"); 137 banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s")); 138 139 var alert = find(".alert"); 140 141 alert.appendChild(createDom("span", { className: "exceptions" }, 142 createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"), 143 createDom("input", { 144 className: "raise", 145 id: "raise-exceptions", 146 type: "checkbox" 147 }) 148 )); 149 var checkbox = find("input"); 150 151 checkbox.checked = !env.catchingExceptions(); 152 checkbox.onclick = onRaiseExceptionsClick; 153 154 if (specsExecuted < totalSpecsDefined) { 155 var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all"; 156 alert.appendChild( 157 createDom("span", {className: "bar skipped"}, 158 createDom("a", {href: "?", title: "Run all specs"}, skippedMessage) 159 ) 160 ); 161 } 162 var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount); 163 if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); } 164 165 var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed"); 166 alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage)); 167 168 var results = find(".results"); 169 results.appendChild(summary); 170 171 summaryList(topResults, summary); 172 173 function summaryList(resultsTree, domParent) { 174 var specListNode; 175 for (var i = 0; i < resultsTree.children.length; i++) { 176 var resultNode = resultsTree.children[i]; 177 if (resultNode.type == "suite") { 178 var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id}, 179 createDom("li", {className: "suite-detail"}, 180 createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description) 181 ) 182 ); 183 184 summaryList(resultNode, suiteListNode); 185 domParent.appendChild(suiteListNode); 186 } 187 if (resultNode.type == "spec") { 188 if (domParent.getAttribute("class") != "specs") { 189 specListNode = createDom("ul", {className: "specs"}); 190 domParent.appendChild(specListNode); 191 } 192 specListNode.appendChild( 193 createDom("li", { 194 className: resultNode.result.status, 195 id: "spec-" + resultNode.result.id 196 }, 197 createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description) 198 ) 199 ); 200 } 201 } 202 } 203 204 if (failures.length) { 205 alert.appendChild( 206 createDom('span', {className: "menu bar spec-list"}, 207 createDom("span", {}, "Spec List | "), 208 createDom('a', {className: "failures-menu", href: "#"}, "Failures"))); 209 alert.appendChild( 210 createDom('span', {className: "menu bar failure-list"}, 211 createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"), 212 createDom("span", {}, " | Failures "))); 213 214 find(".failures-menu").onclick = function() { 215 setMenuModeTo('failure-list'); 216 }; 217 find(".spec-list-menu").onclick = function() { 218 setMenuModeTo('spec-list'); 219 }; 220 221 setMenuModeTo('failure-list'); 222 223 var failureNode = find(".failures"); 224 for (var i = 0; i < failures.length; i++) { 225 failureNode.appendChild(failures[i]); 226 } 227 } 228 }; 229 230 return this; 231 232 function find(selector) { 233 return getContainer().querySelector(selector); 234 } 235 236 function createDom(type, attrs, childrenVarArgs) { 237 var el = createElement(type); 238 239 for (var i = 2; i < arguments.length; i++) { 240 var child = arguments[i]; 241 242 if (typeof child === 'string') { 243 el.appendChild(createTextNode(child)); 244 } else { 245 if (child) { 246 el.appendChild(child); 247 } 248 } 249 } 250 251 for (var attr in attrs) { 252 if (attr == "className") { 253 el[attr] = attrs[attr]; 254 } else { 255 el.setAttribute(attr, attrs[attr]); 256 } 257 } 258 259 return el; 260 } 261 262 function pluralize(singular, count) { 263 var word = (count == 1 ? singular : singular + "s"); 264 265 return "" + count + " " + word; 266 } 267 268 function specHref(result) { 269 return "?spec=" + encodeURIComponent(result.fullName); 270 } 271 272 function setMenuModeTo(mode) { 273 htmlReporterMain.setAttribute("class", "html-reporter " + mode); 274 } 275 } 276 277 return HtmlReporter; 278 }; 279 280 jasmineRequire.HtmlSpecFilter = function() { 281 function HtmlSpecFilter(options) { 282 var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 283 var filterPattern = new RegExp(filterString); 284 285 this.matches = function(specName) { 286 return filterPattern.test(specName); 287 }; 288 } 289 290 return HtmlSpecFilter; 291 }; 292 293 jasmineRequire.ResultsNode = function() { 294 function ResultsNode(result, type, parent) { 295 this.result = result; 296 this.type = type; 297 this.parent = parent; 298 299 this.children = []; 300 301 this.addChild = function(result, type) { 302 this.children.push(new ResultsNode(result, type, this)); 303 }; 304 305 this.last = function() { 306 return this.children[this.children.length - 1]; 307 }; 308 } 309 310 return ResultsNode; 311 }; 312 313 jasmineRequire.QueryString = function() { 314 function QueryString(options) { 315 316 this.setParam = function(key, value) { 317 var paramMap = queryStringToParamMap(); 318 paramMap[key] = value; 319 options.getWindowLocation().search = toQueryString(paramMap); 320 }; 321 322 this.getParam = function(key) { 323 return queryStringToParamMap()[key]; 324 }; 325 326 return this; 327 328 function toQueryString(paramMap) { 329 var qStrPairs = []; 330 for (var prop in paramMap) { 331 qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop])); 332 } 333 return "?" + qStrPairs.join('&'); 334 } 335 336 function queryStringToParamMap() { 337 var paramStr = options.getWindowLocation().search.substring(1), 338 params = [], 339 paramMap = {}; 340 341 if (paramStr.length > 0) { 342 params = paramStr.split('&'); 343 for (var i = 0; i < params.length; i++) { 344 var p = params[i].split('='); 345 var value = decodeURIComponent(p[1]); 346 if (value === "true" || value === "false") { 347 value = JSON.parse(value); 348 } 349 paramMap[decodeURIComponent(p[0])] = value; 350 } 351 } 352 353 return paramMap; 354 } 355 356 } 357 358 return QueryString; 359 };