This example illustrates operator overloading using a Complex
number class.
For further description of operator overloading in STEMCstudio, please see the STEMCstudio Wiki.
import { Complex } from './Complex' | |
export function complexSpec() { | |
describe("constructor", function() { | |
const x = Math.random() | |
const y = Math.random() | |
const z = new Complex(x, y) | |
it("should preserve real argument", function() { | |
expect(z.real).toBe(x) | |
}) | |
it("should preserve imag argument", function() { | |
expect(z.imag).toBe(y) | |
}) | |
}) | |
describe("Complex + Complex", function() { | |
const z1 = new Complex(2, 3) | |
const z2 = new Complex(5, 7) | |
const z = z1 + z2 | |
it("should sum real argument", function() { | |
expect(z.real).toBe(z1.real + z2.real) | |
}) | |
it("should sum imag argument", function() { | |
expect(z.imag).toBe(z1.imag + z2.imag) | |
}) | |
}) | |
describe("Complex + number", function() { | |
const z1 = new Complex(2, 3) | |
const z2 = 5 | |
const z = z1 + z2 | |
it("should sum real argument", function() { | |
expect(z.real).toBe(z1.real + z2) | |
}) | |
it("should sum imag argument", function() { | |
expect(z.imag).toBe(z1.imag) | |
}) | |
}) | |
describe("number + Complex", function() { | |
const z1 = 2 | |
const z2 = new Complex(5, 7) | |
const z = z1 + z2 | |
it("should sum real argument", function() { | |
expect(z.real).toBe(z1 + z2.real) | |
}) | |
it("should sum imag argument", function() { | |
expect(z.imag).toBe(z2.imag) | |
}) | |
}) | |
describe("Complex * Complex", function() { | |
const z1 = new Complex(2, 3) | |
const z2 = new Complex(5, 7) | |
const z = z1 * z2 | |
it("should sum real argument", function() { | |
expect(z.real).toBe(z1.real * z2.real - z1.imag * z2.imag) | |
}) | |
it("should sum imag argument", function() { | |
expect(z.imag).toBe(z1.real * z2.imag + z1.imag * z2.real) | |
}) | |
}) | |
describe("Complex * number", function() { | |
const z1 = new Complex(2, 3) | |
const z2 = 5 | |
const z = z1 * z2 | |
it("should sum real argument", function() { | |
expect(z.real).toBe(z1.real * z2) | |
}) | |
it("should sum imag argument", function() { | |
expect(z.imag).toBe(z1.imag * z2) | |
}) | |
}) | |
describe("number * Complex", function() { | |
const z1 = 2 | |
const z2 = new Complex(5, 7) | |
const z = z1 * z2 | |
it("should sum real argument", function() { | |
expect(z.real).toBe(z1 * z2.real) | |
}) | |
it("should sum imag argument", function() { | |
expect(z.imag).toBe(z1 * z2.imag) | |
}) | |
}) | |
describe("-Complex", function() { | |
const z1 = new Complex(2, 3) | |
const z = -z1 | |
it("should negate real argument", function() { | |
expect(z.real).toBe(z1.real * -1) | |
}) | |
it("should negate imag argument", function() { | |
expect(z.imag).toBe(z1.imag * -1) | |
}) | |
}) | |
} |
export class Complex { | |
constructor(public readonly real: number, public readonly imag: number) { | |
} | |
__add__(rhs: Complex | number): Complex | undefined { | |
if (typeof rhs === 'number') { | |
return new Complex(this.real + rhs, this.imag) | |
} | |
else if (rhs instanceof Complex) { | |
return new Complex(this.real + rhs.real, this.imag + rhs.imag) | |
} | |
else { | |
return void 0 | |
} | |
} | |
__radd__(lhs: number): Complex | undefined { | |
if (typeof lhs === 'number') { | |
return new Complex(lhs + this.real, this.imag) | |
} | |
else { | |
return void 0 | |
} | |
} | |
__mul__(rhs: Complex | number): Complex | undefined { | |
if (typeof rhs === 'number') { | |
return new Complex(this.real * rhs, this.imag * rhs) | |
} | |
else if (rhs instanceof Complex) { | |
const x = this.real * rhs.real - this.imag * rhs.imag | |
const y = this.real * rhs.imag + this.imag * rhs.real | |
return new Complex(x, y) | |
} | |
else { | |
return void 0 | |
} | |
} | |
__rmul__(lhs: number): Complex | undefined { | |
if (typeof lhs === 'number') { | |
return new Complex(lhs * this.real, lhs * this.imag) | |
} | |
else { | |
return void 0 | |
} | |
} | |
__neg__(): Complex { | |
return new Complex(-this.real, -this.imag) | |
} | |
toString(): string { | |
return `${this.real} + ${this.imag} * i` | |
} | |
} | |
export function complex(x: number, y: number): Complex { | |
return new Complex(x, y) | |
} |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine-html.min.js"></script> | |
<script src="/vendor/[email protected]/davinci-mathscript.min.js"></script> | |
<script src="/assets/js/[email protected]/system.js"></script> | |
</head> | |
<body> | |
<script> | |
System.config({ | |
"warnings": true, | |
"map": { | |
"jasmine": "https://cdn.jsdelivr.net/npm/[email protected]/lib/jasmine.js" | |
} | |
}); | |
</script> | |
Nothing to see here, take a look at the tests | |
<script> | |
System.register('./Complex.spec.js', ['./Complex'], function(exports_1, context_1) { | |
'use strict'; | |
var Complex_1; | |
var __moduleName = context_1 && context_1.id; | |
function complexSpec() { | |
describe('constructor', function() { | |
var x = Math.random(); | |
var y = Math.random(); | |
var z = new Complex_1.Complex(x, y); | |
it('should preserve real argument', function() { | |
expect(z.real).toBe(x); | |
}); | |
it('should preserve imag argument', function() { | |
expect(z.imag).toBe(y); | |
}); | |
}); | |
describe('Complex + Complex', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.add(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.add(z1.real, z2.real)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.add(z1.imag, z2.imag)); | |
}); | |
}); | |
describe('Complex + number', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = 5; | |
var z = Ms.add(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.add(z1.real, z2)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(z1.imag); | |
}); | |
}); | |
describe('number + Complex', function() { | |
var z1 = 2; | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.add(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.add(z1, z2.real)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(z2.imag); | |
}); | |
}); | |
describe('Complex * Complex', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.mul(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.sub(Ms.mul(z1.real, z2.real), Ms.mul(z1.imag, z2.imag))); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.add(Ms.mul(z1.real, z2.imag), Ms.mul(z1.imag, z2.real))); | |
}); | |
}); | |
describe('Complex * number', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = 5; | |
var z = Ms.mul(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.mul(z1.real, z2)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.mul(z1.imag, z2)); | |
}); | |
}); | |
describe('number * Complex', function() { | |
var z1 = 2; | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.mul(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.mul(z1, z2.real)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.mul(z1, z2.imag)); | |
}); | |
}); | |
describe('-Complex', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z = Ms.neg(z1); | |
it('should negate real argument', function() { | |
expect(z.real).toBe(Ms.mul(z1.real, Ms.neg(1))); | |
}); | |
it('should negate imag argument', function() { | |
expect(z.imag).toBe(Ms.mul(z1.imag, Ms.neg(1))); | |
}); | |
}); | |
} | |
exports_1('complexSpec', complexSpec); | |
return { | |
setters: [function(Complex_1_1) { | |
Complex_1 = Complex_1_1; | |
}], | |
execute: function() {} | |
}; | |
}); | |
System.register('./Complex.js', [], function(exports_1, context_1) { | |
'use strict'; | |
var Complex; | |
var __moduleName = context_1 && context_1.id; | |
function complex(x, y) { | |
return new Complex(x, y); | |
} | |
exports_1('complex', complex); | |
return { | |
setters: [], | |
execute: function() { | |
Complex = function() { | |
function Complex(real, imag) { | |
this.real = real; | |
this.imag = imag; | |
} | |
Complex.prototype.__add__ = function(rhs) { | |
if (Ms.eq(typeof rhs, 'number')) { | |
return new Complex(Ms.add(this.real, rhs), this.imag); | |
} else if (rhs instanceof Complex) { | |
return new Complex(Ms.add(this.real, rhs.real), Ms.add(this.imag, rhs.imag)); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__radd__ = function(lhs) { | |
if (Ms.eq(typeof lhs, 'number')) { | |
return new Complex(Ms.add(lhs, this.real), this.imag); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__mul__ = function(rhs) { | |
if (Ms.eq(typeof rhs, 'number')) { | |
return new Complex(Ms.mul(this.real, rhs), Ms.mul(this.imag, rhs)); | |
} else if (rhs instanceof Complex) { | |
var x = Ms.sub(Ms.mul(this.real, rhs.real), Ms.mul(this.imag, rhs.imag)); | |
var y = Ms.add(Ms.mul(this.real, rhs.imag), Ms.mul(this.imag, rhs.real)); | |
return new Complex(x, y); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__rmul__ = function(lhs) { | |
if (Ms.eq(typeof lhs, 'number')) { | |
return new Complex(Ms.mul(lhs, this.real), Ms.mul(lhs, this.imag)); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__neg__ = function() { | |
return new Complex(Ms.neg(this.real), Ms.neg(this.imag)); | |
}; | |
Complex.prototype.toString = function() { | |
return ''.concat(this.real, ' + ').concat(this.imag, ' * i'); | |
}; | |
return Complex; | |
}(); | |
exports_1('Complex', Complex); | |
} | |
}; | |
}); | |
System.register('./HtmlReporter.js', [], function(exports_1, context_1) { | |
'use strict'; | |
var ResultsNode, ResultsStateBuilder, HtmlReporter; | |
var __moduleName = context_1 && context_1.id; | |
function failureDom(result, reporter) { | |
var failure = createDom(reporter, 'div', { | |
className: 'jasmine-spec-detail jasmine-failed' | |
}, failureDescription(result, reporter.stateBuilder.currentParent, reporter), createDom(reporter, 'div', { | |
className: 'jasmine-messages' | |
})); | |
var messages = failure.childNodes[1]; | |
var _M9Use = Date.now(); | |
for (var _i = 0, _a = result.failedExpectations; Ms.lt(_i, _a.length); _i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _M9Use), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var expectation = _a[_i]; | |
messages.appendChild(createDom(reporter, 'div', { | |
className: 'jasmine-result-message' | |
}, expectation.message)); | |
messages.appendChild(createDom(reporter, 'div', { | |
className: 'jasmine-stack-trace' | |
}, expectation.stack)); | |
} | |
} | |
if (Ms.eq(result.failedExpectations.length, 0)) { | |
messages.appendChild(createDom(reporter, 'div', { | |
className: 'jasmine-result-message' | |
}, 'Spec has no expectations')); | |
} | |
return failure; | |
} | |
function summaryList(resultsTree, domParent, reporter) { | |
var specListNode; | |
var _JVyFL = Date.now(); | |
for (var i = 0; Ms.lt(i, resultsTree.children.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _JVyFL), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var resultNode = resultsTree.children[i]; | |
if (reporter.filterSpecs && Ms.bang(hasActiveSpec(resultNode))) { | |
continue; | |
} | |
if (Ms.eq(resultNode.type, 'suite')) { | |
var result = resultNode.result; | |
var suiteListNode = createDom(reporter, 'ul', { | |
className: 'jasmine-suite', | |
id: Ms.add('suite-', result.id) | |
}, createDom(reporter, 'li', { | |
className: Ms.add('jasmine-suite-detail jasmine-', result.status) | |
}, reporter.createAnchor({ | |
href: specHref(result, reporter) | |
}, result.description))); | |
summaryList(resultNode, suiteListNode, reporter); | |
domParent.appendChild(suiteListNode); | |
} | |
if (Ms.eq(resultNode.type, 'spec')) { | |
var result = resultNode.result; | |
if (Ms.ne(domParent.getAttribute('class'), 'jasmine-specs')) { | |
specListNode = createDom(reporter, 'ul', { | |
className: 'jasmine-specs' | |
}); | |
domParent.appendChild(specListNode); | |
} | |
var specDescription = result.description; | |
if (noExpectations(result)) { | |
specDescription = Ms.add('SPEC HAS NO EXPECTATIONS ', specDescription); | |
} | |
if (Ms.eq(result.status, 'pending') && Ms.ne(result.pendingReason, '')) { | |
specDescription = Ms.add(Ms.add(specDescription, ' PENDING WITH MESSAGE: '), result.pendingReason); | |
} | |
specListNode.appendChild(createDom(reporter, 'li', { | |
className: Ms.add('jasmine-', result.status), | |
id: Ms.add('spec-', result.id) | |
}, reporter.createAnchor({ | |
href: specHref(result, reporter) | |
}, specDescription))); | |
} | |
} | |
} | |
} | |
function optionsMenu(config, reporter) { | |
var optionsMenuDom = createDom(reporter, 'div', { | |
className: 'jasmine-run-options' | |
}, createDom(reporter, 'span', { | |
className: 'jasmine-trigger' | |
}, 'Options'), createDom(reporter, 'div', { | |
className: 'jasmine-payload' | |
}, createDom(reporter, 'div', { | |
className: 'jasmine-stop-on-failure' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-fail-fast', | |
id: 'jasmine-fail-fast', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-fail-fast' | |
}, 'stop execution on spec failure')), createDom(reporter, 'div', { | |
className: 'jasmine-throw-failures' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-throw', | |
id: 'jasmine-throw-failures', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-throw-failures' | |
}, 'stop spec on expectation failure')), createDom(reporter, 'div', { | |
className: 'jasmine-random-order' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-random', | |
id: 'jasmine-random-order', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-random-order' | |
}, 'run tests in random order')), createDom(reporter, 'div', { | |
className: 'jasmine-hide-disabled' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-disabled', | |
id: 'jasmine-hide-disabled', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-hide-disabled' | |
}, 'hide disabled tests')))); | |
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast'); | |
failFastCheckbox.checked = config.failFast ? true : false; | |
failFastCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('failFast', Ms.bang(config.failFast)); | |
}; | |
var throwCheckbox = optionsMenuDom.querySelector('#jasmine-throw-failures'); | |
throwCheckbox.checked = config.oneFailurePerSpec ? true : false; | |
throwCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('throwFailures', Ms.bang(config.oneFailurePerSpec)); | |
}; | |
var randomCheckbox = optionsMenuDom.querySelector('#jasmine-random-order'); | |
randomCheckbox.checked = config.random ? true : false; | |
randomCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('random', Ms.bang(config.random)); | |
}; | |
var hideDisabled = optionsMenuDom.querySelector('#jasmine-hide-disabled'); | |
hideDisabled.checked = config.hideDisabled ? true : false; | |
hideDisabled.onclick = function() { | |
reporter.navigateWithNewParam('hideDisabled', Ms.bang(config.hideDisabled)); | |
}; | |
var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'); | |
var optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'); | |
var isOpen = /\bjasmine-open\b/; | |
optionsTrigger.onclick = function() { | |
if (isOpen.test(optionsPayload.className)) { | |
optionsPayload.className = optionsPayload.className.replace(isOpen, ''); | |
} else { | |
optionsPayload.className += ' jasmine-open'; | |
} | |
}; | |
return optionsMenuDom; | |
} | |
function failureDescription(result, suite, reporter) { | |
var wrapper = createDom(reporter, 'div', { | |
className: 'jasmine-description' | |
}, reporter.createAnchor({ | |
title: result.description, | |
href: specHref(result, reporter) | |
}, result.description)); | |
var suiteLink; | |
var _TMd9k = Date.now(); | |
while (suite && suite.parent) { | |
if (Ms.gt(Ms.sub(Date.now(), _TMd9k), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
wrapper.insertBefore(reporter.createTextNode(' > '), wrapper.firstChild); | |
suiteLink = reporter.createAnchor({ | |
href: suiteHref(suite, reporter) | |
}, suite.result.description); | |
wrapper.insertBefore(suiteLink, wrapper.firstChild); | |
suite = suite.parent; | |
} | |
} | |
return wrapper; | |
} | |
function suiteHref(suite, reporter) { | |
var els = []; | |
var _1YHv8 = Date.now(); | |
while (suite && suite.parent) { | |
if (Ms.gt(Ms.sub(Date.now(), _1YHv8), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
els.unshift(suite.result.description); | |
suite = suite.parent; | |
} | |
} | |
return reporter.addToExistingQueryString('spec', els.join(' ')); | |
} | |
function addDeprecationWarnings(result, reporter) { | |
if (result && result.deprecationWarnings) { | |
var _qNqOx = Date.now(); | |
for (var i = 0; Ms.lt(i, result.deprecationWarnings.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _qNqOx), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var warning = result.deprecationWarnings[i].message; | |
reporter.deprecationWarnings.push(warning); | |
} | |
} | |
} | |
} | |
function findAnchor(selector, reporter) { | |
var element = find(selector, reporter, 'findAnchor'); | |
if (element instanceof HTMLAnchorElement) { | |
return element; | |
} else { | |
throw new Error(''.concat(selector, ' is not an HTMLAnchorElement')); | |
} | |
} | |
function find(selector, reporter, _origin) { | |
var selectors = Ms.add('.jasmine_html-reporter ', selector); | |
var element = reporter.getContainer().querySelector(selectors); | |
if (element) { | |
return element; | |
} else { | |
throw new Error('Unable to find selectors '.concat(JSON.stringify(selectors))); | |
} | |
} | |
function clearPrior(reporter) { | |
try { | |
var oldReporter = find('', reporter, 'clearPrior'); | |
reporter.getContainer().removeChild(oldReporter); | |
} catch (e) {} | |
} | |
exports_1('clearPrior', clearPrior); | |
function createDom(factory, type, attrs) { | |
var _children = []; | |
var _6giKl = Date.now(); | |
for (var _i = 3; Ms.lt(_i, arguments.length); _i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _6giKl), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
_children[_i - 3] = arguments[_i]; | |
} | |
} | |
var el = factory.createElement(type); | |
var _6GnFk = Date.now(); | |
for (var i = 3; Ms.lt(i, arguments.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _6GnFk), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var child = arguments[i]; | |
if (Ms.eq(typeof child, 'string')) { | |
el.appendChild(factory.createTextNode(child)); | |
} else { | |
if (child) { | |
el.appendChild(child); | |
} | |
} | |
} | |
} | |
for (var attr in attrs) { | |
if (Ms.eq(attr, 'className')) { | |
el[attr] = attrs[attr]; | |
} else { | |
el.setAttribute(attr, attrs[attr]); | |
} | |
} | |
return el; | |
} | |
function pluralize(singular, count) { | |
var word = Ms.eq(count, 1) ? singular : Ms.add(singular, 's'); | |
return Ms.add(Ms.add(Ms.add('', count), ' '), word); | |
} | |
function specHref(result, reporter) { | |
return reporter.addToExistingQueryString('spec', result.fullName); | |
} | |
function seedHref(seed, reporter) { | |
return reporter.addToExistingQueryString('seed', seed); | |
} | |
function defaultQueryString(key, value) { | |
return Ms.add(Ms.add(Ms.add('?', key), '='), value); | |
} | |
function setMenuModeTo(mode, reporter) { | |
reporter.htmlReporterMain.setAttribute('class', Ms.add('jasmine_html-reporter ', mode)); | |
} | |
function noExpectations(result) { | |
var allExpectations = Ms.add(result.failedExpectations.length, result.passedExpectations.length); | |
return Ms.eq(allExpectations, 0) && (Ms.eq(result.status, 'passed') || Ms.eq(result.status, 'failed')); | |
} | |
function hasActiveSpec(resultNode) { | |
if (Ms.eq(resultNode.type, 'spec')) { | |
var result = resultNode.result; | |
if (Ms.ne(result.status, 'excluded')) { | |
return true; | |
} | |
} | |
if (Ms.eq(resultNode.type, 'suite')) { | |
var j = resultNode.children.length; | |
var _PSpDt = Date.now(); | |
for (var i = 0; Ms.lt(i, j); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _PSpDt), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
if (hasActiveSpec(resultNode.children[i])) { | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
return { | |
setters: [], | |
execute: function() { | |
ResultsNode = function() { | |
function ResultsNode(result, type, parent) { | |
this.result = result; | |
this.type = type; | |
this.parent = parent; | |
this.children = []; | |
} | |
ResultsNode.prototype.addChild = function(result, type) { | |
this.children.push(new ResultsNode(result, type, this)); | |
}; | |
ResultsNode.prototype.last = function() { | |
return this.children[this.children.length - 1]; | |
}; | |
ResultsNode.prototype.updateResult = function(result) { | |
this.result = result; | |
}; | |
return ResultsNode; | |
}(); | |
ResultsStateBuilder = function() { | |
function ResultsStateBuilder() { | |
this.topResults = new ResultsNode({ | |
description: '' | |
}, 'suite', null); | |
this.currentParent = this.topResults; | |
this.specsExecuted = 0; | |
this.failureCount = 0; | |
this.pendingSpecCount = 0; | |
} | |
ResultsStateBuilder.prototype.suiteStarted = function(result) { | |
this.currentParent.addChild(result, 'suite'); | |
this.currentParent = this.currentParent.last(); | |
}; | |
ResultsStateBuilder.prototype.suiteDone = function(result) { | |
this.currentParent.updateResult(result); | |
if (Ms.ne(this.currentParent, this.topResults)) { | |
this.currentParent = this.currentParent.parent; | |
} | |
if (Ms.eq(result.status, 'failed')) { | |
this.failureCount++; | |
} | |
}; | |
ResultsStateBuilder.prototype.specStarted = function(_report) {}; | |
ResultsStateBuilder.prototype.specDone = function(result) { | |
this.currentParent.addChild(result, 'spec'); | |
if (Ms.ne(result.status, 'excluded')) { | |
this.specsExecuted++; | |
} | |
if (Ms.eq(result.status, 'failed')) { | |
this.failureCount++; | |
} | |
if (Ms.eq(result.status, 'pending')) { | |
this.pendingSpecCount++; | |
} | |
}; | |
return ResultsStateBuilder; | |
}(); | |
HtmlReporter = function() { | |
function HtmlReporter(options) { | |
this.failures = []; | |
this.deprecationWarnings = []; | |
this.stateBuilder = new ResultsStateBuilder(); | |
this.config = function() { | |
return options.env && options.env.configuration() || {}; | |
}; | |
this.getContainer = options.getContainer; | |
this.createElement = options.createElement; | |
this.createTextNode = options.createTextNode; | |
this.navigateWithNewParam = options.navigateWithNewParam || function() {}; | |
this.addToExistingQueryString = options.addToExistingQueryString || defaultQueryString; | |
this.filterSpecs = options.filterSpecs; | |
this.summary = createDom(this, 'div', { | |
className: 'jasmine-summary' | |
}); | |
} | |
HtmlReporter.prototype.initialize = function() { | |
clearPrior(this); | |
this.htmlReporterMain = createDom(this, 'div', { | |
className: 'jasmine_html-reporter' | |
}, createDom(this, 'div', { | |
className: 'jasmine-banner' | |
}, this.createAnchor({ | |
className: 'jasmine-title', | |
href: 'http://jasmine.github.io/', | |
target: '_blank' | |
}), createDom(this, 'span', { | |
className: 'jasmine-version' | |
}, jasmine.version)), createDom(this, 'ul', { | |
className: 'jasmine-symbol-summary' | |
}), createDom(this, 'div', { | |
className: 'jasmine-alert' | |
}), createDom(this, 'div', { | |
className: 'jasmine-results' | |
}, createDom(this, 'div', { | |
className: 'jasmine-failures' | |
}))); | |
this.getContainer().appendChild(this.htmlReporterMain); | |
}; | |
HtmlReporter.prototype.jasmineStarted = function(options) { | |
this.totalSpecsDefined = options.totalSpecsDefined || 0; | |
}; | |
HtmlReporter.prototype.suiteStarted = function(result) { | |
this.stateBuilder.suiteStarted(result); | |
}; | |
HtmlReporter.prototype.suiteDone = function(result) { | |
this.stateBuilder.suiteDone(result); | |
if (Ms.eq(result.status, 'failed')) { | |
this.failures.push(failureDom(result, this)); | |
} | |
addDeprecationWarnings(result, this); | |
}; | |
HtmlReporter.prototype.specStarted = function(result) { | |
this.stateBuilder.specStarted(result); | |
}; | |
HtmlReporter.prototype.specDone = function(result) { | |
this.stateBuilder.specDone(result); | |
if (noExpectations(result)) { | |
var noSpecMsg = 'Spec "'.concat(result.fullName, '" has no expectations.'); | |
if (Ms.eq(result.status, 'failed')) { | |
console.error(noSpecMsg); | |
} else { | |
console.warn(noSpecMsg); | |
} | |
} | |
if (Ms.bang(this.symbols)) { | |
this.symbols = find('.jasmine-symbol-summary', this, 'specDone'); | |
} | |
this.symbols.appendChild(createDom(this, 'li', { | |
className: this.classNameFromSpecReport(result), | |
id: 'spec_'.concat(result.id), | |
title: result.fullName | |
})); | |
if (Ms.eq(result.status, 'failed')) { | |
this.failures.push(failureDom(result, this)); | |
} | |
addDeprecationWarnings(result, this); | |
}; | |
HtmlReporter.prototype.classNameFromSpecReport = function(report) { | |
return noExpectations(report) && Ms.eq(report.status, 'passed') ? 'jasmine-empty' : this.classNameFromStatus(report.status); | |
}; | |
HtmlReporter.prototype.classNameFromStatus = function(status) { | |
switch (status) { | |
case 'excluded': | |
case 'passed': { | |
return this.config().hideDisabled ? 'jasmine-excluded-no-display' : 'jasmine-excluded'; | |
} | |
case 'pending': | |
return 'jasmine-pending'; | |
case 'failed': | |
return 'jasmine-failed'; | |
default: { | |
throw new Error('classNameFromStatus(\''.concat(status, '\')')); | |
} | |
} | |
}; | |
HtmlReporter.prototype.jasmineDone = function(doneResult) { | |
var _this = this; | |
var banner = find('.jasmine-banner', this, 'jasmineDone'); | |
var alert = find('.jasmine-alert', this, 'jasmineDone'); | |
var order = doneResult && doneResult.order; | |
var i; | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-duration' | |
}, Ms.add(Ms.add('finished in ', Ms.div(doneResult.totalTime, 1000)), 's'))); | |
banner.appendChild(optionsMenu(this.config(), this)); | |
if (Ms.lt(this.stateBuilder.specsExecuted, this.totalSpecsDefined)) { | |
var skippedMessage = Ms.add(Ms.add(Ms.add(Ms.add('Ran ', this.stateBuilder.specsExecuted), ' of '), this.totalSpecsDefined), ' specs - run all'); | |
var skippedLink = this.addToExistingQueryString('spec', ''); | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-bar jasmine-skipped' | |
}, this.createAnchor({ | |
href: skippedLink, | |
title: 'Run all specs' | |
}, skippedMessage))); | |
} | |
var statusBarMessage = ''; | |
var statusBarClassName = 'jasmine-overall-result jasmine-bar '; | |
var globalFailures = doneResult && doneResult.failedExpectations || []; | |
var failed = Ms.gt(Ms.add(this.stateBuilder.failureCount, globalFailures.length), 0); | |
if (Ms.gt(this.totalSpecsDefined, 0) || failed) { | |
statusBarMessage += Ms.add(Ms.add(pluralize('spec', this.stateBuilder.specsExecuted), ', '), pluralize('failure', this.stateBuilder.failureCount)); | |
if (this.stateBuilder.pendingSpecCount) { | |
statusBarMessage += Ms.add(', ', pluralize('pending spec', this.stateBuilder.pendingSpecCount)); | |
} | |
} | |
if (Ms.eq(doneResult.overallStatus, 'passed')) { | |
statusBarClassName += ' jasmine-passed '; | |
} else if (Ms.eq(doneResult.overallStatus, 'incomplete')) { | |
statusBarClassName += ' jasmine-incomplete '; | |
statusBarMessage = Ms.add(Ms.add(Ms.add('Incomplete: ', doneResult.incompleteReason), ', '), statusBarMessage); | |
} else { | |
statusBarClassName += ' jasmine-failed '; | |
} | |
if (order && order.random) { | |
var seedBar = createDom(this, 'span', { | |
className: 'jasmine-seed-bar' | |
}, ', randomized with seed ', this.createAnchor({ | |
title: Ms.add('randomized with seed ', order.seed), | |
href: seedHref(order.seed, this) | |
}, order.seed)); | |
alert.appendChild(createDom(this, 'span', { | |
className: statusBarClassName | |
}, statusBarMessage, seedBar)); | |
} else { | |
alert.appendChild(createDom(this, 'span', { | |
className: statusBarClassName | |
}, statusBarMessage)); | |
} | |
var errorBarClassName = 'jasmine-bar jasmine-errored'; | |
var afterAllMessagePrefix = 'AfterAll '; | |
var _MXXCD = Date.now(); | |
for (i = 0; Ms.lt(i, globalFailures.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _MXXCD), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
alert.appendChild(createDom(this, 'span', { | |
className: errorBarClassName | |
}, globalFailureMessage(globalFailures[i]))); | |
} | |
} | |
function globalFailureMessage(failure) { | |
if (Ms.eq(failure.globalErrorType, 'load')) { | |
var prefix = Ms.add('Error during loading: ', failure.message); | |
if (failure.filename) { | |
return Ms.add(Ms.add(Ms.add(Ms.add(prefix, ' in '), failure.filename), ' line '), failure.lineno); | |
} else { | |
return prefix; | |
} | |
} else { | |
return Ms.add(afterAllMessagePrefix, failure.message); | |
} | |
} | |
addDeprecationWarnings(doneResult, this); | |
var warningBarClassName = 'jasmine-bar jasmine-warning'; | |
var _DCAwT = Date.now(); | |
for (i = 0; Ms.lt(i, this.deprecationWarnings.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _DCAwT), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var warning = this.deprecationWarnings[i]; | |
alert.appendChild(createDom(this, 'span', { | |
className: warningBarClassName | |
}, Ms.add('DEPRECATION: ', warning))); | |
} | |
} | |
var results = find('.jasmine-results', this, 'jasmineDone'); | |
results.appendChild(this.summary); | |
summaryList(this.stateBuilder.topResults, this.summary, this); | |
if (this.failures.length) { | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-menu jasmine-bar jasmine-spec-list' | |
}, createDom(this, 'span', {}, 'Spec List | '), this.createAnchor({ | |
className: 'jasmine-failures-menu', | |
href: '#' | |
}, 'Failures'))); | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-menu jasmine-bar jasmine-failure-list' | |
}, this.createAnchor({ | |
className: 'jasmine-spec-list-menu', | |
href: '#' | |
}, 'Spec List'), createDom(this, 'span', {}, ' | Failures '))); | |
findAnchor('.jasmine-failures-menu', this).onclick = function() { | |
setMenuModeTo('jasmine-failure-list', _this); | |
return false; | |
}; | |
findAnchor('.jasmine-spec-list-menu', this).onclick = function() { | |
setMenuModeTo('jasmine-spec-list', _this); | |
return false; | |
}; | |
setMenuModeTo('jasmine-failure-list', this); | |
var failureNode = find('.jasmine-failures', this, 'jasmineDone'); | |
var _ob7LK = Date.now(); | |
for (i = 0; Ms.lt(i, this.failures.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _ob7LK), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
failureNode.appendChild(this.failures[i]); | |
} | |
} | |
} | |
}; | |
HtmlReporter.prototype.createAnchor = function(attrs, text) { | |
var placeholder = {}; | |
if (attrs.className) { | |
placeholder.className = attrs.className; | |
} | |
if (attrs.title) { | |
placeholder.title = attrs.title; | |
} | |
if (attrs.target) { | |
placeholder.target = attrs.target; | |
} | |
if (attrs.href) { | |
if (Ms.eq(attrs.target, '_blank')) { | |
placeholder.href = attrs.href; | |
} | |
} | |
if (Ms.eq(typeof text, 'string')) { | |
return createDom(this, 'a', placeholder, text); | |
} else { | |
return createDom(this, 'a', placeholder); | |
} | |
}; | |
return HtmlReporter; | |
}(); | |
exports_1('HtmlReporter', HtmlReporter); | |
} | |
}; | |
}); | |
System.register('./index.js', ['./Complex'], function(exports_1, context_1) { | |
'use strict'; | |
var Complex_1, zero, one, i, result; | |
var __moduleName = context_1 && context_1.id; | |
return { | |
setters: [function(Complex_1_1) { | |
Complex_1 = Complex_1_1; | |
}], | |
execute: function() { | |
exports_1('zero', zero = Complex_1.complex(0, 0)); | |
exports_1('one', one = Complex_1.complex(1, 0)); | |
exports_1('i', i = Complex_1.complex(0, 1)); | |
result = Ms.add(Ms.mul(5, one), Ms.mul(Ms.mul(2, one), i)); | |
console.log('The answer to life, the universe, and everything is not '.concat(result.toString())); | |
} | |
}; | |
}); | |
System.register('./tests.js', [ | |
'./HtmlReporter', | |
'./Complex.spec' | |
], function(exports_1, context_1) { | |
'use strict'; | |
var HtmlReporter_1, Complex_spec_1, config, specifications; | |
var __moduleName = context_1 && context_1.id; | |
function getContainer() { | |
var element = document.body; | |
return element; | |
} | |
function onChangeOption(key, value) { | |
switch (key) { | |
case 'failFast': { | |
config.failFast = Ms.bang(config.failFast); | |
break; | |
} | |
case 'throwFailures': { | |
config.oneFailurePerSpec = Ms.bang(config.oneFailurePerSpec); | |
break; | |
} | |
case 'random': { | |
config.random = Ms.bang(config.random); | |
break; | |
} | |
case 'hideDisabled': { | |
config.hideDisabled = Ms.bang(config.hideDisabled); | |
break; | |
} | |
default: { | |
console.warn('navigateWithNewParam(key='.concat(key, ', value=').concat(JSON.stringify(value))); | |
} | |
} | |
runTests(); | |
} | |
function addSpec(value) { | |
specifications.push(value); | |
return ''; | |
} | |
function addSeed(_seed) { | |
return ''; | |
} | |
function runTests() { | |
var jasmineCore = jasmineRequire.core(jasmineRequire); | |
jasmineRequire.html(jasmineCore); | |
var env = jasmineCore.getEnv(); | |
var jasmineInterface = jasmineRequire.interface(jasmineCore, env); | |
extend(window, jasmineInterface); | |
var htmlReporter = new HtmlReporter_1.HtmlReporter({ | |
env: env, | |
addToExistingQueryString: function(key, value) { | |
switch (key) { | |
case 'spec': { | |
return addSpec(value); | |
break; | |
} | |
case 'seed': { | |
return addSeed(parseInt(value, 10)); | |
break; | |
} | |
default: { | |
throw new Error('Unknown key: '.concat(key)); | |
} | |
} | |
}, | |
navigateWithNewParam: onChangeOption, | |
getContainer: getContainer, | |
createElement: function() { | |
return document.createElement.apply(document, arguments); | |
}, | |
createTextNode: function() { | |
return document.createTextNode.apply(document, arguments); | |
}, | |
timer: new jasmine.Timer(), | |
filterSpecs: true | |
}); | |
env.addReporter(jasmineInterface.jsApiReporter); | |
env.addReporter(htmlReporter); | |
env.configure(config); | |
htmlReporter.initialize(); | |
describe('Complex', Complex_spec_1.complexSpec); | |
env.execute(); | |
} | |
function extend(destination, source) { | |
for (var property in source) { | |
if (source.hasOwnProperty(property)) { | |
destination[property] = source[property]; | |
} | |
} | |
return destination; | |
} | |
return { | |
setters: [ | |
function(HtmlReporter_1_1) { | |
HtmlReporter_1 = HtmlReporter_1_1; | |
}, | |
function(Complex_spec_1_1) { | |
Complex_spec_1 = Complex_spec_1_1; | |
} | |
], | |
execute: function() { | |
config = { | |
random: false, | |
failFast: false, | |
failSpecWithNoExpectations: false, | |
oneFailurePerSpec: false, | |
hideDisabled: false, | |
specFilter: void 0, | |
promise: void 0 | |
}; | |
specifications = []; | |
runTests(); | |
} | |
}; | |
}); | |
</script> | |
<script> | |
System.defaultJSExtensions = true | |
System.import('./index.js').catch(function(e) { | |
console.error(e) | |
}) | |
</script> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html> | |
<head> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.6.0/jasmine-html.min.js"></script> | |
<script src="/vendor/[email protected]/davinci-mathscript.min.js"></script> | |
<script src="/assets/js/[email protected]/system.js"></script> | |
</head> | |
<body> | |
<script> | |
System.config({ | |
"warnings": true, | |
"map": { | |
"jasmine": "https://cdn.jsdelivr.net/npm/[email protected]/lib/jasmine.js" | |
} | |
}); | |
</script> | |
<script> | |
System.register('./Complex.spec.js', ['./Complex'], function(exports_1, context_1) { | |
'use strict'; | |
var Complex_1; | |
var __moduleName = context_1 && context_1.id; | |
function complexSpec() { | |
describe('constructor', function() { | |
var x = Math.random(); | |
var y = Math.random(); | |
var z = new Complex_1.Complex(x, y); | |
it('should preserve real argument', function() { | |
expect(z.real).toBe(x); | |
}); | |
it('should preserve imag argument', function() { | |
expect(z.imag).toBe(y); | |
}); | |
}); | |
describe('Complex + Complex', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.add(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.add(z1.real, z2.real)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.add(z1.imag, z2.imag)); | |
}); | |
}); | |
describe('Complex + number', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = 5; | |
var z = Ms.add(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.add(z1.real, z2)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(z1.imag); | |
}); | |
}); | |
describe('number + Complex', function() { | |
var z1 = 2; | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.add(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.add(z1, z2.real)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(z2.imag); | |
}); | |
}); | |
describe('Complex * Complex', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.mul(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.sub(Ms.mul(z1.real, z2.real), Ms.mul(z1.imag, z2.imag))); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.add(Ms.mul(z1.real, z2.imag), Ms.mul(z1.imag, z2.real))); | |
}); | |
}); | |
describe('Complex * number', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z2 = 5; | |
var z = Ms.mul(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.mul(z1.real, z2)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.mul(z1.imag, z2)); | |
}); | |
}); | |
describe('number * Complex', function() { | |
var z1 = 2; | |
var z2 = new Complex_1.Complex(5, 7); | |
var z = Ms.mul(z1, z2); | |
it('should sum real argument', function() { | |
expect(z.real).toBe(Ms.mul(z1, z2.real)); | |
}); | |
it('should sum imag argument', function() { | |
expect(z.imag).toBe(Ms.mul(z1, z2.imag)); | |
}); | |
}); | |
describe('-Complex', function() { | |
var z1 = new Complex_1.Complex(2, 3); | |
var z = Ms.neg(z1); | |
it('should negate real argument', function() { | |
expect(z.real).toBe(Ms.mul(z1.real, Ms.neg(1))); | |
}); | |
it('should negate imag argument', function() { | |
expect(z.imag).toBe(Ms.mul(z1.imag, Ms.neg(1))); | |
}); | |
}); | |
} | |
exports_1('complexSpec', complexSpec); | |
return { | |
setters: [function(Complex_1_1) { | |
Complex_1 = Complex_1_1; | |
}], | |
execute: function() {} | |
}; | |
}); | |
System.register('./Complex.js', [], function(exports_1, context_1) { | |
'use strict'; | |
var Complex; | |
var __moduleName = context_1 && context_1.id; | |
function complex(x, y) { | |
return new Complex(x, y); | |
} | |
exports_1('complex', complex); | |
return { | |
setters: [], | |
execute: function() { | |
Complex = function() { | |
function Complex(real, imag) { | |
this.real = real; | |
this.imag = imag; | |
} | |
Complex.prototype.__add__ = function(rhs) { | |
if (Ms.eq(typeof rhs, 'number')) { | |
return new Complex(Ms.add(this.real, rhs), this.imag); | |
} else if (rhs instanceof Complex) { | |
return new Complex(Ms.add(this.real, rhs.real), Ms.add(this.imag, rhs.imag)); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__radd__ = function(lhs) { | |
if (Ms.eq(typeof lhs, 'number')) { | |
return new Complex(Ms.add(lhs, this.real), this.imag); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__mul__ = function(rhs) { | |
if (Ms.eq(typeof rhs, 'number')) { | |
return new Complex(Ms.mul(this.real, rhs), Ms.mul(this.imag, rhs)); | |
} else if (rhs instanceof Complex) { | |
var x = Ms.sub(Ms.mul(this.real, rhs.real), Ms.mul(this.imag, rhs.imag)); | |
var y = Ms.add(Ms.mul(this.real, rhs.imag), Ms.mul(this.imag, rhs.real)); | |
return new Complex(x, y); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__rmul__ = function(lhs) { | |
if (Ms.eq(typeof lhs, 'number')) { | |
return new Complex(Ms.mul(lhs, this.real), Ms.mul(lhs, this.imag)); | |
} else { | |
return void 0; | |
} | |
}; | |
Complex.prototype.__neg__ = function() { | |
return new Complex(Ms.neg(this.real), Ms.neg(this.imag)); | |
}; | |
Complex.prototype.toString = function() { | |
return ''.concat(this.real, ' + ').concat(this.imag, ' * i'); | |
}; | |
return Complex; | |
}(); | |
exports_1('Complex', Complex); | |
} | |
}; | |
}); | |
System.register('./HtmlReporter.js', [], function(exports_1, context_1) { | |
'use strict'; | |
var ResultsNode, ResultsStateBuilder, HtmlReporter; | |
var __moduleName = context_1 && context_1.id; | |
function failureDom(result, reporter) { | |
var failure = createDom(reporter, 'div', { | |
className: 'jasmine-spec-detail jasmine-failed' | |
}, failureDescription(result, reporter.stateBuilder.currentParent, reporter), createDom(reporter, 'div', { | |
className: 'jasmine-messages' | |
})); | |
var messages = failure.childNodes[1]; | |
var _xLORU = Date.now(); | |
for (var _i = 0, _a = result.failedExpectations; Ms.lt(_i, _a.length); _i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _xLORU), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var expectation = _a[_i]; | |
messages.appendChild(createDom(reporter, 'div', { | |
className: 'jasmine-result-message' | |
}, expectation.message)); | |
messages.appendChild(createDom(reporter, 'div', { | |
className: 'jasmine-stack-trace' | |
}, expectation.stack)); | |
} | |
} | |
if (Ms.eq(result.failedExpectations.length, 0)) { | |
messages.appendChild(createDom(reporter, 'div', { | |
className: 'jasmine-result-message' | |
}, 'Spec has no expectations')); | |
} | |
return failure; | |
} | |
function summaryList(resultsTree, domParent, reporter) { | |
var specListNode; | |
var _lx9O7 = Date.now(); | |
for (var i = 0; Ms.lt(i, resultsTree.children.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _lx9O7), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var resultNode = resultsTree.children[i]; | |
if (reporter.filterSpecs && Ms.bang(hasActiveSpec(resultNode))) { | |
continue; | |
} | |
if (Ms.eq(resultNode.type, 'suite')) { | |
var result = resultNode.result; | |
var suiteListNode = createDom(reporter, 'ul', { | |
className: 'jasmine-suite', | |
id: Ms.add('suite-', result.id) | |
}, createDom(reporter, 'li', { | |
className: Ms.add('jasmine-suite-detail jasmine-', result.status) | |
}, reporter.createAnchor({ | |
href: specHref(result, reporter) | |
}, result.description))); | |
summaryList(resultNode, suiteListNode, reporter); | |
domParent.appendChild(suiteListNode); | |
} | |
if (Ms.eq(resultNode.type, 'spec')) { | |
var result = resultNode.result; | |
if (Ms.ne(domParent.getAttribute('class'), 'jasmine-specs')) { | |
specListNode = createDom(reporter, 'ul', { | |
className: 'jasmine-specs' | |
}); | |
domParent.appendChild(specListNode); | |
} | |
var specDescription = result.description; | |
if (noExpectations(result)) { | |
specDescription = Ms.add('SPEC HAS NO EXPECTATIONS ', specDescription); | |
} | |
if (Ms.eq(result.status, 'pending') && Ms.ne(result.pendingReason, '')) { | |
specDescription = Ms.add(Ms.add(specDescription, ' PENDING WITH MESSAGE: '), result.pendingReason); | |
} | |
specListNode.appendChild(createDom(reporter, 'li', { | |
className: Ms.add('jasmine-', result.status), | |
id: Ms.add('spec-', result.id) | |
}, reporter.createAnchor({ | |
href: specHref(result, reporter) | |
}, specDescription))); | |
} | |
} | |
} | |
} | |
function optionsMenu(config, reporter) { | |
var optionsMenuDom = createDom(reporter, 'div', { | |
className: 'jasmine-run-options' | |
}, createDom(reporter, 'span', { | |
className: 'jasmine-trigger' | |
}, 'Options'), createDom(reporter, 'div', { | |
className: 'jasmine-payload' | |
}, createDom(reporter, 'div', { | |
className: 'jasmine-stop-on-failure' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-fail-fast', | |
id: 'jasmine-fail-fast', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-fail-fast' | |
}, 'stop execution on spec failure')), createDom(reporter, 'div', { | |
className: 'jasmine-throw-failures' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-throw', | |
id: 'jasmine-throw-failures', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-throw-failures' | |
}, 'stop spec on expectation failure')), createDom(reporter, 'div', { | |
className: 'jasmine-random-order' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-random', | |
id: 'jasmine-random-order', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-random-order' | |
}, 'run tests in random order')), createDom(reporter, 'div', { | |
className: 'jasmine-hide-disabled' | |
}, createDom(reporter, 'input', { | |
className: 'jasmine-disabled', | |
id: 'jasmine-hide-disabled', | |
type: 'checkbox' | |
}), createDom(reporter, 'label', { | |
className: 'jasmine-label', | |
for: 'jasmine-hide-disabled' | |
}, 'hide disabled tests')))); | |
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast'); | |
failFastCheckbox.checked = config.failFast ? true : false; | |
failFastCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('failFast', Ms.bang(config.failFast)); | |
}; | |
var throwCheckbox = optionsMenuDom.querySelector('#jasmine-throw-failures'); | |
throwCheckbox.checked = config.oneFailurePerSpec ? true : false; | |
throwCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('throwFailures', Ms.bang(config.oneFailurePerSpec)); | |
}; | |
var randomCheckbox = optionsMenuDom.querySelector('#jasmine-random-order'); | |
randomCheckbox.checked = config.random ? true : false; | |
randomCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('random', Ms.bang(config.random)); | |
}; | |
var hideDisabled = optionsMenuDom.querySelector('#jasmine-hide-disabled'); | |
hideDisabled.checked = config.hideDisabled ? true : false; | |
hideDisabled.onclick = function() { | |
reporter.navigateWithNewParam('hideDisabled', Ms.bang(config.hideDisabled)); | |
}; | |
var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'); | |
var optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'); | |
var isOpen = /\bjasmine-open\b/; | |
optionsTrigger.onclick = function() { | |
if (isOpen.test(optionsPayload.className)) { | |
optionsPayload.className = optionsPayload.className.replace(isOpen, ''); | |
} else { | |
optionsPayload.className += ' jasmine-open'; | |
} | |
}; | |
return optionsMenuDom; | |
} | |
function failureDescription(result, suite, reporter) { | |
var wrapper = createDom(reporter, 'div', { | |
className: 'jasmine-description' | |
}, reporter.createAnchor({ | |
title: result.description, | |
href: specHref(result, reporter) | |
}, result.description)); | |
var suiteLink; | |
var _aT1aZ = Date.now(); | |
while (suite && suite.parent) { | |
if (Ms.gt(Ms.sub(Date.now(), _aT1aZ), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
wrapper.insertBefore(reporter.createTextNode(' > '), wrapper.firstChild); | |
suiteLink = reporter.createAnchor({ | |
href: suiteHref(suite, reporter) | |
}, suite.result.description); | |
wrapper.insertBefore(suiteLink, wrapper.firstChild); | |
suite = suite.parent; | |
} | |
} | |
return wrapper; | |
} | |
function suiteHref(suite, reporter) { | |
var els = []; | |
var _Vpfcm = Date.now(); | |
while (suite && suite.parent) { | |
if (Ms.gt(Ms.sub(Date.now(), _Vpfcm), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
els.unshift(suite.result.description); | |
suite = suite.parent; | |
} | |
} | |
return reporter.addToExistingQueryString('spec', els.join(' ')); | |
} | |
function addDeprecationWarnings(result, reporter) { | |
if (result && result.deprecationWarnings) { | |
var _OqXnC = Date.now(); | |
for (var i = 0; Ms.lt(i, result.deprecationWarnings.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _OqXnC), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var warning = result.deprecationWarnings[i].message; | |
reporter.deprecationWarnings.push(warning); | |
} | |
} | |
} | |
} | |
function findAnchor(selector, reporter) { | |
var element = find(selector, reporter, 'findAnchor'); | |
if (element instanceof HTMLAnchorElement) { | |
return element; | |
} else { | |
throw new Error(''.concat(selector, ' is not an HTMLAnchorElement')); | |
} | |
} | |
function find(selector, reporter, _origin) { | |
var selectors = Ms.add('.jasmine_html-reporter ', selector); | |
var element = reporter.getContainer().querySelector(selectors); | |
if (element) { | |
return element; | |
} else { | |
throw new Error('Unable to find selectors '.concat(JSON.stringify(selectors))); | |
} | |
} | |
function clearPrior(reporter) { | |
try { | |
var oldReporter = find('', reporter, 'clearPrior'); | |
reporter.getContainer().removeChild(oldReporter); | |
} catch (e) {} | |
} | |
exports_1('clearPrior', clearPrior); | |
function createDom(factory, type, attrs) { | |
var _children = []; | |
var _1H2dF = Date.now(); | |
for (var _i = 3; Ms.lt(_i, arguments.length); _i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _1H2dF), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
_children[_i - 3] = arguments[_i]; | |
} | |
} | |
var el = factory.createElement(type); | |
var _01k9R = Date.now(); | |
for (var i = 3; Ms.lt(i, arguments.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _01k9R), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var child = arguments[i]; | |
if (Ms.eq(typeof child, 'string')) { | |
el.appendChild(factory.createTextNode(child)); | |
} else { | |
if (child) { | |
el.appendChild(child); | |
} | |
} | |
} | |
} | |
for (var attr in attrs) { | |
if (Ms.eq(attr, 'className')) { | |
el[attr] = attrs[attr]; | |
} else { | |
el.setAttribute(attr, attrs[attr]); | |
} | |
} | |
return el; | |
} | |
function pluralize(singular, count) { | |
var word = Ms.eq(count, 1) ? singular : Ms.add(singular, 's'); | |
return Ms.add(Ms.add(Ms.add('', count), ' '), word); | |
} | |
function specHref(result, reporter) { | |
return reporter.addToExistingQueryString('spec', result.fullName); | |
} | |
function seedHref(seed, reporter) { | |
return reporter.addToExistingQueryString('seed', seed); | |
} | |
function defaultQueryString(key, value) { | |
return Ms.add(Ms.add(Ms.add('?', key), '='), value); | |
} | |
function setMenuModeTo(mode, reporter) { | |
reporter.htmlReporterMain.setAttribute('class', Ms.add('jasmine_html-reporter ', mode)); | |
} | |
function noExpectations(result) { | |
var allExpectations = Ms.add(result.failedExpectations.length, result.passedExpectations.length); | |
return Ms.eq(allExpectations, 0) && (Ms.eq(result.status, 'passed') || Ms.eq(result.status, 'failed')); | |
} | |
function hasActiveSpec(resultNode) { | |
if (Ms.eq(resultNode.type, 'spec')) { | |
var result = resultNode.result; | |
if (Ms.ne(result.status, 'excluded')) { | |
return true; | |
} | |
} | |
if (Ms.eq(resultNode.type, 'suite')) { | |
var j = resultNode.children.length; | |
var _6nUMa = Date.now(); | |
for (var i = 0; Ms.lt(i, j); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _6nUMa), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
if (hasActiveSpec(resultNode.children[i])) { | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
return { | |
setters: [], | |
execute: function() { | |
ResultsNode = function() { | |
function ResultsNode(result, type, parent) { | |
this.result = result; | |
this.type = type; | |
this.parent = parent; | |
this.children = []; | |
} | |
ResultsNode.prototype.addChild = function(result, type) { | |
this.children.push(new ResultsNode(result, type, this)); | |
}; | |
ResultsNode.prototype.last = function() { | |
return this.children[this.children.length - 1]; | |
}; | |
ResultsNode.prototype.updateResult = function(result) { | |
this.result = result; | |
}; | |
return ResultsNode; | |
}(); | |
ResultsStateBuilder = function() { | |
function ResultsStateBuilder() { | |
this.topResults = new ResultsNode({ | |
description: '' | |
}, 'suite', null); | |
this.currentParent = this.topResults; | |
this.specsExecuted = 0; | |
this.failureCount = 0; | |
this.pendingSpecCount = 0; | |
} | |
ResultsStateBuilder.prototype.suiteStarted = function(result) { | |
this.currentParent.addChild(result, 'suite'); | |
this.currentParent = this.currentParent.last(); | |
}; | |
ResultsStateBuilder.prototype.suiteDone = function(result) { | |
this.currentParent.updateResult(result); | |
if (Ms.ne(this.currentParent, this.topResults)) { | |
this.currentParent = this.currentParent.parent; | |
} | |
if (Ms.eq(result.status, 'failed')) { | |
this.failureCount++; | |
} | |
}; | |
ResultsStateBuilder.prototype.specStarted = function(_report) {}; | |
ResultsStateBuilder.prototype.specDone = function(result) { | |
this.currentParent.addChild(result, 'spec'); | |
if (Ms.ne(result.status, 'excluded')) { | |
this.specsExecuted++; | |
} | |
if (Ms.eq(result.status, 'failed')) { | |
this.failureCount++; | |
} | |
if (Ms.eq(result.status, 'pending')) { | |
this.pendingSpecCount++; | |
} | |
}; | |
return ResultsStateBuilder; | |
}(); | |
HtmlReporter = function() { | |
function HtmlReporter(options) { | |
this.failures = []; | |
this.deprecationWarnings = []; | |
this.stateBuilder = new ResultsStateBuilder(); | |
this.config = function() { | |
return options.env && options.env.configuration() || {}; | |
}; | |
this.getContainer = options.getContainer; | |
this.createElement = options.createElement; | |
this.createTextNode = options.createTextNode; | |
this.navigateWithNewParam = options.navigateWithNewParam || function() {}; | |
this.addToExistingQueryString = options.addToExistingQueryString || defaultQueryString; | |
this.filterSpecs = options.filterSpecs; | |
this.summary = createDom(this, 'div', { | |
className: 'jasmine-summary' | |
}); | |
} | |
HtmlReporter.prototype.initialize = function() { | |
clearPrior(this); | |
this.htmlReporterMain = createDom(this, 'div', { | |
className: 'jasmine_html-reporter' | |
}, createDom(this, 'div', { | |
className: 'jasmine-banner' | |
}, this.createAnchor({ | |
className: 'jasmine-title', | |
href: 'http://jasmine.github.io/', | |
target: '_blank' | |
}), createDom(this, 'span', { | |
className: 'jasmine-version' | |
}, jasmine.version)), createDom(this, 'ul', { | |
className: 'jasmine-symbol-summary' | |
}), createDom(this, 'div', { | |
className: 'jasmine-alert' | |
}), createDom(this, 'div', { | |
className: 'jasmine-results' | |
}, createDom(this, 'div', { | |
className: 'jasmine-failures' | |
}))); | |
this.getContainer().appendChild(this.htmlReporterMain); | |
}; | |
HtmlReporter.prototype.jasmineStarted = function(options) { | |
this.totalSpecsDefined = options.totalSpecsDefined || 0; | |
}; | |
HtmlReporter.prototype.suiteStarted = function(result) { | |
this.stateBuilder.suiteStarted(result); | |
}; | |
HtmlReporter.prototype.suiteDone = function(result) { | |
this.stateBuilder.suiteDone(result); | |
if (Ms.eq(result.status, 'failed')) { | |
this.failures.push(failureDom(result, this)); | |
} | |
addDeprecationWarnings(result, this); | |
}; | |
HtmlReporter.prototype.specStarted = function(result) { | |
this.stateBuilder.specStarted(result); | |
}; | |
HtmlReporter.prototype.specDone = function(result) { | |
this.stateBuilder.specDone(result); | |
if (noExpectations(result)) { | |
var noSpecMsg = 'Spec "'.concat(result.fullName, '" has no expectations.'); | |
if (Ms.eq(result.status, 'failed')) { | |
console.error(noSpecMsg); | |
} else { | |
console.warn(noSpecMsg); | |
} | |
} | |
if (Ms.bang(this.symbols)) { | |
this.symbols = find('.jasmine-symbol-summary', this, 'specDone'); | |
} | |
this.symbols.appendChild(createDom(this, 'li', { | |
className: this.classNameFromSpecReport(result), | |
id: 'spec_'.concat(result.id), | |
title: result.fullName | |
})); | |
if (Ms.eq(result.status, 'failed')) { | |
this.failures.push(failureDom(result, this)); | |
} | |
addDeprecationWarnings(result, this); | |
}; | |
HtmlReporter.prototype.classNameFromSpecReport = function(report) { | |
return noExpectations(report) && Ms.eq(report.status, 'passed') ? 'jasmine-empty' : this.classNameFromStatus(report.status); | |
}; | |
HtmlReporter.prototype.classNameFromStatus = function(status) { | |
switch (status) { | |
case 'excluded': | |
case 'passed': { | |
return this.config().hideDisabled ? 'jasmine-excluded-no-display' : 'jasmine-excluded'; | |
} | |
case 'pending': | |
return 'jasmine-pending'; | |
case 'failed': | |
return 'jasmine-failed'; | |
default: { | |
throw new Error('classNameFromStatus(\''.concat(status, '\')')); | |
} | |
} | |
}; | |
HtmlReporter.prototype.jasmineDone = function(doneResult) { | |
var _this = this; | |
var banner = find('.jasmine-banner', this, 'jasmineDone'); | |
var alert = find('.jasmine-alert', this, 'jasmineDone'); | |
var order = doneResult && doneResult.order; | |
var i; | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-duration' | |
}, Ms.add(Ms.add('finished in ', Ms.div(doneResult.totalTime, 1000)), 's'))); | |
banner.appendChild(optionsMenu(this.config(), this)); | |
if (Ms.lt(this.stateBuilder.specsExecuted, this.totalSpecsDefined)) { | |
var skippedMessage = Ms.add(Ms.add(Ms.add(Ms.add('Ran ', this.stateBuilder.specsExecuted), ' of '), this.totalSpecsDefined), ' specs - run all'); | |
var skippedLink = this.addToExistingQueryString('spec', ''); | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-bar jasmine-skipped' | |
}, this.createAnchor({ | |
href: skippedLink, | |
title: 'Run all specs' | |
}, skippedMessage))); | |
} | |
var statusBarMessage = ''; | |
var statusBarClassName = 'jasmine-overall-result jasmine-bar '; | |
var globalFailures = doneResult && doneResult.failedExpectations || []; | |
var failed = Ms.gt(Ms.add(this.stateBuilder.failureCount, globalFailures.length), 0); | |
if (Ms.gt(this.totalSpecsDefined, 0) || failed) { | |
statusBarMessage += Ms.add(Ms.add(pluralize('spec', this.stateBuilder.specsExecuted), ', '), pluralize('failure', this.stateBuilder.failureCount)); | |
if (this.stateBuilder.pendingSpecCount) { | |
statusBarMessage += Ms.add(', ', pluralize('pending spec', this.stateBuilder.pendingSpecCount)); | |
} | |
} | |
if (Ms.eq(doneResult.overallStatus, 'passed')) { | |
statusBarClassName += ' jasmine-passed '; | |
} else if (Ms.eq(doneResult.overallStatus, 'incomplete')) { | |
statusBarClassName += ' jasmine-incomplete '; | |
statusBarMessage = Ms.add(Ms.add(Ms.add('Incomplete: ', doneResult.incompleteReason), ', '), statusBarMessage); | |
} else { | |
statusBarClassName += ' jasmine-failed '; | |
} | |
if (order && order.random) { | |
var seedBar = createDom(this, 'span', { | |
className: 'jasmine-seed-bar' | |
}, ', randomized with seed ', this.createAnchor({ | |
title: Ms.add('randomized with seed ', order.seed), | |
href: seedHref(order.seed, this) | |
}, order.seed)); | |
alert.appendChild(createDom(this, 'span', { | |
className: statusBarClassName | |
}, statusBarMessage, seedBar)); | |
} else { | |
alert.appendChild(createDom(this, 'span', { | |
className: statusBarClassName | |
}, statusBarMessage)); | |
} | |
var errorBarClassName = 'jasmine-bar jasmine-errored'; | |
var afterAllMessagePrefix = 'AfterAll '; | |
var _jeMSU = Date.now(); | |
for (i = 0; Ms.lt(i, globalFailures.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _jeMSU), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
alert.appendChild(createDom(this, 'span', { | |
className: errorBarClassName | |
}, globalFailureMessage(globalFailures[i]))); | |
} | |
} | |
function globalFailureMessage(failure) { | |
if (Ms.eq(failure.globalErrorType, 'load')) { | |
var prefix = Ms.add('Error during loading: ', failure.message); | |
if (failure.filename) { | |
return Ms.add(Ms.add(Ms.add(Ms.add(prefix, ' in '), failure.filename), ' line '), failure.lineno); | |
} else { | |
return prefix; | |
} | |
} else { | |
return Ms.add(afterAllMessagePrefix, failure.message); | |
} | |
} | |
addDeprecationWarnings(doneResult, this); | |
var warningBarClassName = 'jasmine-bar jasmine-warning'; | |
var _UdJWH = Date.now(); | |
for (i = 0; Ms.lt(i, this.deprecationWarnings.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _UdJWH), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
var warning = this.deprecationWarnings[i]; | |
alert.appendChild(createDom(this, 'span', { | |
className: warningBarClassName | |
}, Ms.add('DEPRECATION: ', warning))); | |
} | |
} | |
var results = find('.jasmine-results', this, 'jasmineDone'); | |
results.appendChild(this.summary); | |
summaryList(this.stateBuilder.topResults, this.summary, this); | |
if (this.failures.length) { | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-menu jasmine-bar jasmine-spec-list' | |
}, createDom(this, 'span', {}, 'Spec List | '), this.createAnchor({ | |
className: 'jasmine-failures-menu', | |
href: '#' | |
}, 'Failures'))); | |
alert.appendChild(createDom(this, 'span', { | |
className: 'jasmine-menu jasmine-bar jasmine-failure-list' | |
}, this.createAnchor({ | |
className: 'jasmine-spec-list-menu', | |
href: '#' | |
}, 'Spec List'), createDom(this, 'span', {}, ' | Failures '))); | |
findAnchor('.jasmine-failures-menu', this).onclick = function() { | |
setMenuModeTo('jasmine-failure-list', _this); | |
return false; | |
}; | |
findAnchor('.jasmine-spec-list-menu', this).onclick = function() { | |
setMenuModeTo('jasmine-spec-list', _this); | |
return false; | |
}; | |
setMenuModeTo('jasmine-failure-list', this); | |
var failureNode = find('.jasmine-failures', this, 'jasmineDone'); | |
var _hemKA = Date.now(); | |
for (i = 0; Ms.lt(i, this.failures.length); i++) { | |
if (Ms.gt(Ms.sub(Date.now(), _hemKA), 1000)) { | |
throw new Error('Infinite loop suspected after 1000 milliseconds.'); | |
} { | |
failureNode.appendChild(this.failures[i]); | |
} | |
} | |
} | |
}; | |
HtmlReporter.prototype.createAnchor = function(attrs, text) { | |
var placeholder = {}; | |
if (attrs.className) { | |
placeholder.className = attrs.className; | |
} | |
if (attrs.title) { | |
placeholder.title = attrs.title; | |
} | |
if (attrs.target) { | |
placeholder.target = attrs.target; | |
} | |
if (attrs.href) { | |
if (Ms.eq(attrs.target, '_blank')) { | |
placeholder.href = attrs.href; | |
} | |
} | |
if (Ms.eq(typeof text, 'string')) { | |
return createDom(this, 'a', placeholder, text); | |
} else { | |
return createDom(this, 'a', placeholder); | |
} | |
}; | |
return HtmlReporter; | |
}(); | |
exports_1('HtmlReporter', HtmlReporter); | |
} | |
}; | |
}); | |
System.register('./index.js', ['./Complex'], function(exports_1, context_1) { | |
'use strict'; | |
var Complex_1, zero, one, i, result; | |
var __moduleName = context_1 && context_1.id; | |
return { | |
setters: [function(Complex_1_1) { | |
Complex_1 = Complex_1_1; | |
}], | |
execute: function() { | |
exports_1('zero', zero = Complex_1.complex(0, 0)); | |
exports_1('one', one = Complex_1.complex(1, 0)); | |
exports_1('i', i = Complex_1.complex(0, 1)); | |
result = Ms.add(Ms.mul(5, one), Ms.mul(Ms.mul(2, one), i)); | |
console.log('The answer to life, the universe, and everything is not '.concat(result.toString())); | |
} | |
}; | |
}); | |
System.register('./tests.js', [ | |
'./HtmlReporter', | |
'./Complex.spec' | |
], function(exports_1, context_1) { | |
'use strict'; | |
var HtmlReporter_1, Complex_spec_1, config, specifications; | |
var __moduleName = context_1 && context_1.id; | |
function getContainer() { | |
var element = document.body; | |
return element; | |
} | |
function onChangeOption(key, value) { | |
switch (key) { | |
case 'failFast': { | |
config.failFast = Ms.bang(config.failFast); | |
break; | |
} | |
case 'throwFailures': { | |
config.oneFailurePerSpec = Ms.bang(config.oneFailurePerSpec); | |
break; | |
} | |
case 'random': { | |
config.random = Ms.bang(config.random); | |
break; | |
} | |
case 'hideDisabled': { | |
config.hideDisabled = Ms.bang(config.hideDisabled); | |
break; | |
} | |
default: { | |
console.warn('navigateWithNewParam(key='.concat(key, ', value=').concat(JSON.stringify(value))); | |
} | |
} | |
runTests(); | |
} | |
function addSpec(value) { | |
specifications.push(value); | |
return ''; | |
} | |
function addSeed(_seed) { | |
return ''; | |
} | |
function runTests() { | |
var jasmineCore = jasmineRequire.core(jasmineRequire); | |
jasmineRequire.html(jasmineCore); | |
var env = jasmineCore.getEnv(); | |
var jasmineInterface = jasmineRequire.interface(jasmineCore, env); | |
extend(window, jasmineInterface); | |
var htmlReporter = new HtmlReporter_1.HtmlReporter({ | |
env: env, | |
addToExistingQueryString: function(key, value) { | |
switch (key) { | |
case 'spec': { | |
return addSpec(value); | |
break; | |
} | |
case 'seed': { | |
return addSeed(parseInt(value, 10)); | |
break; | |
} | |
default: { | |
throw new Error('Unknown key: '.concat(key)); | |
} | |
} | |
}, | |
navigateWithNewParam: onChangeOption, | |
getContainer: getContainer, | |
createElement: function() { | |
return document.createElement.apply(document, arguments); | |
}, | |
createTextNode: function() { | |
return document.createTextNode.apply(document, arguments); | |
}, | |
timer: new jasmine.Timer(), | |
filterSpecs: true | |
}); | |
env.addReporter(jasmineInterface.jsApiReporter); | |
env.addReporter(htmlReporter); | |
env.configure(config); | |
htmlReporter.initialize(); | |
describe('Complex', Complex_spec_1.complexSpec); | |
env.execute(); | |
} | |
function extend(destination, source) { | |
for (var property in source) { | |
if (source.hasOwnProperty(property)) { | |
destination[property] = source[property]; | |
} | |
} | |
return destination; | |
} | |
return { | |
setters: [ | |
function(HtmlReporter_1_1) { | |
HtmlReporter_1 = HtmlReporter_1_1; | |
}, | |
function(Complex_spec_1_1) { | |
Complex_spec_1 = Complex_spec_1_1; | |
} | |
], | |
execute: function() { | |
config = { | |
random: false, | |
failFast: false, | |
failSpecWithNoExpectations: false, | |
oneFailurePerSpec: false, | |
hideDisabled: false, | |
specFilter: void 0, | |
promise: void 0 | |
}; | |
specifications = []; | |
runTests(); | |
} | |
}; | |
}); | |
</script> | |
<script> | |
System.defaultJSExtensions = true | |
System.import('./tests.js').catch(function(e) { | |
console.error(e) | |
}) | |
</script> | |
</body> | |
</html> |
// type ResultStatus = 'excluded' | 'disabled' | 'failed' | 'pending' | 'finished' | |
type ResultsNodeResult = jasmine.SuiteStartedReport | jasmine.SuiteDoneReport | jasmine.SpecDoneReport | { description: string } | |
class ResultsNode { | |
type: 'spec' | 'suite' | |
result: ResultsNodeResult | |
children: ResultsNode[] | |
parent: ResultsNode | null | |
constructor(result: ResultsNodeResult, type: 'spec' | 'suite', parent: ResultsNode | null) { | |
this.result = result | |
this.type = type | |
this.parent = parent | |
this.children = [] | |
} | |
addChild(result: ResultsNodeResult, type: 'spec' | 'suite'): void { | |
this.children.push(new ResultsNode(result, type, this)) | |
} | |
last(): ResultsNode { | |
return this.children[this.children.length - 1] | |
} | |
updateResult(result: ResultsNodeResult): void { | |
this.result = result | |
} | |
} | |
class ResultsStateBuilder { | |
topResults: ResultsNode | |
currentParent: ResultsNode | |
specsExecuted: number | |
failureCount: number | |
pendingSpecCount: number | |
constructor() { | |
this.topResults = new ResultsNode({ description: "" }, 'suite', null) | |
this.currentParent = this.topResults | |
this.specsExecuted = 0 | |
this.failureCount = 0 | |
this.pendingSpecCount = 0 | |
} | |
suiteStarted(result: jasmine.SuiteStartedReport): void { | |
this.currentParent.addChild(result, 'suite') | |
this.currentParent = this.currentParent.last() | |
} | |
suiteDone(result: jasmine.SuiteDoneReport): void { | |
this.currentParent.updateResult(result) | |
if (this.currentParent !== this.topResults) { | |
this.currentParent = this.currentParent.parent as ResultsNode | |
} | |
if (result.status === 'failed') { | |
this.failureCount++ | |
} | |
} | |
specStarted(_report: jasmine.SpecStartedReport): void { | |
// Do nothing | |
} | |
specDone(result: jasmine.SpecDoneReport) { | |
this.currentParent.addChild(result, 'spec') | |
if (result.status !== 'excluded') { | |
this.specsExecuted++ | |
} | |
if (result.status === 'failed') { | |
this.failureCount++ | |
} | |
if (result.status === 'pending') { | |
this.pendingSpecCount++ | |
} | |
} | |
} | |
/** | |
* Customized HtmlReporter so that we can create placeholder hyperlinks. | |
*/ | |
export class HtmlReporter implements jasmine.Reporter { | |
config: () => jasmine.EnvConfiguration | |
failures: HTMLElement[] = [] | |
getContainer: () => HTMLElement | |
createElement: (type: 'div' | 'a' | 'ul' | 'span') => HTMLElement | |
createTextNode: (text: string) => Text | |
navigateWithNewParam: any | |
/** | |
* Use to generate href attributes for HTMLAnchorElements. | |
*/ | |
addToExistingQueryString: (key: 'seed' | 'spec', value: string) => string | |
filterSpecs: any | |
symbols: Element | |
deprecationWarnings: string[] = [] | |
summary: HTMLElement | |
htmlReporterMain: HTMLElement | |
totalSpecsDefined: number | |
stateBuilder = new ResultsStateBuilder() | |
constructor(options: jasmine.HtmlReporterOptions) { | |
this.config = function() { | |
return (options.env && options.env.configuration()) || {} | |
} | |
this.getContainer = options.getContainer | |
this.createElement = options.createElement | |
this.createTextNode = options.createTextNode | |
this.navigateWithNewParam = options.navigateWithNewParam || function() { } | |
this.addToExistingQueryString = options.addToExistingQueryString || defaultQueryString | |
this.filterSpecs = options.filterSpecs | |
this.summary = createDom(this, 'div', { className: 'jasmine-summary' }) | |
} | |
initialize() { | |
clearPrior(this) | |
this.htmlReporterMain = createDom(this, | |
'div', | |
{ className: 'jasmine_html-reporter' }, | |
createDom(this, | |
'div', | |
{ className: 'jasmine-banner' }, | |
this.createAnchor({ className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank' }), | |
createDom(this, 'span', { className: 'jasmine-version' }, jasmine.version) | |
), | |
createDom(this, 'ul', { className: 'jasmine-symbol-summary' }), | |
createDom(this, 'div', { className: 'jasmine-alert' }), | |
createDom(this, 'div', { className: 'jasmine-results' }, createDom(this, 'div', { className: 'jasmine-failures' })) | |
) | |
this.getContainer().appendChild(this.htmlReporterMain) | |
} | |
jasmineStarted(options: jasmine.JasmineStartedReport) { | |
this.totalSpecsDefined = options.totalSpecsDefined || 0 | |
} | |
suiteStarted(result: jasmine.SuiteStartedReport) { | |
this.stateBuilder.suiteStarted(result) | |
} | |
suiteDone(result: jasmine.SuiteDoneReport) { | |
this.stateBuilder.suiteDone(result) | |
if (result.status === 'failed') { | |
this.failures.push(failureDom(result, this)) | |
} | |
addDeprecationWarnings(result, this) | |
} | |
specStarted(result: jasmine.SpecStartedReport) { | |
this.stateBuilder.specStarted(result) | |
} | |
specDone(result: jasmine.SpecDoneReport) { | |
this.stateBuilder.specDone(result) | |
if (noExpectations(result)) { | |
const noSpecMsg = `Spec "${result.fullName}" has no expectations.` | |
if (result.status === 'failed') { | |
console.error(noSpecMsg) | |
} else { | |
console.warn(noSpecMsg) | |
} | |
} | |
if (!this.symbols) { | |
this.symbols = find('.jasmine-symbol-summary', this, 'specDone') | |
} | |
this.symbols.appendChild( | |
createDom(this, 'li', { | |
className: this.classNameFromSpecReport(result), | |
id: `spec_${result.id}`, | |
title: result.fullName | |
}) | |
) | |
if (result.status === 'failed') { | |
this.failures.push(failureDom(result, this)) | |
} | |
addDeprecationWarnings(result, this) | |
} | |
classNameFromSpecReport(report: jasmine.SpecDoneReport) { | |
return noExpectations(report) && (report.status === 'passed') ? 'jasmine-empty' : this.classNameFromStatus(report.status) | |
} | |
classNameFromStatus(status: 'excluded' | 'passed' | 'failed' | 'disabled' | 'pending'): 'jasmine-excluded-no-display' | 'jasmine-excluded' | 'jasmine-pending' | 'jasmine-failed' | 'jasmine-' { | |
switch (status) { | |
case 'excluded': | |
case 'passed': { | |
return this.config().hideDisabled ? 'jasmine-excluded-no-display' : 'jasmine-excluded' | |
} | |
case 'pending': return 'jasmine-pending' | |
case 'failed': return 'jasmine-failed' | |
default: { | |
throw new Error(`classNameFromStatus('${status}')`) | |
} | |
} | |
} | |
jasmineDone(doneResult: jasmine.JasmineDoneReport) { | |
const banner = find('.jasmine-banner', this, 'jasmineDone') | |
const alert = find('.jasmine-alert', this, 'jasmineDone') | |
const order = doneResult && doneResult.order | |
let i: number | |
alert.appendChild( | |
createDom(this, 'span', { className: 'jasmine-duration' }, 'finished in ' + doneResult.totalTime / 1000 + 's') | |
) | |
banner.appendChild(optionsMenu(this.config(), this)) | |
if (this.stateBuilder.specsExecuted < this.totalSpecsDefined) { | |
const skippedMessage = | |
'Ran ' + | |
this.stateBuilder.specsExecuted + | |
' of ' + | |
this.totalSpecsDefined + | |
' specs - run all' | |
const skippedLink = this.addToExistingQueryString('spec', '') | |
alert.appendChild( | |
createDom(this, | |
'span', | |
{ className: 'jasmine-bar jasmine-skipped' }, | |
this.createAnchor({ href: skippedLink, title: 'Run all specs' }, skippedMessage) | |
) | |
) | |
} | |
let statusBarMessage = '' | |
let statusBarClassName = 'jasmine-overall-result jasmine-bar ' | |
const globalFailures = (doneResult && doneResult.failedExpectations) || [] | |
const failed = this.stateBuilder.failureCount + globalFailures.length > 0 | |
if (this.totalSpecsDefined > 0 || failed) { | |
statusBarMessage += pluralize('spec', this.stateBuilder.specsExecuted) + ', ' + pluralize('failure', this.stateBuilder.failureCount) | |
if (this.stateBuilder.pendingSpecCount) { | |
statusBarMessage += ', ' + pluralize('pending spec', this.stateBuilder.pendingSpecCount) | |
} | |
} | |
if (doneResult.overallStatus === 'passed') { | |
statusBarClassName += ' jasmine-passed ' | |
} else if (doneResult.overallStatus === 'incomplete') { | |
statusBarClassName += ' jasmine-incomplete ' | |
statusBarMessage = | |
'Incomplete: ' + | |
doneResult.incompleteReason + | |
', ' + | |
statusBarMessage | |
} else { | |
statusBarClassName += ' jasmine-failed ' | |
} | |
if (order && order.random) { | |
const seedBar = createDom(this, | |
'span', | |
{ className: 'jasmine-seed-bar' }, | |
', randomized with seed ', | |
this.createAnchor({ title: 'randomized with seed ' + order.seed, href: seedHref(order.seed, this) }, order.seed) | |
) | |
alert.appendChild(createDom(this, 'span', { className: statusBarClassName }, statusBarMessage, seedBar)) | |
} | |
else { | |
alert.appendChild(createDom(this, 'span', { className: statusBarClassName }, statusBarMessage)) | |
} | |
const errorBarClassName = 'jasmine-bar jasmine-errored' | |
const afterAllMessagePrefix = 'AfterAll ' | |
for (i = 0; i < globalFailures.length; i++) { | |
alert.appendChild( | |
createDom(this, | |
'span', | |
{ className: errorBarClassName }, | |
globalFailureMessage(globalFailures[i]) | |
) | |
) | |
} | |
function globalFailureMessage(failure: { globalErrorType: 'load'; message: string; filename: string; lineno: number }) { | |
if (failure.globalErrorType === 'load') { | |
const prefix = 'Error during loading: ' + failure.message | |
if (failure.filename) { | |
return ( | |
prefix + ' in ' + failure.filename + ' line ' + failure.lineno | |
) | |
} else { | |
return prefix | |
} | |
} else { | |
return afterAllMessagePrefix + failure.message | |
} | |
} | |
addDeprecationWarnings(doneResult, this) | |
const warningBarClassName = 'jasmine-bar jasmine-warning' | |
for (i = 0; i < this.deprecationWarnings.length; i++) { | |
const warning = this.deprecationWarnings[i] | |
alert.appendChild( | |
createDom(this, | |
'span', | |
{ className: warningBarClassName }, | |
'DEPRECATION: ' + warning | |
) | |
) | |
} | |
const results = find('.jasmine-results', this, 'jasmineDone') | |
results.appendChild(this.summary) | |
summaryList(this.stateBuilder.topResults, this.summary, this) | |
if (this.failures.length) { | |
alert.appendChild( | |
createDom(this, | |
'span', | |
{ className: 'jasmine-menu jasmine-bar jasmine-spec-list' }, | |
createDom(this, 'span', {}, 'Spec List | '), | |
this.createAnchor({ className: 'jasmine-failures-menu', href: '#' }, 'Failures') | |
) | |
) | |
alert.appendChild( | |
createDom(this, | |
'span', | |
{ className: 'jasmine-menu jasmine-bar jasmine-failure-list' }, | |
this.createAnchor({ className: 'jasmine-spec-list-menu', href: '#' }, 'Spec List'), | |
createDom(this, 'span', {}, ' | Failures ') | |
) | |
) | |
findAnchor('.jasmine-failures-menu', this).onclick = () => { | |
setMenuModeTo('jasmine-failure-list', this) | |
return false | |
} | |
findAnchor('.jasmine-spec-list-menu', this).onclick = () => { | |
setMenuModeTo('jasmine-spec-list', this) | |
return false | |
} | |
setMenuModeTo('jasmine-failure-list', this) | |
const failureNode = find('.jasmine-failures', this, 'jasmineDone') | |
for (i = 0; i < this.failures.length; i++) { | |
failureNode.appendChild(this.failures[i]) | |
} | |
} | |
} | |
/** | |
* Intercept all calls to create HTMLAnchorElement(s) so that we can create | |
* placeholder hyperlinks that don't navigate anywhere. | |
*/ | |
public createAnchor(attrs: { className?: string; href?: string; title?: string; target?: '_blank' }, text?: string): HTMLAnchorElement { | |
const placeholder: { className?: string; href?: string; title?: string; target?: string } = {} | |
if (attrs.className) { | |
placeholder.className = attrs.className | |
} | |
if (attrs.title) { | |
placeholder.title = attrs.title | |
} | |
if (attrs.target) { | |
placeholder.target = attrs.target | |
} | |
if (attrs.href) { | |
if (attrs.target === '_blank') { | |
placeholder.href = attrs.href | |
} | |
} | |
if (typeof text === 'string') { | |
return createDom(this, 'a', placeholder, text) as HTMLAnchorElement | |
} | |
else { | |
return createDom(this, 'a', placeholder) as HTMLAnchorElement | |
} | |
} | |
} | |
function failureDom(result: jasmine.SuiteDoneReport | jasmine.SpecDoneReport, reporter: HtmlReporter) { | |
const failure = createDom(reporter, | |
'div', | |
{ className: 'jasmine-spec-detail jasmine-failed' }, | |
failureDescription(result, reporter.stateBuilder.currentParent, reporter), | |
createDom(reporter, 'div', { className: 'jasmine-messages' }) | |
) | |
const messages = failure.childNodes[1] | |
for (const expectation of result.failedExpectations) { | |
messages.appendChild(createDom(reporter, 'div', { className: 'jasmine-result-message' }, expectation.message)) | |
messages.appendChild(createDom(reporter, 'div', { className: 'jasmine-stack-trace' }, expectation.stack) | |
) | |
} | |
if (result.failedExpectations.length === 0) { | |
messages.appendChild(createDom(reporter, 'div', { className: 'jasmine-result-message' }, 'Spec has no expectations')) | |
} | |
return failure | |
} | |
function summaryList(resultsTree: ResultsNode, domParent: HTMLElement, reporter: HtmlReporter) { | |
let specListNode: any | |
for (let i = 0; i < resultsTree.children.length; i++) { | |
const resultNode = resultsTree.children[i] | |
if (reporter.filterSpecs && !hasActiveSpec(resultNode)) { | |
continue | |
} | |
if (resultNode.type === 'suite') { | |
const result = resultNode.result as jasmine.SuiteDoneReport | |
const suiteListNode = createDom(reporter, | |
'ul', | |
{ className: 'jasmine-suite', id: 'suite-' + result.id }, | |
createDom(reporter, 'li', { className: 'jasmine-suite-detail jasmine-' + result.status }, | |
reporter.createAnchor({ href: specHref(result, reporter) }, result.description) | |
) | |
) | |
summaryList(resultNode, suiteListNode, reporter) | |
domParent.appendChild(suiteListNode) | |
} | |
if (resultNode.type === 'spec') { | |
const result = resultNode.result as jasmine.SpecDoneReport | |
if (domParent.getAttribute('class') !== 'jasmine-specs') { | |
specListNode = createDom(reporter, 'ul', { className: 'jasmine-specs' }) | |
domParent.appendChild(specListNode) | |
} | |
let specDescription = result.description | |
if (noExpectations(result)) { | |
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription | |
} | |
if (result.status === 'pending' && result.pendingReason !== '') { | |
specDescription = | |
specDescription + | |
' PENDING WITH MESSAGE: ' + | |
result.pendingReason | |
} | |
specListNode.appendChild( | |
createDom(reporter, | |
'li', | |
{ | |
className: 'jasmine-' + result.status, | |
id: 'spec-' + result.id | |
}, | |
reporter.createAnchor({ href: specHref(result, reporter) }, specDescription) | |
) | |
) | |
} | |
} | |
} | |
function optionsMenu(config: jasmine.EnvConfiguration, reporter: HtmlReporter) { | |
const optionsMenuDom = createDom(reporter, | |
'div', | |
{ className: 'jasmine-run-options' }, | |
createDom(reporter, 'span', { className: 'jasmine-trigger' }, 'Options'), | |
createDom(reporter, | |
'div', | |
{ className: 'jasmine-payload' }, | |
createDom(reporter, | |
'div', | |
{ className: 'jasmine-stop-on-failure' }, | |
createDom(reporter, 'input', { | |
className: 'jasmine-fail-fast', | |
id: 'jasmine-fail-fast', | |
type: 'checkbox' | |
}), | |
createDom(reporter, | |
'label', | |
{ className: 'jasmine-label', for: 'jasmine-fail-fast' }, | |
'stop execution on spec failure' | |
) | |
), | |
createDom(reporter, | |
'div', | |
{ className: 'jasmine-throw-failures' }, | |
createDom(reporter, 'input', { | |
className: 'jasmine-throw', | |
id: 'jasmine-throw-failures', | |
type: 'checkbox' | |
}), | |
createDom(reporter, | |
'label', | |
{ className: 'jasmine-label', for: 'jasmine-throw-failures' }, | |
'stop spec on expectation failure' | |
) | |
), | |
createDom(reporter, | |
'div', | |
{ className: 'jasmine-random-order' }, | |
createDom(reporter, 'input', { | |
className: 'jasmine-random', | |
id: 'jasmine-random-order', | |
type: 'checkbox' | |
}), | |
createDom(reporter, | |
'label', | |
{ className: 'jasmine-label', for: 'jasmine-random-order' }, | |
'run tests in random order' | |
) | |
), | |
createDom(reporter, | |
'div', | |
{ className: 'jasmine-hide-disabled' }, | |
createDom(reporter, 'input', { | |
className: 'jasmine-disabled', | |
id: 'jasmine-hide-disabled', | |
type: 'checkbox' | |
}), | |
createDom(reporter, | |
'label', | |
{ className: 'jasmine-label', for: 'jasmine-hide-disabled' }, | |
'hide disabled tests' | |
) | |
) | |
) | |
) | |
const failFastCheckbox: HTMLInputElement = optionsMenuDom.querySelector('#jasmine-fail-fast') as HTMLInputElement | |
failFastCheckbox.checked = config.failFast ? true : false | |
failFastCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('failFast', !config.failFast) | |
} | |
const throwCheckbox: HTMLInputElement = optionsMenuDom.querySelector('#jasmine-throw-failures') as HTMLInputElement | |
throwCheckbox.checked = config.oneFailurePerSpec ? true : false | |
throwCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('throwFailures', !config.oneFailurePerSpec) | |
} | |
const randomCheckbox = optionsMenuDom.querySelector('#jasmine-random-order') as HTMLInputElement | |
randomCheckbox.checked = config.random ? true : false | |
randomCheckbox.onclick = function() { | |
reporter.navigateWithNewParam('random', !config.random) | |
} | |
const hideDisabled = optionsMenuDom.querySelector('#jasmine-hide-disabled') as HTMLInputElement | |
hideDisabled.checked = config.hideDisabled ? true : false | |
hideDisabled.onclick = function() { | |
reporter.navigateWithNewParam('hideDisabled', !config.hideDisabled) | |
} | |
const optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger') as HTMLButtonElement | |
const optionsPayload = optionsMenuDom.querySelector('.jasmine-payload') as HTMLElement | |
const isOpen = /\bjasmine-open\b/ | |
optionsTrigger.onclick = function() { | |
if (isOpen.test(optionsPayload.className)) { | |
optionsPayload.className = optionsPayload.className.replace( | |
isOpen, | |
'' | |
) | |
} else { | |
optionsPayload.className += ' jasmine-open' | |
} | |
} | |
return optionsMenuDom | |
} | |
function failureDescription(result: jasmine.SuiteDoneReport | jasmine.SpecDoneReport, suite: ResultsNode, reporter: HtmlReporter) { | |
const wrapper = createDom(reporter, | |
'div', | |
{ className: 'jasmine-description' }, | |
reporter.createAnchor({ title: result.description, href: specHref(result, reporter) }, result.description) | |
) | |
let suiteLink | |
while (suite && suite.parent) { | |
wrapper.insertBefore(reporter.createTextNode(' > '), wrapper.firstChild) | |
suiteLink = reporter.createAnchor({ href: suiteHref(suite, reporter) }, suite.result.description) | |
wrapper.insertBefore(suiteLink, wrapper.firstChild) | |
suite = suite.parent | |
} | |
return wrapper | |
} | |
function suiteHref(suite: { parent: any; result: any }, reporter: HtmlReporter) { | |
// console.lg(`suiteHref()`) | |
const els = [] | |
while (suite && suite.parent) { | |
els.unshift(suite.result.description) | |
suite = suite.parent | |
} | |
return reporter.addToExistingQueryString('spec', els.join(' ')) | |
} | |
function addDeprecationWarnings(result: jasmine.SpecDoneReport | jasmine.SuiteDoneReport | jasmine.JasmineDoneReport, reporter: HtmlReporter) { | |
if (result && result.deprecationWarnings) { | |
for (let i = 0; i < result.deprecationWarnings.length; i++) { | |
const warning = result.deprecationWarnings[i].message | |
// if (!j$.util.arrayContains(warning)) { | |
reporter.deprecationWarnings.push(warning) | |
// } | |
} | |
} | |
} | |
function findAnchor(selector: string, reporter: HtmlReporter): HTMLAnchorElement { | |
const element = find(selector, reporter, 'findAnchor') | |
if (element instanceof HTMLAnchorElement) { | |
return element | |
} | |
else { | |
throw new Error(`${selector} is not an HTMLAnchorElement`) | |
} | |
} | |
function find(selector: string, reporter: HtmlReporter, _origin: 'findAnchor' | 'clearPrior' | 'specDone' | 'jasmineDone'): Element { | |
// console.lg(`find(selector=${JSON.stringify(selector)}, origin=${origin})`) | |
const selectors = '.jasmine_html-reporter ' + selector | |
const element = reporter.getContainer().querySelector(selectors) | |
if (element) { | |
return element | |
} | |
else { | |
throw new Error(`Unable to find selectors ${JSON.stringify(selectors)}`) | |
} | |
} | |
export function clearPrior(reporter: HtmlReporter) { | |
try { | |
const oldReporter = find('', reporter, 'clearPrior') | |
reporter.getContainer().removeChild(oldReporter) | |
} | |
catch (e) { | |
// We end up here if the oldReporter does not exist. | |
// TODO: Perhaps we also need a find that does not throw? | |
} | |
} | |
function createDom(factory: jasmine.HtmlReporterFactory, type: 'div' | 'a' | 'ul' | 'li' | 'span' | 'label' | 'input', attrs: {}, ..._children: (string | HTMLElement)[]) { | |
const el = factory.createElement(type) | |
for (let i = 3; i < arguments.length; i++) { | |
const child = arguments[i] | |
if (typeof child === 'string') { | |
el.appendChild(factory.createTextNode(child)) | |
} else { | |
if (child) { | |
el.appendChild(child) | |
} | |
} | |
} | |
for (const attr in attrs) { | |
if (attr === 'className') { | |
el[attr] = attrs[attr] | |
} else { | |
el.setAttribute(attr, attrs[attr]) | |
} | |
} | |
return el | |
} | |
function pluralize(singular: string, count: number): string { | |
const word = count === 1 ? singular : singular + 's' | |
return '' + count + ' ' + word | |
} | |
function specHref(result: { fullName: string }, reporter: HtmlReporter) { | |
return reporter.addToExistingQueryString('spec', result.fullName) | |
} | |
function seedHref(seed: string, reporter: HtmlReporter) { | |
return reporter.addToExistingQueryString('seed', seed) | |
} | |
function defaultQueryString(key: 'spec' | 'seed', value: string): string { | |
return '?' + key + '=' + value | |
} | |
function setMenuModeTo(mode: string, reporter: HtmlReporter) { | |
reporter.htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode) | |
} | |
function noExpectations(result: jasmine.SpecDoneReport) { | |
const allExpectations = | |
result.failedExpectations.length + result.passedExpectations.length | |
return (allExpectations === 0 && (result.status === 'passed' || result.status === 'failed')) | |
} | |
function hasActiveSpec(resultNode: ResultsNode): boolean { | |
if (resultNode.type === 'spec') { | |
const result = resultNode.result as (jasmine.SpecDoneReport) | |
if (result.status !== 'excluded') { | |
return true | |
} | |
} | |
if (resultNode.type === 'suite') { | |
const j = resultNode.children.length | |
for (let i = 0; i < j; i++) { | |
if (hasActiveSpec(resultNode.children[i])) { | |
return true | |
} | |
} | |
} | |
return false | |
} |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
</head> | |
<body> | |
Nothing to see here, take a look at the tests | |
</body> | |
</html> |
import { complex } from './Complex' | |
/** | |
* Life, the universe, and everything. | |
*/ | |
export const zero = complex(0, 0) | |
export const one = complex(1, 0) | |
export const i = complex(0, 1) | |
const result = 5 * one + 2 * one * i | |
console.log(`The answer to life, the universe, and everything is not ${result.toString()}`) |
{ | |
"description": "Operator Overloading", | |
"dependencies": { | |
"jasmine": "3.6.0" | |
}, | |
"name": "operator-overloading-complex-numbers", | |
"version": "1.0.0", | |
"author": "David Geo Holmes", | |
"keywords": [ | |
"Operator", | |
"Overloading", | |
"dunder", | |
"operators", | |
"unary", | |
"binary" | |
] | |
} |
{ | |
"hideConfigFiles": false, | |
"hideReferenceFiles": false, | |
"linting": false, | |
"noLoopCheck": false, | |
"operatorOverloading": true, | |
"overrides": [], | |
"references": {}, | |
"showGeneratedFiles": false | |
} |
body { | |
background-color: white; | |
} |
{ | |
"warnings": true, | |
"map": { | |
"jasmine": "https://cdn.jsdelivr.net/npm/[email protected]/package.json" | |
} | |
} |
<!DOCTYPE html> | |
<html> | |
<head> | |
</head> | |
<body> | |
</body> | |
</html> |
import { HtmlReporter } from './HtmlReporter' | |
import { complexSpec } from './Complex.spec' | |
/** | |
* These configuration parameters determine how the tests are executed. | |
*/ | |
const config: jasmine.EnvConfiguration = { | |
random: false, | |
failFast: false, | |
failSpecWithNoExpectations: false, | |
oneFailurePerSpec: false, | |
hideDisabled: false, | |
specFilter: void 0, | |
promise: void 0 | |
} | |
const specifications: string[] = [] | |
function getContainer(): HTMLElement { | |
const element = document.body | |
return element | |
} | |
function onChangeOption(key: 'failFast' | 'throwFailures' | 'random' | 'hideDisabled', value: string): void { | |
switch (key) { | |
case 'failFast': { | |
config.failFast = !config.failFast | |
break | |
} | |
case 'throwFailures': { | |
config.oneFailurePerSpec = !config.oneFailurePerSpec | |
break | |
} | |
case 'random': { | |
config.random = !config.random | |
break | |
} | |
case 'hideDisabled': { | |
config.hideDisabled = !config.hideDisabled | |
break | |
} | |
default: { | |
console.warn(`navigateWithNewParam(key=${key}, value=${JSON.stringify(value)}`) | |
} | |
} | |
runTests() | |
} | |
/** | |
* Generate an href for an HTMLAnchorElement. | |
*/ | |
function addSpec(value: string): string { | |
specifications.push(value) | |
return '' | |
} | |
/** | |
* Generate an href for an HTMLAnchorElement. | |
*/ | |
function addSeed(_seed: number): string { | |
// console.info(`onSeed(seed=${seed})`) | |
// config.seed = value | |
return '' | |
} | |
function runTests() { | |
const jasmineCore: jasmine.Jasmine = jasmineRequire.core(jasmineRequire) | |
// We shouldn't need to do this... | |
jasmineRequire.html(jasmineCore) | |
const env = jasmineCore.getEnv() | |
// Build the collection of functions that we use in our specs and put them in the global namespace. | |
const jasmineInterface = jasmineRequire.interface(jasmineCore, env) | |
/** | |
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. | |
* For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. | |
*/ | |
extend(window, jasmineInterface) | |
// const catchingExceptions = queryString.getParam("catch") | |
// env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions) | |
const htmlReporter = new /*jasmine.*/HtmlReporter({ | |
env: env, | |
addToExistingQueryString: function(key: 'seed' | 'spec', value: string): string { | |
switch (key) { | |
case 'spec': { | |
return addSpec(value) | |
break | |
} | |
case 'seed': { | |
return addSeed(parseInt(value, 10)) | |
break | |
} | |
default: { | |
throw new Error(`Unknown key: ${key}`) | |
} | |
} | |
}, | |
navigateWithNewParam: onChangeOption, | |
getContainer, | |
createElement: function(): HTMLElement { | |
return document.createElement.apply(document, arguments) | |
}, | |
createTextNode: function(): Text { | |
return document.createTextNode.apply(document, arguments) | |
}, | |
timer: new jasmine.Timer(), | |
filterSpecs: true // Will only be true if query string contains 'spec'. | |
}) | |
env.addReporter(jasmineInterface.jsApiReporter) | |
env.addReporter(htmlReporter) | |
env.configure(config) | |
htmlReporter.initialize() | |
// Declare your specification definitions here. | |
describe("Complex", complexSpec) | |
env.execute() | |
} | |
runTests() | |
/* | |
* Helper function for extending the properties on objects. | |
*/ | |
function extend<T>(destination: T, source: any): T { | |
for (const property in source) { | |
if (source.hasOwnProperty(property)) { | |
(<any> destination)[property] = source[property] | |
} | |
} | |
return destination | |
} |
{ | |
"allowJs": true, | |
"checkJs": true, | |
"declaration": true, | |
"emitDecoratorMetadata": true, | |
"experimentalDecorators": true, | |
"jsx": "react", | |
"module": "system", | |
"noImplicitAny": true, | |
"noImplicitReturns": true, | |
"noImplicitThis": true, | |
"noUnusedLocals": true, | |
"noUnusedParameters": true, | |
"preserveConstEnums": true, | |
"removeComments": false, | |
"skipLibCheck": true, | |
"sourceMap": true, | |
"strictNullChecks": true, | |
"suppressImplicitAnyIndexErrors": true, | |
"target": "es5", | |
"traceResolution": true | |
} |
{ | |
"rules": { | |
"array-type": [ | |
true, | |
"array" | |
], | |
"curly": false, | |
"comment-format": [ | |
true, | |
"check-space" | |
], | |
"eofline": true, | |
"forin": true, | |
"jsdoc-format": true, | |
"new-parens": true, | |
"no-conditional-assignment": false, | |
"no-consecutive-blank-lines": true, | |
"no-construct": true, | |
"no-for-in-array": true, | |
"no-inferrable-types": [ | |
true | |
], | |
"no-magic-numbers": false, | |
"no-shadowed-variable": true, | |
"no-string-throw": true, | |
"no-trailing-whitespace": [ | |
true, | |
"ignore-jsdoc" | |
], | |
"no-var-keyword": true, | |
"one-variable-per-declaration": [ | |
true, | |
"ignore-for-loop" | |
], | |
"prefer-const": true, | |
"prefer-for-of": true, | |
"prefer-function-over-method": false, | |
"prefer-method-signature": true, | |
"radix": true, | |
"semicolon": [ | |
true, | |
"never" | |
], | |
"trailing-comma": [ | |
true, | |
{ | |
"multiline": "never", | |
"singleline": "never" | |
} | |
], | |
"triple-equals": true, | |
"use-isnan": true | |
} | |
} |
{ | |
"warnings": true, | |
"map": { | |
"jasmine": "https://cdn.jsdelivr.net/npm/@types/[email protected]/package.json" | |
} | |
} |