PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/files/jasmine/1.3.1/jasmine-html.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 681 lines | 540 code | 132 blank | 9 comment | 103 complexity | 49f0dfd1034e504589cd8a54f105d04b MD5 | raw file
  1. jasmine.HtmlReporterHelpers = {};
  2. jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
  3. var el = document.createElement(type);
  4. for (var i = 2; i < arguments.length; i++) {
  5. var child = arguments[i];
  6. if (typeof child === 'string') {
  7. el.appendChild(document.createTextNode(child));
  8. } else {
  9. if (child) {
  10. el.appendChild(child);
  11. }
  12. }
  13. }
  14. for (var attr in attrs) {
  15. if (attr == "className") {
  16. el[attr] = attrs[attr];
  17. } else {
  18. el.setAttribute(attr, attrs[attr]);
  19. }
  20. }
  21. return el;
  22. };
  23. jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
  24. var results = child.results();
  25. var status = results.passed() ? 'passed' : 'failed';
  26. if (results.skipped) {
  27. status = 'skipped';
  28. }
  29. return status;
  30. };
  31. jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
  32. var parentDiv = this.dom.summary;
  33. var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
  34. var parent = child[parentSuite];
  35. if (parent) {
  36. if (typeof this.views.suites[parent.id] == 'undefined') {
  37. this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
  38. }
  39. parentDiv = this.views.suites[parent.id].element;
  40. }
  41. parentDiv.appendChild(childElement);
  42. };
  43. jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
  44. for(var fn in jasmine.HtmlReporterHelpers) {
  45. ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
  46. }
  47. };
  48. jasmine.HtmlReporter = function(_doc) {
  49. var self = this;
  50. var doc = _doc || window.document;
  51. var reporterView;
  52. var dom = {};
  53. // Jasmine Reporter Public Interface
  54. self.logRunningSpecs = false;
  55. self.reportRunnerStarting = function(runner) {
  56. var specs = runner.specs() || [];
  57. if (specs.length == 0) {
  58. return;
  59. }
  60. createReporterDom(runner.env.versionString());
  61. doc.body.appendChild(dom.reporter);
  62. setExceptionHandling();
  63. reporterView = new jasmine.HtmlReporter.ReporterView(dom);
  64. reporterView.addSpecs(specs, self.specFilter);
  65. };
  66. self.reportRunnerResults = function(runner) {
  67. reporterView && reporterView.complete();
  68. };
  69. self.reportSuiteResults = function(suite) {
  70. reporterView.suiteComplete(suite);
  71. };
  72. self.reportSpecStarting = function(spec) {
  73. if (self.logRunningSpecs) {
  74. self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
  75. }
  76. };
  77. self.reportSpecResults = function(spec) {
  78. reporterView.specComplete(spec);
  79. };
  80. self.log = function() {
  81. var console = jasmine.getGlobal().console;
  82. if (console && console.log) {
  83. if (console.log.apply) {
  84. console.log.apply(console, arguments);
  85. } else {
  86. console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
  87. }
  88. }
  89. };
  90. self.specFilter = function(spec) {
  91. if (!focusedSpecName()) {
  92. return true;
  93. }
  94. return spec.getFullName().indexOf(focusedSpecName()) === 0;
  95. };
  96. return self;
  97. function focusedSpecName() {
  98. var specName;
  99. (function memoizeFocusedSpec() {
  100. if (specName) {
  101. return;
  102. }
  103. var paramMap = [];
  104. var params = jasmine.HtmlReporter.parameters(doc);
  105. for (var i = 0; i < params.length; i++) {
  106. var p = params[i].split('=');
  107. paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
  108. }
  109. specName = paramMap.spec;
  110. })();
  111. return specName;
  112. }
  113. function createReporterDom(version) {
  114. dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
  115. dom.banner = self.createDom('div', { className: 'banner' },
  116. self.createDom('span', { className: 'title' }, "Jasmine "),
  117. self.createDom('span', { className: 'version' }, version)),
  118. dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
  119. dom.alert = self.createDom('div', {className: 'alert'},
  120. self.createDom('span', { className: 'exceptions' },
  121. self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
  122. self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
  123. dom.results = self.createDom('div', {className: 'results'},
  124. dom.summary = self.createDom('div', { className: 'summary' }),
  125. dom.details = self.createDom('div', { id: 'details' }))
  126. );
  127. }
  128. function noTryCatch() {
  129. return window.location.search.match(/catch=false/);
  130. }
  131. function searchWithCatch() {
  132. var params = jasmine.HtmlReporter.parameters(window.document);
  133. var removed = false;
  134. var i = 0;
  135. while (!removed && i < params.length) {
  136. if (params[i].match(/catch=/)) {
  137. params.splice(i, 1);
  138. removed = true;
  139. }
  140. i++;
  141. }
  142. if (jasmine.CATCH_EXCEPTIONS) {
  143. params.push("catch=false");
  144. }
  145. return params.join("&");
  146. }
  147. function setExceptionHandling() {
  148. var chxCatch = document.getElementById('no_try_catch');
  149. if (noTryCatch()) {
  150. chxCatch.setAttribute('checked', true);
  151. jasmine.CATCH_EXCEPTIONS = false;
  152. }
  153. chxCatch.onclick = function() {
  154. window.location.search = searchWithCatch();
  155. };
  156. }
  157. };
  158. jasmine.HtmlReporter.parameters = function(doc) {
  159. var paramStr = doc.location.search.substring(1);
  160. var params = [];
  161. if (paramStr.length > 0) {
  162. params = paramStr.split('&');
  163. }
  164. return params;
  165. }
  166. jasmine.HtmlReporter.sectionLink = function(sectionName) {
  167. var link = '?';
  168. var params = [];
  169. if (sectionName) {
  170. params.push('spec=' + encodeURIComponent(sectionName));
  171. }
  172. if (!jasmine.CATCH_EXCEPTIONS) {
  173. params.push("catch=false");
  174. }
  175. if (params.length > 0) {
  176. link += params.join("&");
  177. }
  178. return link;
  179. };
  180. jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
  181. jasmine.HtmlReporter.ReporterView = function(dom) {
  182. this.startedAt = new Date();
  183. this.runningSpecCount = 0;
  184. this.completeSpecCount = 0;
  185. this.passedCount = 0;
  186. this.failedCount = 0;
  187. this.skippedCount = 0;
  188. this.createResultsMenu = function() {
  189. this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
  190. this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
  191. ' | ',
  192. this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
  193. this.summaryMenuItem.onclick = function() {
  194. dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
  195. };
  196. this.detailsMenuItem.onclick = function() {
  197. showDetails();
  198. };
  199. };
  200. this.addSpecs = function(specs, specFilter) {
  201. this.totalSpecCount = specs.length;
  202. this.views = {
  203. specs: {},
  204. suites: {}
  205. };
  206. for (var i = 0; i < specs.length; i++) {
  207. var spec = specs[i];
  208. this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
  209. if (specFilter(spec)) {
  210. this.runningSpecCount++;
  211. }
  212. }
  213. };
  214. this.specComplete = function(spec) {
  215. this.completeSpecCount++;
  216. if (isUndefined(this.views.specs[spec.id])) {
  217. this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
  218. }
  219. var specView = this.views.specs[spec.id];
  220. switch (specView.status()) {
  221. case 'passed':
  222. this.passedCount++;
  223. break;
  224. case 'failed':
  225. this.failedCount++;
  226. break;
  227. case 'skipped':
  228. this.skippedCount++;
  229. break;
  230. }
  231. specView.refresh();
  232. this.refresh();
  233. };
  234. this.suiteComplete = function(suite) {
  235. var suiteView = this.views.suites[suite.id];
  236. if (isUndefined(suiteView)) {
  237. return;
  238. }
  239. suiteView.refresh();
  240. };
  241. this.refresh = function() {
  242. if (isUndefined(this.resultsMenu)) {
  243. this.createResultsMenu();
  244. }
  245. // currently running UI
  246. if (isUndefined(this.runningAlert)) {
  247. this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
  248. dom.alert.appendChild(this.runningAlert);
  249. }
  250. this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
  251. // skipped specs UI
  252. if (isUndefined(this.skippedAlert)) {
  253. this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
  254. }
  255. this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
  256. if (this.skippedCount === 1 && isDefined(dom.alert)) {
  257. dom.alert.appendChild(this.skippedAlert);
  258. }
  259. // passing specs UI
  260. if (isUndefined(this.passedAlert)) {
  261. this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
  262. }
  263. this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
  264. // failing specs UI
  265. if (isUndefined(this.failedAlert)) {
  266. this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
  267. }
  268. this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
  269. if (this.failedCount === 1 && isDefined(dom.alert)) {
  270. dom.alert.appendChild(this.failedAlert);
  271. dom.alert.appendChild(this.resultsMenu);
  272. }
  273. // summary info
  274. this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
  275. this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
  276. };
  277. this.complete = function() {
  278. dom.alert.removeChild(this.runningAlert);
  279. this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
  280. if (this.failedCount === 0) {
  281. dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
  282. } else {
  283. showDetails();
  284. }
  285. dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
  286. };
  287. return this;
  288. function showDetails() {
  289. if (dom.reporter.className.search(/showDetails/) === -1) {
  290. dom.reporter.className += " showDetails";
  291. }
  292. }
  293. function isUndefined(obj) {
  294. return typeof obj === 'undefined';
  295. }
  296. function isDefined(obj) {
  297. return !isUndefined(obj);
  298. }
  299. function specPluralizedFor(count) {
  300. var str = count + " spec";
  301. if (count > 1) {
  302. str += "s"
  303. }
  304. return str;
  305. }
  306. };
  307. jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
  308. jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
  309. this.spec = spec;
  310. this.dom = dom;
  311. this.views = views;
  312. this.symbol = this.createDom('li', { className: 'pending' });
  313. this.dom.symbolSummary.appendChild(this.symbol);
  314. this.summary = this.createDom('div', { className: 'specSummary' },
  315. this.createDom('a', {
  316. className: 'description',
  317. href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
  318. title: this.spec.getFullName()
  319. }, this.spec.description)
  320. );
  321. this.detail = this.createDom('div', { className: 'specDetail' },
  322. this.createDom('a', {
  323. className: 'description',
  324. href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
  325. title: this.spec.getFullName()
  326. }, this.spec.getFullName())
  327. );
  328. };
  329. jasmine.HtmlReporter.SpecView.prototype.status = function() {
  330. return this.getSpecStatus(this.spec);
  331. };
  332. jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
  333. this.symbol.className = this.status();
  334. switch (this.status()) {
  335. case 'skipped':
  336. break;
  337. case 'passed':
  338. this.appendSummaryToSuiteDiv();
  339. break;
  340. case 'failed':
  341. this.appendSummaryToSuiteDiv();
  342. this.appendFailureDetail();
  343. break;
  344. }
  345. };
  346. jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
  347. this.summary.className += ' ' + this.status();
  348. this.appendToSummary(this.spec, this.summary);
  349. };
  350. jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
  351. this.detail.className += ' ' + this.status();
  352. var resultItems = this.spec.results().getItems();
  353. var messagesDiv = this.createDom('div', { className: 'messages' });
  354. for (var i = 0; i < resultItems.length; i++) {
  355. var result = resultItems[i];
  356. if (result.type == 'log') {
  357. messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
  358. } else if (result.type == 'expect' && result.passed && !result.passed()) {
  359. messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
  360. if (result.trace.stack) {
  361. messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
  362. }
  363. }
  364. }
  365. if (messagesDiv.childNodes.length > 0) {
  366. this.detail.appendChild(messagesDiv);
  367. this.dom.details.appendChild(this.detail);
  368. }
  369. };
  370. jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
  371. this.suite = suite;
  372. this.dom = dom;
  373. this.views = views;
  374. this.element = this.createDom('div', { className: 'suite' },
  375. this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
  376. );
  377. this.appendToSummary(this.suite, this.element);
  378. };
  379. jasmine.HtmlReporter.SuiteView.prototype.status = function() {
  380. return this.getSpecStatus(this.suite);
  381. };
  382. jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
  383. this.element.className += " " + this.status();
  384. };
  385. jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
  386. /* @deprecated Use jasmine.HtmlReporter instead
  387. */
  388. jasmine.TrivialReporter = function(doc) {
  389. this.document = doc || document;
  390. this.suiteDivs = {};
  391. this.logRunningSpecs = false;
  392. };
  393. jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
  394. var el = document.createElement(type);
  395. for (var i = 2; i < arguments.length; i++) {
  396. var child = arguments[i];
  397. if (typeof child === 'string') {
  398. el.appendChild(document.createTextNode(child));
  399. } else {
  400. if (child) { el.appendChild(child); }
  401. }
  402. }
  403. for (var attr in attrs) {
  404. if (attr == "className") {
  405. el[attr] = attrs[attr];
  406. } else {
  407. el.setAttribute(attr, attrs[attr]);
  408. }
  409. }
  410. return el;
  411. };
  412. jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
  413. var showPassed, showSkipped;
  414. this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
  415. this.createDom('div', { className: 'banner' },
  416. this.createDom('div', { className: 'logo' },
  417. this.createDom('span', { className: 'title' }, "Jasmine"),
  418. this.createDom('span', { className: 'version' }, runner.env.versionString())),
  419. this.createDom('div', { className: 'options' },
  420. "Show ",
  421. showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
  422. this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
  423. showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
  424. this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
  425. )
  426. ),
  427. this.runnerDiv = this.createDom('div', { className: 'runner running' },
  428. this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
  429. this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
  430. this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
  431. );
  432. this.document.body.appendChild(this.outerDiv);
  433. var suites = runner.suites();
  434. for (var i = 0; i < suites.length; i++) {
  435. var suite = suites[i];
  436. var suiteDiv = this.createDom('div', { className: 'suite' },
  437. this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
  438. this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
  439. this.suiteDivs[suite.id] = suiteDiv;
  440. var parentDiv = this.outerDiv;
  441. if (suite.parentSuite) {
  442. parentDiv = this.suiteDivs[suite.parentSuite.id];
  443. }
  444. parentDiv.appendChild(suiteDiv);
  445. }
  446. this.startedAt = new Date();
  447. var self = this;
  448. showPassed.onclick = function(evt) {
  449. if (showPassed.checked) {
  450. self.outerDiv.className += ' show-passed';
  451. } else {
  452. self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
  453. }
  454. };
  455. showSkipped.onclick = function(evt) {
  456. if (showSkipped.checked) {
  457. self.outerDiv.className += ' show-skipped';
  458. } else {
  459. self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
  460. }
  461. };
  462. };
  463. jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
  464. var results = runner.results();
  465. var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
  466. this.runnerDiv.setAttribute("class", className);
  467. //do it twice for IE
  468. this.runnerDiv.setAttribute("className", className);
  469. var specs = runner.specs();
  470. var specCount = 0;
  471. for (var i = 0; i < specs.length; i++) {
  472. if (this.specFilter(specs[i])) {
  473. specCount++;
  474. }
  475. }
  476. var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
  477. message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
  478. this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
  479. this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
  480. };
  481. jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
  482. var results = suite.results();
  483. var status = results.passed() ? 'passed' : 'failed';
  484. if (results.totalCount === 0) { // todo: change this to check results.skipped
  485. status = 'skipped';
  486. }
  487. this.suiteDivs[suite.id].className += " " + status;
  488. };
  489. jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
  490. if (this.logRunningSpecs) {
  491. this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
  492. }
  493. };
  494. jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
  495. var results = spec.results();
  496. var status = results.passed() ? 'passed' : 'failed';
  497. if (results.skipped) {
  498. status = 'skipped';
  499. }
  500. var specDiv = this.createDom('div', { className: 'spec ' + status },
  501. this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
  502. this.createDom('a', {
  503. className: 'description',
  504. href: '?spec=' + encodeURIComponent(spec.getFullName()),
  505. title: spec.getFullName()
  506. }, spec.description));
  507. var resultItems = results.getItems();
  508. var messagesDiv = this.createDom('div', { className: 'messages' });
  509. for (var i = 0; i < resultItems.length; i++) {
  510. var result = resultItems[i];
  511. if (result.type == 'log') {
  512. messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
  513. } else if (result.type == 'expect' && result.passed && !result.passed()) {
  514. messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
  515. if (result.trace.stack) {
  516. messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
  517. }
  518. }
  519. }
  520. if (messagesDiv.childNodes.length > 0) {
  521. specDiv.appendChild(messagesDiv);
  522. }
  523. this.suiteDivs[spec.suite.id].appendChild(specDiv);
  524. };
  525. jasmine.TrivialReporter.prototype.log = function() {
  526. var console = jasmine.getGlobal().console;
  527. if (console && console.log) {
  528. if (console.log.apply) {
  529. console.log.apply(console, arguments);
  530. } else {
  531. console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
  532. }
  533. }
  534. };
  535. jasmine.TrivialReporter.prototype.getLocation = function() {
  536. return this.document.location;
  537. };
  538. jasmine.TrivialReporter.prototype.specFilter = function(spec) {
  539. var paramMap = {};
  540. var params = this.getLocation().search.substring(1).split('&');
  541. for (var i = 0; i < params.length; i++) {
  542. var p = params[i].split('=');
  543. paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
  544. }
  545. if (!paramMap.spec) {
  546. return true;
  547. }
  548. return spec.getFullName().indexOf(paramMap.spec) === 0;
  549. };