Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e5d947faa | ||
|
|
c2603efeb4 | ||
|
|
fbec3cc230 |
19
.travis.yml
19
.travis.yml
@@ -22,6 +22,9 @@ addons:
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v0.12.18"
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v4"
|
||||
@@ -31,10 +34,6 @@ matrix:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v9"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.12"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.11"
|
||||
@@ -47,10 +46,6 @@ matrix:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.9"
|
||||
- SAUCE_BROWSER_VERSION=7
|
||||
- env:
|
||||
- JASMINE_BROWSER="MicrosoftEdge"
|
||||
- SAUCE_OS="Windows 10"
|
||||
- SAUCE_BROWSER_VERSION="15"
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8.1"
|
||||
@@ -59,6 +54,14 @@ matrix:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="chrome"
|
||||
- SAUCE_OS="Linux"
|
||||
|
||||
4
Gemfile
4
Gemfile
@@ -1,9 +1,9 @@
|
||||
source 'https://rubygems.org'
|
||||
gem "jasmine", :git => 'https://github.com/jasmine/jasmine-gem.git'
|
||||
gem "jasmine", :git => 'https://github.com/jasmine/jasmine-gem.git', :tag => 'v2.99.0'
|
||||
# gem "jasmine", path: "../jasmine-gem"
|
||||
|
||||
gemspec
|
||||
|
||||
gem "jasmine_selenium_runner", :github => 'jasmine/jasmine_selenium_runner'
|
||||
gem "jasmine_selenium_runner", :github => 'jasmine/jasmine_selenium_runner', :tag => 'v2.4.0'
|
||||
|
||||
gem "anchorman"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
recursive-include . *.py
|
||||
prune node_modules
|
||||
include lib/jasmine-core/*.js
|
||||
include lib/jasmine-core/*.css
|
||||
include images/*.png
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
[](https://travis-ci.org/jasmine/jasmine)
|
||||
|
||||
# A JavaScript Testing Framework
|
||||
=======
|
||||
|
||||
**A JavaScript Testing Framework**
|
||||
|
||||
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
|
||||
|
||||
@@ -50,7 +52,7 @@ Add the following to your HTML file:
|
||||
|
||||
## Supported environments
|
||||
|
||||
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, Microsoft Edge, and new Internet Explorer) as well as nodejs. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
|
||||
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
@@ -2,6 +2,7 @@ var standaloneLibDir = "lib/jasmine-" + jasmineVersion;
|
||||
|
||||
function root(path) { return "./" + path; }
|
||||
function libJasmineCore(path) { return root("lib/jasmine-core/" + path); }
|
||||
function libConsole() { return "lib/console/" }
|
||||
function dist(path) { return root("dist/" + path); }
|
||||
|
||||
module.exports = {
|
||||
@@ -28,6 +29,14 @@ module.exports = {
|
||||
expand: true,
|
||||
cwd: libJasmineCore("")
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"console.js"
|
||||
],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: libConsole()
|
||||
},
|
||||
{
|
||||
src: [ "boot.js" ],
|
||||
dest: standaloneLibDir,
|
||||
|
||||
@@ -15,8 +15,7 @@ module.exports = {
|
||||
'src/html/HtmlReporter.js',
|
||||
'src/html/HtmlSpecFilter.js',
|
||||
'src/html/ResultsNode.js',
|
||||
'src/html/QueryString.js',
|
||||
'src/html/**/*.js'
|
||||
'src/html/QueryString.js'
|
||||
],
|
||||
dest: 'lib/jasmine-core/jasmine-html.js'
|
||||
},
|
||||
@@ -45,6 +44,13 @@ module.exports = {
|
||||
src: ['lib/jasmine-core/boot/node_boot.js'],
|
||||
dest: 'lib/jasmine-core/node_boot.js'
|
||||
},
|
||||
console: {
|
||||
src: [
|
||||
'src/console/requireConsole.js',
|
||||
'src/console/ConsoleReporter.js'
|
||||
],
|
||||
dest: 'lib/console/console.js'
|
||||
},
|
||||
options: {
|
||||
banner: license(),
|
||||
process: {
|
||||
|
||||
190
lib/console/console.js
Normal file
190
lib/console/console.js
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
Copyright (c) 2008-2018 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
function getJasmineRequireObj() {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
return exports;
|
||||
} else {
|
||||
window.jasmineRequire = window.jasmineRequire || {};
|
||||
return window.jasmineRequire;
|
||||
}
|
||||
}
|
||||
|
||||
getJasmineRequireObj().console = function(jRequire, j$) {
|
||||
j$.ConsoleReporter = jRequire.ConsoleReporter();
|
||||
};
|
||||
|
||||
getJasmineRequireObj().ConsoleReporter = function() {
|
||||
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
function ConsoleReporter(options) {
|
||||
var print = options.print,
|
||||
showColors = options.showColors || false,
|
||||
onComplete = options.onComplete || function() {},
|
||||
timer = options.timer || noopTimer,
|
||||
specCount,
|
||||
failureCount,
|
||||
failedSpecs = [],
|
||||
pendingCount,
|
||||
ansi = {
|
||||
green: '\x1B[32m',
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
print('ConsoleReporter is deprecated and will be removed in a future version.');
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
failureCount = 0;
|
||||
pendingCount = 0;
|
||||
print('Started');
|
||||
printNewline();
|
||||
timer.start();
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
printNewline();
|
||||
for (var i = 0; i < failedSpecs.length; i++) {
|
||||
specFailureDetails(failedSpecs[i]);
|
||||
}
|
||||
|
||||
if(specCount > 0) {
|
||||
printNewline();
|
||||
|
||||
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
|
||||
failureCount + ' ' + plural('failure', failureCount);
|
||||
|
||||
if (pendingCount) {
|
||||
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
|
||||
}
|
||||
|
||||
print(specCounts);
|
||||
} else {
|
||||
print('No specs found');
|
||||
}
|
||||
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
this.specDone = function(result) {
|
||||
specCount++;
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingCount++;
|
||||
print(colored('yellow', '*'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'passed') {
|
||||
print(colored('green', '.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
failedSpecs.push(result);
|
||||
print(colored('red', 'F'));
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
print('\n');
|
||||
}
|
||||
|
||||
function colored(color, str) {
|
||||
return showColors ? (ansi[color] + str + ansi.none) : str;
|
||||
}
|
||||
|
||||
function plural(str, count) {
|
||||
return count == 1 ? str : str + 's';
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) {
|
||||
arr.push(thing);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
function indent(str, spaces) {
|
||||
var lines = (str || '').split('\n');
|
||||
var newArr = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
newArr.push(repeat(' ', spaces).join('') + lines[i]);
|
||||
}
|
||||
return newArr.join('\n');
|
||||
}
|
||||
|
||||
function specFailureDetails(result) {
|
||||
printNewline();
|
||||
print(result.fullName);
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var failedExpectation = result.failedExpectations[i];
|
||||
printNewline();
|
||||
print(indent(failedExpectation.message, 2));
|
||||
print(indent(failedExpectation.stack, 2));
|
||||
}
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
};
|
||||
@@ -73,17 +73,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var filterSpecs = !!queryString.getParam("spec");
|
||||
|
||||
var stoppingOnSpecFailure = queryString.getParam("failFast");
|
||||
env.stopOnSpecFailure(stoppingOnSpecFailure);
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
|
||||
if (random !== undefined && random !== "") {
|
||||
env.randomizeTests(random);
|
||||
}
|
||||
env.randomizeTests(random);
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
@@ -96,7 +93,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
|
||||
@@ -51,17 +51,14 @@
|
||||
|
||||
var filterSpecs = !!queryString.getParam("spec");
|
||||
|
||||
var stoppingOnSpecFailure = queryString.getParam("failFast");
|
||||
env.stopOnSpecFailure(stoppingOnSpecFailure);
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
|
||||
if (random !== undefined && random !== "") {
|
||||
env.randomizeTests(random);
|
||||
}
|
||||
env.randomizeTests(random);
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
@@ -74,7 +71,9 @@
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
module.exports = function(jasmineRequire) {
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../console/console.js');
|
||||
consoleFns.console(consoleFns, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
@@ -25,7 +25,6 @@ jasmineRequire.html = function(j$) {
|
||||
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
|
||||
j$.QueryString = jasmineRequire.QueryString();
|
||||
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
|
||||
j$.matchers.toHaveClass = jasmineRequire.toHaveClass(j$);
|
||||
};
|
||||
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
@@ -49,14 +48,9 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.suiteDone = function(result) {
|
||||
this.currentParent.updateResult(result);
|
||||
if (this.currentParent !== this.topResults) {
|
||||
this.currentParent = this.currentParent.parent;
|
||||
}
|
||||
|
||||
if (result.status === 'failed') {
|
||||
this.failureCount++;
|
||||
}
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specStarted = function(result) {
|
||||
@@ -65,7 +59,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
ResultsStateBuilder.prototype.specDone = function(result) {
|
||||
this.currentParent.addChild(result, 'spec');
|
||||
|
||||
if (result.status !== 'excluded') {
|
||||
if (result.status !== 'disabled') {
|
||||
this.specsExecuted++;
|
||||
}
|
||||
|
||||
@@ -85,12 +79,16 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
getContainer = options.getContainer,
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
navigateWithNewParam = options.navigateWithNewParam || function() {},
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
onRandomClick = options.onRandomClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
filterSpecs = options.filterSpecs,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [],
|
||||
deprecationWarnings = [];
|
||||
|
||||
this.initialize = function() {
|
||||
@@ -124,11 +122,11 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
stateBuilder.suiteDone(result);
|
||||
|
||||
if (result.status === 'failed') {
|
||||
failures.push(failureDom(result));
|
||||
if (result.status == 'failed') {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
stateBuilder.suiteDone(result);
|
||||
addDeprecationWarnings(result);
|
||||
};
|
||||
|
||||
@@ -155,8 +153,23 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
));
|
||||
|
||||
if (result.status === 'failed') {
|
||||
failures.push(failureDom(result));
|
||||
if (result.status == 'failed') {
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
|
||||
),
|
||||
createDom('div', {className: 'jasmine-messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
addDeprecationWarnings(result);
|
||||
@@ -168,7 +181,59 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
var order = doneResult && doneResult.order;
|
||||
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
banner.appendChild(optionsMenu(env));
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-exceptions' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-raise',
|
||||
id: 'jasmine-raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
));
|
||||
|
||||
var raiseCheckbox = find('#jasmine-raise-exceptions');
|
||||
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var randomCheckbox = find('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = onRandomClick;
|
||||
|
||||
var optionsMenu = find('.jasmine-run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
|
||||
isOpen = /\bjasmine-open\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' jasmine-open';
|
||||
}
|
||||
};
|
||||
|
||||
if (stateBuilder.specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + stateBuilder.specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
@@ -180,22 +245,15 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
);
|
||||
}
|
||||
var statusBarMessage = '';
|
||||
var statusBarClassName = 'jasmine-overall-result jasmine-bar ';
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
var failed = stateBuilder.failureCount + globalFailures.length > 0;
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
|
||||
if (totalSpecsDefined > 0 || failed) {
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', stateBuilder.specsExecuted) + ', ' + pluralize('failure', stateBuilder.failureCount);
|
||||
if (stateBuilder.pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', stateBuilder.pendingSpecCount); }
|
||||
}
|
||||
|
||||
if (doneResult.overallStatus === 'passed') {
|
||||
statusBarClassName += ' jasmine-passed ';
|
||||
} else if (doneResult.overallStatus === 'incomplete') {
|
||||
statusBarClassName += ' jasmine-incomplete ';
|
||||
statusBarMessage = 'Incomplete: ' + doneResult.incompleteReason + ', ' + statusBarMessage;
|
||||
statusBarClassName += (stateBuilder.failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
} else {
|
||||
statusBarClassName += ' jasmine-failed ';
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
}
|
||||
|
||||
var seedBar;
|
||||
@@ -209,24 +267,19 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
|
||||
|
||||
var errorBarClassName = 'jasmine-bar jasmine-errored';
|
||||
var afterAllMessagePrefix = 'AfterAll ';
|
||||
var errorBarMessagePrefix = 'AfterAll ';
|
||||
|
||||
for(i = 0; i < globalFailures.length; i++) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, globalFailureMessage(globalFailures[i])));
|
||||
for(var i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
|
||||
}
|
||||
}
|
||||
|
||||
function globalFailureMessage(failure) {
|
||||
if (failure.globalErrorType === 'load') {
|
||||
var 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;
|
||||
}
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
for(i = 0; i < globalFailures.length; i++) {
|
||||
var failure = globalFailures[i];
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
|
||||
}
|
||||
|
||||
addDeprecationWarnings(doneResult);
|
||||
@@ -242,6 +295,47 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
summaryList(stateBuilder.topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (filterSpecs && !hasActiveSpec(resultNode)) {
|
||||
continue;
|
||||
}
|
||||
if (resultNode.type == 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-suite-detail'},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type == 'spec') {
|
||||
if (domParent.getAttribute('class') != 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
|
||||
@@ -270,153 +364,6 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
return this;
|
||||
|
||||
function failureDom(result) {
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
failureDescription(result, stateBuilder.currentParent),
|
||||
createDom('div', {className: 'jasmine-messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
return failure;
|
||||
}
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (filterSpecs && !hasActiveSpec(resultNode)) {
|
||||
continue;
|
||||
}
|
||||
if (resultNode.type === 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-suite-detail jasmine-' + resultNode.result.status},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type === 'spec') {
|
||||
if (domParent.getAttribute('class') !== 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function optionsMenu(env) {
|
||||
var optionsMenuDom = createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-stop-on-failure' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-fail-fast',
|
||||
id: 'jasmine-fail-fast',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-fail-fast' }, 'stop execution on spec failure')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
);
|
||||
|
||||
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
|
||||
failFastCheckbox.checked = env.stoppingOnSpecFailure();
|
||||
failFastCheckbox.onclick = function() {
|
||||
navigateWithNewParam('failFast', !env.stoppingOnSpecFailure());
|
||||
};
|
||||
|
||||
var throwCheckbox = optionsMenuDom.querySelector('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = function() {
|
||||
navigateWithNewParam('throwFailures', !env.throwingExpectationFailures());
|
||||
};
|
||||
|
||||
var randomCheckbox = optionsMenuDom.querySelector('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = function() {
|
||||
navigateWithNewParam('random', !env.randomTests());
|
||||
};
|
||||
|
||||
var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'),
|
||||
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) {
|
||||
var wrapper = createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.description, href: specHref(result)}, result.description)
|
||||
);
|
||||
var suiteLink;
|
||||
|
||||
while (suite && suite.parent) {
|
||||
wrapper.insertBefore(createTextNode(' > '), wrapper.firstChild);
|
||||
suiteLink = createDom('a', {href: suiteHref(suite)}, suite.result.description);
|
||||
wrapper.insertBefore(suiteLink, wrapper.firstChild);
|
||||
|
||||
suite = suite.parent;
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function suiteHref(suite) {
|
||||
var els = [];
|
||||
|
||||
while (suite && suite.parent) {
|
||||
els.unshift(suite.result.description);
|
||||
suite = suite.parent;
|
||||
}
|
||||
|
||||
return addToExistingQueryString('spec', els.join(' '));
|
||||
}
|
||||
|
||||
function addDeprecationWarnings(result) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for(var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
@@ -495,7 +442,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function hasActiveSpec(resultNode) {
|
||||
if (resultNode.type == 'spec' && resultNode.result.status != 'excluded') {
|
||||
if (resultNode.type == 'spec' && resultNode.result.status != 'disabled') {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -540,10 +487,6 @@ jasmineRequire.ResultsNode = function() {
|
||||
this.last = function() {
|
||||
return this.children[this.children.length - 1];
|
||||
};
|
||||
|
||||
this.updateResult = function(result) {
|
||||
this.result = result;
|
||||
};
|
||||
}
|
||||
|
||||
return ResultsNode;
|
||||
@@ -600,37 +543,3 @@ jasmineRequire.QueryString = function() {
|
||||
|
||||
return QueryString;
|
||||
};
|
||||
|
||||
jasmineRequire.toHaveClass = function(j$) {
|
||||
/**
|
||||
* {@link expect} the actual value to be a DOM element that has the expected class
|
||||
* @function
|
||||
* @name matchers#toHaveClass
|
||||
* @param {Object} expected - The class name to test for
|
||||
* @example
|
||||
* var el = document.createElement('div');
|
||||
* el.className = 'foo bar baz';
|
||||
* expect(el).toHaveClass('bar');
|
||||
*/
|
||||
function toHaveClass(util, customEqualityTesters) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
if (!isElement(actual)) {
|
||||
throw new Error(j$.pp(actual) + ' is not a DOM element');
|
||||
}
|
||||
|
||||
return {
|
||||
pass: actual.classList.contains(expected)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isElement(maybeEl) {
|
||||
return maybeEl &&
|
||||
maybeEl.classList &&
|
||||
j$.isFunction_(maybeEl.classList.contains);
|
||||
}
|
||||
|
||||
return toHaveClass;
|
||||
};
|
||||
|
||||
@@ -18,8 +18,8 @@ body { overflow-y: scroll; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed:before { color: #007069; content: "\02022"; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed { line-height: 9px; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-excluded { font-size: 14px; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-excluded:before { color: #bababa; content: "\02022"; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled { font-size: 14px; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled:before { color: #bababa; content: "\02022"; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending { line-height: 17px; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending:before { color: #ba9d37; content: "*"; }
|
||||
.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty { font-size: 14px; }
|
||||
@@ -29,17 +29,11 @@ body { overflow-y: scroll; }
|
||||
.jasmine_html-reporter .jasmine-run-options .jasmine-payload { position: absolute; display: none; right: -1px; border: 1px solid #8a4182; background-color: #eee; white-space: nowrap; padding: 4px 8px; }
|
||||
.jasmine_html-reporter .jasmine-run-options .jasmine-payload.jasmine-open { display: block; }
|
||||
.jasmine_html-reporter .jasmine-bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-failed, .jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; border-bottom: 1px solid #eee; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-failed { background-color: #ca3a11; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-incomplete { background-color: #bababa; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; }
|
||||
<<<<<<< HEAD
|
||||
||||||| merged common ancestors
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
|
||||
=======
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; color: #333; }
|
||||
>>>>>>> master
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; }
|
||||
.jasmine_html-reporter .jasmine-bar a { color: white; }
|
||||
@@ -53,12 +47,12 @@ body { overflow-y: scroll; }
|
||||
.jasmine_html-reporter .jasmine-summary li.jasmine-failed a { color: #ca3a11; }
|
||||
.jasmine_html-reporter .jasmine-summary li.jasmine-empty a { color: #ba9d37; }
|
||||
.jasmine_html-reporter .jasmine-summary li.jasmine-pending a { color: #ba9d37; }
|
||||
.jasmine_html-reporter .jasmine-summary li.jasmine-excluded a { color: #bababa; }
|
||||
.jasmine_html-reporter .jasmine-summary li.jasmine-disabled a { color: #bababa; }
|
||||
.jasmine_html-reporter .jasmine-description + .jasmine-suite { margin-top: 0; }
|
||||
.jasmine_html-reporter .jasmine-suite { margin-top: 14px; }
|
||||
.jasmine_html-reporter .jasmine-suite a { color: #333; }
|
||||
.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail { margin-bottom: 28px; }
|
||||
.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description { background-color: #ca3a11; color: white; }
|
||||
.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description { background-color: #ca3a11; }
|
||||
.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description a { color: white; }
|
||||
.jasmine_html-reporter .jasmine-result-message { padding-top: 14px; color: #333; white-space: pre; }
|
||||
.jasmine_html-reporter .jasmine-result-message span.jasmine-result { display: block; }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
module.exports = function(jasmineRequire) {
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../console/console.js');
|
||||
consoleFns.console(consoleFns, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "3.0.0"
|
||||
VERSION = "2.99.1"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "3.0.0",
|
||||
"version": "2.99.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
# Jasmine-Core 3.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
Jasmine 3.0 is a major release of Jasmine, and as such includes some breaking changes in addition to various new features.
|
||||
|
||||
There is also a 2.99 release of Jasmine that will present deprecation warnings for suites that will encounter different behavior in 3.0.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
* Replace old "catch exceptions" logic with proper fail fast with error reporting
|
||||
- Fixes [#414](https://github.com/jasmine/jasmine/issues/414)
|
||||
- Fixes [jasmine/jasmine-npm#16](https://github.com/jasmine/jasmine/jasmine-npm/issues/16)
|
||||
|
||||
* Detect an Error passed to `done` and add an expectation failure
|
||||
- Fixes [#567](https://github.com/jasmine/jasmine/issues/567)
|
||||
|
||||
* Unify status for xdescribe and xit
|
||||
- Ensure *All's only execute if at least one child will run
|
||||
- Specs will report a status of `excluded` instead of disabled
|
||||
- Fixes [#1418](https://github.com/jasmine/jasmine/issues/1418)
|
||||
|
||||
* Suite level errors all report the same way (on suiteDone)
|
||||
|
||||
* Refactor QueueRunner and remove references to functions that Jasmine is done with
|
||||
|
||||
* expect(null).toEqual(jasmine.any(Object)) no longer passes
|
||||
- Fixes [#1255](https://github.com/jasmine/jasmine/issues/1255)
|
||||
|
||||
* Default to running tests in random order
|
||||
|
||||
## Changes
|
||||
|
||||
* Remove node modules from python wheel, and update languages
|
||||
|
||||
* Allow reporter callbacks to be asynchronous
|
||||
- Fixes [#842](https://github.com/jasmine/jasmine/issues/842)
|
||||
|
||||
* Allow adding custom spy strategies
|
||||
|
||||
* Add the ability to specify the strategy to use for a spy based on which parameters are passed
|
||||
|
||||
* Added links to re-run the suites containing a failing spec
|
||||
|
||||
* Added a toHaveClass matcher
|
||||
|
||||
* More informative pretty-printing of DOM elements
|
||||
|
||||
* Allow jasmine-npm to handle its own load errors
|
||||
|
||||
* Treat random= as a no-op rather than disabling randomization
|
||||
|
||||
* Use prototype for spy strategy for better memory management
|
||||
|
||||
* Remove console.js altogether
|
||||
|
||||
* Add safari 10 and update readme to include edge
|
||||
|
||||
* Determine overall status in core, not reporters
|
||||
|
||||
* Filter Jasmine frames from stack traces
|
||||
|
||||
* Treat afterAll errors at any level as failures
|
||||
|
||||
* Improved reporting of load errors and afterAll errors
|
||||
- Pass file and line number to reporters when present
|
||||
- Show file and line number in the HTML reporter when present
|
||||
- Visually separate adjacent errors in the HTML reporter
|
||||
|
||||
* Report loading errors as loading errors, not afterAll errors
|
||||
|
||||
* HTML reporter reports overall failure if there are any global errors
|
||||
|
||||
* Fail if error events (e.g. syntax errors) occur during loading
|
||||
|
||||
* Allow use of a predicate function to validate thrown exceptions
|
||||
|
||||
* Check truthiness of toThrowError args, not arg count
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
3
setup.py
3
setup.py
@@ -23,6 +23,9 @@ setup(
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
|
||||
270
spec/console/ConsoleReporterSpec.js
Normal file
270
spec/console/ConsoleReporterSpec.js
Normal file
@@ -0,0 +1,270 @@
|
||||
describe("ConsoleReporter", function() {
|
||||
var out;
|
||||
|
||||
beforeEach(function() {
|
||||
out = (function() {
|
||||
var output = "";
|
||||
return {
|
||||
print: function(str) {
|
||||
output += str;
|
||||
},
|
||||
getOutput: function() {
|
||||
return output.replace('ConsoleReporter is deprecated and will be removed in a future version.', '');
|
||||
},
|
||||
clear: function() {
|
||||
output = "";
|
||||
}
|
||||
};
|
||||
}());
|
||||
});
|
||||
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
it("starts the provided timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start']),
|
||||
reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual(".");
|
||||
});
|
||||
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "disabled"});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "failed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("F");
|
||||
});
|
||||
|
||||
it("reports a pending spec as a '*'", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "pending"});
|
||||
|
||||
expect(out.getOutput()).toEqual("*");
|
||||
});
|
||||
|
||||
it("alerts user if there are no specs", function(){
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
out.clear();
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/No specs found/);
|
||||
});
|
||||
|
||||
it("reports a summary when done (singular spec and time)", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
timerSpy.elapsed.and.returnValue(1000);
|
||||
|
||||
out.clear();
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/1 spec, 0 failures/);
|
||||
expect(out.getOutput()).not.toMatch(/0 pending specs/);
|
||||
expect(out.getOutput()).toMatch("Finished in 1 second\n");
|
||||
});
|
||||
|
||||
it("reports a summary when done (pluralized specs and seconds)", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.specDone({status: "pending"});
|
||||
reporter.specDone({
|
||||
status: "failed",
|
||||
description: "with a failing spec",
|
||||
fullName: "A suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
passed: false,
|
||||
message: "Expected true to be false.",
|
||||
expected: false,
|
||||
actual: true,
|
||||
stack: "foo\nbar\nbaz"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
out.clear();
|
||||
|
||||
timerSpy.elapsed.and.returnValue(100);
|
||||
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/3 specs, 1 failure, 1 pending spec/);
|
||||
expect(out.getOutput()).toMatch("Finished in 0.1 seconds\n");
|
||||
});
|
||||
|
||||
it("reports a summary when done that includes stack traces for a failing suite", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.specDone({
|
||||
status: "failed",
|
||||
description: "with a failing spec",
|
||||
fullName: "A suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
passed: false,
|
||||
message: "Expected true to be false.",
|
||||
expected: false,
|
||||
actual: true,
|
||||
stack: "foo bar baz"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
out.clear();
|
||||
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/true to be false/);
|
||||
expect(out.getOutput()).toMatch(/foo bar baz/);
|
||||
});
|
||||
|
||||
describe('onComplete callback', function(){
|
||||
var onComplete, reporter;
|
||||
|
||||
beforeEach(function() {
|
||||
onComplete = jasmine.createSpy('onComplete');
|
||||
reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
onComplete: onComplete
|
||||
});
|
||||
reporter.jasmineStarted();
|
||||
});
|
||||
|
||||
it("is called when the suite is done", function() {
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('calls it with false if there are spec failures', function() {
|
||||
reporter.specDone({status: "failed", failedExpectations: []});
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('calls it with false if there are suite failures', function() {
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.suiteDone({failedExpectations: [{ message: 'bananas' }] });
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with color", function() {
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("\x1B[32m.\x1B[0m");
|
||||
});
|
||||
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: 'disabled'});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: 'failed'});
|
||||
|
||||
expect(out.getOutput()).toEqual("\x1B[31mF\x1B[0m");
|
||||
});
|
||||
|
||||
it("displays all afterAll exceptions", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'After All Exception' }] });
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'Some Other Exception' }] });
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/After All Exception/);
|
||||
expect(out.getOutput()).toMatch(/Some Other Exception/);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -411,6 +411,50 @@ describe("Clock", function() {
|
||||
clock.tick(50);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("on IE < 9, fails if extra args are passed to fake clock", function() {
|
||||
//fail, because this would break in IE9.
|
||||
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
|
||||
fakeSetInterval = jasmine.createSpy('setInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fakeGlobal = {
|
||||
setTimeout: fakeSetTimeout,
|
||||
setInterval: fakeSetInterval
|
||||
},
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeout = new clock.FakeTimeout();
|
||||
|
||||
fakeSetTimeout.apply = null;
|
||||
fakeSetInterval.apply = null;
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.setTimeout(fn, 0);
|
||||
|
||||
if (!NODE_JS) {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, []);
|
||||
} else {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], false, timeout);
|
||||
}
|
||||
|
||||
expect(function() {
|
||||
clock.setTimeout(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
|
||||
clock.setInterval(fn, 0);
|
||||
|
||||
if (!NODE_JS) {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true);
|
||||
} else {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true, timeout);
|
||||
}
|
||||
|
||||
expect(function() {
|
||||
clock.setInterval(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Clock (acceptance)", function() {
|
||||
|
||||
@@ -47,72 +47,15 @@ describe("ExceptionFormatter", function() {
|
||||
});
|
||||
|
||||
describe("#stack", function() {
|
||||
it("formats stack traces", function() {
|
||||
it("formats stack traces from Webkit, Firefox, node.js or IE10+", function() {
|
||||
if (jasmine.getEnv().ieVersion < 10 || jasmine.getEnv().safariVersion < 6) { return; }
|
||||
|
||||
var error;
|
||||
try { throw new Error("an error") } catch(e) { error = e; }
|
||||
|
||||
expect(new jasmineUnderTest.ExceptionFormatter().stack(error)).toMatch(/ExceptionFormatterSpec\.js.*\d+/)
|
||||
});
|
||||
|
||||
it("filters Jasmine stack frames from V8 style traces", function() {
|
||||
var error = {
|
||||
stack: 'Error: nope\n' +
|
||||
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' at fn2 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
|
||||
' at fn3 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
|
||||
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)\n'
|
||||
};
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
expect(result).toEqual('Error: nope\n' +
|
||||
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' at <Jasmine>\n' +
|
||||
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)'
|
||||
);
|
||||
});
|
||||
|
||||
it("filters Jamine stack frames from Webkit style traces", function() {
|
||||
var error = {
|
||||
stack: 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
|
||||
'fn1@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
|
||||
'fn2@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
|
||||
};
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
expect(result).toEqual(
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
|
||||
'<Jasmine>\n' +
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
|
||||
);
|
||||
});
|
||||
|
||||
it("filters Jasmine stack frames in this environment", function() {
|
||||
var error, i;
|
||||
try { throw new Error("an error"); } catch(e) { error = e; }
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: jasmine.util.jasmineFile()
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
var lines = result.split('\n');
|
||||
|
||||
if (lines[0].match(/an error/)) {
|
||||
lines.shift();
|
||||
}
|
||||
|
||||
expect(lines[0]).toMatch(/ExceptionFormatterSpec.js/);
|
||||
expect(lines[1]).toMatch(/<Jasmine>/);
|
||||
|
||||
// Node has some number of additional frames below Jasmine.
|
||||
for (i = 2; i < lines.length; i++) {
|
||||
expect(lines[i]).not.toMatch(/jasmine.js/);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns null if no Error provided", function() {
|
||||
expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull();
|
||||
});
|
||||
|
||||
@@ -5,42 +5,64 @@ describe('Exceptions:', function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
});
|
||||
|
||||
it('should handle exceptions thrown, but continue', function(done) {
|
||||
var secondTest = jasmine.createSpy('second test');
|
||||
env.describe('Suite for handles exceptions', function () {
|
||||
env.it('should be a test that fails because it throws an exception', function() {
|
||||
throw new Error();
|
||||
describe('with break on exception', function() {
|
||||
it('should not catch the exception', function() {
|
||||
env.catchExceptions(false);
|
||||
env.describe('suite for break on exceptions', function() {
|
||||
env.it('should break when an exception is thrown', function() {
|
||||
throw new Error('I should hit a breakpoint!');
|
||||
});
|
||||
});
|
||||
env.it('should be a passing test that runs after exceptions are thrown from a async test', secondTest);
|
||||
var spy = jasmine.createSpy('spy');
|
||||
|
||||
try {
|
||||
env.execute();
|
||||
spy();
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
var expectations = function() {
|
||||
expect(secondTest).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function(done) {
|
||||
var secondDescribe = jasmine.createSpy("second describe");
|
||||
env.describe("a suite that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
describe("with catch on exception", function() {
|
||||
it('should handle exceptions thrown, but continue', function(done) {
|
||||
var secondTest = jasmine.createSpy('second test');
|
||||
env.describe('Suite for handles exceptions', function () {
|
||||
env.it('should be a test that fails because it throws an exception', function() {
|
||||
throw new Error();
|
||||
});
|
||||
env.it('should be a passing test that runs after exceptions are thrown from a async test', secondTest);
|
||||
});
|
||||
|
||||
throw new Error("top level error");
|
||||
var expectations = function() {
|
||||
expect(secondTest).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
});
|
||||
env.describe("a suite that doesn't throw an exception", secondDescribe);
|
||||
|
||||
var expectations = function() {
|
||||
expect(secondDescribe).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function(done) {
|
||||
var secondDescribe = jasmine.createSpy("second describe");
|
||||
env.describe("a suite that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
throw new Error("top level error");
|
||||
});
|
||||
env.describe("a suite that doesn't throw an exception", secondDescribe);
|
||||
|
||||
var expectations = function() {
|
||||
expect(secondDescribe).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ describe("JsApiReporter", function() {
|
||||
};
|
||||
suiteResult2 = {
|
||||
id: 2,
|
||||
status: 'passed'
|
||||
status: 'finished'
|
||||
};
|
||||
|
||||
reporter.suiteStarted(suiteStarted1);
|
||||
|
||||
@@ -268,17 +268,12 @@ describe("jasmineUnderTest.pp", function () {
|
||||
},
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {return [];},
|
||||
createSpy: function(name, originalFn) {
|
||||
return jasmineUnderTest.Spy(name, originalFn);
|
||||
}
|
||||
});
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() {return [];}});
|
||||
|
||||
spyRegistry.spyOn(TestObject, 'someFunction');
|
||||
expect(jasmineUnderTest.pp(TestObject.someFunction)).toEqual("spy on someFunction");
|
||||
|
||||
expect(jasmineUnderTest.pp(env.createSpy("something"))).toEqual("spy on something");
|
||||
expect(jasmineUnderTest.pp(jasmineUnderTest.createSpy("something"))).toEqual("spy on something");
|
||||
});
|
||||
|
||||
it("should stringify objects that implement jasmineToString", function () {
|
||||
@@ -303,7 +298,11 @@ describe("jasmineUnderTest.pp", function () {
|
||||
toString: function () { return Object.prototype.toString.call(this); }
|
||||
};
|
||||
|
||||
expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar', toString: Function })");
|
||||
if (jasmine.getEnv().ieVersion < 9) {
|
||||
expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar' })");
|
||||
} else {
|
||||
expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar', toString: Function })");
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify objects have have a toString that isn't a function", function() {
|
||||
@@ -311,7 +310,11 @@ describe("jasmineUnderTest.pp", function () {
|
||||
toString: "foo"
|
||||
};
|
||||
|
||||
expect(jasmineUnderTest.pp(obj)).toEqual("Object({ toString: 'foo' })");
|
||||
if (jasmine.getEnv().ieVersion < 9) {
|
||||
expect(jasmineUnderTest.pp(obj)).toEqual("Object({ })");
|
||||
} else {
|
||||
expect(jasmineUnderTest.pp(obj)).toEqual("Object({ toString: 'foo' })");
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify objects from anonymous constructors with custom toString", function () {
|
||||
@@ -324,6 +327,8 @@ describe("jasmineUnderTest.pp", function () {
|
||||
});
|
||||
|
||||
it("should handle objects with null prototype", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var obj = Object.create(null);
|
||||
obj.foo = 'bar';
|
||||
|
||||
|
||||
@@ -135,52 +135,6 @@ describe("QueueRunner", function() {
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("explicitly fails an async function when next is called with an Error and moves to the next function", function() {
|
||||
var err = new Error('foo'),
|
||||
queueableFn1 = { fn: function(done) {
|
||||
setTimeout(function() { done(err); }, 100);
|
||||
} },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
fail: failFn
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(failFn).toHaveBeenCalledWith(err);
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not cause an explicit fail if execution is being stopped", function() {
|
||||
var err = new jasmineUnderTest.StopExecutionError('foo'),
|
||||
queueableFn1 = { fn: function(done) {
|
||||
setTimeout(function() { done(err); }, 100);
|
||||
} },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
fail: failFn
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
|
||||
var timeout = 3,
|
||||
beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
|
||||
@@ -465,6 +419,20 @@ describe("QueueRunner", function() {
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
});
|
||||
|
||||
it("rethrows an exception if told to", function() {
|
||||
var queueableFn = { fn: function() {
|
||||
throw new Error('fake error');
|
||||
} },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
catchException: function(e) { return false; }
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
queueRunner.execute();
|
||||
}).toThrowError('fake error');
|
||||
});
|
||||
|
||||
it("continues running the functions even after an exception is thrown in an async spec", function() {
|
||||
var queueableFn = { fn: function(done) { throw new Error("error"); } },
|
||||
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
|
||||
@@ -554,24 +522,6 @@ describe("QueueRunner", function() {
|
||||
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(cleanupFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("skips to cleanup functions when next is called with an Error", function() {
|
||||
var queueableFn = { fn: function(done) {
|
||||
done(new Error('nope'));
|
||||
} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
cleanupFn = { fn: jasmine.createSpy('cleanup') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn],
|
||||
cleanupFns: [cleanupFn],
|
||||
completeOnFirstError: true,
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick();
|
||||
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(cleanupFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -9,131 +9,70 @@ describe("ReportDispatcher", function() {
|
||||
});
|
||||
|
||||
it("dispatches requested methods to added reporters", function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
|
||||
|
||||
dispatcher.addReporter(reporter);
|
||||
dispatcher.addReporter(anotherReporter);
|
||||
|
||||
dispatcher.foo(123, 456, completeCallback);
|
||||
dispatcher.foo(123, 456);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{fn: jasmine.any(Function)}, {fn: jasmine.any(Function)}],
|
||||
isReporter: true
|
||||
}));
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(reporter.foo.calls.mostRecent().object).toBe(reporter);
|
||||
|
||||
fns[1].fn();
|
||||
expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(anotherReporter.foo.calls.mostRecent().object).toBe(anotherReporter);
|
||||
|
||||
queueRunnerFactory.calls.reset();
|
||||
dispatcher.bar('a', 'b');
|
||||
|
||||
dispatcher.bar('a', 'b', completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{fn: jasmine.any(Function)}, {fn: jasmine.any(Function)}],
|
||||
isReporter: true
|
||||
}));
|
||||
|
||||
fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
|
||||
|
||||
fns[1].fn();
|
||||
expect(anotherReporter.bar).toHaveBeenCalledWith('a', 'b');
|
||||
});
|
||||
|
||||
it("does not dispatch to a reporter if the reporter doesn't accept the method", function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo'], queueRunnerFactory),
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['baz']);
|
||||
|
||||
dispatcher.addReporter(reporter);
|
||||
|
||||
dispatcher.foo(123, 456);
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: []
|
||||
}));
|
||||
expect(function() {
|
||||
dispatcher.foo(123, 456);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("allows providing a fallback reporter in case there's no other reporter", function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
it("allows providing a fallback reporter in case there's no other report", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
|
||||
|
||||
dispatcher.provideFallbackReporter(reporter);
|
||||
dispatcher.foo(123, 456, completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{fn: jasmine.any(Function)}],
|
||||
isReporter: true
|
||||
}));
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
dispatcher.foo(123, 456);
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
});
|
||||
|
||||
it("does not call fallback reporting methods when another reporter is provided", function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
|
||||
it("does not call fallback reporting methods when another report is provided", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']);
|
||||
|
||||
dispatcher.provideFallbackReporter(fallbackReporter);
|
||||
dispatcher.addReporter(reporter);
|
||||
dispatcher.foo(123, 456, completeCallback);
|
||||
dispatcher.foo(123, 456);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{fn: jasmine.any(Function)}],
|
||||
isReporter: true
|
||||
}));
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(fallbackReporter.foo).not.toHaveBeenCalledWith(123, 456);
|
||||
});
|
||||
|
||||
it("allows registered reporters to be cleared", function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
reporter1 = jasmine.createSpyObj('reporter1', ['foo', 'bar']),
|
||||
reporter2 = jasmine.createSpyObj('reporter2', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
reporter2 = jasmine.createSpyObj('reporter2', ['foo', 'bar']);
|
||||
|
||||
dispatcher.addReporter(reporter1);
|
||||
dispatcher.foo(123, completeCallback);
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{fn: jasmine.any(Function)}],
|
||||
isReporter: true
|
||||
}));
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
dispatcher.foo(123);
|
||||
expect(reporter1.foo).toHaveBeenCalledWith(123);
|
||||
|
||||
dispatcher.clearReporters();
|
||||
dispatcher.addReporter(reporter2);
|
||||
dispatcher.bar(456, completeCallback);
|
||||
dispatcher.bar(456);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{fn: jasmine.any(Function)}],
|
||||
isReporter: true
|
||||
}));
|
||||
|
||||
fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter1.bar).not.toHaveBeenCalled();
|
||||
expect(reporter2.bar).toHaveBeenCalledWith(456);
|
||||
});
|
||||
|
||||
@@ -55,7 +55,6 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
// TODO: due to some issue with the Pretty Printer, this line fails, but the other two pass.
|
||||
// This means toHaveBeenCalledWith on IE8 will always be broken.
|
||||
|
||||
@@ -83,7 +82,6 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -106,8 +104,8 @@ describe("Spec", function() {
|
||||
spec.execute();
|
||||
|
||||
var options = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
expect(options.queueableFns).toEqual([{fn: jasmine.any(Function)}, before, queueableFn]);
|
||||
expect(options.cleanupFns).toEqual([after, {fn: jasmine.any(Function)}]);
|
||||
expect(options.queueableFns).toEqual([before, queueableFn]);
|
||||
expect(options.cleanupFns).toEqual([after]);
|
||||
});
|
||||
|
||||
it("tells the queue runner that it's a leaf node", function() {
|
||||
@@ -142,8 +140,9 @@ describe("Spec", function() {
|
||||
expect(spec.status()).toBe('pending');
|
||||
});
|
||||
|
||||
it("can be excluded at execution time by a parent", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
it("can be disabled, but still calls callbacks", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner')
|
||||
.and.callFake(function(attrs) { attrs.onComplete(); }),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
specBody = jasmine.createSpy('specBody'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
@@ -154,26 +153,46 @@ describe("Spec", function() {
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute('cally-back', true);
|
||||
spec.disable();
|
||||
|
||||
expect(fakeQueueRunner).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
onComplete: jasmine.any(Function),
|
||||
queueableFns: [{fn: jasmine.any(Function)}],
|
||||
cleanupFns: [{fn: jasmine.any(Function)}]
|
||||
}));
|
||||
expect(spec.status()).toBe('disabled');
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(fakeQueueRunner).toHaveBeenCalled();
|
||||
expect(specBody).not.toHaveBeenCalled();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.queueableFns[0].fn();
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
expect(spec.result.status).toBe('excluded');
|
||||
it("can be disabled at execution time by a parent", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner')
|
||||
.and.callFake(function(attrs) { attrs.onComplete(); }),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
specBody = jasmine.createSpy('specBody'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
onStart:startCallback,
|
||||
queueableFn: { fn: specBody },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute(undefined, false);
|
||||
|
||||
expect(spec.result.status).toBe('disabled');
|
||||
|
||||
expect(fakeQueueRunner).toHaveBeenCalled();
|
||||
expect(specBody).not.toHaveBeenCalled();
|
||||
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be marked pending, but still calls callbacks when executed", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner')
|
||||
.and.callFake(function(attrs) { attrs.onComplete(); }),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
@@ -195,10 +214,7 @@ describe("Spec", function() {
|
||||
|
||||
expect(fakeQueueRunner).toHaveBeenCalled();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.queueableFns[0].fn();
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
args.cleanupFns[0].fn('things');
|
||||
expect(resultCallback).toHaveBeenCalledWith({
|
||||
id: spec.id,
|
||||
status: 'pending',
|
||||
@@ -208,7 +224,7 @@ describe("Spec", function() {
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
}, 'things');
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the done callback on execution complete", function() {
|
||||
@@ -225,23 +241,6 @@ describe("Spec", function() {
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should call the done callback with an error if the spec is failed", function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
catchExceptions: function() { return false; },
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) {
|
||||
spec.result.status = 'failed';
|
||||
attrs.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
spec.execute(done);
|
||||
|
||||
expect(done).toHaveBeenCalledWith(jasmine.any(jasmineUnderTest.StopExecutionError));
|
||||
});
|
||||
|
||||
it("#status returns passing by default", function() {
|
||||
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
expect(spec.status()).toBe('passed');
|
||||
@@ -261,12 +260,11 @@ describe("Spec", function() {
|
||||
});
|
||||
|
||||
it("keeps track of passed and failed expectations", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy("spec body") },
|
||||
expectationResultFactory: function (data) { return data; },
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
spec.addExpectationResult(true, 'expectation1');
|
||||
@@ -274,21 +272,19 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['expectation1']);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['expectation2']);
|
||||
});
|
||||
|
||||
it("throws an ExpectationFailed error upon receiving a failed expectation when 'throwOnExpectationFailure' is set", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
spec.addExpectationResult(true, 'passed');
|
||||
expect(function() {
|
||||
@@ -297,7 +293,6 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['passed']);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['failed']);
|
||||
});
|
||||
@@ -364,20 +359,17 @@ describe("Spec", function() {
|
||||
});
|
||||
|
||||
it("should log a failure when handling an exception", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException('foo');
|
||||
spec.execute();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([{
|
||||
error: 'foo',
|
||||
matcherName: '',
|
||||
@@ -388,20 +380,63 @@ describe("Spec", function() {
|
||||
});
|
||||
|
||||
it("should not log an additional failure when handling an ExpectationFailed error", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
spec.execute();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it("retrieves a result with updated status", function() {
|
||||
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
|
||||
|
||||
expect(spec.getResult().status).toBe('passed');
|
||||
});
|
||||
|
||||
it("retrives a result with disabled status", function() {
|
||||
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
|
||||
spec.disable();
|
||||
|
||||
expect(spec.getResult().status).toBe('disabled');
|
||||
});
|
||||
|
||||
it("retrives a result with pending status", function() {
|
||||
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
|
||||
spec.pend();
|
||||
|
||||
expect(spec.getResult().status).toBe('pending');
|
||||
});
|
||||
|
||||
it("should not be executable when disabled", function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.disable();
|
||||
|
||||
expect(spec.isExecutable()).toBe(false);
|
||||
});
|
||||
|
||||
it("should be executable when pending", function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.pend();
|
||||
|
||||
expect(spec.isExecutable()).toBe(true);
|
||||
});
|
||||
|
||||
it("should be executable when not disabled or pending", function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
|
||||
expect(spec.isExecutable()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
describe("SpyRegistry", function() {
|
||||
function createSpy(name, originalFn) {
|
||||
return jasmineUnderTest.Spy(name, originalFn);
|
||||
}
|
||||
|
||||
describe("#spyOn", function() {
|
||||
it("checks for the existence of the object", function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy});
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
@@ -47,10 +43,7 @@ describe("SpyRegistry", function() {
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
subject = { spiedFunc: function() {} };
|
||||
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
@@ -61,6 +54,9 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("checks if it can be spied upon", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var scope = {};
|
||||
|
||||
function myFunc() {
|
||||
@@ -88,7 +84,7 @@ describe("SpyRegistry", function() {
|
||||
|
||||
it("overrides the method on the object and returns the spy", function() {
|
||||
var originalFunctionWasCalled = false,
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
|
||||
|
||||
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
@@ -98,6 +94,9 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
describe("#spyOnProperty", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
it("checks for the existence of the object", function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
expect(function() {
|
||||
@@ -138,7 +137,7 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
Object.defineProperty(subject, 'spiedProp', {
|
||||
@@ -177,7 +176,7 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("overrides the property getter on the object and returns the spy", function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {},
|
||||
returnValue = 1;
|
||||
|
||||
@@ -196,7 +195,7 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("overrides the property setter on the object and returns the spy", function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {},
|
||||
returnValue = 1;
|
||||
|
||||
@@ -217,10 +216,7 @@ describe("SpyRegistry", function() {
|
||||
describe("#clearSpies", function() {
|
||||
it("restores the original functions on the spied-upon objects", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalFunction = function() {},
|
||||
subject = { spiedFunc: originalFunction };
|
||||
|
||||
@@ -232,10 +228,7 @@ describe("SpyRegistry", function() {
|
||||
|
||||
it("restores the original functions, even when that spy has been replace and re-spied upon", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalFunction = function() {},
|
||||
subject = { spiedFunc: originalFunction };
|
||||
|
||||
@@ -253,11 +246,11 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("does not add a property that the spied-upon object didn't originally have", function() {
|
||||
// IE 8 doesn't support `Object.create`
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalFunction = function() {},
|
||||
subjectParent = {spiedFunc: originalFunction};
|
||||
|
||||
@@ -273,11 +266,11 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("restores the original function when it\'s inherited and cannot be deleted", function() {
|
||||
// IE 8 doesn't support `Object.create` or `Object.defineProperty`
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalFunction = function() {},
|
||||
subjectParent = {spiedFunc: originalFunction};
|
||||
|
||||
@@ -304,7 +297,6 @@ describe("SpyRegistry", function() {
|
||||
global = new FakeWindow(),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy,
|
||||
global: global
|
||||
});
|
||||
|
||||
@@ -317,11 +309,11 @@ describe("SpyRegistry", function() {
|
||||
|
||||
describe('spying on properties', function() {
|
||||
it("restores the original properties on the spied-upon objects", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalReturn = 1,
|
||||
subject = {};
|
||||
|
||||
@@ -337,11 +329,11 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("does not add a property that the spied-upon object didn't originally have", function() {
|
||||
// IE 8 doesn't support `Object.create`
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy
|
||||
}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalReturn = 1,
|
||||
subjectParent = {};
|
||||
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
describe('Spies', function () {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
});
|
||||
|
||||
describe("createSpy", function() {
|
||||
var TestClass;
|
||||
|
||||
@@ -15,7 +9,7 @@ describe('Spies', function () {
|
||||
});
|
||||
|
||||
it("preserves the properties of the spied function", function() {
|
||||
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
|
||||
expect(spy.bob).toEqual("test");
|
||||
});
|
||||
@@ -24,19 +18,19 @@ describe('Spies', function () {
|
||||
TestClass.prototype.someFunction.and = "turkey";
|
||||
|
||||
expect(function() {
|
||||
env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
}).toThrowError("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon");
|
||||
});
|
||||
|
||||
it("adds a spyStrategy and callTracker to the spy", function() {
|
||||
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
|
||||
expect(spy.and).toEqual(jasmine.any(jasmineUnderTest.SpyStrategy));
|
||||
expect(spy.calls).toEqual(jasmine.any(jasmineUnderTest.CallTracker));
|
||||
});
|
||||
|
||||
it("tracks the argument of calls", function () {
|
||||
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
|
||||
spy("arg");
|
||||
@@ -45,7 +39,7 @@ describe('Spies', function () {
|
||||
});
|
||||
|
||||
it("tracks the context of calls", function () {
|
||||
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
|
||||
var contextObject = { spyMethod: spy };
|
||||
@@ -55,7 +49,7 @@ describe('Spies', function () {
|
||||
});
|
||||
|
||||
it("tracks the return value of calls", function () {
|
||||
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
|
||||
spy.and.returnValue("return value");
|
||||
@@ -77,7 +71,7 @@ describe('Spies', function () {
|
||||
|
||||
for (var arity = 0; arity < functions.length; arity++) {
|
||||
var someFunction = functions[arity],
|
||||
spy = env.createSpy(someFunction.name, someFunction);
|
||||
spy = jasmineUnderTest.createSpy(someFunction.name, someFunction);
|
||||
|
||||
expect(spy.length).toEqual(arity);
|
||||
}
|
||||
@@ -86,92 +80,48 @@ describe('Spies', function () {
|
||||
|
||||
describe("createSpyObj", function() {
|
||||
it("should create an object with spy methods and corresponding return values when you call jasmine.createSpyObj() with an object", function () {
|
||||
var spyObj = env.createSpyObj('BaseName', {'method1': 42, 'method2': 'special sauce' });
|
||||
var spyObj = jasmineUnderTest.createSpyObj('BaseName', {'method1': 42, 'method2': 'special sauce' });
|
||||
|
||||
expect(spyObj.method1()).toEqual(42);
|
||||
expect(spyObj.method1.and.identity).toEqual('BaseName.method1');
|
||||
expect(spyObj.method1.and.identity()).toEqual('BaseName.method1');
|
||||
|
||||
expect(spyObj.method2()).toEqual('special sauce');
|
||||
expect(spyObj.method2.and.identity).toEqual('BaseName.method2');
|
||||
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
|
||||
});
|
||||
|
||||
|
||||
it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
|
||||
var spyObj = env.createSpyObj('BaseName', ['method1', 'method2']);
|
||||
var spyObj = jasmineUnderTest.createSpyObj('BaseName', ['method1', 'method2']);
|
||||
|
||||
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
|
||||
expect(spyObj.method1.and.identity).toEqual('BaseName.method1');
|
||||
expect(spyObj.method2.and.identity).toEqual('BaseName.method2');
|
||||
expect(spyObj.method1.and.identity()).toEqual('BaseName.method1');
|
||||
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
|
||||
});
|
||||
|
||||
it("should allow you to omit the baseName", function() {
|
||||
var spyObj = env.createSpyObj(['method1', 'method2']);
|
||||
var spyObj = jasmineUnderTest.createSpyObj(['method1', 'method2']);
|
||||
|
||||
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
|
||||
expect(spyObj.method1.and.identity).toEqual('unknown.method1');
|
||||
expect(spyObj.method2.and.identity).toEqual('unknown.method2');
|
||||
expect(spyObj.method1.and.identity()).toEqual('unknown.method1');
|
||||
expect(spyObj.method2.and.identity()).toEqual('unknown.method2');
|
||||
});
|
||||
|
||||
it("should throw if you do not pass an array or object argument", function() {
|
||||
expect(function() {
|
||||
env.createSpyObj('BaseName');
|
||||
jasmineUnderTest.createSpyObj('BaseName');
|
||||
}).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
|
||||
});
|
||||
|
||||
it("should throw if you pass an empty array argument", function() {
|
||||
expect(function() {
|
||||
env.createSpyObj('BaseName', []);
|
||||
jasmineUnderTest.createSpyObj('BaseName', []);
|
||||
}).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
|
||||
});
|
||||
|
||||
it("should throw if you pass an empty object argument", function() {
|
||||
expect(function() {
|
||||
env.createSpyObj('BaseName', {});
|
||||
jasmineUnderTest.createSpyObj('BaseName', {});
|
||||
}).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
|
||||
});
|
||||
});
|
||||
|
||||
it("can use different strategies for different arguments", function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.and.returnValue(42);
|
||||
spy.withArgs('baz', 'grault').and.returnValue(-1);
|
||||
spy.withArgs('thud').and.returnValue('bob');
|
||||
|
||||
expect(spy('foo')).toEqual(42);
|
||||
expect(spy('baz', 'grault')).toEqual(-1);
|
||||
expect(spy('thud')).toEqual('bob');
|
||||
expect(spy('baz', 'grault', 'waldo')).toEqual(42);
|
||||
});
|
||||
|
||||
it("uses custom equality testers when selecting a strategy", function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.and.returnValue(42);
|
||||
spy.withArgs(jasmineUnderTest.any(String)).and.returnValue(-1);
|
||||
|
||||
expect(spy('foo')).toEqual(-1);
|
||||
expect(spy({})).toEqual(42);
|
||||
});
|
||||
|
||||
it("can reconfigure an argument-specific strategy", function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('foo').and.returnValue(42);
|
||||
spy.withArgs('foo').and.returnValue(17);
|
||||
expect(spy('foo')).toEqual(17);
|
||||
});
|
||||
|
||||
describe("When withArgs is used without a base strategy", function() {
|
||||
it("uses the matching strategy", function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('baz').and.returnValue(-1);
|
||||
|
||||
expect(spy('baz')).toEqual(-1);
|
||||
});
|
||||
|
||||
it("throws if the args don't match", function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('bar').and.returnValue(-1);
|
||||
|
||||
expect(function() { spy('baz', {qux: 42}); }).toThrowError('Spy \'foo\' receieved a call with arguments [ \'baz\', Object({ qux: 42 }) ] but all configured strategies specify other arguments.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,13 +3,13 @@ describe("SpyStrategy", function() {
|
||||
it("defaults its name to unknown", function() {
|
||||
var spyStrategy = new jasmineUnderTest.SpyStrategy();
|
||||
|
||||
expect(spyStrategy.identity).toEqual("unknown");
|
||||
expect(spyStrategy.identity()).toEqual("unknown");
|
||||
});
|
||||
|
||||
it("takes a name", function() {
|
||||
var spyStrategy = new jasmineUnderTest.SpyStrategy({name: "foo"});
|
||||
|
||||
expect(spyStrategy.identity).toEqual("foo");
|
||||
expect(spyStrategy.identity()).toEqual("foo");
|
||||
});
|
||||
|
||||
it("stubs an original function, if provided", function() {
|
||||
@@ -27,7 +27,7 @@ describe("SpyStrategy", function() {
|
||||
returnValue;
|
||||
|
||||
spyStrategy.callThrough();
|
||||
returnValue = spyStrategy.exec(null, ["foo"]);
|
||||
returnValue = spyStrategy.exec("foo");
|
||||
|
||||
expect(originalFn).toHaveBeenCalled();
|
||||
expect(originalFn.calls.mostRecent().args).toEqual(["foo"]);
|
||||
@@ -110,49 +110,6 @@ describe("SpyStrategy", function() {
|
||||
})
|
||||
});
|
||||
|
||||
it("allows a custom strategy to be used", function() {
|
||||
var plan = jasmine.createSpy('custom strategy')
|
||||
.and.returnValue('custom strategy result'),
|
||||
customStrategy = jasmine.createSpy('custom strategy')
|
||||
.and.returnValue(plan),
|
||||
originalFn = jasmine.createSpy('original'),
|
||||
spyStrategy = new jasmineUnderTest.SpyStrategy({
|
||||
fn: originalFn,
|
||||
customStrategies: {
|
||||
doSomething: customStrategy
|
||||
}
|
||||
});
|
||||
|
||||
spyStrategy.doSomething(1, 2, 3);
|
||||
expect(customStrategy).toHaveBeenCalledWith(1, 2, 3);
|
||||
expect(spyStrategy.exec(null, ['some', 'args']))
|
||||
.toEqual('custom strategy result');
|
||||
expect(plan).toHaveBeenCalledWith('some', 'args');
|
||||
});
|
||||
|
||||
it("throws an error if a custom strategy doesn't return a function", function() {
|
||||
var originalFn = jasmine.createSpy('original'),
|
||||
spyStrategy = new jasmineUnderTest.SpyStrategy({
|
||||
fn: originalFn,
|
||||
customStrategies: {
|
||||
doSomething: function() { return 'not a function' }
|
||||
}
|
||||
});
|
||||
|
||||
expect(function() { spyStrategy.doSomething(1, 2, 3) }).toThrowError('Spy strategy must return a function');
|
||||
});
|
||||
|
||||
it("does not allow custom strategies to overwrite existing methods", function() {
|
||||
var spyStrategy = new jasmineUnderTest.SpyStrategy({
|
||||
fn: function() {},
|
||||
customStrategies: {
|
||||
exec: function() {}
|
||||
}
|
||||
});
|
||||
|
||||
expect(spyStrategy.exec).toBe(jasmineUnderTest.SpyStrategy.prototype.exec);
|
||||
});
|
||||
|
||||
it('throws an error when a non-function is passed to callFake strategy', function() {
|
||||
var originalFn = jasmine.createSpy('original'),
|
||||
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
describe("StackTrace", function() {
|
||||
it("understands Chrome/IE/Edge style traces", function() {
|
||||
var raw =
|
||||
'Error: nope\n' +
|
||||
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)';
|
||||
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
|
||||
expect(result.message).toEqual('Error: nope');
|
||||
expect(result.style).toEqual('v8');
|
||||
expect(result.frames).toEqual([
|
||||
{
|
||||
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
|
||||
func: 'UserContext.<anonymous>',
|
||||
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
|
||||
line: 115
|
||||
},
|
||||
{
|
||||
raw: ' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)',
|
||||
func: 'QueueRunner.run',
|
||||
file: 'http://localhost:8888/__jasmine__/jasmine.js',
|
||||
line: 4320
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("understands Node style traces", function() {
|
||||
var raw = 'Error\n' +
|
||||
' at /somewhere/jasmine/lib/jasmine-core/jasmine.js:4255:9\n' +
|
||||
' at QueueRunner.complete [as onComplete] (/somewhere/jasmine/lib/jasmine-core/jasmine.js:579:9)\n' +
|
||||
' at Immediate.<anonymous> (/somewhere/jasmine/lib/jasmine-core/jasmine.js:4314:12)\n' +
|
||||
' at runCallback (timers.js:672:20)';
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
|
||||
expect(result.message).toEqual('Error');
|
||||
expect(result.style).toEqual('v8');
|
||||
expect(result.frames).toEqual([
|
||||
{
|
||||
raw: ' at /somewhere/jasmine/lib/jasmine-core/jasmine.js:4255:9',
|
||||
func: undefined,
|
||||
file: '/somewhere/jasmine/lib/jasmine-core/jasmine.js',
|
||||
line: 4255
|
||||
},
|
||||
{
|
||||
raw: ' at QueueRunner.complete [as onComplete] (/somewhere/jasmine/lib/jasmine-core/jasmine.js:579:9)',
|
||||
func: 'QueueRunner.complete [as onComplete]',
|
||||
file: '/somewhere/jasmine/lib/jasmine-core/jasmine.js',
|
||||
line: 579
|
||||
},
|
||||
{
|
||||
raw: ' at Immediate.<anonymous> (/somewhere/jasmine/lib/jasmine-core/jasmine.js:4314:12)',
|
||||
func: 'Immediate.<anonymous>',
|
||||
file: '/somewhere/jasmine/lib/jasmine-core/jasmine.js',
|
||||
line: 4314
|
||||
},
|
||||
{
|
||||
raw: ' at runCallback (timers.js:672:20)',
|
||||
func: 'runCallback',
|
||||
file: 'timers.js',
|
||||
line: 672
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("understands Safari/Firefox/Phantom-OS X style traces", function() {
|
||||
var raw =
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
|
||||
'run@http://localhost:8888/__jasmine__/jasmine.js:4320:27';
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
|
||||
expect(result.message).toBeFalsy();
|
||||
expect(result.style).toEqual('webkit');
|
||||
expect(result.frames).toEqual([
|
||||
{
|
||||
raw: 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28',
|
||||
func: undefined,
|
||||
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
|
||||
line: 115
|
||||
},
|
||||
{
|
||||
raw: 'run@http://localhost:8888/__jasmine__/jasmine.js:4320:27',
|
||||
func: 'run',
|
||||
file: 'http://localhost:8888/__jasmine__/jasmine.js',
|
||||
line: 4320
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not mistake gibberish for Safari/Firefox/Phantom-OS X style traces", function() {
|
||||
var raw = 'randomcharsnotincludingwhitespace';
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
expect(result.style).toBeNull();
|
||||
expect(result.frames).toEqual([
|
||||
{ raw: raw }
|
||||
]);
|
||||
});
|
||||
|
||||
it("understands Phantom-Linux style traces", function() {
|
||||
var raw =
|
||||
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)';
|
||||
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
|
||||
expect(result.message).toBeFalsy();
|
||||
expect(result.style).toEqual('v8');
|
||||
expect(result.frames).toEqual([
|
||||
{
|
||||
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
|
||||
func: 'UserContext.<anonymous>',
|
||||
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
|
||||
line: 115
|
||||
},
|
||||
{
|
||||
raw: ' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)',
|
||||
func: 'QueueRunner.run',
|
||||
file: 'http://localhost:8888/__jasmine__/jasmine.js',
|
||||
line: 4320
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("ignores blank lines", function() {
|
||||
var raw =
|
||||
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n';
|
||||
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
|
||||
expect(result.frames).toEqual([
|
||||
{
|
||||
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
|
||||
func: 'UserContext.<anonymous>',
|
||||
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
|
||||
line: 115
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("omits properties except 'raw' for frames that are not understood", function() {
|
||||
var raw =
|
||||
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' but this is quite unexpected\n' +
|
||||
' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)';
|
||||
|
||||
var result = new jasmineUnderTest.StackTrace(raw);
|
||||
expect(result.style).toEqual('v8');
|
||||
expect(result.frames).toEqual([
|
||||
{
|
||||
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
|
||||
func: 'UserContext.<anonymous>',
|
||||
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
|
||||
line: 115
|
||||
},
|
||||
{
|
||||
raw: ' but this is quite unexpected'
|
||||
},
|
||||
{
|
||||
raw: ' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)',
|
||||
func: 'QueueRunner.run',
|
||||
file: 'http://localhost:8888/__jasmine__/jasmine.js',
|
||||
line: 4320
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -67,10 +67,11 @@ describe("Suite", function() {
|
||||
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
|
||||
});
|
||||
|
||||
it('has a status of failed if any expectations have failed', function() {
|
||||
it('has a status of failed if any afterAll expectations have failed', function() {
|
||||
var suite = new jasmineUnderTest.Suite({
|
||||
expectationResultFactory: function() { return 'hi'; }
|
||||
});
|
||||
suite.addChild({ result: { status: 'done' } });
|
||||
|
||||
suite.addExpectationResult(false);
|
||||
expect(suite.status()).toBe('failed');
|
||||
@@ -79,7 +80,7 @@ describe("Suite", function() {
|
||||
it("retrieves a result with updated status", function() {
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
|
||||
expect(suite.getResult().status).toBe('passed');
|
||||
expect(suite.getResult().status).toBe('finished');
|
||||
});
|
||||
|
||||
it("retrieves a result with pending status", function() {
|
||||
@@ -89,11 +90,41 @@ describe("Suite", function() {
|
||||
expect(suite.getResult().status).toBe('pending');
|
||||
});
|
||||
|
||||
it("throws an ExpectationFailed when receiving a failed expectation when throwOnExpectationFailure is set", function() {
|
||||
it("is executable if not pending", function() {
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
|
||||
expect(suite.isExecutable()).toBe(true);
|
||||
});
|
||||
|
||||
it("is not executable if pending", function() {
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
suite.pend();
|
||||
|
||||
expect(suite.isExecutable()).toBe(false);
|
||||
});
|
||||
|
||||
it("tells all children about expectation failures, even if one throws", function() {
|
||||
var suite = new jasmineUnderTest.Suite({}),
|
||||
child1 = { addExpectationResult: jasmine.createSpy('child1#expectationResult'), result: {} },
|
||||
child2 = { addExpectationResult: jasmine.createSpy('child2#expectationResult'), result: {} };
|
||||
|
||||
suite.addChild(child1);
|
||||
suite.addChild(child2);
|
||||
|
||||
child1.addExpectationResult.and.throwError('foo');
|
||||
|
||||
suite.addExpectationResult('stuff');
|
||||
|
||||
expect(child1.addExpectationResult).toHaveBeenCalledWith('stuff');
|
||||
expect(child2.addExpectationResult).toHaveBeenCalledWith('stuff');
|
||||
});
|
||||
|
||||
it("throws an ExpectationFailed when receiving a failed expectation in an afterAll when throwOnExpectationFailure is set", function() {
|
||||
var suite = new jasmineUnderTest.Suite({
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
suite.addChild({ result: { status: 'done' } });
|
||||
|
||||
expect(function() {
|
||||
suite.addExpectationResult(false, 'failed');
|
||||
@@ -103,8 +134,9 @@ describe("Suite", function() {
|
||||
expect(suite.result.failedExpectations).toEqual(['failed']);
|
||||
});
|
||||
|
||||
it("does not add an additional failure when an expectation fails", function(){
|
||||
it("does not add an additional failure when an expectation fails in an afterAll", function(){
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
suite.addChild({ result: { status: 'done' } });
|
||||
|
||||
suite.onException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
|
||||
|
||||
@@ -8,24 +8,27 @@ describe("TreeProcessor", function() {
|
||||
this.canBeReentered = function() {
|
||||
return !attrs.noReenter;
|
||||
};
|
||||
this.markedPending = attrs.markedPending || false;
|
||||
this.isExecutable = function() {
|
||||
return attrs.executable !== false;
|
||||
};
|
||||
this.sharedUserContext = function() {
|
||||
return attrs.userContext || {};
|
||||
};
|
||||
this.getResult = jasmine.createSpy(this.id + '#execute');
|
||||
this.beforeAllFns = attrs.beforeAllFns || [];
|
||||
this.afterAllFns = attrs.afterAllFns || [];
|
||||
this.cleanupBeforeAfter = function() { };
|
||||
}
|
||||
|
||||
function Leaf(attrs) {
|
||||
attrs = attrs || {};
|
||||
this.id = 'leaf' + leafNumber++;
|
||||
this.markedPending = attrs.markedPending || false;
|
||||
this.isExecutable = function() {
|
||||
return attrs.executable !== false;
|
||||
};
|
||||
this.execute = jasmine.createSpy(this.id + '#execute');
|
||||
}
|
||||
|
||||
it("processes a single leaf", function() {
|
||||
it("processes a single executable leaf", function() {
|
||||
var leaf = new Leaf(),
|
||||
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
|
||||
result = processor.processTree();
|
||||
@@ -33,22 +36,20 @@ describe("TreeProcessor", function() {
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: true,
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a single pending leaf", function() {
|
||||
var leaf = new Leaf({ markedPending: true }),
|
||||
it("processes a single non-executable leaf", function() {
|
||||
var leaf = new Leaf({ executable: false }),
|
||||
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
@@ -61,26 +62,7 @@ describe("TreeProcessor", function() {
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
excluded: true,
|
||||
willExecute: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a single excluded leaf", function() {
|
||||
var leaf = new Leaf(),
|
||||
processor = new jasmineUnderTest.TreeProcessor({
|
||||
tree: leaf,
|
||||
runnableIds: [leaf.id],
|
||||
excludeNode: function(node) { return true; }
|
||||
}),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
excluded: true,
|
||||
willExecute: false,
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
@@ -94,20 +76,18 @@ describe("TreeProcessor", function() {
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[parent.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: true,
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: true,
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a tree with a single pending leaf, with the root specified", function() {
|
||||
var leaf = new Leaf({ markedPending: true }),
|
||||
it("processes a tree with a single non-executable leaf, with the root specified", function() {
|
||||
var leaf = new Leaf({ executable: false }),
|
||||
parent = new Node({ children: [leaf] }),
|
||||
processor = new jasmineUnderTest.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
|
||||
result = processor.processTree();
|
||||
@@ -115,77 +95,61 @@ describe("TreeProcessor", function() {
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[parent.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a complicated tree with the root specified", function() {
|
||||
var pendingLeaf = new Leaf({ markedPending: true }),
|
||||
executableLeaf = new Leaf({ markedPending: false }),
|
||||
parent = new Node({ children: [pendingLeaf, executableLeaf] }),
|
||||
var nonExecutable = new Leaf({ executable: false }),
|
||||
executable = new Leaf({ executable: true }),
|
||||
parent = new Node({ children: [nonExecutable, executable] }),
|
||||
childless = new Node(),
|
||||
childOfPending = new Leaf({ markedPending: true }),
|
||||
pendingNode = new Node({ markedPending: true, children: [childOfPending] }),
|
||||
parentOfPendings = new Node({ markedPending: false, children: [childless, pendingNode] }),
|
||||
root = new Node({ children: [parent, parentOfPendings] }),
|
||||
childOfDisabled = new Leaf({ executable: true }),
|
||||
disabledNode = new Node({ executable: false, children: [childOfDisabled] }),
|
||||
root = new Node({ children: [parent, childless, disabledNode] }),
|
||||
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [root.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[root.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[parentOfPendings.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[childless.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[pendingLeaf.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
expect(result[nonExecutable.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[executableLeaf.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: true,
|
||||
expect(result[executable.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[parent.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: true,
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[pendingNode.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
expect(result[disabledNode.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[childOfPending.id]).toEqual({
|
||||
excluded: false,
|
||||
willExecute: false,
|
||||
expect(result[childOfDisabled.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
@@ -254,7 +218,7 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
|
||||
|
||||
expect(leaf.execute).toHaveBeenCalledWith('foo', false);
|
||||
expect(leaf.execute).toHaveBeenCalledWith('foo', true);
|
||||
});
|
||||
|
||||
it("runs a node with no children", function() {
|
||||
@@ -284,20 +248,19 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn(nodeDone);
|
||||
|
||||
expect(nodeStart).toHaveBeenCalledWith(node);
|
||||
expect(queueRunner).toHaveBeenCalledWith({
|
||||
onComplete: jasmine.any(Function),
|
||||
queueableFns: [{ fn: jasmine.any(Function) }],
|
||||
queueableFns: [],
|
||||
userContext: { node: 'context' },
|
||||
onException: jasmine.any(Function)
|
||||
});
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
|
||||
expect(nodeStart).toHaveBeenCalledWith(node, 'foo');
|
||||
|
||||
node.getResult.and.returnValue({ my: 'result' });
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].onComplete();
|
||||
expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' }, nodeDone);
|
||||
expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' });
|
||||
expect(nodeDone).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs a node with children", function() {
|
||||
@@ -319,25 +282,25 @@ describe("TreeProcessor", function() {
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(3);
|
||||
expect(queueableFns.length).toBe(2);
|
||||
|
||||
queueableFns[1].fn('foo');
|
||||
expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
|
||||
queueableFns[0].fn('foo');
|
||||
expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
|
||||
|
||||
queueableFns[2].fn('bar');
|
||||
expect(leaf2.execute).toHaveBeenCalledWith('bar', false);
|
||||
queueableFns[1].fn('bar');
|
||||
expect(leaf2.execute).toHaveBeenCalledWith('bar', true);
|
||||
});
|
||||
|
||||
it("runs an excluded node with leaf", function() {
|
||||
it("runs a disabled node", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
node = new Node({ children: [leaf1] }),
|
||||
node = new Node({ children: [leaf1], executable: false }),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
nodeStart = jasmine.createSpy('nodeStart'),
|
||||
nodeComplete = jasmine.createSpy('nodeComplete'),
|
||||
processor = new jasmineUnderTest.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [],
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner,
|
||||
nodeStart: nodeStart,
|
||||
nodeComplete: nodeComplete
|
||||
@@ -349,19 +312,18 @@ describe("TreeProcessor", function() {
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
expect(nodeStart).toHaveBeenCalledWith(node);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(2);
|
||||
expect(queueableFns.length).toBe(1);
|
||||
|
||||
queueableFns[0].fn('bar');
|
||||
expect(nodeStart).toHaveBeenCalledWith(node, 'bar');
|
||||
|
||||
queueableFns[1].fn('foo');
|
||||
expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
|
||||
queueableFns[0].fn('foo');
|
||||
expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
|
||||
|
||||
node.getResult.and.returnValue({ im: 'disabled' });
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].onComplete();
|
||||
expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' }, nodeDone);
|
||||
expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' });
|
||||
});
|
||||
|
||||
it("runs beforeAlls for a node with children", function() {
|
||||
@@ -386,7 +348,7 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, 'beforeAll1', 'beforeAll2', { fn: jasmine.any(Function) }]);
|
||||
expect(queueableFns).toEqual(['beforeAll1', 'beforeAll2', { fn: jasmine.any(Function) }]);
|
||||
});
|
||||
|
||||
it("runs afterAlls for a node with children", function() {
|
||||
@@ -411,7 +373,7 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) }, 'afterAll1', 'afterAll2']);
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, 'afterAll1', 'afterAll2']);
|
||||
});
|
||||
|
||||
it("does not run beforeAlls or afterAlls for a node with no children", function() {
|
||||
@@ -435,16 +397,16 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([{fn: jasmine.any(Function)}]);
|
||||
expect(queueableFns).toEqual([]);
|
||||
});
|
||||
|
||||
it("does not run beforeAlls or afterAlls for a node with only pending children", function() {
|
||||
var leaf = new Leaf({ markedPending: true }),
|
||||
it("does not run beforeAlls or afterAlls for a disabled node", function() {
|
||||
var leaf = new Leaf(),
|
||||
node = new Node({
|
||||
children: [leaf],
|
||||
beforeAllFns: ['before'],
|
||||
afterAllFns: ['after'],
|
||||
markedPending: false
|
||||
executable: false
|
||||
}),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
@@ -462,7 +424,7 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) }]);
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }]);
|
||||
});
|
||||
|
||||
it("runs leaves in the order specified", function() {
|
||||
@@ -489,7 +451,7 @@ describe("TreeProcessor", function() {
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs specified leaves before non-specified leaves within a parent node", function() {
|
||||
it("runs specified leaves before non-specified leaves", function() {
|
||||
var specified = new Leaf(),
|
||||
nonSpecified = new Leaf(),
|
||||
root = new Node({ children: [nonSpecified, specified] }),
|
||||
@@ -506,11 +468,11 @@ describe("TreeProcessor", function() {
|
||||
queueableFns[0].fn();
|
||||
|
||||
expect(nonSpecified.execute).not.toHaveBeenCalled();
|
||||
expect(specified.execute).toHaveBeenCalledWith(undefined, false);
|
||||
expect(specified.execute).toHaveBeenCalledWith(undefined, true);
|
||||
|
||||
queueableFns[1].fn();
|
||||
|
||||
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, true);
|
||||
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, false);
|
||||
});
|
||||
|
||||
it("runs nodes and leaves with a specified order", function() {
|
||||
@@ -531,7 +493,7 @@ describe("TreeProcessor", function() {
|
||||
|
||||
expect(specifiedLeaf.execute).not.toHaveBeenCalled();
|
||||
var nodeQueueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
nodeQueueableFns[1].fn();
|
||||
nodeQueueableFns[0].fn();
|
||||
|
||||
expect(childLeaf.execute).toHaveBeenCalled();
|
||||
|
||||
@@ -560,8 +522,8 @@ describe("TreeProcessor", function() {
|
||||
expect(queueableFns.length).toBe(5);
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
@@ -569,8 +531,8 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns[2].fn();
|
||||
expect(queueRunner.calls.count()).toBe(3);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[3].fn();
|
||||
@@ -578,8 +540,8 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns[4].fn();
|
||||
expect(queueRunner.calls.count()).toBe(4);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -605,12 +567,12 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(2);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(3);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
@@ -618,12 +580,12 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns[2].fn();
|
||||
expect(queueRunner.calls.count()).toBe(4);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(5);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[3].fn();
|
||||
@@ -631,12 +593,12 @@ describe("TreeProcessor", function() {
|
||||
|
||||
queueableFns[4].fn();
|
||||
expect(queueRunner.calls.count()).toBe(6);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(7);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -663,11 +625,11 @@ describe("TreeProcessor", function() {
|
||||
queueableFns[1].fn();
|
||||
|
||||
var childFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(childFns.length).toBe(3);
|
||||
childFns[1].fn();
|
||||
expect(childFns.length).toBe(2);
|
||||
childFns[0].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
childFns[2].fn();
|
||||
childFns[1].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -729,7 +691,7 @@ describe("TreeProcessor", function() {
|
||||
expect(leaf11.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs nodes in a custom order when orderChildren is overridden", function() {
|
||||
it("runs nodes in a custom order when orderChildren is overrided", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
|
||||
@@ -43,6 +43,9 @@ describe("jasmineUnderTest.util", function() {
|
||||
});
|
||||
|
||||
describe("getPropertyDescriptor", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
it("get property descriptor from object", function() {
|
||||
var obj = {prop: 1},
|
||||
actual = jasmineUnderTest.util.getPropertyDescriptor(obj, 'prop'),
|
||||
@@ -91,15 +94,6 @@ describe("jasmineUnderTest.util", function() {
|
||||
|
||||
expect(jasmineUnderTest.util.objectDifference(a, b)).toEqual({x: 1});
|
||||
expect(jasmineUnderTest.util.objectDifference(b, a)).toEqual({y: 2});
|
||||
});
|
||||
});
|
||||
|
||||
describe("jasmineFile", function() {
|
||||
it("returns the file containing jasmine.util", function() {
|
||||
// Chrome sometimes reports foo.js as foo.js/, so tolerate
|
||||
// a trailing slash if present.
|
||||
expect(jasmineUnderTest.util.jasmineFile()).toMatch(/util.js\/?$/);
|
||||
expect(jasmine.util.jasmineFile()).toMatch(/jasmine.js\/?$/);
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
@@ -68,17 +68,10 @@ describe("Any", function() {
|
||||
expect(any.asymmetricMatch(new Thing())).toBe(true);
|
||||
});
|
||||
|
||||
it("does not treat null as an Object", function() {
|
||||
var any = new jasmineUnderTest.Any(Object);
|
||||
|
||||
expect(any.asymmetricMatch(null)).toBe(false);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var any = new jasmineUnderTest.Any(Number);
|
||||
|
||||
expect(any.jasmineToString()).toEqual('<jasmine.any(Number)>');
|
||||
expect(any.jasmineToString()).toEqual('<jasmine.any(Number)>');
|
||||
});
|
||||
|
||||
describe("when called without an argument", function() {
|
||||
|
||||
@@ -57,6 +57,9 @@ describe("ObjectContaining", function() {
|
||||
});
|
||||
|
||||
it("matches defined properties", function(){
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
|
||||
|
||||
var definedPropertyObject = {};
|
||||
|
||||
@@ -4,7 +4,6 @@ describe("Custom Matchers (Integration)", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
env.randomizeTests(false);
|
||||
});
|
||||
|
||||
it("allows adding more matchers local to a spec", function(done) {
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
describe('Custom Spy Strategies (Integration)', function() {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
env.randomizeTests(false);
|
||||
});
|
||||
|
||||
it('allows adding more strategies local to a suite', function(done) {
|
||||
var plan = jasmine.createSpy('custom strategy plan')
|
||||
.and.returnValue(42);
|
||||
var strategy = jasmine.createSpy('custom strategy')
|
||||
.and.returnValue(plan);
|
||||
|
||||
env.describe('suite defining a custom spy strategy', function() {
|
||||
env.beforeEach(function() {
|
||||
env.addSpyStrategy('frobnicate', strategy);
|
||||
});
|
||||
|
||||
env.it('spec in the suite', function() {
|
||||
var spy = env.createSpy('something').and.frobnicate(17);
|
||||
expect(spy(1, 2, 3)).toEqual(42);
|
||||
expect(strategy).toHaveBeenCalledWith(17);
|
||||
expect(plan).toHaveBeenCalledWith(1, 2, 3);
|
||||
});
|
||||
});
|
||||
|
||||
env.it('spec without custom strategy defined', function() {
|
||||
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
|
||||
});
|
||||
|
||||
function jasmineDone(result) {
|
||||
expect(result.overallStatus).toEqual('passed');
|
||||
done();
|
||||
}
|
||||
|
||||
env.addReporter({ jasmineDone: jasmineDone });
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('allows adding more strategies local to a spec', function(done) {
|
||||
var plan = jasmine.createSpy('custom strategy plan')
|
||||
.and.returnValue(42);
|
||||
var strategy = jasmine.createSpy('custom strategy')
|
||||
.and.returnValue(plan);
|
||||
|
||||
env.it('spec defining a custom spy strategy', function() {
|
||||
env.addSpyStrategy('frobnicate', strategy);
|
||||
var spy = env.createSpy('something').and.frobnicate(17);
|
||||
expect(spy(1, 2, 3)).toEqual(42);
|
||||
expect(strategy).toHaveBeenCalledWith(17);
|
||||
expect(plan).toHaveBeenCalledWith(1, 2, 3);
|
||||
});
|
||||
|
||||
env.it('spec without custom strategy defined', function() {
|
||||
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
|
||||
});
|
||||
|
||||
function jasmineDone(result) {
|
||||
expect(result.overallStatus).toEqual('passed');
|
||||
done();
|
||||
}
|
||||
|
||||
env.addReporter({ jasmineDone: jasmineDone });
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('allows using custom strategies on a per-argument basis', function(done) {
|
||||
var plan = jasmine.createSpy('custom strategy plan')
|
||||
.and.returnValue(42);
|
||||
var strategy = jasmine.createSpy('custom strategy')
|
||||
.and.returnValue(plan);
|
||||
|
||||
env.it('spec defining a custom spy strategy', function() {
|
||||
env.addSpyStrategy('frobnicate', strategy);
|
||||
var spy = env.createSpy('something')
|
||||
.and.returnValue('no args return')
|
||||
.withArgs(1, 2, 3).and.frobnicate(17);
|
||||
|
||||
expect(spy()).toEqual('no args return');
|
||||
expect(plan).not.toHaveBeenCalled();
|
||||
expect(spy(1, 2, 3)).toEqual(42);
|
||||
expect(plan).toHaveBeenCalledWith(1, 2, 3);
|
||||
});
|
||||
|
||||
env.it('spec without custom strategy defined', function() {
|
||||
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
|
||||
});
|
||||
|
||||
function jasmineDone(result) {
|
||||
expect(result.overallStatus).toEqual('passed');
|
||||
done();
|
||||
}
|
||||
|
||||
env.addReporter({ jasmineDone: jasmineDone });
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('allows multiple custom strategies to be used', function(done) {
|
||||
var plan1 = jasmine.createSpy('plan 1').and.returnValue(42),
|
||||
strategy1 = jasmine.createSpy('strat 1').and.returnValue(plan1),
|
||||
plan2 = jasmine.createSpy('plan 2').and.returnValue(24),
|
||||
strategy2 = jasmine.createSpy('strat 2').and.returnValue(plan2),
|
||||
specDone = jasmine.createSpy('specDone');
|
||||
|
||||
env.beforeEach(function() {
|
||||
env.addSpyStrategy('frobnicate', strategy1);
|
||||
env.addSpyStrategy('jiggle', strategy2);
|
||||
});
|
||||
|
||||
env.it('frobnicates', function() {
|
||||
plan1.calls.reset();
|
||||
plan2.calls.reset();
|
||||
var spy = env.createSpy('spy').and.frobnicate();
|
||||
expect(spy()).toEqual(42);
|
||||
expect(plan1).toHaveBeenCalled();
|
||||
expect(plan2).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
env.it('jiggles', function() {
|
||||
plan1.calls.reset();
|
||||
plan2.calls.reset();
|
||||
var spy = env.createSpy('spy').and.jiggle();
|
||||
expect(spy()).toEqual(24);
|
||||
expect(plan1).not.toHaveBeenCalled();
|
||||
expect(plan2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
function jasmineDone(result) {
|
||||
expect(result.overallStatus).toEqual('passed');
|
||||
expect(specDone.calls.count()).toBe(2);
|
||||
done();
|
||||
}
|
||||
|
||||
env.addReporter({ jasmineDone: jasmineDone, specDone: specDone });
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,8 @@
|
||||
describe("spec running", function () {
|
||||
describe("jasmine spec running", function () {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
jasmine.getEnv().registerIntegrationMatchers();
|
||||
env = new jasmineUnderTest.Env();
|
||||
env.randomizeTests(false);
|
||||
});
|
||||
|
||||
it('should assign spec ids sequentially', function() {
|
||||
@@ -602,16 +600,18 @@ describe("spec running", function () {
|
||||
|
||||
it("should recover gracefully when there are errors in describe functions", function(done) {
|
||||
var specs = [],
|
||||
reporter = jasmine.createSpyObj(['specDone', 'suiteDone', 'jasmineDone']);
|
||||
reporter = jasmine.createSpyObj(['specDone', 'jasmineDone']);
|
||||
|
||||
reporter.specDone.and.callFake(function(result) {
|
||||
specs.push(result.fullName);
|
||||
});
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(specs).toEqual(['outer1 inner1 should thingy', 'outer1 inner2 should other thingy', 'outer2 should xxx']);
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1 inner1', [/inner error/]);
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1', [/outer error/]);
|
||||
expect(specs).toContain('outer1 inner1 should thingy');
|
||||
expect(specs).toContain('outer1 inner1 encountered a declaration exception');
|
||||
expect(specs).toContain('outer1 inner2 should other thingy');
|
||||
expect(specs).toContain('outer1 encountered a declaration exception');
|
||||
expect(specs).toContain('outer2 should xxx');
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -622,7 +622,7 @@ describe("spec running", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
throw new Error("inner error");
|
||||
throw new Error("fake error");
|
||||
});
|
||||
|
||||
env.describe("inner2", function() {
|
||||
@@ -631,7 +631,7 @@ describe("spec running", function () {
|
||||
});
|
||||
});
|
||||
|
||||
throw new Error("outer error");
|
||||
throw new Error("fake error");
|
||||
|
||||
});
|
||||
}).not.toThrow();
|
||||
@@ -740,8 +740,8 @@ describe("spec running", function () {
|
||||
|
||||
it("should run the tests in a consistent order when a seed is supplied", function(done) {
|
||||
var actions = [];
|
||||
env.seed('123456');
|
||||
env.randomizeTests(true);
|
||||
env.seed('123456');
|
||||
|
||||
env.beforeEach(function () {
|
||||
actions.push('topSuite beforeEach');
|
||||
@@ -947,30 +947,4 @@ describe("spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when stopOnSpecFailure is on", function() {
|
||||
it("does not run further specs when one fails", function(done) {
|
||||
var actions = [];
|
||||
|
||||
env.it('fails', function() {
|
||||
actions.push('fails');
|
||||
env.expect(1).toBe(2);
|
||||
});
|
||||
|
||||
env.it('does not run', function() {
|
||||
actions.push('does not run');
|
||||
});
|
||||
|
||||
env.randomizeTests(false);
|
||||
env.stopOnSpecFailure(true);
|
||||
|
||||
var assertions = function() {
|
||||
expect(actions).toEqual(['fails']);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -156,6 +156,8 @@ describe("matchersUtil", function() {
|
||||
});
|
||||
|
||||
it("passes for equivalent frozen objects (GitHub issue #266)", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var a = { foo: 1 },
|
||||
b = {foo: 1 };
|
||||
|
||||
@@ -199,6 +201,10 @@ describe("matchersUtil", function() {
|
||||
if (isNotRunningInBrowser()) {
|
||||
return;
|
||||
}
|
||||
// iframe.contentWindow.eval isn't supported in ie8
|
||||
if (jasmine.getEnv().ieVersion < 9) {
|
||||
return;
|
||||
}
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.contentWindow.eval('window.testObject = {}');
|
||||
@@ -360,6 +366,8 @@ describe("matchersUtil", function() {
|
||||
});
|
||||
|
||||
it("passes for null prototype objects with same properties", function () {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var objA = Object.create(null),
|
||||
objB = Object.create(null);
|
||||
|
||||
@@ -370,6 +378,8 @@ describe("matchersUtil", function() {
|
||||
});
|
||||
|
||||
it("fails for null prototype objects with different properties", function () {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var objA = Object.create(null),
|
||||
objB = Object.create(null);
|
||||
|
||||
@@ -525,6 +535,9 @@ describe("matchersUtil", function() {
|
||||
});
|
||||
|
||||
describe("when running in an environment with array polyfills", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var findIndexDescriptor = Object.getOwnPropertyDescriptor(Array.prototype, 'findIndex');
|
||||
if (!findIndexDescriptor) {
|
||||
return;
|
||||
|
||||
@@ -299,7 +299,22 @@ describe("toEqual", function() {
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
function constructorIsNotEnumerable() {
|
||||
// in IE8, the constructor property is not enumerable, even if it is an
|
||||
// own property of the object.
|
||||
// Objects that differ only by an own `constructor` property are thus
|
||||
// considered equal in IE8.
|
||||
for (var key in {constructor: 1}) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
it("reports mismatches between objects with their own constructor property", function () {
|
||||
if (constructorIsNotEnumerable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
function Foo() {}
|
||||
function Bar() {}
|
||||
|
||||
@@ -311,6 +326,10 @@ describe("toEqual", function() {
|
||||
});
|
||||
|
||||
it("reports mismatches between an object with a real constructor and one with its own constructor property", function () {
|
||||
if (constructorIsNotEnumerable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
function Foo() {}
|
||||
function Bar() {}
|
||||
|
||||
@@ -581,7 +600,7 @@ describe("toEqual", function() {
|
||||
|
||||
var actual = {a: document.createElement('div')},
|
||||
expected = {a: document.createElement('p')},
|
||||
message = 'Expected $.a = <div> to equal <p>.';
|
||||
message = 'Expected $.a = HTMLNode to equal HTMLNode.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -599,7 +618,7 @@ describe("toEqual", function() {
|
||||
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <div>...</div> to equal <div>...</div>.';
|
||||
message = 'Expected $.a = HTMLNode to equal HTMLNode.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
})
|
||||
@@ -611,7 +630,7 @@ describe("toEqual", function() {
|
||||
|
||||
var actual = {a: document.createElement('div')},
|
||||
expected = {a: {}},
|
||||
message = 'Expected $.a = <div> to equal Object({ }).';
|
||||
message = 'Expected $.a = HTMLNode to equal Object({ }).';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
@@ -2,14 +2,14 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
it("throws an exception when the actual is not a spy", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
fn = function() {},
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy');
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy');
|
||||
|
||||
expect(function() { matcher.compare(fn, secondSpy) }).toThrowError(Error, /Expected a spy, but got Function./);
|
||||
});
|
||||
|
||||
it("throws an exception when the expected is not a spy", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
fn = function() {};
|
||||
|
||||
expect(function() { matcher.compare(firstSpy, fn) }).toThrowError(Error, /Expected a spy, but got Function./);
|
||||
@@ -17,8 +17,8 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
|
||||
it("fails when the actual was not called", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy');
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy');
|
||||
|
||||
secondSpy();
|
||||
|
||||
@@ -29,8 +29,8 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
|
||||
it("fails when the expected was not called", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy');
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy');
|
||||
|
||||
firstSpy();
|
||||
|
||||
@@ -41,8 +41,8 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
|
||||
it("fails when the actual is called after the expected", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy'),
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy'),
|
||||
result;
|
||||
|
||||
secondSpy();
|
||||
@@ -55,8 +55,8 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
|
||||
it("fails when the actual is called before and after the expected", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy'),
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy'),
|
||||
result;
|
||||
|
||||
firstSpy();
|
||||
@@ -70,8 +70,8 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
|
||||
it("fails when the expected is called before and after the actual", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy'),
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy'),
|
||||
result;
|
||||
|
||||
secondSpy();
|
||||
@@ -85,8 +85,8 @@ describe("toHaveBeenCalledBefore", function() {
|
||||
|
||||
it("passes when the actual is called before the expected", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledBefore(),
|
||||
firstSpy = new jasmineUnderTest.Env().createSpy('first spy'),
|
||||
secondSpy = new jasmineUnderTest.Env().createSpy('second spy'),
|
||||
firstSpy = jasmineUnderTest.createSpy('first spy'),
|
||||
secondSpy = jasmineUnderTest.createSpy('second spy'),
|
||||
result;
|
||||
|
||||
firstSpy();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
describe("toHaveBeenCalled", function() {
|
||||
it("passes when the actual was called, with a custom .not fail message", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(),
|
||||
calledSpy = new jasmineUnderTest.Env().createSpy('called-spy'),
|
||||
calledSpy = jasmineUnderTest.createSpy('called-spy'),
|
||||
result;
|
||||
|
||||
calledSpy();
|
||||
@@ -13,7 +13,7 @@ describe("toHaveBeenCalled", function() {
|
||||
|
||||
it("fails when the actual was not called", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(),
|
||||
uncalledSpy = new jasmineUnderTest.Env().createSpy('uncalled spy'),
|
||||
uncalledSpy = jasmineUnderTest.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(uncalledSpy);
|
||||
@@ -29,14 +29,14 @@ describe("toHaveBeenCalled", function() {
|
||||
|
||||
it("throws an exception when invoked with any arguments", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(),
|
||||
spy = new jasmineUnderTest.Env().createSpy('sample spy');
|
||||
spy = jasmineUnderTest.createSpy('sample spy');
|
||||
|
||||
expect(function() { matcher.compare(spy, 'foo') }).toThrowError(Error, /Does not take arguments, use toHaveBeenCalledWith/);
|
||||
});
|
||||
|
||||
it("has a custom message on failure", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(),
|
||||
spy = new jasmineUnderTest.Env().createSpy('sample-spy'),
|
||||
spy = jasmineUnderTest.createSpy('sample-spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(spy);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
describe("toHaveBeenCalledTimes", function() {
|
||||
it("passes when the actual 0 matches the expected 0 ", function () {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
calledSpy = new jasmineUnderTest.Env().createSpy('called-spy'),
|
||||
calledSpy = jasmineUnderTest.createSpy('called-spy'),
|
||||
result;
|
||||
result = matcher.compare(calledSpy, 0);
|
||||
expect(result.pass).toBeTruthy();
|
||||
});
|
||||
it("passes when the actual matches the expected", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
calledSpy = new jasmineUnderTest.Env().createSpy('called-spy'),
|
||||
calledSpy = jasmineUnderTest.createSpy('called-spy'),
|
||||
result;
|
||||
calledSpy();
|
||||
|
||||
@@ -18,7 +18,7 @@ describe("toHaveBeenCalledTimes", function() {
|
||||
|
||||
it("fails when expected numbers is not supplied", function(){
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
spy = new jasmineUnderTest.Env().createSpy('spy'),
|
||||
spy = jasmineUnderTest.createSpy('spy'),
|
||||
result;
|
||||
|
||||
spy();
|
||||
@@ -29,7 +29,7 @@ describe("toHaveBeenCalledTimes", function() {
|
||||
|
||||
it("fails when the actual was called less than the expected", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
uncalledSpy = new jasmineUnderTest.Env().createSpy('uncalled spy'),
|
||||
uncalledSpy = jasmineUnderTest.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(uncalledSpy, 2);
|
||||
@@ -38,7 +38,7 @@ describe("toHaveBeenCalledTimes", function() {
|
||||
|
||||
it("fails when the actual was called more than expected", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
uncalledSpy = new jasmineUnderTest.Env().createSpy('uncalled spy'),
|
||||
uncalledSpy = jasmineUnderTest.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
uncalledSpy();
|
||||
@@ -59,7 +59,7 @@ describe("toHaveBeenCalledTimes", function() {
|
||||
|
||||
it("has a custom message on failure that tells it was called only once", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
spy = new jasmineUnderTest.Env().createSpy('sample-spy'),
|
||||
spy = jasmineUnderTest.createSpy('sample-spy'),
|
||||
result;
|
||||
spy();
|
||||
spy();
|
||||
@@ -72,7 +72,7 @@ describe("toHaveBeenCalledTimes", function() {
|
||||
|
||||
it("has a custom message on failure that tells how many times it was called", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveBeenCalledTimes(),
|
||||
spy = new jasmineUnderTest.Env().createSpy('sample-spy'),
|
||||
spy = jasmineUnderTest.createSpy('sample-spy'),
|
||||
result;
|
||||
spy();
|
||||
spy();
|
||||
|
||||
@@ -5,7 +5,7 @@ describe("toHaveBeenCalledWith", function() {
|
||||
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
|
||||
},
|
||||
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util),
|
||||
calledSpy = new jasmineUnderTest.Env().createSpy('called-spy'),
|
||||
calledSpy = jasmineUnderTest.createSpy('called-spy'),
|
||||
result;
|
||||
|
||||
calledSpy('a', 'b');
|
||||
@@ -21,7 +21,7 @@ describe("toHaveBeenCalledWith", function() {
|
||||
},
|
||||
customEqualityTesters = [function() { return true; }],
|
||||
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util, customEqualityTesters),
|
||||
calledSpy = new jasmineUnderTest.Env().createSpy('called-spy');
|
||||
calledSpy = jasmineUnderTest.createSpy('called-spy');
|
||||
|
||||
calledSpy('a', 'b');
|
||||
matcher.compare(calledSpy, 'a', 'b');
|
||||
@@ -34,7 +34,7 @@ describe("toHaveBeenCalledWith", function() {
|
||||
contains: jasmine.createSpy('delegated-contains').and.returnValue(false)
|
||||
},
|
||||
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util),
|
||||
uncalledSpy = new jasmineUnderTest.Env().createSpy('uncalled spy'),
|
||||
uncalledSpy = jasmineUnderTest.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(uncalledSpy);
|
||||
@@ -47,7 +47,7 @@ describe("toHaveBeenCalledWith", function() {
|
||||
contains: jasmine.createSpy('delegated-contains').and.returnValue(false)
|
||||
},
|
||||
matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(util),
|
||||
calledSpy = new jasmineUnderTest.Env().createSpy('called spy'),
|
||||
calledSpy = jasmineUnderTest.createSpy('called spy'),
|
||||
result;
|
||||
|
||||
calledSpy('a');
|
||||
|
||||
@@ -79,7 +79,7 @@ describe("toThrowError", function() {
|
||||
});
|
||||
|
||||
it("passes if thrown is an instanceof Error regardless of global that contains its constructor", function() {
|
||||
if (isNotRunningInBrowser()) {
|
||||
if (isNotRunningInBrowser() || jasmine.getEnv().phantomVersion < 2 || jasmine.getEnv().ieVersion < 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ describe("toThrowError", function() {
|
||||
iframeDocument.body.appendChild(iframeDocument.createElement("script"))
|
||||
.textContent = "function method() { throw new Error('foo'); }";
|
||||
} else {
|
||||
// IE 10 and older
|
||||
// older IE
|
||||
iframeDocument.write("<html><head><script>function method() { throw new Error('foo'); }</script></head></html>");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
describe("toThrowMatching", function() {
|
||||
it("throws an error when the actual is not a function", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toThrowMatching();
|
||||
|
||||
expect(function() {
|
||||
matcher.compare({}, function() { return true; });
|
||||
}).toThrowError(/Actual is not a Function/);
|
||||
});
|
||||
|
||||
it("throws an error when the expected is not a function", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toThrowMatching(),
|
||||
fn = function() {
|
||||
throw new Error("foo");
|
||||
};
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(fn, 1);
|
||||
}).toThrowError(/Predicate is not a Function/);
|
||||
});
|
||||
|
||||
it("fails if actual does not throw at all", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toThrowMatching(),
|
||||
fn = function() {
|
||||
return true;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, function() { return true; });
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an exception.");
|
||||
});
|
||||
|
||||
it("fails with the correct message if thrown is a falsy value", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toThrowMatching(),
|
||||
fn = function() {
|
||||
throw undefined;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, function() { return false; });
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message()).toEqual("Expected function to throw an exception matching a predicate, but it threw undefined.");
|
||||
});
|
||||
|
||||
it("passes if the argument is a function that returns true when called with the error", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toThrowMatching(),
|
||||
predicate = function(e) { return e.message === "nope" },
|
||||
fn = function() {
|
||||
throw new TypeError("nope");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, predicate);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw an exception matching a predicate.");
|
||||
});
|
||||
|
||||
it("fails if the argument is a function that returns false when called with the error", function() {
|
||||
var matcher = jasmineUnderTest.matchers.toThrowMatching(),
|
||||
predicate = function(e) { return e.message === "oh no" },
|
||||
fn = function() {
|
||||
throw new TypeError("nope");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, predicate);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message()).toEqual("Expected function to throw an exception matching a predicate, but it threw TypeError with message 'nope'.");
|
||||
});
|
||||
});
|
||||
@@ -8,8 +8,20 @@
|
||||
return match ? parseFloat(match[1]) : void 0;
|
||||
}
|
||||
|
||||
env.ieVersion = browserVersion(function(userAgent) {
|
||||
return /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
|
||||
});
|
||||
|
||||
env.safariVersion = browserVersion(function(userAgent) {
|
||||
return /Safari/.exec(userAgent) && /Version\/([0-9]{0,})/.exec(userAgent);
|
||||
});
|
||||
|
||||
env.firefoxVersion = browserVersion(function(userAgent) {
|
||||
return /Firefox\/([0-9]{0,})/.exec(userAgent);
|
||||
});
|
||||
|
||||
env.phantomVersion = browserVersion(function(userAgent) {
|
||||
return /PhantomJS\/([0-9]{0,})/.exec(userAgent);
|
||||
});
|
||||
|
||||
})(jasmine.getEnv());
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
// to the Jasmine source files (and not jasmine.js). So re-require
|
||||
window.jasmineUnderTest = jasmineRequire.core(jasmineRequire);
|
||||
jasmineRequire.html(jasmineUnderTest);
|
||||
jasmineRequire.console(jasmineRequire, jasmineUnderTest);
|
||||
})();
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
(function(env) {
|
||||
env.registerIntegrationMatchers = function() {
|
||||
jasmine.addMatchers({
|
||||
toHaveFailedExpectationsForRunnable: function (util, customeEqualityTesters) {
|
||||
return {
|
||||
compare: function (actual, fullName, expectedFailures) {
|
||||
var foundRunnable = false, expectations = true, foundFailures = [];
|
||||
for (var i = 0; i < actual.calls.count(); i++) {
|
||||
var args = actual.calls.argsFor(i)[0];
|
||||
|
||||
if (args.fullName === fullName) {
|
||||
foundRunnable = true;
|
||||
|
||||
for (var j = 0; j < args.failedExpectations.length; j++) {
|
||||
foundFailures.push(args.failedExpectations[j].message);
|
||||
}
|
||||
|
||||
for (var j = 0; j < expectedFailures.length; j++) {
|
||||
var failure = foundFailures[j];
|
||||
var expectedFailure = expectedFailures[j];
|
||||
|
||||
if (Object.prototype.toString.call(expectedFailure) === '[object RegExp]') {
|
||||
expectations = expectations && expectedFailure.test(failure);
|
||||
} else {
|
||||
expectations = expectations && failure === expectedFailure;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
pass: foundRunnable && expectations,
|
||||
message: !foundRunnable ? 'The runnable "' + fullName + '" never finished' :
|
||||
'Expected runnable "' + fullName + '" to have failures ' + jasmine.pp(expectedFailures) + ' but it had ' + jasmine.pp(foundFailures)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
})(jasmine.getEnv());
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
}
|
||||
|
||||
function getSourceFiles() {
|
||||
var src_files = ['core/**/*.js', 'version.js'];
|
||||
var src_files = ['core/**/*.js', 'console/**/*.js', 'version.js'];
|
||||
src_files.forEach(function(file) {
|
||||
var filePath = path.join(__dirname, "../../", 'src/', file);
|
||||
glob.sync(filePath).forEach(function(resolvedFile) {
|
||||
@@ -25,6 +25,9 @@
|
||||
});
|
||||
}
|
||||
|
||||
extend(jasmineUnderTestRequire, require(path.join(__dirname,"../../src/console/requireConsole.js")));
|
||||
getSourceFiles();
|
||||
global.jasmineUnderTest = jasmineUnderTestRequire.core(jasmineUnderTestRequire);
|
||||
|
||||
jasmineUnderTestRequire.console(jasmineUnderTestRequire, jasmineUnderTest);
|
||||
})();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe("HtmlReporter", function() {
|
||||
describe("New HtmlReporter", function() {
|
||||
it("builds the initial DOM elements, including the title banner", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
@@ -26,8 +26,9 @@ describe("HtmlReporter", function() {
|
||||
expect(title.getAttribute('href')).toEqual('http://jasmine.github.io/');
|
||||
expect(title.getAttribute('target')).toEqual('_blank');
|
||||
|
||||
var version = banner.querySelector(".jasmine-version");
|
||||
expect(version.textContent).toEqual(jasmineUnderTest.version);
|
||||
var version = banner.querySelector(".jasmine-version"),
|
||||
versionText = 'textContent' in version ? version.textContent : version.innerText;
|
||||
expect(versionText).toEqual(jasmineUnderTest.version);
|
||||
});
|
||||
|
||||
it("builds a single reporter even if initialized multiple times", function() {
|
||||
@@ -92,7 +93,7 @@ describe("HtmlReporter", function() {
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-empty");
|
||||
});
|
||||
|
||||
it("reports the status symbol of a excluded spec", function() {
|
||||
it("reports the status symbol of a disabled spec", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
@@ -104,10 +105,10 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
reporter.initialize();
|
||||
|
||||
reporter.specDone({id: 789, status: "excluded", fullName: "symbols should have titles", passedExpectations: [], failedExpectations: []});
|
||||
reporter.specDone({id: 789, status: "disabled", fullName: "symbols should have titles", passedExpectations: [], failedExpectations: []});
|
||||
|
||||
var specEl = container.querySelector('.jasmine-symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-excluded");
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-disabled");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_789");
|
||||
expect(specEl.getAttribute("title")).toEqual("symbols should have titles");
|
||||
});
|
||||
@@ -177,6 +178,36 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("when there are suite failures", function () {
|
||||
it("displays the exceptions in their own alert bars", function(){
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.suiteDone({ status: 'failed', failedExpectations: [{ message: 'My After All Exception' }] });
|
||||
reporter.suiteDone({ status: 'failed', failedExpectations: [{ message: 'My Other Exception' }] });
|
||||
reporter.jasmineDone({ failedExpectations: [{ message: 'Global After All Failure' }, { message: 'Other Global' }] });
|
||||
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(5);
|
||||
expect(alertBars[1].innerHTML).toMatch(/My After All Exception/);
|
||||
expect(alertBars[1].getAttribute("class")).toEqual('jasmine-bar jasmine-errored');
|
||||
expect(alertBars[2].innerHTML).toMatch(/My Other Exception/);
|
||||
expect(alertBars[3].innerHTML).toMatch(/Global After All Failure/);
|
||||
expect(alertBars[4].innerHTML).toMatch(/Other Global/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there are deprecation warnings', function() {
|
||||
it('displays the messages in their own alert bars', function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
@@ -275,7 +306,7 @@ describe("HtmlReporter", function() {
|
||||
reporter.jasmineStarted({});
|
||||
|
||||
timer.elapsed.and.returnValue(100);
|
||||
reporter.jasmineDone({});
|
||||
reporter.jasmineDone();
|
||||
|
||||
var duration = container.querySelector(".jasmine-alert .jasmine-duration");
|
||||
expect(duration.innerHTML).toMatch(/finished in 0.1s/);
|
||||
@@ -329,12 +360,7 @@ describe("HtmlReporter", function() {
|
||||
reporter.specStarted(specResult);
|
||||
reporter.specDone(specResult);
|
||||
|
||||
reporter.suiteDone({
|
||||
id: 2,
|
||||
status: 'things',
|
||||
description: "inner suite",
|
||||
fullName: "A Suite inner suite"
|
||||
});
|
||||
reporter.suiteDone({id: 2});
|
||||
|
||||
specResult = {
|
||||
id: 209,
|
||||
@@ -347,12 +373,7 @@ describe("HtmlReporter", function() {
|
||||
reporter.specStarted(specResult);
|
||||
reporter.specDone(specResult);
|
||||
|
||||
reporter.suiteDone({
|
||||
id: 1,
|
||||
status: 'things',
|
||||
description: "A Suite",
|
||||
fullName: "A Suite"
|
||||
});
|
||||
reporter.suiteDone({id: 1});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
var summary = container.querySelector(".jasmine-summary");
|
||||
@@ -367,7 +388,7 @@ describe("HtmlReporter", function() {
|
||||
var node = outerSuite.childNodes[i];
|
||||
classes.push(node.getAttribute("class"));
|
||||
}
|
||||
expect(classes).toEqual(["jasmine-suite-detail jasmine-things", "jasmine-specs", "jasmine-suite", "jasmine-specs"]);
|
||||
expect(classes).toEqual(["jasmine-suite-detail", "jasmine-specs", "jasmine-suite", "jasmine-specs"]);
|
||||
|
||||
var suiteDetail = outerSuite.childNodes[0];
|
||||
var suiteLink = suiteDetail.childNodes[0];
|
||||
@@ -382,6 +403,7 @@ describe("HtmlReporter", function() {
|
||||
var specLink = spec.childNodes[0];
|
||||
expect(specLink.innerHTML).toEqual("with a spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?foo=bar&spec=A Suite with a spec");
|
||||
// expect(specLink.getAttribute("title")).toEqual("A Suite with a spec");
|
||||
});
|
||||
|
||||
it("has an options menu", function() {
|
||||
@@ -407,78 +429,19 @@ describe("HtmlReporter", function() {
|
||||
var trigger = container.querySelector('.jasmine-run-options .jasmine-trigger'),
|
||||
payload = container.querySelector('.jasmine-run-options .jasmine-payload');
|
||||
|
||||
expect(payload).not.toHaveClass('jasmine-open');
|
||||
expect(payload.className).not.toContain('jasmine-open');
|
||||
|
||||
trigger.onclick();
|
||||
|
||||
expect(payload).toHaveClass('jasmine-open');
|
||||
expect(payload.className).toContain('jasmine-open');
|
||||
|
||||
trigger.onclick();
|
||||
|
||||
expect(payload).not.toHaveClass('jasmine-open');
|
||||
expect(payload.className).not.toContain('jasmine-open');
|
||||
});
|
||||
|
||||
describe("when there are global errors", function() {
|
||||
it("displays the exceptions in their own alert bars", function(){
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({ failedExpectations: [
|
||||
{ message: 'Global After All Failure', globalErrorType: 'afterAll' },
|
||||
{ message: 'Your JS is borken', globalErrorType: 'load' }
|
||||
] });
|
||||
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(3);
|
||||
expect(alertBars[1].getAttribute("class")).toEqual('jasmine-bar jasmine-errored');
|
||||
expect(alertBars[1].innerHTML).toMatch(/AfterAll Global After All Failure/);
|
||||
expect(alertBars[2].innerHTML).toMatch(/Error during loading: Your JS is borken/);
|
||||
expect(alertBars[2].innerHTML).not.toMatch(/line/);
|
||||
});
|
||||
|
||||
it("displays file and line information if available", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({ failedExpectations: [
|
||||
{
|
||||
message: 'Your JS is borken',
|
||||
globalErrorType: 'load',
|
||||
filename: 'some/file.js',
|
||||
lineno: 42
|
||||
}
|
||||
] });
|
||||
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(2);
|
||||
expect(alertBars[1].innerHTML).toMatch(/Error during loading: Your JS is borken in some\/file.js line 42/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("UI for stop on spec failure", function() {
|
||||
it("should be unchecked for full execution", function() {
|
||||
describe("UI for raising/catching exceptions", function() {
|
||||
it("should be unchecked if the env is catching", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() {
|
||||
@@ -498,11 +461,11 @@ describe("HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var stopOnFailureUI = container.querySelector(".jasmine-fail-fast");
|
||||
expect(stopOnFailureUI.checked).toBe(false);
|
||||
var raisingExceptionsUI = container.querySelector(".jasmine-raise");
|
||||
expect(raisingExceptionsUI.checked).toBe(false);
|
||||
});
|
||||
|
||||
it("should be checked if stopping short", function() {
|
||||
it("should be checked if the env is not catching", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() {
|
||||
@@ -519,26 +482,25 @@ describe("HtmlReporter", function() {
|
||||
}
|
||||
});
|
||||
|
||||
env.stopOnSpecFailure(true);
|
||||
|
||||
reporter.initialize();
|
||||
env.catchExceptions(false);
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var stopOnFailureUI = container.querySelector(".jasmine-fail-fast");
|
||||
expect(stopOnFailureUI.checked).toBe(true);
|
||||
var raisingExceptionsUI = container.querySelector(".jasmine-raise");
|
||||
expect(raisingExceptionsUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("should navigate and turn the setting on", function() {
|
||||
it("should affect the query param for catching exceptions", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
navigationHandler = jasmine.createSpy('navigate'),
|
||||
exceptionsClickHandler = jasmine.createSpy("raise exceptions checked"),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
navigateWithNewParam: navigationHandler,
|
||||
getContainer: getContainer,
|
||||
onRaiseExceptionsClick: exceptionsClickHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
@@ -550,40 +512,9 @@ describe("HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var stopOnFailureUI = container.querySelector(".jasmine-fail-fast");
|
||||
stopOnFailureUI.click();
|
||||
|
||||
expect(navigationHandler).toHaveBeenCalledWith('failFast', true);
|
||||
});
|
||||
|
||||
it("should navigate and turn the setting off", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
navigationHandler = jasmine.createSpy('navigate'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
navigateWithNewParam: navigationHandler,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
env.stopOnSpecFailure(true);
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var stopOnFailureUI = container.querySelector(".jasmine-fail-fast");
|
||||
stopOnFailureUI.click();
|
||||
|
||||
expect(navigationHandler).toHaveBeenCalledWith('failFast', false);
|
||||
var input = container.querySelector(".jasmine-raise");
|
||||
input.click();
|
||||
expect(exceptionsClickHandler).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -638,17 +569,17 @@ describe("HtmlReporter", function() {
|
||||
expect(throwingExpectationsUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("should navigate and change the setting to on", function() {
|
||||
it("should affect the query param for throw expectation failures", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
navigateHandler = jasmine.createSpy('navigate'),
|
||||
throwingExceptionHandler = jasmine.createSpy('throwingExceptions'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
navigateWithNewParam: navigateHandler,
|
||||
onThrowExpectationsClick: throwingExceptionHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
@@ -663,37 +594,7 @@ describe("HtmlReporter", function() {
|
||||
var throwingExpectationsUI = container.querySelector(".jasmine-throw");
|
||||
throwingExpectationsUI.click();
|
||||
|
||||
expect(navigateHandler).toHaveBeenCalledWith('throwFailures', true);
|
||||
});
|
||||
|
||||
it("should navigate and change the setting to off", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
navigateHandler = jasmine.createSpy('navigate'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
navigateWithNewParam: navigateHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
env.throwOnExpectationFailure(true);
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var throwingExpectationsUI = container.querySelector(".jasmine-throw");
|
||||
throwingExpectationsUI.click();
|
||||
|
||||
expect(navigateHandler).toHaveBeenCalledWith('throwFailures', false);
|
||||
expect(throwingExceptionHandler).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -715,7 +616,6 @@ describe("HtmlReporter", function() {
|
||||
}
|
||||
});
|
||||
|
||||
env.randomizeTests(false);
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
@@ -748,17 +648,17 @@ describe("HtmlReporter", function() {
|
||||
expect(randomUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("should navigate and change the setting to on", function() {
|
||||
it("should affect the query param for random tests", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
navigateHandler = jasmine.createSpy('navigate'),
|
||||
randomHandler = jasmine.createSpy('randomHandler'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
navigateWithNewParam: navigateHandler,
|
||||
onRandomClick: randomHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
@@ -767,43 +667,13 @@ describe("HtmlReporter", function() {
|
||||
}
|
||||
});
|
||||
|
||||
env.randomizeTests(false);
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var randomUI = container.querySelector(".jasmine-random");
|
||||
randomUI.click();
|
||||
|
||||
expect(navigateHandler).toHaveBeenCalledWith('random', true);
|
||||
});
|
||||
|
||||
it("should navigate and change the setting to off", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
navigateHandler = jasmine.createSpy('navigate'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
navigateWithNewParam: navigateHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
env.randomizeTests(true);
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var randomUI = container.querySelector(".jasmine-random");
|
||||
randomUI.click();
|
||||
|
||||
expect(navigateHandler).toHaveBeenCalledWith('random', false);
|
||||
expect(randomHandler).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should show the seed bar if randomizing", function() {
|
||||
@@ -832,7 +702,8 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
|
||||
var seedBar = container.querySelector(".jasmine-seed-bar");
|
||||
expect(seedBar.textContent).toBe(', randomized with seed 424242');
|
||||
var seedBarText = 'textContent' in seedBar ? seedBar.textContent : seedBar.innerText;
|
||||
expect(seedBarText).toBe(', randomized with seed 424242');
|
||||
var seedLink = container.querySelector(".jasmine-seed-bar a");
|
||||
expect(seedLink.getAttribute('href')).toBe('?seed=424242');
|
||||
});
|
||||
@@ -855,7 +726,7 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
reporter.jasmineDone();
|
||||
|
||||
var seedBar = container.querySelector(".jasmine-seed-bar");
|
||||
expect(seedBar).toBeNull();
|
||||
@@ -881,6 +752,27 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
it("shows a message if no specs are run", function(){
|
||||
var env, container, reporter;
|
||||
env = new jasmineUnderTest.Env();
|
||||
container = document.createElement("div");
|
||||
var getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/jasmine-skipped/);
|
||||
expect(alertBars[0].innerHTML).toMatch(/No specs found/);
|
||||
});
|
||||
|
||||
describe("and all specs pass", function() {
|
||||
var env, container, reporter;
|
||||
beforeEach(function() {
|
||||
@@ -919,6 +811,7 @@ describe("HtmlReporter", function() {
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(1);
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/jasmine-passed/);
|
||||
expect(alertBars[0].innerHTML).toMatch(/2 specs, 0 failures/);
|
||||
});
|
||||
|
||||
@@ -935,7 +828,7 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("and there are excluded specs", function() {
|
||||
describe("and there are disabled specs", function() {
|
||||
var env, container, reporter, reporterConfig, specStatus;
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
@@ -948,9 +841,9 @@ describe("HtmlReporter", function() {
|
||||
};
|
||||
specStatus = {
|
||||
id: 123,
|
||||
description: "with a excluded spec",
|
||||
fullName: "A Suite with a excluded spec",
|
||||
status: "excluded",
|
||||
description: "with a disabled spec",
|
||||
fullName: "A Suite with a disabled spec",
|
||||
status: "disabled",
|
||||
passedExpectations: [],
|
||||
failedExpectations: []
|
||||
};
|
||||
@@ -967,10 +860,10 @@ describe("HtmlReporter", function() {
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
it("shows the excluded spec in the spec list", function() {
|
||||
it("shows the disabled spec in the spec list", function() {
|
||||
var specList = container.querySelector(".jasmine-summary");
|
||||
|
||||
expect(specList.innerHTML).toContain('with a excluded spec');
|
||||
expect(specList.innerHTML).toContain('with a disabled spec');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -985,7 +878,7 @@ describe("HtmlReporter", function() {
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
it("doesn't show the excluded spec in the spec list", function() {
|
||||
it("doesn't show the disabled spec in the spec list", function() {
|
||||
var specList = container.querySelector(".jasmine-summary");
|
||||
|
||||
expect(specList.innerHTML).toEqual('');
|
||||
@@ -1058,24 +951,16 @@ describe("HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({ totalSpecsDefined: 1 });
|
||||
reporter.suiteStarted({
|
||||
id: 1,
|
||||
description: "A suite"
|
||||
});
|
||||
reporter.suiteStarted({
|
||||
id: 2,
|
||||
description: "inner suite"
|
||||
});
|
||||
|
||||
var passingSpecResult = {id: 123, status: "passed", passedExpectations: [{passed: true}], failedExpectations: []};
|
||||
reporter.specStarted(passingSpecResult);
|
||||
reporter.specDone(passingSpecResult);
|
||||
var passingResult = {id: 123, status: "passed", passedExpectations: [{passed: true}], failedExpectations: []};
|
||||
reporter.specStarted(passingResult);
|
||||
reporter.specDone(passingResult);
|
||||
|
||||
var failingSpecResult = {
|
||||
var failingResult = {
|
||||
id: 124,
|
||||
status: "failed",
|
||||
description: "a failing spec",
|
||||
fullName: "a suite inner suite a failing spec",
|
||||
fullName: "a suite with a failing spec",
|
||||
passedExpectations: [],
|
||||
failedExpectations: [
|
||||
{
|
||||
@@ -1084,83 +969,39 @@ describe("HtmlReporter", function() {
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var passingSuiteResult = {
|
||||
id: 1,
|
||||
description: "A suite"
|
||||
};
|
||||
var failingSuiteResult = {
|
||||
id: 2,
|
||||
description: 'a suite',
|
||||
fullName: 'a suite',
|
||||
status: 'failed',
|
||||
failedExpectations: [{ message: 'My After All Exception' }]
|
||||
};
|
||||
reporter.specStarted(failingSpecResult);
|
||||
reporter.specDone(failingSpecResult);
|
||||
reporter.suiteDone(passingSuiteResult);
|
||||
reporter.suiteDone(failingSuiteResult);
|
||||
reporter.suiteDone(passingSuiteResult);
|
||||
reporter.specStarted(failingResult);
|
||||
reporter.specDone(failingResult);
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
it("reports the specs counts", function() {
|
||||
var alertBar = container.querySelector(".jasmine-alert .jasmine-bar");
|
||||
expect(alertBar.innerHTML).toMatch(/2 specs, 2 failure/);
|
||||
|
||||
expect(alertBar.getAttribute('class')).toMatch(/jasmine-failed/);
|
||||
expect(alertBar.innerHTML).toMatch(/2 specs, 1 failure/);
|
||||
});
|
||||
|
||||
it("reports failure messages and stack traces", function() {
|
||||
var specFailures = container.querySelector(".jasmine-failures");
|
||||
|
||||
expect(specFailures.childNodes.length).toEqual(2);
|
||||
var failure = specFailures.childNodes[0];
|
||||
expect(failure.getAttribute("class")).toMatch(/jasmine-failed/);
|
||||
expect(failure.getAttribute("class")).toMatch(/jasmine-spec-detail/);
|
||||
|
||||
var specFailure = specFailures.childNodes[0];
|
||||
expect(specFailure.getAttribute("class")).toMatch(/jasmine-failed/);
|
||||
expect(specFailure.getAttribute("class")).toMatch(/jasmine-spec-detail/);
|
||||
|
||||
var specDiv = specFailure.childNodes[0];
|
||||
var specDiv = failure.childNodes[0];
|
||||
expect(specDiv.getAttribute("class")).toEqual("jasmine-description");
|
||||
|
||||
var message = specFailure.childNodes[1].childNodes[0];
|
||||
var specLink = specDiv.childNodes[0];
|
||||
expect(specLink.getAttribute("title")).toEqual("a suite with a failing spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?foo=bar&spec=a suite with a failing spec");
|
||||
|
||||
var message = failure.childNodes[1].childNodes[0];
|
||||
expect(message.getAttribute("class")).toEqual("jasmine-result-message");
|
||||
expect(message.innerHTML).toEqual("a failure message");
|
||||
|
||||
var stackTrace = specFailure.childNodes[1].childNodes[1];
|
||||
var stackTrace = failure.childNodes[1].childNodes[1];
|
||||
expect(stackTrace.getAttribute("class")).toEqual("jasmine-stack-trace");
|
||||
expect(stackTrace.innerHTML).toEqual("a stack trace");
|
||||
|
||||
var suiteFailure = specFailures.childNodes[0];
|
||||
expect(suiteFailure.getAttribute("class")).toMatch(/jasmine-failed/);
|
||||
expect(suiteFailure.getAttribute("class")).toMatch(/jasmine-spec-detail/);
|
||||
|
||||
var suiteDiv = suiteFailure.childNodes[0];
|
||||
expect(suiteDiv.getAttribute("class")).toEqual("jasmine-description");
|
||||
|
||||
var suiteMessage = suiteFailure.childNodes[1].childNodes[0];
|
||||
expect(suiteMessage.getAttribute("class")).toEqual("jasmine-result-message");
|
||||
expect(suiteMessage.innerHTML).toEqual("a failure message");
|
||||
|
||||
var suiteStackTrace = suiteFailure.childNodes[1].childNodes[1];
|
||||
expect(suiteStackTrace.getAttribute("class")).toEqual("jasmine-stack-trace");
|
||||
expect(suiteStackTrace.innerHTML).toEqual("a stack trace");
|
||||
});
|
||||
|
||||
it('provides links to focus on a failure and each containing suite', function() {
|
||||
var description = container.querySelector('.jasmine-failures .jasmine-description');
|
||||
var links = description.querySelectorAll('a');
|
||||
|
||||
expect(description.textContent).toEqual('A suite > inner suite > a failing spec');
|
||||
|
||||
expect(links.length).toEqual(3);
|
||||
expect(links[0].textContent).toEqual('A suite');
|
||||
|
||||
expect(links[0].getAttribute('href')).toMatch(/\?foo=bar&spec=A suite/);
|
||||
|
||||
expect(links[1].textContent).toEqual('inner suite');
|
||||
expect(links[1].getAttribute('href')).toMatch(/\?foo=bar&spec=A suite inner suite/);
|
||||
|
||||
expect(links[2].textContent).toEqual('a failing spec');
|
||||
expect(links[2].getAttribute('href')).toMatch(/\?foo=bar&spec=a suite inner suite a failing spec/);
|
||||
});
|
||||
|
||||
it("allows switching between failure details and the spec summary", function() {
|
||||
@@ -1179,83 +1020,4 @@ describe("HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("The overall result bar", function() {
|
||||
describe("When the jasmineDone event's overallStatus is 'passed'", function() {
|
||||
it("has class jasmine-passed", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({
|
||||
overallStatus: 'passed',
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
var alertBar = container.querySelector(".jasmine-overall-result");
|
||||
expect(alertBar).toHaveClass("jasmine-passed");
|
||||
});
|
||||
});
|
||||
|
||||
describe("When the jasmineDone event's overallStatus is 'failed'", function() {
|
||||
it("has class jasmine-failed", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({
|
||||
overallStatus: 'failed',
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
var alertBar = container.querySelector(".jasmine-overall-result");
|
||||
expect(alertBar).toHaveClass("jasmine-failed");
|
||||
});
|
||||
});
|
||||
|
||||
describe("When the jasmineDone event's overallStatus is 'incomplete'", function() {
|
||||
it("has class jasmine-incomplete", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({
|
||||
overallStatus: 'incomplete',
|
||||
incompleteReason: 'because nope',
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
var alertBar = container.querySelector(".jasmine-overall-result");
|
||||
expect(alertBar).toHaveClass("jasmine-incomplete");
|
||||
expect(alertBar.textContent).toContain("Incomplete: because nope");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
describe("jasmineUnderTest.pp (HTML Dependent)", function () {
|
||||
it("should stringify non-element HTML nodes properly", function() {
|
||||
var sampleNode = document.createTextNode("");
|
||||
it("should stringify HTML nodes properly", function() {
|
||||
var sampleNode = document.createElement('div');
|
||||
sampleNode.innerHTML = 'foo<b>bar</b>';
|
||||
expect(jasmineUnderTest.pp(sampleNode)).toEqual("HTMLNode");
|
||||
expect(jasmineUnderTest.pp({foo: sampleNode})).toEqual("Object({ foo: HTMLNode })");
|
||||
});
|
||||
|
||||
it("should stringify empty HTML elements as their opening tags", function () {
|
||||
var simple = document.createElement('div');
|
||||
simple.className = 'foo';
|
||||
expect(jasmineUnderTest.pp(simple)).toEqual('<div class="foo">');
|
||||
});
|
||||
|
||||
it("should stringify non-empty HTML elements as tags with placeholders", function() {
|
||||
var nonEmpty = document.createElement('div');
|
||||
nonEmpty.className = 'foo';
|
||||
nonEmpty.innerHTML = '<p>Irrelevant</p>';
|
||||
expect(jasmineUnderTest.pp(nonEmpty)).toEqual('<div class="foo">...</div>');
|
||||
});
|
||||
|
||||
it("should print Firefox's wrapped native objects correctly", function() {
|
||||
if(jasmine.getEnv().firefoxVersion) {
|
||||
try { new CustomEvent(); } catch(e) { var err = e; };
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
describe('Spy Registry browser-specific behavior', function() {
|
||||
function createSpy(name, originalFn) {
|
||||
return jasmineUnderTest.Spy(name, originalFn);
|
||||
}
|
||||
|
||||
it('can spy on and unspy window.onerror', function() {
|
||||
requireWriteableOnerror();
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
createSpy: createSpy,
|
||||
global: window
|
||||
}),
|
||||
currentSpies: function() { return spies; },
|
||||
global: window
|
||||
}),
|
||||
originalHandler = window.onerror;
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
describe('toHaveClass', function() {
|
||||
it('fails for a DOM element that lacks the expected class', function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveClass(),
|
||||
result = matcher.compare(document.createElement('div'), 'foo');
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it('passes for a DOM element that has the expected class', function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveClass(),
|
||||
el = document.createElement('div');
|
||||
|
||||
el.className = 'foo bar baz';
|
||||
|
||||
expect(matcher.compare(el, 'foo').pass).toBe(true);
|
||||
expect(matcher.compare(el, 'bar').pass).toBe(true);
|
||||
expect(matcher.compare(el, 'bar').pass).toBe(true);
|
||||
});
|
||||
|
||||
it('fails for a DOM element that only has other classes', function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveClass(),
|
||||
el = document.createElement('div');
|
||||
|
||||
el.className = 'foo bar';
|
||||
|
||||
expect(matcher.compare(el, 'fo').pass).toBe(false);
|
||||
});
|
||||
|
||||
it('throws an exception when actual is not a DOM element', function() {
|
||||
var matcher = jasmineUnderTest.matchers.toHaveClass();
|
||||
|
||||
expect(function() {
|
||||
matcher.compare('x', 'foo');
|
||||
}).toThrowError("'x' is not a DOM element");
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(undefined, 'foo');
|
||||
}).toThrowError('undefined is not a DOM element');
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(document.createTextNode(''), 'foo')
|
||||
}).toThrowError('HTMLNode is not a DOM element');
|
||||
|
||||
expect(function() {
|
||||
matcher.compare({classList: ''}, 'foo');
|
||||
}).toThrowError("Object({ classList: '' }) is not a DOM element");
|
||||
});
|
||||
});
|
||||
@@ -2,6 +2,7 @@
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"core/**/*.js",
|
||||
"console/**/*.js",
|
||||
"npmPackage/**/*.js"
|
||||
],
|
||||
"helpers": [
|
||||
@@ -10,7 +11,6 @@
|
||||
"helpers/checkForSet.js",
|
||||
"helpers/checkForSymbol.js",
|
||||
"helpers/checkForTypedArrays.js",
|
||||
"helpers/integrationMatchers.js",
|
||||
"helpers/nodeDefineJasmineUnderTest.js"
|
||||
],
|
||||
"random": true
|
||||
|
||||
@@ -13,7 +13,7 @@ src_files:
|
||||
- 'core/PrettyPrinter.js'
|
||||
- 'core/Suite.js'
|
||||
- 'core/**/*.js'
|
||||
- 'html/**/*.js'
|
||||
- 'html/**.js'
|
||||
- '**/*.js'
|
||||
stylesheets:
|
||||
helpers:
|
||||
@@ -23,7 +23,6 @@ helpers:
|
||||
- 'helpers/checkForSet.js'
|
||||
- 'helpers/checkForSymbol.js'
|
||||
- 'helpers/checkForTypedArrays.js'
|
||||
- 'helpers/integrationMatchers.js'
|
||||
- 'helpers/defineJasmineUnderTest.js'
|
||||
spec_files:
|
||||
- '**/*[Ss]pec.js'
|
||||
|
||||
155
src/console/ConsoleReporter.js
Normal file
155
src/console/ConsoleReporter.js
Normal file
@@ -0,0 +1,155 @@
|
||||
getJasmineRequireObj().ConsoleReporter = function() {
|
||||
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
function ConsoleReporter(options) {
|
||||
var print = options.print,
|
||||
showColors = options.showColors || false,
|
||||
onComplete = options.onComplete || function() {},
|
||||
timer = options.timer || noopTimer,
|
||||
specCount,
|
||||
failureCount,
|
||||
failedSpecs = [],
|
||||
pendingCount,
|
||||
ansi = {
|
||||
green: '\x1B[32m',
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
print('ConsoleReporter is deprecated and will be removed in a future version.');
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
failureCount = 0;
|
||||
pendingCount = 0;
|
||||
print('Started');
|
||||
printNewline();
|
||||
timer.start();
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
printNewline();
|
||||
for (var i = 0; i < failedSpecs.length; i++) {
|
||||
specFailureDetails(failedSpecs[i]);
|
||||
}
|
||||
|
||||
if(specCount > 0) {
|
||||
printNewline();
|
||||
|
||||
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
|
||||
failureCount + ' ' + plural('failure', failureCount);
|
||||
|
||||
if (pendingCount) {
|
||||
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
|
||||
}
|
||||
|
||||
print(specCounts);
|
||||
} else {
|
||||
print('No specs found');
|
||||
}
|
||||
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
this.specDone = function(result) {
|
||||
specCount++;
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingCount++;
|
||||
print(colored('yellow', '*'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'passed') {
|
||||
print(colored('green', '.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
failedSpecs.push(result);
|
||||
print(colored('red', 'F'));
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
print('\n');
|
||||
}
|
||||
|
||||
function colored(color, str) {
|
||||
return showColors ? (ansi[color] + str + ansi.none) : str;
|
||||
}
|
||||
|
||||
function plural(str, count) {
|
||||
return count == 1 ? str : str + 's';
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) {
|
||||
arr.push(thing);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
function indent(str, spaces) {
|
||||
var lines = (str || '').split('\n');
|
||||
var newArr = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
newArr.push(repeat(' ', spaces).join('') + lines[i]);
|
||||
}
|
||||
return newArr.join('\n');
|
||||
}
|
||||
|
||||
function specFailureDetails(result) {
|
||||
printNewline();
|
||||
print(result.fullName);
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var failedExpectation = result.failedExpectations[i];
|
||||
printNewline();
|
||||
print(indent(failedExpectation.message, 2));
|
||||
print(indent(failedExpectation.stack, 2));
|
||||
}
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
};
|
||||
12
src/console/requireConsole.js
Normal file
12
src/console/requireConsole.js
Normal file
@@ -0,0 +1,12 @@
|
||||
function getJasmineRequireObj() {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
return exports;
|
||||
} else {
|
||||
window.jasmineRequire = window.jasmineRequire || {};
|
||||
return window.jasmineRequire;
|
||||
}
|
||||
}
|
||||
|
||||
getJasmineRequireObj().console = function(jRequire, j$) {
|
||||
j$.ConsoleReporter = jRequire.ConsoleReporter();
|
||||
};
|
||||
@@ -87,10 +87,22 @@ getJasmineRequireObj().Clock = function() {
|
||||
};
|
||||
|
||||
self.setTimeout = function(fn, delay, params) {
|
||||
if (legacyIE()) {
|
||||
if (arguments.length > 2) {
|
||||
throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill');
|
||||
}
|
||||
return timer.setTimeout(fn, delay);
|
||||
}
|
||||
return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
|
||||
};
|
||||
|
||||
self.setInterval = function(fn, delay, params) {
|
||||
if (legacyIE()) {
|
||||
if (arguments.length > 2) {
|
||||
throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill');
|
||||
}
|
||||
return timer.setInterval(fn, delay);
|
||||
}
|
||||
return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
|
||||
};
|
||||
|
||||
@@ -125,6 +137,11 @@ getJasmineRequireObj().Clock = function() {
|
||||
global.clearInterval === realTimingFunctions.clearInterval;
|
||||
}
|
||||
|
||||
function legacyIE() {
|
||||
//if these methods are polyfilled, apply will be present
|
||||
return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
|
||||
}
|
||||
|
||||
function replace(dest, source) {
|
||||
for (var prop in source) {
|
||||
dest[prop] = source[prop];
|
||||
|
||||
@@ -147,7 +147,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
}
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
});
|
||||
deletedKeys = [];
|
||||
} while (scheduledLookup.length > 0 &&
|
||||
// checking first if we're out of time prevents setTimeout(0)
|
||||
// scheduled in a funcToRun from forcing an extra iteration
|
||||
|
||||
538
src/core/Env.js
538
src/core/Env.js
@@ -11,8 +11,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var self = this;
|
||||
var global = options.global || j$.getGlobal();
|
||||
|
||||
var hasExecuted = false;
|
||||
|
||||
var totalSpecsDefined = 0;
|
||||
|
||||
var catchExceptions = true;
|
||||
|
||||
var realSetTimeout = j$.getGlobal().setTimeout;
|
||||
var realClearTimeout = j$.getGlobal().clearTimeout;
|
||||
var clearStack = j$.getClearStack(j$.getGlobal());
|
||||
@@ -24,11 +28,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
var throwOnExpectationFailure = false;
|
||||
var stopOnSpecFailure = false;
|
||||
var random = true;
|
||||
var random = false;
|
||||
var seed = null;
|
||||
var handlingLoadErrors = true;
|
||||
var hasFailures = false;
|
||||
|
||||
var currentSuite = function() {
|
||||
return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
|
||||
@@ -38,210 +39,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return currentSpec || currentSuite();
|
||||
};
|
||||
|
||||
var globalErrors = new j$.GlobalErrors();
|
||||
globalErrors.install();
|
||||
globalErrors.pushListener(function(message, filename, lineno) {
|
||||
topSuite.result.failedExpectations.push({
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: message,
|
||||
filename: filename,
|
||||
lineno: lineno
|
||||
});
|
||||
});
|
||||
|
||||
this.specFilter = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
this.addSpyStrategy = function(name, fn) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Custom spy strategies must be added in a before function or a spec');
|
||||
}
|
||||
runnableResources[currentRunnable().id].customSpyStrategies[name] = fn;
|
||||
};
|
||||
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Custom Equalities must be added in a before function or a spec');
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Matchers must be added in a before function or a spec');
|
||||
}
|
||||
var customMatchers = runnableResources[currentRunnable().id].customMatchers;
|
||||
for (var matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
|
||||
var nextSpecId = 0;
|
||||
var getNextSpecId = function() {
|
||||
return 'spec' + nextSpecId++;
|
||||
};
|
||||
|
||||
var nextSuiteId = 0;
|
||||
var getNextSuiteId = function() {
|
||||
return 'suite' + nextSuiteId++;
|
||||
};
|
||||
|
||||
var expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.Factory({
|
||||
util: j$.matchersUtil,
|
||||
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
function addExpectationResult(passed, result) {
|
||||
return spec.addExpectationResult(passed, result);
|
||||
}
|
||||
};
|
||||
|
||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}, customSpyStrategies: {}};
|
||||
|
||||
if(runnableResources[parentRunnableId]){
|
||||
resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
|
||||
resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
};
|
||||
|
||||
var clearResourcesForRunnable = function(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
};
|
||||
|
||||
var beforeAndAfterFns = function(suite) {
|
||||
return function() {
|
||||
var befores = [],
|
||||
afters = [];
|
||||
|
||||
while(suite) {
|
||||
befores = befores.concat(suite.beforeFns);
|
||||
afters = afters.concat(suite.afterFns);
|
||||
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
|
||||
return {
|
||||
befores: befores.reverse(),
|
||||
afters: afters
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
var getSpecName = function(spec, suite) {
|
||||
var fullName = [spec.description],
|
||||
suiteFullName = suite.getFullName();
|
||||
|
||||
if (suiteFullName !== '') {
|
||||
fullName.unshift(suiteFullName);
|
||||
}
|
||||
return fullName.join(' ');
|
||||
};
|
||||
|
||||
// TODO: we may just be able to pass in the fn instead of wrapping here
|
||||
var buildExpectationResult = j$.buildExpectationResult,
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
expectationResultFactory = function(attrs) {
|
||||
attrs.messageFormatter = exceptionFormatter.message;
|
||||
attrs.stackFormatter = exceptionFormatter.stack;
|
||||
|
||||
return buildExpectationResult(attrs);
|
||||
};
|
||||
|
||||
var maximumSpecCallbackDepth = 20;
|
||||
var currentSpecCallbackDepth = 0;
|
||||
|
||||
this.throwOnExpectationFailure = function(value) {
|
||||
throwOnExpectationFailure = !!value;
|
||||
};
|
||||
|
||||
this.throwingExpectationFailures = function() {
|
||||
return throwOnExpectationFailure;
|
||||
};
|
||||
|
||||
this.stopOnSpecFailure = function(value) {
|
||||
stopOnSpecFailure = !!value;
|
||||
};
|
||||
|
||||
this.stoppingOnSpecFailure = function() {
|
||||
return stopOnSpecFailure;
|
||||
};
|
||||
|
||||
this.randomizeTests = function(value) {
|
||||
random = !!value;
|
||||
};
|
||||
|
||||
this.randomTests = function() {
|
||||
return random;
|
||||
};
|
||||
|
||||
this.seed = function(value) {
|
||||
if (value) {
|
||||
seed = value;
|
||||
}
|
||||
return seed;
|
||||
};
|
||||
|
||||
this.suppressLoadErrors = function() {
|
||||
if (handlingLoadErrors) {
|
||||
globalErrors.popListener();
|
||||
}
|
||||
handlingLoadErrors = false;
|
||||
};
|
||||
|
||||
this.deprecated = function(msg) {
|
||||
var runnable = currentRunnable() || topSuite;
|
||||
runnable.addDeprecationWarning(msg);
|
||||
if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') {
|
||||
console.error('DEPRECATION: ' + msg);
|
||||
}
|
||||
};
|
||||
|
||||
var queueRunnerFactory = function(options, args) {
|
||||
var failFast = false;
|
||||
if (options.isLeaf) {
|
||||
failFast = throwOnExpectationFailure;
|
||||
} else if (!options.isReporter) {
|
||||
failFast = stopOnSpecFailure;
|
||||
}
|
||||
options.clearStack = options.clearStack || clearStack;
|
||||
options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
|
||||
options.fail = self.fail;
|
||||
options.globalErrors = globalErrors;
|
||||
options.completeOnFirstError = failFast;
|
||||
options.onException = options.onException || function(e) {
|
||||
(currentRunnable() || topSuite).onException(e);
|
||||
};
|
||||
options.deprecated = self.deprecated;
|
||||
|
||||
new j$.QueueRunner(options).execute(args);
|
||||
};
|
||||
|
||||
var topSuite = new j$.Suite({
|
||||
env: this,
|
||||
id: getNextSuiteId(),
|
||||
description: 'Jasmine__TopLevel__Suite',
|
||||
expectationFactory: expectationFactory,
|
||||
expectationResultFactory: expectationResultFactory
|
||||
});
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
};
|
||||
|
||||
/**
|
||||
* This represents the available reporter callback for an object passed to {@link Env#addReporter}.
|
||||
* @interface Reporter
|
||||
@@ -293,11 +90,195 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @param {SpecResult} result
|
||||
*/
|
||||
'specDone'
|
||||
], queueRunnerFactory);
|
||||
]);
|
||||
|
||||
var globalErrors = new j$.GlobalErrors();
|
||||
|
||||
this.specFilter = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Custom Equalities must be added in a before function or a spec');
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Matchers must be added in a before function or a spec');
|
||||
}
|
||||
var customMatchers = runnableResources[currentRunnable().id].customMatchers;
|
||||
for (var matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
|
||||
var nextSpecId = 0;
|
||||
var getNextSpecId = function() {
|
||||
return 'spec' + nextSpecId++;
|
||||
};
|
||||
|
||||
var nextSuiteId = 0;
|
||||
var getNextSuiteId = function() {
|
||||
return 'suite' + nextSuiteId++;
|
||||
};
|
||||
|
||||
var expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.Factory({
|
||||
util: j$.matchersUtil,
|
||||
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
function addExpectationResult(passed, result) {
|
||||
return spec.addExpectationResult(passed, result);
|
||||
}
|
||||
};
|
||||
|
||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
|
||||
|
||||
if(runnableResources[parentRunnableId]){
|
||||
resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
|
||||
resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
};
|
||||
|
||||
var clearResourcesForRunnable = function(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
};
|
||||
|
||||
var beforeAndAfterFns = function(suite) {
|
||||
return function() {
|
||||
var befores = [],
|
||||
afters = [];
|
||||
|
||||
while(suite) {
|
||||
befores = befores.concat(suite.beforeFns);
|
||||
afters = afters.concat(suite.afterFns);
|
||||
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
|
||||
return {
|
||||
befores: befores.reverse(),
|
||||
afters: afters
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
var getSpecName = function(spec, suite) {
|
||||
var fullName = [spec.description],
|
||||
suiteFullName = suite.getFullName();
|
||||
|
||||
if (suiteFullName !== '') {
|
||||
fullName.unshift(suiteFullName);
|
||||
}
|
||||
return fullName.join(' ');
|
||||
};
|
||||
|
||||
// TODO: we may just be able to pass in the fn instead of wrapping here
|
||||
var buildExpectationResult = j$.buildExpectationResult,
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
expectationResultFactory = function(attrs) {
|
||||
attrs.messageFormatter = exceptionFormatter.message;
|
||||
attrs.stackFormatter = exceptionFormatter.stack;
|
||||
|
||||
return buildExpectationResult(attrs);
|
||||
};
|
||||
|
||||
// TODO: fix this naming, and here's where the value comes in
|
||||
this.catchExceptions = function(value) {
|
||||
catchExceptions = !!value;
|
||||
if (!catchExceptions) {
|
||||
this.deprecated('The catchExceptions option is deprecated and will be replaced with stopOnSpecFailure in Jasmine 3.0');
|
||||
}
|
||||
return catchExceptions;
|
||||
};
|
||||
|
||||
this.catchingExceptions = function() {
|
||||
return catchExceptions;
|
||||
};
|
||||
|
||||
var maximumSpecCallbackDepth = 20;
|
||||
var currentSpecCallbackDepth = 0;
|
||||
|
||||
var catchException = function(e) {
|
||||
return j$.Spec.isPendingSpecException(e) || catchExceptions;
|
||||
};
|
||||
|
||||
this.throwOnExpectationFailure = function(value) {
|
||||
throwOnExpectationFailure = !!value;
|
||||
};
|
||||
|
||||
this.throwingExpectationFailures = function() {
|
||||
return throwOnExpectationFailure;
|
||||
};
|
||||
|
||||
this.randomizeTests = function(value) {
|
||||
random = !!value;
|
||||
};
|
||||
|
||||
this.randomTests = function() {
|
||||
return random;
|
||||
};
|
||||
|
||||
this.seed = function(value) {
|
||||
if (value) {
|
||||
seed = value;
|
||||
}
|
||||
return seed;
|
||||
};
|
||||
|
||||
this.deprecated = function(msg) {
|
||||
var runnable = currentRunnable() || topSuite;
|
||||
runnable.addDeprecationWarning(msg);
|
||||
if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') {
|
||||
console.error('DEPRECATION: ' + msg);
|
||||
}
|
||||
};
|
||||
|
||||
var queueRunnerFactory = function(options) {
|
||||
options.catchException = catchException;
|
||||
options.clearStack = options.clearStack || clearStack;
|
||||
options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
|
||||
options.fail = self.fail;
|
||||
options.globalErrors = globalErrors;
|
||||
options.completeOnFirstError = throwOnExpectationFailure && options.isLeaf;
|
||||
options.deprecated = self.deprecated;
|
||||
|
||||
new j$.QueueRunner(options).execute();
|
||||
};
|
||||
|
||||
var topSuite = new j$.Suite({
|
||||
env: this,
|
||||
id: getNextSuiteId(),
|
||||
description: 'Jasmine__TopLevel__Suite',
|
||||
expectationFactory: expectationFactory,
|
||||
expectationResultFactory: expectationResultFactory
|
||||
});
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
var self = this;
|
||||
this.suppressLoadErrors();
|
||||
if (hasExecuted) {
|
||||
this.deprecated('Executing the same Jasmine multiple times will no longer work in Jasmine 3.0');
|
||||
}
|
||||
|
||||
hasExecuted = true;
|
||||
|
||||
if(!runnablesToRun) {
|
||||
if (focusedRunnables.length) {
|
||||
@@ -316,30 +297,24 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
tree: topSuite,
|
||||
runnableIds: runnablesToRun,
|
||||
queueRunnerFactory: queueRunnerFactory,
|
||||
nodeStart: function(suite, next) {
|
||||
nodeStart: function(suite) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result, next);
|
||||
reporter.suiteStarted(suite.result);
|
||||
},
|
||||
nodeComplete: function(suite, result, next) {
|
||||
nodeComplete: function(suite, result) {
|
||||
if (suite !== currentSuite()) {
|
||||
throw new Error('Tried to complete the wrong suite');
|
||||
}
|
||||
|
||||
clearResourcesForRunnable(suite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
|
||||
if (result.status === 'failed') {
|
||||
hasFailures = true;
|
||||
if (!suite.markedPending) {
|
||||
clearResourcesForRunnable(suite.id);
|
||||
}
|
||||
|
||||
reporter.suiteDone(result, next);
|
||||
currentlyExecutingSuites.pop();
|
||||
reporter.suiteDone(result);
|
||||
},
|
||||
orderChildren: function(node) {
|
||||
return order.sort(node.children);
|
||||
},
|
||||
excludeNode: function(spec) {
|
||||
return !self.specFilter(spec);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -356,42 +331,27 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
reporter.jasmineStarted({
|
||||
totalSpecsDefined: totalSpecsDefined,
|
||||
order: order
|
||||
}, function() {
|
||||
currentlyExecutingSuites.push(topSuite);
|
||||
});
|
||||
|
||||
processor.execute(function () {
|
||||
clearResourcesForRunnable(topSuite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
var overallStatus, incompleteReason;
|
||||
currentlyExecutingSuites.push(topSuite);
|
||||
|
||||
if (hasFailures || topSuite.result.failedExpectations.length > 0) {
|
||||
overallStatus = 'failed';
|
||||
} else if (focusedRunnables.length > 0) {
|
||||
overallStatus = 'incomplete';
|
||||
incompleteReason = 'fit() or fdescribe() was found';
|
||||
} else if (totalSpecsDefined === 0) {
|
||||
overallStatus = 'incomplete';
|
||||
incompleteReason = 'No specs found';
|
||||
} else {
|
||||
overallStatus = 'passed';
|
||||
}
|
||||
globalErrors.install();
|
||||
processor.execute(function() {
|
||||
clearResourcesForRunnable(topSuite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
globalErrors.uninstall();
|
||||
|
||||
/**
|
||||
* Information passed to the {@link Reporter#jasmineDone} event.
|
||||
* @typedef JasmineDoneInfo
|
||||
* @property {OverallStatus} - The overall result of the sute: 'passed', 'failed', or 'incomplete'.
|
||||
* @property {IncompleteReason} - Explanation of why the suite was incimplete.
|
||||
* @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
|
||||
* @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
|
||||
* @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
|
||||
*/
|
||||
reporter.jasmineDone({
|
||||
overallStatus: overallStatus,
|
||||
incompleteReason: incompleteReason,
|
||||
order: order,
|
||||
failedExpectations: topSuite.result.failedExpectations,
|
||||
deprecationWarnings: topSuite.result.deprecationWarnings
|
||||
}, function() {});
|
||||
/**
|
||||
* Information passed to the {@link Reporter#jasmineDone} event.
|
||||
* @typedef JasmineDoneInfo
|
||||
* @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
|
||||
* @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
|
||||
* @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
|
||||
*/
|
||||
reporter.jasmineDone({
|
||||
order: order,
|
||||
failedExpectations: topSuite.result.failedExpectations,
|
||||
deprecationWarnings: topSuite.result.deprecationWarnings
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -415,27 +375,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
reporter.clearReporters();
|
||||
};
|
||||
|
||||
var spyFactory = new j$.SpyFactory(function() {
|
||||
var runnable = currentRunnable();
|
||||
|
||||
if (runnable) {
|
||||
return runnableResources[runnable.id].customSpyStrategies;
|
||||
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Spies must be created in a before function or a spec');
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
var spyRegistry = new j$.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Spies must be created in a before function or a spec');
|
||||
}
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
},
|
||||
createSpy: function(name, originalFn) {
|
||||
return self.createSpy(name, originalFn);
|
||||
}
|
||||
});
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
}});
|
||||
|
||||
this.allowRespy = function(allow){
|
||||
spyRegistry.allowRespy(allow);
|
||||
@@ -449,14 +394,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return spyRegistry.spyOnProperty.apply(spyRegistry, arguments);
|
||||
};
|
||||
|
||||
this.createSpy = function(name, originalFn) {
|
||||
return spyFactory.createSpy(name, originalFn);
|
||||
};
|
||||
|
||||
this.createSpyObj = function(baseName, methodNames) {
|
||||
return spyFactory.createSpyObj(baseName, methodNames);
|
||||
};
|
||||
|
||||
var ensureIsFunction = function(fn, caller) {
|
||||
if (!j$.isFunction_(fn)) {
|
||||
throw new Error(caller + ' expects a function argument; received ' + j$.getType_(fn));
|
||||
@@ -516,6 +453,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var focusedRunnables = [];
|
||||
|
||||
this.fdescribe = function(description, specDefinitions) {
|
||||
this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0');
|
||||
ensureIsNotNested('fdescribe');
|
||||
ensureIsFunction(specDefinitions, 'fdescribe');
|
||||
var suite = suiteFactory(description);
|
||||
@@ -541,7 +479,9 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
suite.onException(declarationError);
|
||||
self.it('encountered a declaration exception', function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
currentDeclarationSuite = parentSuite;
|
||||
@@ -592,23 +532,22 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
throwOnExpectationFailure: throwOnExpectationFailure
|
||||
});
|
||||
|
||||
return spec;
|
||||
|
||||
function specResultCallback(result, next) {
|
||||
clearResourcesForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
|
||||
if (result.status === 'failed') {
|
||||
hasFailures = true;
|
||||
}
|
||||
|
||||
reporter.specDone(result, next);
|
||||
if (!self.specFilter(spec)) {
|
||||
spec.disable();
|
||||
}
|
||||
|
||||
function specStarted(spec, next) {
|
||||
return spec;
|
||||
|
||||
function specResultCallback(result) {
|
||||
clearResourcesForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
reporter.specDone(result);
|
||||
}
|
||||
|
||||
function specStarted(spec) {
|
||||
currentSpec = spec;
|
||||
defaultResourcesForRunnable(spec.id, suite.id);
|
||||
reporter.specStarted(spec.result, next);
|
||||
reporter.specStarted(spec.result);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -640,6 +579,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.fit = function(description, fn, timeout){
|
||||
this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0');
|
||||
ensureIsNotNested('fit');
|
||||
ensureIsFunctionOrAsync(fn, 'fit');
|
||||
var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
|
||||
function ExceptionFormatter(options) {
|
||||
var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();
|
||||
getJasmineRequireObj().ExceptionFormatter = function() {
|
||||
function ExceptionFormatter() {
|
||||
this.message = function(error) {
|
||||
var message = '';
|
||||
|
||||
@@ -23,34 +21,8 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
};
|
||||
|
||||
this.stack = function(error) {
|
||||
if (!error || !error.stack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var stackTrace = new j$.StackTrace(error.stack);
|
||||
var lines = filterJasmine(stackTrace);
|
||||
|
||||
if (stackTrace.message) {
|
||||
lines.unshift(stackTrace.message);
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
return error ? error.stack : null;
|
||||
};
|
||||
|
||||
function filterJasmine(stackTrace) {
|
||||
var result = [],
|
||||
jasmineMarker = stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
|
||||
|
||||
stackTrace.frames.forEach(function(frame) {
|
||||
if (frame.file && frame.file !== jasmineFile) {
|
||||
result.push(frame.raw);
|
||||
} else if (result[result.length - 1] !== jasmineMarker) {
|
||||
result.push(jasmineMarker);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return ExceptionFormatter;
|
||||
|
||||
@@ -13,6 +13,8 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
this.uninstall = function noop() {};
|
||||
|
||||
this.install = function install() {
|
||||
if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) {
|
||||
var originalHandlers = global.process.listeners('uncaughtException');
|
||||
|
||||
@@ -29,13 +29,11 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
} else if (typeof value === 'string') {
|
||||
this.emitString(value);
|
||||
} else if (j$.isSpy(value)) {
|
||||
this.emitScalar('spy on ' + value.and.identity);
|
||||
this.emitScalar('spy on ' + value.and.identity());
|
||||
} else if (value instanceof RegExp) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
} else if (value.nodeType === 1) {
|
||||
this.emitDomElement(value);
|
||||
} else if (typeof value.nodeType === 'number') {
|
||||
this.emitScalar('HTMLNode');
|
||||
} else if (value instanceof Date) {
|
||||
@@ -227,18 +225,6 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(constructorName + ' [ ' + itemsString + ' ]');
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitDomElement = function(el) {
|
||||
var closingTag = '</' + el.tagName.toLowerCase() + '>';
|
||||
|
||||
if (el.innerHTML === '') {
|
||||
this.append(el.outerHTML.replace(closingTag, ''));
|
||||
} else {
|
||||
var tagEnd = el.outerHTML.indexOf(el.innerHTML);
|
||||
this.append(el.outerHTML.substring(0, tagEnd));
|
||||
this.append('...' + closingTag);
|
||||
}
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
this.append(property);
|
||||
this.append(': ');
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
function StopExecutionError() {}
|
||||
StopExecutionError.prototype = new Error();
|
||||
j$.StopExecutionError = StopExecutionError;
|
||||
|
||||
function once(fn) {
|
||||
var called = false;
|
||||
@@ -21,16 +18,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.onComplete = attrs.onComplete || function() {};
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.onException = attrs.onException || function() {};
|
||||
this.catchException = attrs.catchException || function() { return true; };
|
||||
this.userContext = attrs.userContext || new j$.UserContext();
|
||||
this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
|
||||
this.fail = attrs.fail || function() {};
|
||||
this.globalErrors = attrs.globalErrors || { pushListener: function() {}, popListener: function() {} };
|
||||
this.completeOnFirstError = !!attrs.completeOnFirstError;
|
||||
this.errored = false;
|
||||
|
||||
if (typeof(this.onComplete) !== 'function') {
|
||||
throw new Error('invalid onComplete ' + JSON.stringify(this.onComplete));
|
||||
}
|
||||
this.deprecated = attrs.deprecated;
|
||||
}
|
||||
|
||||
@@ -51,101 +44,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
QueueRunner.prototype.clearTimeout = function(timeoutId) {
|
||||
Function.prototype.apply.apply(this.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
};
|
||||
|
||||
QueueRunner.prototype.setTimeout = function(fn, timeout) {
|
||||
return Function.prototype.apply.apply(this.timeout.setTimeout, [j$.getGlobal(), [fn, timeout]]);
|
||||
};
|
||||
|
||||
QueueRunner.prototype.attempt = function attempt(iterativeIndex) {
|
||||
var self = this, completedSynchronously = true,
|
||||
handleError = function handleError(error) {
|
||||
onException(error);
|
||||
next(error);
|
||||
},
|
||||
cleanup = once(function cleanup() {
|
||||
self.clearTimeout(timeoutId);
|
||||
self.globalErrors.popListener(handleError);
|
||||
}),
|
||||
next = once(function next(err) {
|
||||
cleanup();
|
||||
|
||||
if (j$.isError_(err)) {
|
||||
if (!(err instanceof StopExecutionError)) {
|
||||
self.fail(err);
|
||||
}
|
||||
self.errored = errored = true;
|
||||
}
|
||||
|
||||
function runNext() {
|
||||
if (self.completeOnFirstError && errored) {
|
||||
self.skipToCleanup(iterativeIndex);
|
||||
} else {
|
||||
self.run(iterativeIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (completedSynchronously) {
|
||||
self.setTimeout(runNext);
|
||||
} else {
|
||||
runNext();
|
||||
}
|
||||
}),
|
||||
errored = false,
|
||||
queueableFn = self.queueableFns[iterativeIndex],
|
||||
timeoutId;
|
||||
|
||||
next.fail = function nextFail() {
|
||||
self.fail.apply(null, arguments);
|
||||
self.errored = errored = true;
|
||||
next();
|
||||
};
|
||||
|
||||
self.globalErrors.pushListener(handleError);
|
||||
|
||||
if (queueableFn.timeout) {
|
||||
timeoutId = self.setTimeout(function() {
|
||||
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
|
||||
onException(error);
|
||||
next();
|
||||
}, queueableFn.timeout());
|
||||
}
|
||||
|
||||
try {
|
||||
if (queueableFn.fn.length === 0) {
|
||||
var maybeThenable = queueableFn.fn.call(self.userContext);
|
||||
|
||||
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
|
||||
maybeThenable.then(next, onPromiseRejection);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
} else {
|
||||
queueableFn.fn.call(self.userContext, next);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
} catch (e) {
|
||||
onException(e);
|
||||
self.errored = errored = true;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
return { completedSynchronously: true, errored: errored };
|
||||
|
||||
function onException(e) {
|
||||
self.onException(e);
|
||||
self.errored = errored = true;
|
||||
}
|
||||
|
||||
function onPromiseRejection(e) {
|
||||
onException(e);
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
QueueRunner.prototype.run = function(recursiveIndex) {
|
||||
var length = this.queueableFns.length,
|
||||
self = this,
|
||||
@@ -153,14 +51,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
|
||||
|
||||
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
|
||||
var result = this.attempt(iterativeIndex);
|
||||
var result = attempt(iterativeIndex);
|
||||
|
||||
if (!result.completedSynchronously) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.errored = result.errored;
|
||||
|
||||
if (this.completeOnFirstError && result.errored) {
|
||||
this.skipToCleanup(iterativeIndex);
|
||||
return;
|
||||
@@ -169,9 +65,107 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
|
||||
this.clearStack(function() {
|
||||
self.globalErrors.popListener(self.handleFinalError);
|
||||
self.onComplete(self.errored && new StopExecutionError());
|
||||
self.onComplete();
|
||||
});
|
||||
|
||||
function attempt() {
|
||||
var clearTimeout = function () {
|
||||
Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
},
|
||||
setTimeout = function(delayedFn, delay) {
|
||||
return Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [delayedFn, delay]]);
|
||||
},
|
||||
completedSynchronously = true,
|
||||
handleError = function(error) {
|
||||
onException(error);
|
||||
next();
|
||||
},
|
||||
cleanup = once(function() {
|
||||
clearTimeout(timeoutId);
|
||||
self.globalErrors.popListener(handleError);
|
||||
}),
|
||||
next = once(function (err) {
|
||||
cleanup();
|
||||
|
||||
if (err instanceof Error) {
|
||||
self.deprecated('done callback received an Error object. Jasmine 3.0 will treat this as a failure');
|
||||
}
|
||||
|
||||
function runNext() {
|
||||
if (self.completeOnFirstError && errored) {
|
||||
self.skipToCleanup(iterativeIndex);
|
||||
} else {
|
||||
self.run(iterativeIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (completedSynchronously) {
|
||||
setTimeout(runNext);
|
||||
} else {
|
||||
runNext();
|
||||
}
|
||||
}),
|
||||
errored = false,
|
||||
queueableFn = self.queueableFns[iterativeIndex],
|
||||
timeoutId;
|
||||
|
||||
next.fail = function() {
|
||||
self.fail.apply(null, arguments);
|
||||
errored = true;
|
||||
next();
|
||||
};
|
||||
|
||||
self.globalErrors.pushListener(handleError);
|
||||
|
||||
if (queueableFn.timeout) {
|
||||
timeoutId = setTimeout(function() {
|
||||
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
|
||||
onException(error);
|
||||
next();
|
||||
}, queueableFn.timeout());
|
||||
}
|
||||
|
||||
try {
|
||||
if (queueableFn.fn.length === 0) {
|
||||
var maybeThenable = queueableFn.fn.call(self.userContext);
|
||||
|
||||
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
|
||||
maybeThenable.then(next, onPromiseRejection);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
} else {
|
||||
queueableFn.fn.call(self.userContext, next);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
} catch (e) {
|
||||
handleException(e, queueableFn);
|
||||
errored = true;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
return { completedSynchronously: true, errored: errored };
|
||||
|
||||
function onException(e) {
|
||||
self.onException(e);
|
||||
errored = true;
|
||||
}
|
||||
|
||||
function onPromiseRejection(e) {
|
||||
onException(e);
|
||||
next();
|
||||
}
|
||||
|
||||
function handleException(e, queueableFn) {
|
||||
onException(e);
|
||||
if (!self.catchException(e)) {
|
||||
//TODO: set a var when we catch an exception and
|
||||
//use a finally block to close the loop in a nice way..
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return QueueRunner;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
function ReportDispatcher(methods, queueRunnerFactory) {
|
||||
function ReportDispatcher(methods) {
|
||||
|
||||
var dispatchedMethods = methods || [];
|
||||
|
||||
@@ -33,40 +33,11 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
if (reporters.length === 0 && fallbackReporter !== null) {
|
||||
reporters.push(fallbackReporter);
|
||||
}
|
||||
var onComplete = args[args.length - 1];
|
||||
args = j$.util.argsToArray(args).splice(0, args.length - 1);
|
||||
var fns = [];
|
||||
for (var i = 0; i < reporters.length; i++) {
|
||||
var reporter = reporters[i];
|
||||
addFn(fns, reporter, method, args);
|
||||
}
|
||||
|
||||
queueRunnerFactory({
|
||||
queueableFns: fns,
|
||||
onComplete: onComplete,
|
||||
isReporter: true
|
||||
});
|
||||
}
|
||||
|
||||
function addFn(fns, reporter, method, args) {
|
||||
var fn = reporter[method];
|
||||
if (!fn) {
|
||||
return;
|
||||
}
|
||||
|
||||
var thisArgs = j$.util.cloneArgs(args);
|
||||
if (fn.length <= 1) {
|
||||
fns.push({
|
||||
fn: function () {
|
||||
return fn.apply(reporter, thisArgs);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fns.push({
|
||||
fn: function (done) {
|
||||
return fn.apply(reporter, thisArgs.concat([done]));
|
||||
}
|
||||
});
|
||||
if (reporter[method]) {
|
||||
reporter[method].apply(reporter, j$.util.cloneArgs(args));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,22 +57,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.expectationFactory(actual, this);
|
||||
};
|
||||
|
||||
Spec.prototype.execute = function(onComplete, excluded) {
|
||||
Spec.prototype.execute = function(onComplete, enabled) {
|
||||
var self = this;
|
||||
|
||||
var onStart = {
|
||||
fn: function(done) {
|
||||
self.onStart(self, done);
|
||||
}
|
||||
};
|
||||
|
||||
var complete = {
|
||||
fn: function(done) {
|
||||
self.queueableFn.fn = null;
|
||||
self.result.status = self.status(excluded);
|
||||
self.resultCallback(self.result, done);
|
||||
}
|
||||
};
|
||||
this.onStart(this);
|
||||
|
||||
var fns = this.beforeAndAfterFns();
|
||||
var regularFns = fns.befores.concat(this.queueableFn);
|
||||
@@ -81,24 +69,27 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
isLeaf: true,
|
||||
queueableFns: regularFns,
|
||||
cleanupFns: fns.afters,
|
||||
onException: function () {
|
||||
self.onException.apply(self, arguments);
|
||||
},
|
||||
onComplete: function() {
|
||||
onComplete(self.result.status === 'failed' && new j$.StopExecutionError('spec failed'));
|
||||
},
|
||||
onException: function() { self.onException.apply(self, arguments); },
|
||||
onComplete: complete,
|
||||
userContext: this.userContext()
|
||||
};
|
||||
|
||||
if (this.markedPending || excluded === true) {
|
||||
if (!this.isExecutable() || this.markedPending || enabled === false) {
|
||||
runnerConfig.queueableFns = [];
|
||||
runnerConfig.cleanupFns = [];
|
||||
runnerConfig.onComplete = function() { complete(enabled); };
|
||||
}
|
||||
|
||||
runnerConfig.queueableFns.unshift(onStart);
|
||||
runnerConfig.cleanupFns.push(complete);
|
||||
|
||||
this.queueRunnerFactory(runnerConfig);
|
||||
|
||||
function complete(enabledAgain) {
|
||||
self.result.status = self.status(enabledAgain);
|
||||
self.resultCallback(self.result);
|
||||
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.onException = function onException(e) {
|
||||
@@ -120,6 +111,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}, true);
|
||||
};
|
||||
|
||||
Spec.prototype.disable = function() {
|
||||
this.disabled = true;
|
||||
};
|
||||
|
||||
Spec.prototype.pend = function(message) {
|
||||
this.markedPending = true;
|
||||
if (message) {
|
||||
@@ -132,9 +127,9 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.result;
|
||||
};
|
||||
|
||||
Spec.prototype.status = function(excluded) {
|
||||
if (excluded === true) {
|
||||
return 'excluded';
|
||||
Spec.prototype.status = function(enabled) {
|
||||
if (this.disabled || enabled === false) {
|
||||
return 'disabled';
|
||||
}
|
||||
|
||||
if (this.markedPending) {
|
||||
@@ -148,6 +143,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.isExecutable = function() {
|
||||
return !this.disabled;
|
||||
};
|
||||
|
||||
Spec.prototype.getFullName = function() {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
|
||||
@@ -13,18 +13,17 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
* @constructor
|
||||
* @name Spy
|
||||
*/
|
||||
function Spy(name, originalFn, customStrategies) {
|
||||
function Spy(name, originalFn) {
|
||||
var numArgs = (typeof originalFn === 'function' ? originalFn.length : 0),
|
||||
wrapper = makeFunc(numArgs, function () {
|
||||
return spy.apply(this, Array.prototype.slice.call(arguments));
|
||||
}),
|
||||
strategyDispatcher = new SpyStrategyDispatcher({
|
||||
spyStrategy = new j$.SpyStrategy({
|
||||
name: name,
|
||||
fn: originalFn,
|
||||
getSpy: function () {
|
||||
return wrapper;
|
||||
},
|
||||
customStrategies: customStrategies
|
||||
}
|
||||
}),
|
||||
callTracker = new j$.CallTracker(),
|
||||
spy = function () {
|
||||
@@ -41,7 +40,7 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
};
|
||||
|
||||
callTracker.track(callData);
|
||||
var returnValue = strategyDispatcher.exec(this, arguments);
|
||||
var returnValue = spyStrategy.exec.apply(this, arguments);
|
||||
callData.returnValue = returnValue;
|
||||
|
||||
return returnValue;
|
||||
@@ -70,94 +69,11 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
wrapper[prop] = originalFn[prop];
|
||||
}
|
||||
|
||||
/**
|
||||
* @member {SpyStrategy} - Accesses the default strategy for the spy. This strategy will be used
|
||||
* whenever the spy is called with arguments that don't match any strategy
|
||||
* created with {@link Spy#withArgs}.
|
||||
* @name Spy#and
|
||||
* @example
|
||||
* spyOn(someObj, 'func').and.returnValue(42);
|
||||
*/
|
||||
wrapper.and = strategyDispatcher.and;
|
||||
/**
|
||||
* Specifies a strategy to be used for calls to the spy that have the
|
||||
* specified arguments.
|
||||
* @name Spy#withArgs
|
||||
* @function
|
||||
* @param {...*} args - The arguments to match
|
||||
* @type {SpyStrategy}
|
||||
* @example
|
||||
* spyOn(someObj, 'func').withArgs(1, 2, 3).and.returnValue(42);
|
||||
* someObj.func(1, 2, 3); // returns 42
|
||||
*/
|
||||
wrapper.withArgs = function() {
|
||||
return strategyDispatcher.withArgs.apply(strategyDispatcher, arguments);
|
||||
};
|
||||
wrapper.and = spyStrategy;
|
||||
wrapper.calls = callTracker;
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
function SpyStrategyDispatcher(strategyArgs) {
|
||||
var baseStrategy = new j$.SpyStrategy(strategyArgs);
|
||||
var argsStrategies = new StrategyDict(function() {
|
||||
return new j$.SpyStrategy(strategyArgs);
|
||||
});
|
||||
|
||||
this.and = baseStrategy;
|
||||
|
||||
this.exec = function(spy, args) {
|
||||
var strategy = argsStrategies.get(args);
|
||||
|
||||
if (!strategy) {
|
||||
if (argsStrategies.any() && !baseStrategy.isConfigured()) {
|
||||
throw new Error('Spy \'' + strategyArgs.name + '\' receieved a call with arguments ' + j$.pp(Array.prototype.slice.call(args)) + ' but all configured strategies specify other arguments.');
|
||||
} else {
|
||||
strategy = baseStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
return strategy.exec(spy, args);
|
||||
};
|
||||
|
||||
this.withArgs = function() {
|
||||
return { and: argsStrategies.getOrCreate(arguments) };
|
||||
};
|
||||
}
|
||||
|
||||
function StrategyDict(strategyFactory) {
|
||||
this.strategies = [];
|
||||
this.strategyFactory = strategyFactory;
|
||||
}
|
||||
|
||||
StrategyDict.prototype.any = function() {
|
||||
return this.strategies.length > 0;
|
||||
};
|
||||
|
||||
StrategyDict.prototype.getOrCreate = function(args) {
|
||||
var strategy = this.get(args);
|
||||
|
||||
if (!strategy) {
|
||||
strategy = this.strategyFactory();
|
||||
this.strategies.push({
|
||||
args: args,
|
||||
strategy: strategy
|
||||
});
|
||||
}
|
||||
|
||||
return strategy;
|
||||
};
|
||||
|
||||
StrategyDict.prototype.get = function(args) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.strategies.length; i++) {
|
||||
if (j$.matchersUtil.equals(args, this.strategies[i].args)) {
|
||||
return this.strategies[i].strategy;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Spy;
|
||||
};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
getJasmineRequireObj().SpyFactory = function(j$) {
|
||||
|
||||
function SpyFactory(getCustomStrategies) {
|
||||
var self = this;
|
||||
|
||||
this.createSpy = function(name, originalFn) {
|
||||
return j$.Spy(name, originalFn, getCustomStrategies());
|
||||
};
|
||||
|
||||
this.createSpyObj = function(baseName, methodNames) {
|
||||
var baseNameIsCollection = j$.isObject_(baseName) || j$.isArray_(baseName);
|
||||
|
||||
if (baseNameIsCollection && j$.util.isUndefined(methodNames)) {
|
||||
methodNames = baseName;
|
||||
baseName = 'unknown';
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
var spiesWereSet = false;
|
||||
|
||||
if (j$.isArray_(methodNames)) {
|
||||
for (var i = 0; i < methodNames.length; i++) {
|
||||
obj[methodNames[i]] = self.createSpy(baseName + '.' + methodNames[i]);
|
||||
spiesWereSet = true;
|
||||
}
|
||||
} else if (j$.isObject_(methodNames)) {
|
||||
for (var key in methodNames) {
|
||||
if (methodNames.hasOwnProperty(key)) {
|
||||
obj[key] = self.createSpy(baseName + '.' + key);
|
||||
obj[key].and.returnValue(methodNames[key]);
|
||||
spiesWereSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!spiesWereSet) {
|
||||
throw 'createSpyObj requires a non-empty array or object of method names to create spies for';
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
return SpyFactory;
|
||||
};
|
||||
@@ -5,7 +5,6 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
function SpyRegistry(options) {
|
||||
options = options || {};
|
||||
var global = options.global || j$.getGlobal();
|
||||
var createSpy = options.createSpy;
|
||||
var currentSpies = options.currentSpies || function() { return []; };
|
||||
|
||||
this.allowRespy = function(allow){
|
||||
@@ -34,14 +33,19 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
var descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
|
||||
var descriptor;
|
||||
try {
|
||||
descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
|
||||
} catch(e) {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
}
|
||||
|
||||
if (descriptor && !(descriptor.writable || descriptor.set)) {
|
||||
throw new Error(getErrorMsg(methodName + ' is not declared writable or has no setter'));
|
||||
}
|
||||
|
||||
var originalMethod = obj[methodName],
|
||||
spiedMethod = createSpy(methodName, originalMethod),
|
||||
spiedMethod = j$.createSpy(methodName, originalMethod),
|
||||
restoreStrategy;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(obj, methodName) || (obj === global && methodName === 'onerror')) {
|
||||
@@ -76,7 +80,12 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
throw new Error('No property name supplied');
|
||||
}
|
||||
|
||||
var descriptor = j$.util.getPropertyDescriptor(obj, propertyName);
|
||||
var descriptor;
|
||||
try {
|
||||
descriptor = j$.util.getPropertyDescriptor(obj, propertyName);
|
||||
} catch(e) {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
}
|
||||
|
||||
if (!descriptor) {
|
||||
throw new Error(propertyName + ' property does not exist');
|
||||
@@ -96,7 +105,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
}
|
||||
|
||||
var originalDescriptor = j$.util.clone(descriptor),
|
||||
spy = createSpy(propertyName, descriptor[accessType]),
|
||||
spy = j$.createSpy(propertyName, descriptor[accessType]),
|
||||
restoreStrategy;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(obj, propertyName)) {
|
||||
|
||||
@@ -1,130 +1,110 @@
|
||||
getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
|
||||
/**
|
||||
* @interface SpyStrategy
|
||||
* @namespace Spy#and
|
||||
*/
|
||||
function SpyStrategy(options) {
|
||||
options = options || {};
|
||||
|
||||
var identity = options.name || 'unknown',
|
||||
originalFn = options.fn || function() {},
|
||||
getSpy = options.getSpy || function() {},
|
||||
plan = function() {};
|
||||
|
||||
/**
|
||||
* Get the identifying information for the spy.
|
||||
* @name SpyStrategy#identity
|
||||
* @member
|
||||
* @type {String}
|
||||
* Return the identifying information for the spy.
|
||||
* @name Spy#and#identity
|
||||
* @function
|
||||
* @returns {String}
|
||||
*/
|
||||
this.identity = options.name || 'unknown';
|
||||
this.originalFn = options.fn || function() {};
|
||||
this.getSpy = options.getSpy || function() {};
|
||||
this.plan = this._defaultPlan = function() {};
|
||||
this.identity = function() {
|
||||
return identity;
|
||||
};
|
||||
|
||||
var k, cs = options.customStrategies || {};
|
||||
for (k in cs) {
|
||||
if (j$.util.has(cs, k) && !this[k]) {
|
||||
this[k] = createCustomPlan(cs[k]);
|
||||
/**
|
||||
* Execute the current spy strategy.
|
||||
* @name Spy#and#exec
|
||||
* @function
|
||||
*/
|
||||
this.exec = function() {
|
||||
return plan.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to call through to the real implementation when invoked.
|
||||
* @name Spy#and#callThrough
|
||||
* @function
|
||||
*/
|
||||
this.callThrough = function() {
|
||||
plan = originalFn;
|
||||
return getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to return the value when invoked.
|
||||
* @name Spy#and#returnValue
|
||||
* @function
|
||||
* @param {*} value The value to return.
|
||||
*/
|
||||
this.returnValue = function(value) {
|
||||
plan = function() {
|
||||
return value;
|
||||
};
|
||||
return getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to return one of the specified values (sequentially) each time the spy is invoked.
|
||||
* @name Spy#and#returnValues
|
||||
* @function
|
||||
* @param {...*} values - Values to be returned on subsequent calls to the spy.
|
||||
*/
|
||||
this.returnValues = function() {
|
||||
var values = Array.prototype.slice.call(arguments);
|
||||
plan = function () {
|
||||
return values.shift();
|
||||
};
|
||||
return getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to throw an error when invoked.
|
||||
* @name Spy#and#throwError
|
||||
* @function
|
||||
* @param {Error|String} something Thing to throw
|
||||
*/
|
||||
this.throwError = function(something) {
|
||||
var error = (something instanceof Error) ? something : new Error(something);
|
||||
plan = function() {
|
||||
throw error;
|
||||
};
|
||||
return getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to call a fake implementation when invoked.
|
||||
* @name Spy#and#callFake
|
||||
* @function
|
||||
* @param {Function} fn The function to invoke with the passed parameters.
|
||||
*/
|
||||
this.callFake = function(fn) {
|
||||
if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
|
||||
throw new Error('Argument passed to callFake should be a function, got ' + fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
plan = fn;
|
||||
return getSpy();
|
||||
};
|
||||
|
||||
function createCustomPlan(factory) {
|
||||
return function() {
|
||||
var plan = factory.apply(null, arguments);
|
||||
|
||||
if (!j$.isFunction_(plan)) {
|
||||
throw new Error('Spy strategy must return a function');
|
||||
}
|
||||
|
||||
this.plan = plan;
|
||||
return this.getSpy();
|
||||
/**
|
||||
* Tell the spy to do nothing when invoked. This is the default.
|
||||
* @name Spy#and#stub
|
||||
* @function
|
||||
*/
|
||||
this.stub = function(fn) {
|
||||
plan = function() {};
|
||||
return getSpy();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the current spy strategy.
|
||||
* @name SpyStrategy#exec
|
||||
* @function
|
||||
*/
|
||||
SpyStrategy.prototype.exec = function(context, args) {
|
||||
return this.plan.apply(context, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to call through to the real implementation when invoked.
|
||||
* @name SpyStrategy#callThrough
|
||||
* @function
|
||||
*/
|
||||
SpyStrategy.prototype.callThrough = function() {
|
||||
this.plan = this.originalFn;
|
||||
return this.getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to return the value when invoked.
|
||||
* @name SpyStrategy#returnValue
|
||||
* @function
|
||||
* @param {*} value The value to return.
|
||||
*/
|
||||
SpyStrategy.prototype.returnValue = function(value) {
|
||||
this.plan = function() {
|
||||
return value;
|
||||
};
|
||||
return this.getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to return one of the specified values (sequentially) each time the spy is invoked.
|
||||
* @name SpyStrategy#returnValues
|
||||
* @function
|
||||
* @param {...*} values - Values to be returned on subsequent calls to the spy.
|
||||
*/
|
||||
SpyStrategy.prototype.returnValues = function() {
|
||||
var values = Array.prototype.slice.call(arguments);
|
||||
this.plan = function () {
|
||||
return values.shift();
|
||||
};
|
||||
return this.getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to throw an error when invoked.
|
||||
* @name SpyStrategy#throwError
|
||||
* @function
|
||||
* @param {Error|String} something Thing to throw
|
||||
*/
|
||||
SpyStrategy.prototype.throwError = function(something) {
|
||||
var error = (something instanceof Error) ? something : new Error(something);
|
||||
this.plan = function() {
|
||||
throw error;
|
||||
};
|
||||
return this.getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to call a fake implementation when invoked.
|
||||
* @name SpyStrategy#callFake
|
||||
* @function
|
||||
* @param {Function} fn The function to invoke with the passed parameters.
|
||||
*/
|
||||
SpyStrategy.prototype.callFake = function(fn) {
|
||||
if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
|
||||
throw new Error('Argument passed to callFake should be a function, got ' + fn);
|
||||
}
|
||||
this.plan = fn;
|
||||
return this.getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to do nothing when invoked. This is the default.
|
||||
* @name SpyStrategy#stub
|
||||
* @function
|
||||
*/
|
||||
SpyStrategy.prototype.stub = function(fn) {
|
||||
this.plan = function() {};
|
||||
return this.getSpy();
|
||||
};
|
||||
|
||||
SpyStrategy.prototype.isConfigured = function() {
|
||||
return this.plan !== this._defaultPlan;
|
||||
};
|
||||
|
||||
return SpyStrategy;
|
||||
};
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
getJasmineRequireObj().StackTrace = function(j$) {
|
||||
function StackTrace(rawTrace) {
|
||||
var lines = rawTrace
|
||||
.split('\n')
|
||||
.filter(function(line) { return line !== ''; });
|
||||
|
||||
if (lines[0].match(/^Error/)) {
|
||||
this.message = lines.shift();
|
||||
} else {
|
||||
this.message = undefined;
|
||||
}
|
||||
|
||||
var parseResult = tryParseFrames(lines);
|
||||
this.frames = parseResult.frames;
|
||||
this.style = parseResult.style;
|
||||
}
|
||||
|
||||
var framePatterns = [
|
||||
// PhantomJS on Linux, Node, Chrome, IE, Edge
|
||||
// e.g. " at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)"
|
||||
// Note that the "function name" can include a surprisingly large set of
|
||||
// characters, including angle brackets and square brackets.
|
||||
{ re: /^\s*at ([^\)]+) \(([^\)]+)\)$/, fnIx: 1, fileLineColIx: 2, style: 'v8' },
|
||||
|
||||
// NodeJS alternate form, often mixed in with the Chrome style
|
||||
// e.g. " at /some/path:4320:20
|
||||
{ re: /\s*at (.+)$/, fileLineColIx: 1, style: 'v8' },
|
||||
|
||||
// PhantomJS on OS X, Safari, Firefox
|
||||
// e.g. "run@http://localhost:8888/__jasmine__/jasmine.js:4320:27"
|
||||
// or "http://localhost:8888/__jasmine__/jasmine.js:4320:27"
|
||||
{ re: /^(([^@\s]+)@)?([^\s]+)$/, fnIx: 2, fileLineColIx: 3, style: 'webkit' }
|
||||
];
|
||||
|
||||
// regexes should capture the function name (if any) as group 1
|
||||
// and the file, line, and column as group 2.
|
||||
function tryParseFrames(lines) {
|
||||
var style = null;
|
||||
var frames = lines.map(function(line) {
|
||||
var convertedLine = first(framePatterns, function(pattern) {
|
||||
var overallMatch = line.match(pattern.re),
|
||||
fileLineColMatch;
|
||||
if (!overallMatch) { return null; }
|
||||
|
||||
fileLineColMatch = overallMatch[pattern.fileLineColIx].match(
|
||||
/^(.*):(\d+):\d+$/);
|
||||
if (!fileLineColMatch) { return null; }
|
||||
|
||||
style = style || pattern.style;
|
||||
return {
|
||||
raw: line,
|
||||
file: fileLineColMatch[1],
|
||||
line: parseInt(fileLineColMatch[2], 10),
|
||||
func: overallMatch[pattern.fnIx]
|
||||
};
|
||||
});
|
||||
|
||||
return convertedLine || { raw: line };
|
||||
});
|
||||
|
||||
return {
|
||||
style: style,
|
||||
frames: frames
|
||||
};
|
||||
}
|
||||
|
||||
function first(items, fn) {
|
||||
var i, result;
|
||||
|
||||
for (i = 0; i < items.length; i++) {
|
||||
result = fn(items[i]);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return StackTrace;
|
||||
};
|
||||
@@ -67,19 +67,6 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.afterAllFns.unshift(fn);
|
||||
};
|
||||
|
||||
function removeFns(queueableFns) {
|
||||
for(var i = 0; i < queueableFns.length; i++) {
|
||||
queueableFns[i].fn = null;
|
||||
}
|
||||
}
|
||||
|
||||
Suite.prototype.cleanupBeforeAfter = function() {
|
||||
removeFns(this.beforeAllFns);
|
||||
removeFns(this.afterAllFns);
|
||||
removeFns(this.beforeFns);
|
||||
removeFns(this.afterFns);
|
||||
};
|
||||
|
||||
Suite.prototype.addChild = function(child) {
|
||||
this.children.push(child);
|
||||
};
|
||||
@@ -92,10 +79,14 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
if (this.result.failedExpectations.length > 0) {
|
||||
return 'failed';
|
||||
} else {
|
||||
return 'passed';
|
||||
return 'finished';
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.isExecutable = function() {
|
||||
return !this.markedPending;
|
||||
};
|
||||
|
||||
Suite.prototype.canBeReentered = function() {
|
||||
return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
|
||||
};
|
||||
@@ -122,29 +113,39 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: arguments[0]
|
||||
};
|
||||
var failedExpectation = this.expectationResultFactory(data);
|
||||
|
||||
if (!this.parentSuite) {
|
||||
failedExpectation.globalErrorType = 'afterAll';
|
||||
if(isAfterAll(this.children)) {
|
||||
var data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: arguments[0]
|
||||
};
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.onException.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
this.result.failedExpectations.push(failedExpectation);
|
||||
};
|
||||
|
||||
Suite.prototype.addExpectationResult = function () {
|
||||
if(isFailure(arguments)) {
|
||||
if(isAfterAll(this.children) && isFailure(arguments)){
|
||||
var data = arguments[1];
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
if(this.throwOnExpectationFailure) {
|
||||
throw new j$.errors.ExpectationFailed();
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
try {
|
||||
child.addExpectationResult.apply(child, arguments);
|
||||
} catch(e) {
|
||||
// keep going
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -152,6 +153,10 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
|
||||
};
|
||||
|
||||
function isAfterAll(children) {
|
||||
return children && children[0].result.status;
|
||||
}
|
||||
|
||||
function isFailure(args) {
|
||||
return !args[0];
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
nodeStart = attrs.nodeStart || function() {},
|
||||
nodeComplete = attrs.nodeComplete || function() {},
|
||||
orderChildren = attrs.orderChildren || function(node) { return node.children; },
|
||||
excludeNode = attrs.excludeNode || function(node) { return false; },
|
||||
stats = { valid: true },
|
||||
processed = false,
|
||||
defaultMin = Infinity,
|
||||
defaultMax = 1 - Infinity;
|
||||
|
||||
this.processTree = function() {
|
||||
processNode(tree, true);
|
||||
processNode(tree, false);
|
||||
processed = true;
|
||||
return stats;
|
||||
};
|
||||
@@ -47,18 +46,18 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
}
|
||||
}
|
||||
|
||||
function processNode(node, parentExcluded) {
|
||||
function processNode(node, parentEnabled) {
|
||||
var executableIndex = runnableIndex(node.id);
|
||||
|
||||
if (executableIndex !== undefined) {
|
||||
parentExcluded = false;
|
||||
parentEnabled = true;
|
||||
}
|
||||
|
||||
parentEnabled = parentEnabled && node.isExecutable();
|
||||
|
||||
if (!node.children) {
|
||||
var excluded = parentExcluded || excludeNode(node);
|
||||
stats[node.id] = {
|
||||
excluded: excluded,
|
||||
willExecute: !excluded && !node.markedPending,
|
||||
executable: parentEnabled && node.isExecutable(),
|
||||
segments: [{
|
||||
index: 0,
|
||||
owner: node,
|
||||
@@ -75,7 +74,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
for (var i = 0; i < orderedChildren.length; i++) {
|
||||
var child = orderedChildren[i];
|
||||
|
||||
processNode(child, parentExcluded);
|
||||
processNode(child, parentEnabled);
|
||||
|
||||
if (!stats.valid) {
|
||||
return;
|
||||
@@ -83,12 +82,11 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
|
||||
var childStats = stats[child.id];
|
||||
|
||||
hasExecutableChild = hasExecutableChild || childStats.willExecute;
|
||||
hasExecutableChild = hasExecutableChild || childStats.executable;
|
||||
}
|
||||
|
||||
stats[node.id] = {
|
||||
excluded: parentExcluded,
|
||||
willExecute: hasExecutableChild
|
||||
executable: hasExecutableChild
|
||||
};
|
||||
|
||||
segmentChildren(node, orderedChildren, stats[node.id], executableIndex);
|
||||
@@ -166,20 +164,16 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
if (node.children) {
|
||||
return {
|
||||
fn: function(done) {
|
||||
var onStart = {
|
||||
fn: function(next) {
|
||||
nodeStart(node, next);
|
||||
}
|
||||
};
|
||||
nodeStart(node);
|
||||
|
||||
queueRunnerFactory({
|
||||
onComplete: function () {
|
||||
node.cleanupBeforeAfter();
|
||||
nodeComplete(node, node.getResult(), done);
|
||||
onComplete: function() {
|
||||
nodeComplete(node, node.getResult());
|
||||
done();
|
||||
},
|
||||
queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)),
|
||||
queueableFns: wrapChildren(node, segmentNumber),
|
||||
userContext: node.sharedUserContext(),
|
||||
onException: function () {
|
||||
onException: function() {
|
||||
node.onException.apply(node, arguments);
|
||||
}
|
||||
});
|
||||
@@ -187,7 +181,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fn: function(done) { node.execute(done, stats[node.id].excluded); }
|
||||
fn: function(done) { node.execute(done, stats[node.id].executable); }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -200,7 +194,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
|
||||
}
|
||||
|
||||
if (!stats[node.id].willExecute) {
|
||||
if (!stats[node.id].executable) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,10 @@ getJasmineRequireObj().Any = function(j$) {
|
||||
}
|
||||
|
||||
if (this.expectedObject == Object) {
|
||||
return other !== null && typeof other == 'object';
|
||||
if (other === null) {
|
||||
j$.getEnv().deprecated('jasmine.Any(Object) will no longer match null in Jasmine 3.0');
|
||||
}
|
||||
return typeof other == 'object';
|
||||
}
|
||||
|
||||
if (this.expectedObject == Boolean) {
|
||||
|
||||
@@ -85,17 +85,6 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return j$.getType_(value) === '[object ' + typeName + ']';
|
||||
};
|
||||
|
||||
j$.isError_ = function(value) {
|
||||
if (value instanceof Error) {
|
||||
return true;
|
||||
}
|
||||
if (value && value.constructor && value.constructor.constructor &&
|
||||
(value instanceof (value.constructor.constructor('return this')()).Error)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
j$.getType_ = function(value) {
|
||||
return Object.prototype.toString.apply(value);
|
||||
};
|
||||
@@ -192,6 +181,18 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return new j$.ArrayWithExactContents(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a bare {@link Spy} object. This won't be installed anywhere and will not have any implementation behind it.
|
||||
* @name jasmine.createSpy
|
||||
* @function
|
||||
* @param {String} [name] - Name to give the spy. This will be displayed in failure messages.
|
||||
* @param {Function} [originalFn] - Function to act as the real implementation.
|
||||
* @return {Spy}
|
||||
*/
|
||||
j$.createSpy = function(name, originalFn) {
|
||||
return j$.Spy(name, originalFn);
|
||||
};
|
||||
|
||||
j$.isSpy = function(putativeSpy) {
|
||||
if (!putativeSpy) {
|
||||
return false;
|
||||
@@ -199,4 +200,45 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return putativeSpy.and instanceof j$.SpyStrategy &&
|
||||
putativeSpy.calls instanceof j$.CallTracker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an object with multiple {@link Spy}s as its members.
|
||||
* @name jasmine.createSpyObj
|
||||
* @function
|
||||
* @param {String} [baseName] - Base name for the spies in the object.
|
||||
* @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.
|
||||
* @return {Object}
|
||||
*/
|
||||
j$.createSpyObj = function(baseName, methodNames) {
|
||||
var baseNameIsCollection = j$.isObject_(baseName) || j$.isArray_(baseName);
|
||||
|
||||
if (baseNameIsCollection && j$.util.isUndefined(methodNames)) {
|
||||
methodNames = baseName;
|
||||
baseName = 'unknown';
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
var spiesWereSet = false;
|
||||
|
||||
if (j$.isArray_(methodNames)) {
|
||||
for (var i = 0; i < methodNames.length; i++) {
|
||||
obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);
|
||||
spiesWereSet = true;
|
||||
}
|
||||
} else if (j$.isObject_(methodNames)) {
|
||||
for (var key in methodNames) {
|
||||
if (methodNames.hasOwnProperty(key)) {
|
||||
obj[key] = j$.createSpy(baseName + '.' + key);
|
||||
obj[key].and.returnValue(methodNames[key]);
|
||||
spiesWereSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!spiesWereSet) {
|
||||
throw 'createSpyObj requires a non-empty array or object of method names to create spies for';
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -182,7 +182,28 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
var bIsDomNode = j$.isDomNode(b);
|
||||
if (aIsDomNode && bIsDomNode) {
|
||||
// At first try to use DOM3 method isEqualNode
|
||||
result = a.isEqualNode(b);
|
||||
if (a.isEqualNode) {
|
||||
result = a.isEqualNode(b);
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// IE8 doesn't support isEqualNode, try to use outerHTML && innerText
|
||||
var aIsElement = a instanceof Element;
|
||||
var bIsElement = b instanceof Element;
|
||||
if (aIsElement && bIsElement) {
|
||||
result = a.outerHTML == b.outerHTML;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (aIsElement || bIsElement) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
result = a.innerText == b.innerText && a.textContent == b.textContent;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
|
||||
'toHaveBeenCalledWith',
|
||||
'toMatch',
|
||||
'toThrow',
|
||||
'toThrowError',
|
||||
'toThrowMatching',
|
||||
'toThrowError'
|
||||
],
|
||||
matchers = {};
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) {
|
||||
result.pass = actual.calls.any();
|
||||
|
||||
result.message = result.pass ?
|
||||
'Expected spy ' + actual.and.identity + ' not to have been called.' :
|
||||
'Expected spy ' + actual.and.identity + ' to have been called.';
|
||||
'Expected spy ' + actual.and.identity() + ' not to have been called.' :
|
||||
'Expected spy ' + actual.and.identity() + ' to have been called.';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
|
||||
var result = { pass: false };
|
||||
|
||||
if (!firstSpy.calls.count()) {
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity + ' to have been called.';
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity() + ' to have been called.';
|
||||
return result;
|
||||
}
|
||||
if (!latterSpy.calls.count()) {
|
||||
result.message = 'Expected spy ' + latterSpy.and.identity + ' to have been called.';
|
||||
result.message = 'Expected spy ' + latterSpy.and.identity() + ' to have been called.';
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -37,17 +37,17 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
|
||||
result.pass = latest1stSpyCall < first2ndSpyCall;
|
||||
|
||||
if (result.pass) {
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity + ' to not have been called before spy ' + latterSpy.and.identity + ', but it was';
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity() + ' to not have been called before spy ' + latterSpy.and.identity() + ', but it was';
|
||||
} else {
|
||||
var first1stSpyCall = firstSpy.calls.first().invocationOrder;
|
||||
var latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder;
|
||||
|
||||
if(first1stSpyCall < first2ndSpyCall) {
|
||||
result.message = 'Expected latest call to spy ' + firstSpy.and.identity + ' to have been called before first call to spy ' + latterSpy.and.identity + ' (no interleaved calls)';
|
||||
result.message = 'Expected latest call to spy ' + firstSpy.and.identity() + ' to have been called before first call to spy ' + latterSpy.and.identity() + ' (no interleaved calls)';
|
||||
} else if (latest2ndSpyCall > latest1stSpyCall) {
|
||||
result.message = 'Expected first call to spy ' + latterSpy.and.identity + ' to have been called after latest call to spy ' + firstSpy.and.identity + ' (no interleaved calls)';
|
||||
result.message = 'Expected first call to spy ' + latterSpy.and.identity() + ' to have been called after latest call to spy ' + firstSpy.and.identity() + ' (no interleaved calls)';
|
||||
} else {
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity + ' to have been called before spy ' + latterSpy.and.identity;
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity() + ' to have been called before spy ' + latterSpy.and.identity();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
|
||||
var timesMessage = expected === 1 ? 'once' : expected + ' times';
|
||||
result.pass = calls === expected;
|
||||
result.message = result.pass ?
|
||||
'Expected spy ' + actual.and.identity + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
|
||||
'Expected spy ' + actual.and.identity + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.';
|
||||
'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
|
||||
'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.';
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -23,15 +23,15 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
|
||||
}
|
||||
|
||||
if (!actual.calls.any()) {
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; };
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; };
|
||||
return result;
|
||||
}
|
||||
|
||||
if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) {
|
||||
result.pass = true;
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; };
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; };
|
||||
} else {
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; };
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; };
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -18,61 +18,73 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
function toThrowError () {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
var errorMatcher = getMatcher.apply(null, arguments),
|
||||
var threw = false,
|
||||
pass = {pass: true},
|
||||
fail = {pass: false},
|
||||
thrown;
|
||||
|
||||
if (typeof actual != 'function') {
|
||||
throw new Error(getErrorMsg('Actual is not a Function'));
|
||||
}
|
||||
|
||||
var errorMatcher = getMatcher.apply(null, arguments);
|
||||
|
||||
try {
|
||||
actual();
|
||||
return fail('Expected function to throw an Error.');
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
thrown = e;
|
||||
}
|
||||
|
||||
if (!j$.isError_(thrown)) {
|
||||
return fail(function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; });
|
||||
if (!threw) {
|
||||
fail.message = 'Expected function to throw an Error.';
|
||||
return fail;
|
||||
}
|
||||
|
||||
return errorMatcher.match(thrown);
|
||||
// Get Error constructor of thrown
|
||||
if (!isErrorObject(thrown)) {
|
||||
fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; };
|
||||
return fail;
|
||||
}
|
||||
|
||||
if (errorMatcher.hasNoSpecifics()) {
|
||||
pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.';
|
||||
return pass;
|
||||
}
|
||||
|
||||
if (errorMatcher.matches(thrown)) {
|
||||
pass.message = function() {
|
||||
return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.';
|
||||
};
|
||||
return pass;
|
||||
} else {
|
||||
fail.message = function() {
|
||||
return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() +
|
||||
', but it threw ' + errorMatcher.thrownDescription(thrown) + '.';
|
||||
};
|
||||
return fail;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getMatcher() {
|
||||
var expected, errorType;
|
||||
var expected = null,
|
||||
errorType = null;
|
||||
|
||||
if (arguments[2]) {
|
||||
if (arguments.length == 2) {
|
||||
expected = arguments[1];
|
||||
if (isAnErrorType(expected)) {
|
||||
errorType = expected;
|
||||
expected = null;
|
||||
}
|
||||
} else if (arguments.length > 2) {
|
||||
errorType = arguments[1];
|
||||
expected = arguments[2];
|
||||
if (!isAnErrorType(errorType)) {
|
||||
throw new Error(getErrorMsg('Expected error type is not an Error.'));
|
||||
}
|
||||
|
||||
return exactMatcher(expected, errorType);
|
||||
} else if (arguments[1]) {
|
||||
expected = arguments[1];
|
||||
|
||||
if (isAnErrorType(arguments[1])) {
|
||||
return exactMatcher(null, arguments[1]);
|
||||
} else {
|
||||
return exactMatcher(arguments[1], null);
|
||||
}
|
||||
} else {
|
||||
return anyMatcher();
|
||||
}
|
||||
}
|
||||
|
||||
function anyMatcher() {
|
||||
return {
|
||||
match: function(error) {
|
||||
return pass('Expected function not to throw an Error, but it threw ' + j$.fnNameFor(error) + '.');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function exactMatcher(expected, errorType) {
|
||||
if (expected && !isStringOrRegExp(expected)) {
|
||||
if (errorType) {
|
||||
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
||||
@@ -89,46 +101,33 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
var errorTypeDescription = errorType ? j$.fnNameFor(errorType) : 'an exception';
|
||||
|
||||
function thrownDescription(thrown) {
|
||||
var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
|
||||
thrownMessage = '';
|
||||
|
||||
if (expected) {
|
||||
thrownMessage = ' with message ' + j$.pp(thrown.message);
|
||||
}
|
||||
|
||||
return thrownName + thrownMessage;
|
||||
}
|
||||
|
||||
function messageDescription() {
|
||||
if (expected === null) {
|
||||
return '';
|
||||
} else if (expected instanceof RegExp) {
|
||||
return ' with a message matching ' + j$.pp(expected);
|
||||
} else {
|
||||
return ' with message ' + j$.pp(expected);
|
||||
}
|
||||
}
|
||||
|
||||
function matches(error) {
|
||||
return (errorType === null || error instanceof errorType) &&
|
||||
(expected === null || messageMatch(error.message));
|
||||
}
|
||||
|
||||
return {
|
||||
match: function(thrown) {
|
||||
if (matches(thrown)) {
|
||||
return pass(function() {
|
||||
return 'Expected function not to throw ' + errorTypeDescription + messageDescription() + '.';
|
||||
});
|
||||
} else {
|
||||
return fail(function() {
|
||||
return 'Expected function to throw ' + errorTypeDescription + messageDescription() +
|
||||
', but it threw ' + thrownDescription(thrown) + '.';
|
||||
});
|
||||
errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception',
|
||||
thrownDescription: function(thrown) {
|
||||
var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
|
||||
thrownMessage = '';
|
||||
|
||||
if (expected) {
|
||||
thrownMessage = ' with message ' + j$.pp(thrown.message);
|
||||
}
|
||||
|
||||
return thrownName + thrownMessage;
|
||||
},
|
||||
messageDescription: function() {
|
||||
if (expected === null) {
|
||||
return '';
|
||||
} else if (expected instanceof RegExp) {
|
||||
return ' with a message matching ' + j$.pp(expected);
|
||||
} else {
|
||||
return ' with message ' + j$.pp(expected);
|
||||
}
|
||||
},
|
||||
hasNoSpecifics: function() {
|
||||
return expected === null && errorType === null;
|
||||
},
|
||||
matches: function(error) {
|
||||
return (errorType === null || error instanceof errorType) &&
|
||||
(expected === null || messageMatch(error.message));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -144,22 +143,19 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
|
||||
var Surrogate = function() {};
|
||||
Surrogate.prototype = type.prototype;
|
||||
return j$.isError_(new Surrogate());
|
||||
return isErrorObject(new Surrogate());
|
||||
}
|
||||
}
|
||||
|
||||
function pass(message) {
|
||||
return {
|
||||
pass: true,
|
||||
message: message
|
||||
};
|
||||
}
|
||||
|
||||
function fail(message) {
|
||||
return {
|
||||
pass: false,
|
||||
message: message
|
||||
};
|
||||
function isErrorObject(thrown) {
|
||||
if (thrown instanceof Error) {
|
||||
return true;
|
||||
}
|
||||
if (thrown && thrown.constructor && thrown.constructor.constructor &&
|
||||
(thrown instanceof (thrown.constructor.constructor('return this')()).Error)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return toThrowError;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
getJasmineRequireObj().toThrowMatching = function(j$) {
|
||||
var usageError = j$.formatErrorMsg('<toThrowMatching>', 'expect(function() {<expectation>}).toThrowMatching(<Predicate>)');
|
||||
|
||||
/**
|
||||
* {@link expect} a function to `throw` something matching a predicate.
|
||||
* @function
|
||||
* @name matchers#toThrowMatching
|
||||
* @param {Function} predicate - A function that takes the thrown exception as its parameter and returns true if it matches.
|
||||
* @example
|
||||
* expect(function() { throw new Error('nope'); }).toThrowMatching(function(thrown) { return thrown.message === 'nope'; });
|
||||
*/
|
||||
function toThrowMatching() {
|
||||
return {
|
||||
compare: function(actual, predicate) {
|
||||
var thrown;
|
||||
|
||||
if (typeof actual !== 'function') {
|
||||
throw new Error(usageError('Actual is not a Function'));
|
||||
}
|
||||
|
||||
if (typeof predicate !== 'function') {
|
||||
throw new Error(usageError('Predicate is not a Function'));
|
||||
}
|
||||
|
||||
try {
|
||||
actual();
|
||||
return fail('Expected function to throw an exception.');
|
||||
} catch (e) {
|
||||
thrown = e;
|
||||
}
|
||||
|
||||
if (predicate(thrown)) {
|
||||
return pass('Expected function not to throw an exception matching a predicate.');
|
||||
} else {
|
||||
return fail(function() {
|
||||
return 'Expected function to throw an exception matching a predicate, ' +
|
||||
'but it threw ' + thrownDescription(thrown) + '.';
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function thrownDescription(thrown) {
|
||||
if (thrown && thrown.constructor) {
|
||||
return j$.fnNameFor(thrown.constructor) + ' with message ' +
|
||||
j$.pp(thrown.message);
|
||||
} else {
|
||||
return j$.pp(thrown);
|
||||
}
|
||||
}
|
||||
|
||||
function pass(message) {
|
||||
return {
|
||||
pass: true,
|
||||
message: message
|
||||
};
|
||||
}
|
||||
|
||||
function fail(message) {
|
||||
return {
|
||||
pass: false,
|
||||
message: message
|
||||
};
|
||||
}
|
||||
|
||||
return toThrowMatching;
|
||||
};
|
||||
@@ -34,8 +34,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
j$.StackTrace = jRequire.StackTrace(j$);
|
||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter();
|
||||
j$.Expectation = jRequire.Expectation();
|
||||
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
||||
j$.JsApiReporter = jRequire.JsApiReporter();
|
||||
@@ -48,7 +47,6 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.Spy = jRequire.Spy(j$);
|
||||
j$.SpyFactory = jRequire.SpyFactory(j$);
|
||||
j$.SpyRegistry = jRequire.SpyRegistry(j$);
|
||||
j$.SpyStrategy = jRequire.SpyStrategy(j$);
|
||||
j$.StringMatching = jRequire.StringMatching(j$);
|
||||
|
||||
@@ -256,42 +256,5 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.clock;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a bare {@link Spy} object. This won't be installed anywhere and will not have any implementation behind it.
|
||||
* @name jasmine.createSpy
|
||||
* @function
|
||||
* @param {String} [name] - Name to give the spy. This will be displayed in failure messages.
|
||||
* @param {Function} [originalFn] - Function to act as the real implementation.
|
||||
* @return {Spy}
|
||||
*/
|
||||
jasmine.createSpy = function(name, originalFn) {
|
||||
return env.createSpy(name, originalFn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an object with multiple {@link Spy}s as its members.
|
||||
* @name jasmine.createSpyObj
|
||||
* @function
|
||||
* @param {String} [baseName] - Base name for the spies in the object.
|
||||
* @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.
|
||||
* @return {Object}
|
||||
*/
|
||||
jasmine.createSpyObj = function(baseName, methodNames) {
|
||||
return env.createSpyObj(baseName, methodNames);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a custom spy strategy for the current scope of specs.
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.addSpyStrategy
|
||||
* @function
|
||||
* @param {String} name - The name of the strategy (i.e. what you call from `and`)
|
||||
* @param {Function} factory - Factory function that returns the plan to be executed.
|
||||
*/
|
||||
jasmine.addSpyStrategy = function(name, factory) {
|
||||
return env.addSpyStrategy(name, factory);
|
||||
};
|
||||
|
||||
return jasmineInterface;
|
||||
};
|
||||
|
||||
@@ -100,53 +100,5 @@ getJasmineRequireObj().util = function(j$) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
};
|
||||
|
||||
function anyMatch(pattern, lines) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
if (lines[i].match(pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function errorWithStack() {
|
||||
// Don't throw and catch if we don't have to, because it makes it harder
|
||||
// for users to debug their code with exception breakpoints.
|
||||
var error = new Error();
|
||||
|
||||
if (error.stack) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// But some browsers (e.g. Phantom) only provide a stack trace if we throw.
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
function callerFile() {
|
||||
var trace = new j$.StackTrace(errorWithStack().stack);
|
||||
return trace.frames[2].file;
|
||||
}
|
||||
|
||||
util.jasmineFile = (function() {
|
||||
var result;
|
||||
|
||||
return function() {
|
||||
var trace;
|
||||
|
||||
if (!result) {
|
||||
result = callerFile();
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}());
|
||||
|
||||
return util;
|
||||
};
|
||||
|
||||
@@ -19,14 +19,9 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.suiteDone = function(result) {
|
||||
this.currentParent.updateResult(result);
|
||||
if (this.currentParent !== this.topResults) {
|
||||
this.currentParent = this.currentParent.parent;
|
||||
}
|
||||
|
||||
if (result.status === 'failed') {
|
||||
this.failureCount++;
|
||||
}
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specStarted = function(result) {
|
||||
@@ -35,7 +30,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
ResultsStateBuilder.prototype.specDone = function(result) {
|
||||
this.currentParent.addChild(result, 'spec');
|
||||
|
||||
if (result.status !== 'excluded') {
|
||||
if (result.status !== 'disabled') {
|
||||
this.specsExecuted++;
|
||||
}
|
||||
|
||||
@@ -55,12 +50,16 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
getContainer = options.getContainer,
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
navigateWithNewParam = options.navigateWithNewParam || function() {},
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
onRandomClick = options.onRandomClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
filterSpecs = options.filterSpecs,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [],
|
||||
deprecationWarnings = [];
|
||||
|
||||
this.initialize = function() {
|
||||
@@ -94,11 +93,11 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
stateBuilder.suiteDone(result);
|
||||
|
||||
if (result.status === 'failed') {
|
||||
failures.push(failureDom(result));
|
||||
if (result.status == 'failed') {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
stateBuilder.suiteDone(result);
|
||||
addDeprecationWarnings(result);
|
||||
};
|
||||
|
||||
@@ -125,8 +124,23 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
));
|
||||
|
||||
if (result.status === 'failed') {
|
||||
failures.push(failureDom(result));
|
||||
if (result.status == 'failed') {
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
|
||||
),
|
||||
createDom('div', {className: 'jasmine-messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
addDeprecationWarnings(result);
|
||||
@@ -138,7 +152,59 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
var order = doneResult && doneResult.order;
|
||||
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
banner.appendChild(optionsMenu(env));
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-exceptions' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-raise',
|
||||
id: 'jasmine-raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
));
|
||||
|
||||
var raiseCheckbox = find('#jasmine-raise-exceptions');
|
||||
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var randomCheckbox = find('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = onRandomClick;
|
||||
|
||||
var optionsMenu = find('.jasmine-run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
|
||||
isOpen = /\bjasmine-open\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' jasmine-open';
|
||||
}
|
||||
};
|
||||
|
||||
if (stateBuilder.specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + stateBuilder.specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
@@ -150,22 +216,15 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
);
|
||||
}
|
||||
var statusBarMessage = '';
|
||||
var statusBarClassName = 'jasmine-overall-result jasmine-bar ';
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
var failed = stateBuilder.failureCount + globalFailures.length > 0;
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
|
||||
if (totalSpecsDefined > 0 || failed) {
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', stateBuilder.specsExecuted) + ', ' + pluralize('failure', stateBuilder.failureCount);
|
||||
if (stateBuilder.pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', stateBuilder.pendingSpecCount); }
|
||||
}
|
||||
|
||||
if (doneResult.overallStatus === 'passed') {
|
||||
statusBarClassName += ' jasmine-passed ';
|
||||
} else if (doneResult.overallStatus === 'incomplete') {
|
||||
statusBarClassName += ' jasmine-incomplete ';
|
||||
statusBarMessage = 'Incomplete: ' + doneResult.incompleteReason + ', ' + statusBarMessage;
|
||||
statusBarClassName += (stateBuilder.failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
} else {
|
||||
statusBarClassName += ' jasmine-failed ';
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
}
|
||||
|
||||
var seedBar;
|
||||
@@ -179,24 +238,19 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
|
||||
|
||||
var errorBarClassName = 'jasmine-bar jasmine-errored';
|
||||
var afterAllMessagePrefix = 'AfterAll ';
|
||||
var errorBarMessagePrefix = 'AfterAll ';
|
||||
|
||||
for(i = 0; i < globalFailures.length; i++) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, globalFailureMessage(globalFailures[i])));
|
||||
for(var i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
|
||||
}
|
||||
}
|
||||
|
||||
function globalFailureMessage(failure) {
|
||||
if (failure.globalErrorType === 'load') {
|
||||
var 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;
|
||||
}
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
for(i = 0; i < globalFailures.length; i++) {
|
||||
var failure = globalFailures[i];
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
|
||||
}
|
||||
|
||||
addDeprecationWarnings(doneResult);
|
||||
@@ -212,6 +266,47 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
summaryList(stateBuilder.topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (filterSpecs && !hasActiveSpec(resultNode)) {
|
||||
continue;
|
||||
}
|
||||
if (resultNode.type == 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-suite-detail'},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type == 'spec') {
|
||||
if (domParent.getAttribute('class') != 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
|
||||
@@ -240,153 +335,6 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
return this;
|
||||
|
||||
function failureDom(result) {
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
failureDescription(result, stateBuilder.currentParent),
|
||||
createDom('div', {className: 'jasmine-messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
return failure;
|
||||
}
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (filterSpecs && !hasActiveSpec(resultNode)) {
|
||||
continue;
|
||||
}
|
||||
if (resultNode.type === 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-suite-detail jasmine-' + resultNode.result.status},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type === 'spec') {
|
||||
if (domParent.getAttribute('class') !== 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function optionsMenu(env) {
|
||||
var optionsMenuDom = createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-stop-on-failure' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-fail-fast',
|
||||
id: 'jasmine-fail-fast',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-fail-fast' }, 'stop execution on spec failure')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
);
|
||||
|
||||
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
|
||||
failFastCheckbox.checked = env.stoppingOnSpecFailure();
|
||||
failFastCheckbox.onclick = function() {
|
||||
navigateWithNewParam('failFast', !env.stoppingOnSpecFailure());
|
||||
};
|
||||
|
||||
var throwCheckbox = optionsMenuDom.querySelector('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = function() {
|
||||
navigateWithNewParam('throwFailures', !env.throwingExpectationFailures());
|
||||
};
|
||||
|
||||
var randomCheckbox = optionsMenuDom.querySelector('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = function() {
|
||||
navigateWithNewParam('random', !env.randomTests());
|
||||
};
|
||||
|
||||
var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'),
|
||||
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) {
|
||||
var wrapper = createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.description, href: specHref(result)}, result.description)
|
||||
);
|
||||
var suiteLink;
|
||||
|
||||
while (suite && suite.parent) {
|
||||
wrapper.insertBefore(createTextNode(' > '), wrapper.firstChild);
|
||||
suiteLink = createDom('a', {href: suiteHref(suite)}, suite.result.description);
|
||||
wrapper.insertBefore(suiteLink, wrapper.firstChild);
|
||||
|
||||
suite = suite.parent;
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function suiteHref(suite) {
|
||||
var els = [];
|
||||
|
||||
while (suite && suite.parent) {
|
||||
els.unshift(suite.result.description);
|
||||
suite = suite.parent;
|
||||
}
|
||||
|
||||
return addToExistingQueryString('spec', els.join(' '));
|
||||
}
|
||||
|
||||
function addDeprecationWarnings(result) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for(var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
@@ -465,7 +413,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function hasActiveSpec(resultNode) {
|
||||
if (resultNode.type == 'spec' && resultNode.result.status != 'excluded') {
|
||||
if (resultNode.type == 'spec' && resultNode.result.status != 'disabled') {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,6 @@ jasmineRequire.ResultsNode = function() {
|
||||
this.last = function() {
|
||||
return this.children[this.children.length - 1];
|
||||
};
|
||||
|
||||
this.updateResult = function(result) {
|
||||
this.result = result;
|
||||
};
|
||||
}
|
||||
|
||||
return ResultsNode;
|
||||
|
||||
@@ -135,7 +135,7 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
&.jasmine-excluded {
|
||||
&.jasmine-disabled {
|
||||
font-size: 14px;
|
||||
|
||||
&:before {
|
||||
@@ -200,22 +200,20 @@ body {
|
||||
display: block;
|
||||
color: #eee;
|
||||
|
||||
&.jasmine-failed, &.jasmine-errored {
|
||||
&.jasmine-failed {
|
||||
background-color: $failing-color;
|
||||
border-bottom: 1px solid $page-background-color;
|
||||
}
|
||||
|
||||
&.jasmine-passed {
|
||||
background-color: $passing-color;
|
||||
}
|
||||
|
||||
&.jasmine-incomplete {
|
||||
&.jasmine-skipped {
|
||||
background-color: $neutral-color;
|
||||
}
|
||||
|
||||
|
||||
&.jasmine-skipped {
|
||||
background-color: $neutral-color;
|
||||
&.jasmine-errored {
|
||||
background-color: $failing-color;
|
||||
}
|
||||
|
||||
&.jasmine-warning {
|
||||
@@ -292,7 +290,7 @@ body {
|
||||
color: $pending-color;
|
||||
}
|
||||
|
||||
&.jasmine-excluded a {
|
||||
&.jasmine-disabled a {
|
||||
color: $neutral-color;
|
||||
}
|
||||
}
|
||||
@@ -318,7 +316,6 @@ body {
|
||||
|
||||
.jasmine-description {
|
||||
background-color: $failing-color;
|
||||
color: white;
|
||||
|
||||
a {
|
||||
color: white;
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
jasmineRequire.toHaveClass = function(j$) {
|
||||
/**
|
||||
* {@link expect} the actual value to be a DOM element that has the expected class
|
||||
* @function
|
||||
* @name matchers#toHaveClass
|
||||
* @param {Object} expected - The class name to test for
|
||||
* @example
|
||||
* var el = document.createElement('div');
|
||||
* el.className = 'foo bar baz';
|
||||
* expect(el).toHaveClass('bar');
|
||||
*/
|
||||
function toHaveClass(util, customEqualityTesters) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
if (!isElement(actual)) {
|
||||
throw new Error(j$.pp(actual) + ' is not a DOM element');
|
||||
}
|
||||
|
||||
return {
|
||||
pass: actual.classList.contains(expected)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isElement(maybeEl) {
|
||||
return maybeEl &&
|
||||
maybeEl.classList &&
|
||||
j$.isFunction_(maybeEl.classList.contains);
|
||||
}
|
||||
|
||||
return toHaveClass;
|
||||
};
|
||||
@@ -3,5 +3,4 @@ jasmineRequire.html = function(j$) {
|
||||
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
|
||||
j$.QueryString = jasmineRequire.QueryString();
|
||||
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
|
||||
j$.matchers.toHaveClass = jasmineRequire.toHaveClass(j$);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user