Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c6308f1dc | ||
|
|
4e5d947faa | ||
|
|
c2603efeb4 | ||
|
|
fbec3cc230 | ||
|
|
4530f9431f | ||
|
|
9911d37f06 | ||
|
|
32f99ef99d | ||
|
|
c142490c69 | ||
|
|
24bf3489dc | ||
|
|
5afe1222f4 | ||
|
|
70bce55721 | ||
|
|
53529bdc9a | ||
|
|
c82e5947f5 | ||
|
|
f76b452816 | ||
|
|
91aab8e1b8 | ||
|
|
486a64658f | ||
|
|
1dfdc89ba9 | ||
|
|
085a1f8a16 | ||
|
|
aeeb5b7107 | ||
|
|
cb6de64e58 | ||
|
|
f69949ebc0 | ||
|
|
1136fddcde | ||
|
|
b943f6b736 | ||
|
|
b439e2fb37 | ||
|
|
c79ce125c0 | ||
|
|
62b815c485 | ||
|
|
65b4499dec | ||
|
|
b6cc34d9e9 | ||
|
|
d3a3cf1ff3 | ||
|
|
c0d0513199 | ||
|
|
86a38fceb9 | ||
|
|
c74af1d900 | ||
|
|
8ea4c6d3a1 | ||
|
|
0b5dce7d84 | ||
|
|
0183b1642d | ||
|
|
18ed34e9be | ||
|
|
f4caf27208 | ||
|
|
13b9e669bd | ||
|
|
2eef0747a0 | ||
|
|
7ac1244f58 | ||
|
|
6ef0e93880 | ||
|
|
2be5e0a962 | ||
|
|
285f06d5c4 | ||
|
|
3aece2ac74 | ||
|
|
3a9d4ee08d | ||
|
|
b4dfdd7a48 | ||
|
|
c260c67e7e | ||
|
|
554d0efab7 | ||
|
|
ea3cf14ef8 | ||
|
|
a4bdd47a8a | ||
|
|
89306551a0 | ||
|
|
0e95b04900 | ||
|
|
da91294182 | ||
|
|
bd41a97cd5 | ||
|
|
6d3953356d | ||
|
|
62f769767a | ||
|
|
03f7f76bca | ||
|
|
4c6dadb9b1 | ||
|
|
8973e4e44f | ||
|
|
b7e9594c86 | ||
|
|
6c363f11b3 | ||
|
|
0f650e1d03 | ||
|
|
78fe42ac2d | ||
|
|
20d86b2a00 | ||
|
|
516e00d7ba | ||
|
|
c1957ecd7c | ||
|
|
1f6c91de7c | ||
|
|
f6342ad4fe | ||
|
|
7ca571a746 | ||
|
|
4240b3514b | ||
|
|
ab116fbd0f | ||
|
|
da2673e02f | ||
|
|
6ddf64568e |
@@ -1,16 +0,0 @@
|
||||
languages:
|
||||
JavaScript: true
|
||||
ratings:
|
||||
paths:
|
||||
- "src/**/*.js"
|
||||
exclude_paths:
|
||||
- "lib/**"
|
||||
- "dist/*"
|
||||
- "grunt/**"
|
||||
- "images/*"
|
||||
- "**/*.md"
|
||||
- "**/*.yml"
|
||||
- "**/*.json"
|
||||
- "**/*.scss"
|
||||
- "**/*.erb"
|
||||
- "*.sh"
|
||||
13
.github/CONTRIBUTING.md
vendored
13
.github/CONTRIBUTING.md
vendored
@@ -16,7 +16,8 @@ Please submit pull requests via feature branches using the semi-standard workflo
|
||||
git clone git@github.com:yourUserName/jasmine.git # Clone your fork
|
||||
cd jasmine # Change directory
|
||||
git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream'
|
||||
git fetch upstream # Pull in changes not present in your local repository
|
||||
git fetch upstream # Fetch changes not present in your local repository
|
||||
git merge upstream/master # Sync local master with upstream repository
|
||||
git checkout -b my-new-feature # Create your feature branch
|
||||
git commit -am 'Add some feature' # Commit your changes
|
||||
git push origin my-new-feature # Push to the branch
|
||||
@@ -40,9 +41,9 @@ Once you've pushed a feature branch to your forked repo, you're ready to open a
|
||||
|
||||
### Self-testing
|
||||
|
||||
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `j$`. So there are two copies of the code loaded under test.
|
||||
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `jasmineUnderTest`. So there are two copies of the code loaded under test.
|
||||
|
||||
The tests should always use `j$` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
|
||||
The tests should always use `jasmineUnderTest` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
|
||||
|
||||
### `boot.js`
|
||||
|
||||
@@ -129,11 +130,9 @@ The easiest way to run the tests in **Internet Explorer** is to run a VM that ha
|
||||
1. Ensure all specs are green in browser *and* node
|
||||
1. Ensure JSHint is green with `grunt jshint`
|
||||
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
|
||||
|
||||
## Submitting a Pull Request
|
||||
1. Revert your changes to `jasmine.js` and `jasmine-html.js`
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
|
||||
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
|
||||
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
|
||||
|
||||
Note that we use Travis for Continuous Integration. We only accept green pull requests.
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,6 +11,7 @@ site/
|
||||
.bundle
|
||||
tags
|
||||
Gemfile.lock
|
||||
package-lock.json
|
||||
pkg/*
|
||||
.sass-cache/*
|
||||
src/html/.sass-cache/*
|
||||
|
||||
15
.travis.yml
15
.travis.yml
@@ -24,7 +24,16 @@ matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- TEST_COMMAND="bash travis-node-script.sh v0.12.18"
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v4"
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v8"
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v9"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.11"
|
||||
@@ -37,10 +46,6 @@ matrix:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.9"
|
||||
- SAUCE_BROWSER_VERSION=7
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.8"
|
||||
- SAUCE_BROWSER_VERSION=6
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8.1"
|
||||
|
||||
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,7 +1,6 @@
|
||||
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
|
||||
|
||||
[](https://travis-ci.org/jasmine/jasmine)
|
||||
[](https://codeclimate.com/github/pivotal/jasmine)
|
||||
|
||||
=======
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@ Follow the instructions in `CONTRIBUTING.md` during development.
|
||||
|
||||
### Git Rules
|
||||
|
||||
Please work on feature branches.
|
||||
|
||||
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`.
|
||||
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when pushing to `master`.
|
||||
|
||||
### Version
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
||||
s.rubyforge_project = "jasmine-core"
|
||||
s.license = "MIT"
|
||||
|
||||
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
|
||||
s.files = Dir.glob("./lib/**/*")
|
||||
s.require_paths = ["lib"]
|
||||
s.add_development_dependency "rake"
|
||||
s.add_development_dependency "sauce-connect"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 Pivotal Labs
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 Pivotal Labs
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 Pivotal Labs
|
||||
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
|
||||
@@ -34,6 +34,46 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
|
||||
function ResultsStateBuilder() {
|
||||
this.topResults = new j$.ResultsNode({}, '', null);
|
||||
this.currentParent = this.topResults;
|
||||
this.specsExecuted = 0;
|
||||
this.failureCount = 0;
|
||||
this.pendingSpecCount = 0;
|
||||
}
|
||||
|
||||
ResultsStateBuilder.prototype.suiteStarted = function(result) {
|
||||
this.currentParent.addChild(result, 'suite');
|
||||
this.currentParent = this.currentParent.last();
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.suiteDone = function(result) {
|
||||
if (this.currentParent !== this.topResults) {
|
||||
this.currentParent = this.currentParent.parent;
|
||||
}
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specStarted = function(result) {
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specDone = function(result) {
|
||||
this.currentParent.addChild(result, 'spec');
|
||||
|
||||
if (result.status !== 'disabled') {
|
||||
this.specsExecuted++;
|
||||
}
|
||||
|
||||
if (result.status === 'failed') {
|
||||
this.failureCount++;
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
this.pendingSpecCount++;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
function HtmlReporter(options) {
|
||||
var env = options.env || {},
|
||||
getContainer = options.getContainer,
|
||||
@@ -46,12 +86,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
filterSpecs = options.filterSpecs,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
failedSuites = [],
|
||||
deprecationWarnings = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
@@ -77,12 +115,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
var summary = createDom('div', {className: 'jasmine-summary'});
|
||||
|
||||
var topResults = new j$.ResultsNode({}, '', null),
|
||||
currentParent = topResults;
|
||||
var stateBuilder = new ResultsStateBuilder();
|
||||
|
||||
this.suiteStarted = function(result) {
|
||||
currentParent.addChild(result, 'suite');
|
||||
currentParent = currentParent.last();
|
||||
stateBuilder.suiteStarted(result);
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
@@ -90,27 +126,22 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentParent = currentParent.parent;
|
||||
stateBuilder.suiteDone(result);
|
||||
addDeprecationWarnings(result);
|
||||
};
|
||||
|
||||
this.specStarted = function(result) {
|
||||
currentParent.addChild(result, 'spec');
|
||||
stateBuilder.specStarted(result);
|
||||
};
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
stateBuilder.specDone(result);
|
||||
|
||||
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
|
||||
console.error('Spec \'' + result.fullName + '\' has no expectations.');
|
||||
}
|
||||
|
||||
if (result.status != 'disabled') {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
if (!symbols){
|
||||
symbols = find('.jasmine-symbol-summary');
|
||||
}
|
||||
@@ -123,8 +154,6 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
));
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
@@ -143,9 +172,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingSpecCount++;
|
||||
}
|
||||
addDeprecationWarnings(result);
|
||||
};
|
||||
|
||||
this.jasmineDone = function(doneResult) {
|
||||
@@ -208,8 +235,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
if (stateBuilder.specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + stateBuilder.specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
var skippedLink = addToExistingQueryString('spec', '');
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
|
||||
@@ -221,9 +248,9 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
|
||||
statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
statusBarMessage += pluralize('spec', stateBuilder.specsExecuted) + ', ' + pluralize('failure', stateBuilder.failureCount);
|
||||
if (stateBuilder.pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', stateBuilder.pendingSpecCount); }
|
||||
statusBarClassName += (stateBuilder.failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
} else {
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
@@ -255,10 +282,18 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
|
||||
}
|
||||
|
||||
addDeprecationWarnings(doneResult);
|
||||
|
||||
var warningBarClassName = 'jasmine-bar jasmine-warning';
|
||||
for(i = 0; i < deprecationWarnings.length; i++) {
|
||||
var warning = deprecationWarnings[i];
|
||||
alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning));
|
||||
}
|
||||
|
||||
var results = find('.jasmine-results');
|
||||
results.appendChild(summary);
|
||||
|
||||
summaryList(topResults, summary);
|
||||
summaryList(stateBuilder.topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
@@ -329,6 +364,17 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
return this;
|
||||
|
||||
function addDeprecationWarnings(result) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for(var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
var warning = result.deprecationWarnings[i].message;
|
||||
if (!j$.util.arrayContains(warning)) {
|
||||
deprecationWarnings.push(warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ body { overflow-y: scroll; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; color: #333; }
|
||||
.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; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 Pivotal Labs
|
||||
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
|
||||
@@ -34,7 +34,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
|
||||
jasmineGlobal = window;
|
||||
}
|
||||
jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {};
|
||||
jasmineRequire = jasmineGlobal.jasmineRequire = {};
|
||||
}
|
||||
|
||||
function getJasmineRequire() {
|
||||
@@ -45,7 +45,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
var j$ = {};
|
||||
|
||||
jRequire.base(j$, jasmineGlobal);
|
||||
j$.util = jRequire.util();
|
||||
j$.util = jRequire.util(j$);
|
||||
j$.errors = jRequire.errors();
|
||||
j$.formatErrorMsg = jRequire.formatErrorMsg();
|
||||
j$.Any = jRequire.Any(j$);
|
||||
@@ -54,7 +54,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.MockDate = jRequire.MockDate();
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter();
|
||||
j$.Expectation = jRequire.Expectation();
|
||||
@@ -66,7 +66,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$);
|
||||
j$.pp = jRequire.pp(j$);
|
||||
j$.QueueRunner = jRequire.QueueRunner(j$);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher();
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.Spy = jRequire.Spy(j$);
|
||||
j$.SpyRegistry = jRequire.SpyRegistry(j$);
|
||||
@@ -138,14 +138,20 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Set this to a lower value to speed up pretty printing if you have large objects.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_DEPTH
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 40;
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 8;
|
||||
/**
|
||||
* Maximum number of array elements to display when pretty printing objects.
|
||||
* This will also limit the number of keys and values displayed for an object.
|
||||
* Elements past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100;
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
|
||||
/**
|
||||
* Maximum number of charasters to display when pretty printing objects.
|
||||
* Characters past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_CHARS
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_CHARS = 1000;
|
||||
/**
|
||||
* Default number of milliseconds Jasmine will wait for an asynchronous spec to complete.
|
||||
* @name jasmine.DEFAULT_TIMEOUT_INTERVAL
|
||||
@@ -217,6 +223,18 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return obj.nodeType > 0;
|
||||
};
|
||||
|
||||
j$.isMap = function(obj) {
|
||||
return typeof jasmineGlobal.Map !== 'undefined' && obj.constructor === jasmineGlobal.Map;
|
||||
};
|
||||
|
||||
j$.isSet = function(obj) {
|
||||
return typeof jasmineGlobal.Set !== 'undefined' && obj.constructor === jasmineGlobal.Set;
|
||||
};
|
||||
|
||||
j$.isPromise = function(obj) {
|
||||
return typeof jasmineGlobal.Promise !== 'undefined' && obj.constructor === jasmineGlobal.Promise;
|
||||
};
|
||||
|
||||
j$.fnNameFor = function(func) {
|
||||
if (func.name) {
|
||||
return func.name;
|
||||
@@ -355,7 +373,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
};
|
||||
};
|
||||
|
||||
getJasmineRequireObj().util = function() {
|
||||
getJasmineRequireObj().util = function(j$) {
|
||||
|
||||
var util = {};
|
||||
|
||||
@@ -412,6 +430,23 @@ getJasmineRequireObj().util = function() {
|
||||
return cloned;
|
||||
};
|
||||
|
||||
util.cloneArgs = function(args) {
|
||||
var clonedArgs = [];
|
||||
var argsAsArray = j$.util.argsToArray(args);
|
||||
for(var i = 0; i < argsAsArray.length; i++) {
|
||||
var str = Object.prototype.toString.apply(argsAsArray[i]),
|
||||
primitives = /^\[object (Boolean|String|RegExp|Number)/;
|
||||
|
||||
// All falsey values are either primitives, `null`, or `undefined.
|
||||
if (!argsAsArray[i] || str.match(primitives)) {
|
||||
clonedArgs.push(argsAsArray[i]);
|
||||
} else {
|
||||
clonedArgs.push(j$.util.clone(argsAsArray[i]));
|
||||
}
|
||||
}
|
||||
return clonedArgs;
|
||||
};
|
||||
|
||||
util.getPropertyDescriptor = function(obj, methodName) {
|
||||
var descriptor,
|
||||
proto = obj;
|
||||
@@ -470,6 +505,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @property {String} fullName - The full description including all ancestors of this spec.
|
||||
* @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
|
||||
* @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
|
||||
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
|
||||
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
|
||||
*/
|
||||
@@ -479,6 +515,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
};
|
||||
}
|
||||
@@ -594,6 +631,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
|
||||
Spec.prototype.addDeprecationWarning = function(msg) {
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
|
||||
};
|
||||
|
||||
var extractCustomPendingMessage = function(e) {
|
||||
var fullMessage = e.toString(),
|
||||
boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
|
||||
@@ -675,6 +716,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var self = this;
|
||||
var global = options.global || j$.getGlobal();
|
||||
|
||||
var hasExecuted = false;
|
||||
|
||||
var totalSpecsDefined = 0;
|
||||
|
||||
var catchExceptions = true;
|
||||
@@ -861,6 +904,9 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
// 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;
|
||||
};
|
||||
|
||||
@@ -898,6 +944,14 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
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;
|
||||
@@ -905,6 +959,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
options.fail = self.fail;
|
||||
options.globalErrors = globalErrors;
|
||||
options.completeOnFirstError = throwOnExpectationFailure && options.isLeaf;
|
||||
options.deprecated = self.deprecated;
|
||||
|
||||
new j$.QueueRunner(options).execute();
|
||||
};
|
||||
@@ -924,6 +979,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
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) {
|
||||
runnablesToRun = focusedRunnables;
|
||||
@@ -990,10 +1051,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @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
|
||||
failedExpectations: topSuite.result.failedExpectations,
|
||||
deprecationWarnings: topSuite.result.deprecationWarnings
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1048,6 +1111,13 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
function ensureIsNotNested(method) {
|
||||
var runnable = currentRunnable();
|
||||
if (runnable !== null && runnable !== undefined) {
|
||||
throw new Error('\'' + method + '\' should only be used in \'describe\' function');
|
||||
}
|
||||
}
|
||||
|
||||
var suiteFactory = function(description) {
|
||||
var suite = new j$.Suite({
|
||||
env: self,
|
||||
@@ -1063,6 +1133,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.describe = function(description, specDefinitions) {
|
||||
ensureIsNotNested('describe');
|
||||
ensureIsFunction(specDefinitions, 'describe');
|
||||
var suite = suiteFactory(description);
|
||||
if (specDefinitions.length > 0) {
|
||||
@@ -1076,6 +1147,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.xdescribe = function(description, specDefinitions) {
|
||||
ensureIsNotNested('xdescribe');
|
||||
ensureIsFunction(specDefinitions, 'xdescribe');
|
||||
var suite = suiteFactory(description);
|
||||
suite.pend();
|
||||
@@ -1086,6 +1158,8 @@ 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);
|
||||
suite.isFocused = true;
|
||||
@@ -1183,6 +1257,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.it = function(description, fn, timeout) {
|
||||
ensureIsNotNested('it');
|
||||
// it() sometimes doesn't have a fn argument, so only check the type if
|
||||
// it's given.
|
||||
if (arguments.length > 1 && typeof fn !== 'undefined') {
|
||||
@@ -1197,6 +1272,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.xit = function(description, fn, timeout) {
|
||||
ensureIsNotNested('xit');
|
||||
// xit(), like it(), doesn't always have a fn argument, so only check the
|
||||
// type when needed.
|
||||
if (arguments.length > 1 && typeof fn !== 'undefined') {
|
||||
@@ -1208,6 +1284,8 @@ 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);
|
||||
currentDeclarationSuite.addChild(spec);
|
||||
@@ -1225,6 +1303,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||
ensureIsNotNested('beforeEach');
|
||||
ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
|
||||
currentDeclarationSuite.beforeEach({
|
||||
fn: beforeEachFunction,
|
||||
@@ -1233,6 +1312,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.beforeAll = function(beforeAllFunction, timeout) {
|
||||
ensureIsNotNested('beforeAll');
|
||||
ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');
|
||||
currentDeclarationSuite.beforeAll({
|
||||
fn: beforeAllFunction,
|
||||
@@ -1241,6 +1321,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.afterEach = function(afterEachFunction, timeout) {
|
||||
ensureIsNotNested('afterEach');
|
||||
ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');
|
||||
afterEachFunction.isCleanup = true;
|
||||
currentDeclarationSuite.afterEach({
|
||||
@@ -1250,6 +1331,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.afterAll = function(afterAllFunction, timeout) {
|
||||
ensureIsNotNested('afterAll');
|
||||
ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');
|
||||
currentDeclarationSuite.afterAll({
|
||||
fn: afterAllFunction,
|
||||
@@ -1458,6 +1540,9 @@ getJasmineRequireObj().Any = function(j$) {
|
||||
}
|
||||
|
||||
if (this.expectedObject == Object) {
|
||||
if (other === null) {
|
||||
j$.getEnv().deprecated('jasmine.Any(Object) will no longer match null in Jasmine 3.0');
|
||||
}
|
||||
return typeof other == 'object';
|
||||
}
|
||||
|
||||
@@ -1465,6 +1550,12 @@ getJasmineRequireObj().Any = function(j$) {
|
||||
return typeof other == 'boolean';
|
||||
}
|
||||
|
||||
/* jshint -W122 */
|
||||
if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) {
|
||||
return typeof other == 'symbol';
|
||||
}
|
||||
/* jshint +W122 */
|
||||
|
||||
return other instanceof this.expectedObject;
|
||||
};
|
||||
|
||||
@@ -1629,25 +1720,9 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
var calls = [];
|
||||
var opts = {};
|
||||
|
||||
function argCloner(context) {
|
||||
var clonedArgs = [];
|
||||
var argsAsArray = j$.util.argsToArray(context.args);
|
||||
for(var i = 0; i < argsAsArray.length; i++) {
|
||||
var str = Object.prototype.toString.apply(argsAsArray[i]),
|
||||
primitives = /^\[object (Boolean|String|RegExp|Number)/;
|
||||
|
||||
if (argsAsArray[i] == null || str.match(primitives)) {
|
||||
clonedArgs.push(argsAsArray[i]);
|
||||
} else {
|
||||
clonedArgs.push(j$.util.clone(argsAsArray[i]));
|
||||
}
|
||||
}
|
||||
context.args = clonedArgs;
|
||||
}
|
||||
|
||||
this.track = function(context) {
|
||||
if(opts.cloneArgs) {
|
||||
argCloner(context);
|
||||
context.args = j$.util.cloneArgs(context.args);
|
||||
}
|
||||
calls.push(context);
|
||||
};
|
||||
@@ -1823,6 +1898,9 @@ getJasmineRequireObj().clearStack = function(j$) {
|
||||
};
|
||||
|
||||
getJasmineRequireObj().Clock = function() {
|
||||
|
||||
var NODE_JS = typeof process !== 'undefined' && process.versions && typeof process.versions.node === 'string';
|
||||
|
||||
/**
|
||||
* _Note:_ Do not construct this directly, Jasmine will make one during booting. You can get the current clock with {@link jasmine.clock}.
|
||||
* @class Clock
|
||||
@@ -1846,6 +1924,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
delayedFunctionScheduler,
|
||||
timer;
|
||||
|
||||
self.FakeTimeout = FakeTimeout;
|
||||
|
||||
/**
|
||||
* Install the mock clock over the built-in methods.
|
||||
@@ -1969,7 +2048,15 @@ getJasmineRequireObj().Clock = function() {
|
||||
}
|
||||
|
||||
function setTimeout(fn, delay) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
|
||||
if (!NODE_JS) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
|
||||
}
|
||||
|
||||
var timeout = new FakeTimeout();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2), false, timeout);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
function clearTimeout(id) {
|
||||
@@ -1977,7 +2064,15 @@ getJasmineRequireObj().Clock = function() {
|
||||
}
|
||||
|
||||
function setInterval(fn, interval) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
|
||||
if (!NODE_JS) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
|
||||
}
|
||||
|
||||
var timeout = new FakeTimeout();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true, timeout);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
function clearInterval(id) {
|
||||
@@ -1989,16 +2084,30 @@ getJasmineRequireObj().Clock = function() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks Node.js Timeout class
|
||||
*/
|
||||
function FakeTimeout() {}
|
||||
|
||||
FakeTimeout.prototype.ref = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
FakeTimeout.prototype.unref = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
return Clock;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
function DelayedFunctionScheduler() {
|
||||
var self = this;
|
||||
var scheduledLookup = [];
|
||||
var scheduledFunctions = {};
|
||||
var currentTime = 0;
|
||||
var delayedFnCount = 0;
|
||||
var deletedKeys = [];
|
||||
|
||||
self.tick = function(millis, tickDate) {
|
||||
millis = millis || 0;
|
||||
@@ -2045,6 +2154,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
};
|
||||
|
||||
self.removeFunctionWithId = function(timeoutKey) {
|
||||
deletedKeys.push(timeoutKey);
|
||||
|
||||
for (var runAtMillis in scheduledFunctions) {
|
||||
var funcs = scheduledFunctions[runAtMillis];
|
||||
var i = indexOfFirstToPass(funcs, function (func) {
|
||||
@@ -2115,12 +2226,14 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
}
|
||||
|
||||
do {
|
||||
deletedKeys = [];
|
||||
var newCurrentTime = scheduledLookup.shift();
|
||||
tickDate(newCurrentTime - currentTime);
|
||||
|
||||
currentTime = newCurrentTime;
|
||||
|
||||
var funcsToRun = scheduledFunctions[currentTime];
|
||||
|
||||
delete scheduledFunctions[currentTime];
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
@@ -2130,6 +2243,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
});
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) {
|
||||
// skip a timeoutKey deleted whilst we were running
|
||||
return;
|
||||
}
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
});
|
||||
} while (scheduledLookup.length > 0 &&
|
||||
@@ -2660,6 +2777,12 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aIsPromise = j$.isPromise(a);
|
||||
var bIsPromise = j$.isPromise(b);
|
||||
if (aIsPromise && bIsPromise) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
var length = aStack.length;
|
||||
@@ -2693,22 +2816,46 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
} else if (className == '[object Map]') {
|
||||
} else if (j$.isMap(a) && j$.isMap(b)) {
|
||||
if (a.size != b.size) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
|
||||
// For both sets of keys, check they map to equal values in both maps
|
||||
var mapKeys = [a.keys(), b.keys()];
|
||||
var mapIter, mapKeyIt, mapKey;
|
||||
var keysA = [];
|
||||
var keysB = [];
|
||||
a.forEach( function( valueA, keyA ) {
|
||||
keysA.push( keyA );
|
||||
});
|
||||
b.forEach( function( valueB, keyB ) {
|
||||
keysB.push( keyB );
|
||||
});
|
||||
|
||||
// For both sets of keys, check they map to equal values in both maps.
|
||||
// Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys.
|
||||
var mapKeys = [keysA, keysB];
|
||||
var cmpKeys = [keysB, keysA];
|
||||
var mapIter, mapKey, mapValueA, mapValueB;
|
||||
var cmpIter, cmpKey;
|
||||
for (i = 0; result && i < mapKeys.length; i++) {
|
||||
mapIter = mapKeys[i];
|
||||
mapKeyIt = mapIter.next();
|
||||
while (result && !mapKeyIt.done) {
|
||||
mapKey = mapKeyIt.value;
|
||||
result = eq(a.get(mapKey), b.get(mapKey), aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
mapKeyIt = mapIter.next();
|
||||
cmpIter = cmpKeys[i];
|
||||
|
||||
for (var j = 0; result && j < mapIter.length; j++) {
|
||||
mapKey = mapIter[j];
|
||||
cmpKey = cmpIter[j];
|
||||
mapValueA = a.get(mapKey);
|
||||
|
||||
// Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches,
|
||||
// otherwise explicitly look up the mapKey in the other Map since we want keys with unique
|
||||
// obj identity (that are otherwise equal) to not match.
|
||||
if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) &&
|
||||
eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) {
|
||||
mapValueB = b.get(cmpKey);
|
||||
} else {
|
||||
mapValueB = b.get(mapKey);
|
||||
}
|
||||
result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2716,36 +2863,49 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
} else if (className == '[object Set]') {
|
||||
} else if (j$.isSet(a) && j$.isSet(b)) {
|
||||
if (a.size != b.size) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
|
||||
var valuesA = [];
|
||||
a.forEach( function( valueA ) {
|
||||
valuesA.push( valueA );
|
||||
});
|
||||
var valuesB = [];
|
||||
b.forEach( function( valueB ) {
|
||||
valuesB.push( valueB );
|
||||
});
|
||||
|
||||
// For both sets, check they are all contained in the other set
|
||||
var setPairs = [[a, b], [b, a]];
|
||||
var baseIter, baseValueIt, baseValue;
|
||||
var otherSet, otherIter, otherValueIt, otherValue, found;
|
||||
var setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
|
||||
var stackPairs = [[aStack, bStack], [bStack, aStack]];
|
||||
var baseValues, baseValue, baseStack;
|
||||
var otherValues, otherValue, otherStack;
|
||||
var found;
|
||||
var prevStackSize;
|
||||
for (i = 0; result && i < setPairs.length; i++) {
|
||||
baseIter = setPairs[i][0].values();
|
||||
otherSet = setPairs[i][1];
|
||||
baseValues = setPairs[i][0];
|
||||
otherValues = setPairs[i][1];
|
||||
baseStack = stackPairs[i][0];
|
||||
otherStack = stackPairs[i][1];
|
||||
// For each value in the base set...
|
||||
baseValueIt = baseIter.next();
|
||||
while (result && !baseValueIt.done) {
|
||||
baseValue = baseValueIt.value;
|
||||
for (var k = 0; result && k < baseValues.length; k++) {
|
||||
baseValue = baseValues[k];
|
||||
found = false;
|
||||
// ... test that it is present in the other set
|
||||
otherIter = otherSet.values();
|
||||
otherValueIt = otherIter.next();
|
||||
// Optimisation: start looking for value by object identity
|
||||
found = otherSet.has(baseValue);
|
||||
// If not found, compare by value equality
|
||||
while (!found && !otherValueIt.done) {
|
||||
otherValue = otherValueIt.value;
|
||||
found = eq(baseValue, otherValue, aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
otherValueIt = otherIter.next();
|
||||
for (var l = 0; !found && l < otherValues.length; l++) {
|
||||
otherValue = otherValues[l];
|
||||
prevStackSize = baseStack.length;
|
||||
// compare by value equality
|
||||
found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder());
|
||||
if (!found && prevStackSize !== baseStack.length) {
|
||||
baseStack.splice(prevStackSize);
|
||||
otherStack.splice(prevStackSize);
|
||||
}
|
||||
}
|
||||
result = result && found;
|
||||
baseValueIt = baseIter.next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3891,6 +4051,8 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
function PrettyPrinter() {
|
||||
this.ppNestLevel_ = 0;
|
||||
this.seen = [];
|
||||
this.length = 0;
|
||||
this.stringParts = [];
|
||||
}
|
||||
|
||||
function hasCustomToString(value) {
|
||||
@@ -3924,9 +4086,9 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.emitScalar('HTMLNode');
|
||||
} else if (value instanceof Date) {
|
||||
this.emitScalar('Date(' + value + ')');
|
||||
} else if (j$.getType_(value) == '[object Set]') {
|
||||
} else if (j$.isSet(value)) {
|
||||
this.emitSet(value);
|
||||
} else if (j$.getType_(value) == '[object Map]') {
|
||||
} else if (j$.isMap(value)) {
|
||||
this.emitMap(value);
|
||||
} else if (j$.isTypedArray_(value)) {
|
||||
this.emitTypedArray(value);
|
||||
@@ -3945,6 +4107,10 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
} else {
|
||||
this.emitScalar(value.toString());
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
this.ppNestLevel_--;
|
||||
}
|
||||
@@ -3970,30 +4136,15 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
return objKeys.length > length;
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitSet = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitMap = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;
|
||||
|
||||
function StringPrettyPrinter() {
|
||||
PrettyPrinter.call(this);
|
||||
|
||||
this.stringParts = [];
|
||||
}
|
||||
|
||||
j$.util.inherit(StringPrettyPrinter, PrettyPrinter);
|
||||
|
||||
StringPrettyPrinter.prototype.emitScalar = function(value) {
|
||||
PrettyPrinter.prototype.emitScalar = function(value) {
|
||||
this.append(value);
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitString = function(value) {
|
||||
PrettyPrinter.prototype.emitString = function(value) {
|
||||
this.append('\'' + value + '\'');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitArray = function(array) {
|
||||
PrettyPrinter.prototype.emitArray = function(array) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Array');
|
||||
return;
|
||||
@@ -4027,47 +4178,57 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(' ]');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitSet = function(set) {
|
||||
PrettyPrinter.prototype.emitSet = function(set) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Set');
|
||||
return;
|
||||
}
|
||||
this.append('Set( ');
|
||||
var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var iter = set.values();
|
||||
for (var i = 0; i < size; i++) {
|
||||
var i = 0;
|
||||
set.forEach( function( value, key ) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(iter.next().value);
|
||||
}
|
||||
this.format(value);
|
||||
|
||||
i++;
|
||||
}, this );
|
||||
if (set.size > size){
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitMap = function(map) {
|
||||
PrettyPrinter.prototype.emitMap = function(map) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Map');
|
||||
return;
|
||||
}
|
||||
this.append('Map( ');
|
||||
var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var iter = map.entries();
|
||||
for (var i = 0; i < size; i++) {
|
||||
var i = 0;
|
||||
map.forEach( function( value, key ) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(iter.next().value);
|
||||
}
|
||||
this.format([key,value]);
|
||||
|
||||
i++;
|
||||
}, this );
|
||||
if (map.size > size){
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitObject = function(obj) {
|
||||
PrettyPrinter.prototype.emitObject = function(obj) {
|
||||
var ctor = obj.constructor,
|
||||
constructorName;
|
||||
|
||||
@@ -4100,7 +4261,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(' })');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitTypedArray = function(arr) {
|
||||
PrettyPrinter.prototype.emitTypedArray = function(arr) {
|
||||
var constructorName = j$.fnNameFor(arr.constructor),
|
||||
limitedArray = Array.prototype.slice.call(arr, 0, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH),
|
||||
itemsString = Array.prototype.join.call(limitedArray, ', ');
|
||||
@@ -4112,7 +4273,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(constructorName + ' [ ' + itemsString + ' ]');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
this.append(property);
|
||||
this.append(': ');
|
||||
if (isGetter) {
|
||||
@@ -4122,10 +4283,33 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.append = function(value) {
|
||||
this.stringParts.push(value);
|
||||
PrettyPrinter.prototype.append = function(value) {
|
||||
var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);
|
||||
this.length += result.value.length;
|
||||
this.stringParts.push(result.value);
|
||||
|
||||
if (result.truncated) {
|
||||
throw new MaxCharsReachedError();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function truncate(s, maxlen) {
|
||||
if (s.length <= maxlen) {
|
||||
return { value: s, truncated: false };
|
||||
}
|
||||
|
||||
s = s.substring(0, maxlen - 4) + ' ...';
|
||||
return { value: s, truncated: true };
|
||||
}
|
||||
|
||||
function MaxCharsReachedError() {
|
||||
this.message = 'Exceeded ' + j$.MAX_PRETTY_PRINT_CHARS +
|
||||
' characters while pretty-printing a value';
|
||||
}
|
||||
|
||||
MaxCharsReachedError.prototype = new Error();
|
||||
|
||||
function keys(obj, isArray) {
|
||||
var allKeys = Object.keys ? Object.keys(obj) :
|
||||
(function(o) {
|
||||
@@ -4156,9 +4340,9 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
return extraKeys;
|
||||
}
|
||||
return function(value) {
|
||||
var stringPrettyPrinter = new StringPrettyPrinter();
|
||||
stringPrettyPrinter.format(value);
|
||||
return stringPrettyPrinter.stringParts.join('');
|
||||
var prettyPrinter = new PrettyPrinter();
|
||||
prettyPrinter.format(value);
|
||||
return prettyPrinter.stringParts.join('');
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4169,7 +4353,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
return function() {
|
||||
if (!called) {
|
||||
called = true;
|
||||
fn();
|
||||
fn.apply(null, arguments);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -4188,6 +4372,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.fail = attrs.fail || function() {};
|
||||
this.globalErrors = attrs.globalErrors || { pushListener: function() {}, popListener: function() {} };
|
||||
this.completeOnFirstError = !!attrs.completeOnFirstError;
|
||||
this.deprecated = attrs.deprecated;
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
@@ -4247,9 +4432,13 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
clearTimeout(timeoutId);
|
||||
self.globalErrors.popListener(handleError);
|
||||
}),
|
||||
next = once(function () {
|
||||
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);
|
||||
@@ -4289,7 +4478,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
var maybeThenable = queueableFn.fn.call(self.userContext);
|
||||
|
||||
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
|
||||
maybeThenable.then(next, next.fail);
|
||||
maybeThenable.then(next, onPromiseRejection);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
@@ -4311,6 +4500,11 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
errored = true;
|
||||
}
|
||||
|
||||
function onPromiseRejection(e) {
|
||||
onException(e);
|
||||
next();
|
||||
}
|
||||
|
||||
function handleException(e, queueableFn) {
|
||||
onException(e);
|
||||
if (!self.catchException(e)) {
|
||||
@@ -4325,7 +4519,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
return QueueRunner;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().ReportDispatcher = function() {
|
||||
getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
function ReportDispatcher(methods) {
|
||||
|
||||
var dispatchedMethods = methods || [];
|
||||
@@ -4363,7 +4557,7 @@ getJasmineRequireObj().ReportDispatcher = function() {
|
||||
for (var i = 0; i < reporters.length; i++) {
|
||||
var reporter = reporters[i];
|
||||
if (reporter[method]) {
|
||||
reporter[method].apply(reporter, args);
|
||||
reporter[method].apply(reporter, j$.util.cloneArgs(args));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4572,7 +4766,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Install a spy on a property onto an existing object.
|
||||
* Install a spy on a property installed with `Object.defineProperty` onto an existing object.
|
||||
* @name spyOnProperty
|
||||
* @function
|
||||
* @global
|
||||
@@ -4720,6 +4914,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
|
||||
function SpyRegistry(options) {
|
||||
options = options || {};
|
||||
var global = options.global || j$.getGlobal();
|
||||
var currentSpies = options.currentSpies || function() { return []; };
|
||||
|
||||
this.allowRespy = function(allow){
|
||||
@@ -4763,7 +4958,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
spiedMethod = j$.createSpy(methodName, originalMethod),
|
||||
restoreStrategy;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(obj, methodName)) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, methodName) || (obj === global && methodName === 'onerror')) {
|
||||
restoreStrategy = function() {
|
||||
obj[methodName] = originalMethod;
|
||||
};
|
||||
@@ -4946,7 +5141,7 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
* @param {Function} fn The function to invoke with the passed parameters.
|
||||
*/
|
||||
this.callFake = function(fn) {
|
||||
if(!j$.isFunction_(fn)) {
|
||||
if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
|
||||
throw new Error('Argument passed to callFake should be a function, got ' + fn);
|
||||
}
|
||||
plan = fn;
|
||||
@@ -4990,13 +5185,15 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @property {String} description - The description text passed to the {@link describe} that made this suite.
|
||||
* @property {String} fullName - The full description including all ancestors of this suite.
|
||||
* @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
|
||||
* @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
description: this.description,
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: []
|
||||
failedExpectations: [],
|
||||
deprecationWarnings: []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5116,6 +5313,10 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.addDeprecationWarning = function(msg) {
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
|
||||
};
|
||||
|
||||
function isAfterAll(children) {
|
||||
return children && children[0].result.status;
|
||||
}
|
||||
@@ -5381,5 +5582,5 @@ getJasmineRequireObj().UserContext = function(j$) {
|
||||
};
|
||||
|
||||
getJasmineRequireObj().version = function() {
|
||||
return '2.8.0';
|
||||
return '2.99.0';
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 Pivotal Labs
|
||||
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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../spec
|
||||
@@ -4,6 +4,6 @@
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "2.8.0"
|
||||
VERSION = "2.99.2"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "2.8.0",
|
||||
"version": "2.99.2",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
|
||||
99
release_notes/2.9.0.md
Normal file
99
release_notes/2.9.0.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Jasmine 2.9 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests.
|
||||
|
||||
## Changes
|
||||
|
||||
* Fixed DelayedFunctionScheduler IE 8 compatibility issue
|
||||
* Fixed SPEC HAS NO EXPECTATIONS warning in HTML reporter
|
||||
* Correctly remove spies of window.onerror on IE
|
||||
* Truncate pretty printer output that is more than j$.MAX_PRETTY_PRINT_CHARS long
|
||||
* Reduced pretty printer limits to much smaller values
|
||||
* Update contributing for new naming of `jasmineUnderTest`
|
||||
* Allowed async functions to be passed into spy#callFake
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Added complete support for Set also for IE11.
|
||||
- Merges [#1478](https://github.com/jasmine/jasmine/issues/1478) from @Volox
|
||||
- Fixes [#1355](https://github.com/jasmine/jasmine/issues/1355)
|
||||
|
||||
|
||||
* Added complete support for Map also for IE11.
|
||||
- Merges [#1477](https://github.com/jasmine/jasmine/issues/1477) from @Volox
|
||||
- Fixes [#1472](https://github.com/jasmine/jasmine/issues/1472)
|
||||
|
||||
|
||||
* Use timeout objects when in node
|
||||
- Merges [#1470](https://github.com/jasmine/jasmine/issues/1470) from @chris--young
|
||||
- Fixes [#1469](https://github.com/jasmine/jasmine/issues/1469)
|
||||
|
||||
|
||||
* Fixed `pending()` for `async`/promise-returning specs
|
||||
- Fixes [#1449](https://github.com/jasmine/jasmine/issues/1449)
|
||||
- Fixes [#1450](https://github.com/jasmine/jasmine/issues/1450)
|
||||
|
||||
|
||||
* Added test steps for other major node versions
|
||||
- Merges [#1448](https://github.com/jasmine/jasmine/issues/1448) from @mrlannigan
|
||||
|
||||
|
||||
* Fix equality computation for ES6 Sets.
|
||||
- Merges [#1445](https://github.com/jasmine/jasmine/issues/1445) from @b-3-n
|
||||
- Fixes [#1444](https://github.com/jasmine/jasmine/issues/1444)
|
||||
|
||||
|
||||
* Add instruction to sync local master with upstream
|
||||
- Merges [#1440](https://github.com/jasmine/jasmine/issues/1440) from aaronang
|
||||
|
||||
|
||||
* Add some unit tests that exercise jasmine.anything() and Map matching.
|
||||
- Merges [#1437](https://github.com/jasmine/jasmine/issues/1437) from @voithos
|
||||
|
||||
|
||||
* Add special handling of asymmetric matcher objects as keys in Maps.
|
||||
- Merges [#1436](https://github.com/jasmine/jasmine/issues/1436) from @voithos
|
||||
- Fixes [#1432](https://github.com/jasmine/jasmine/issues/1432)
|
||||
|
||||
|
||||
* Add support for jasmine.any(Symbol).
|
||||
- Merge [#1435](https://github.com/jasmine/jasmine/issues/1435) from @voithos
|
||||
- Fixes [#1431](https://github.com/jasmine/jasmine/issues/1431)
|
||||
|
||||
|
||||
* Throw an error for invalid nesting of a suite functions
|
||||
- Merges [#1411](https://github.com/jasmine/jasmine/issues/1411) from @ksvitkovsky
|
||||
- Fixes [#1295](https://github.com/jasmine/jasmine/issues/1295)
|
||||
|
||||
|
||||
* Deep clone args before passing them to reporters
|
||||
- Merges [#1424](https://github.com/jasmine/jasmine/issues/1424) from @aj-dev
|
||||
|
||||
|
||||
* Fix "Before Committing" section of CONTRIBUTING.md.
|
||||
- Merges [#1429](https://github.com/jasmine/jasmine/issues/1429) from @voithos
|
||||
|
||||
|
||||
* Fix lint warning in CallTracker.
|
||||
- Merges [#1428](https://github.com/jasmine/jasmine/issues/1428) from @voithos
|
||||
|
||||
|
||||
* clearTimeout should now correctly clear a timeout that is also scheduled to run at the same tick.
|
||||
- Merges [#1427](https://github.com/jasmine/jasmine/issues/1427) from @leahciMic
|
||||
- Fixes [#1426](https://github.com/jasmine/jasmine/issues/1426)
|
||||
|
||||
|
||||
* Add a note about `defineProperty` for `spyOnProperty`
|
||||
- Fixes [#1415](https://github.com/jasmine/jasmine/issues/1415)
|
||||
|
||||
|
||||
* Add Promise checking to eq
|
||||
- Merges [#1386](https://github.com/jasmine/jasmine/issues/1386) from @sderickson
|
||||
- Fixes [#1314](https://github.com/jasmine/jasmine/issues/1314)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
15
release_notes/2.9.1.md
Normal file
15
release_notes/2.9.1.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Jasmine Core 2.9.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release to fix a breaking change from the 2.9.0 release
|
||||
|
||||
## Changes
|
||||
|
||||
* Clear timeouts when starting to process a milli instead of at the end
|
||||
- Fixes #1482
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
19
release_notes/2.99.md
Normal file
19
release_notes/2.99.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Jasmine-Core 2.99 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is part of the upgrade path to Jasmine 3.0. It deprecates some functionality that will change.
|
||||
|
||||
## Changes
|
||||
|
||||
* Add ability to report deprecation warnings from within the suite and display them in the HTML reporter
|
||||
* Add deprecation messages for things that will change/break in 3.0
|
||||
* * done for async functionality will now add a failure if it is invoked with an Error
|
||||
* * Env.catchExceptions and the query param are going away, in favor of a more fully functional fail fast handler
|
||||
* * jasmine.Any(Object) will no longer match null
|
||||
* * Unhandled errors during suite load will be caught and reported as failures by Jasmine
|
||||
* * Calling execute more than once on the same spec will definitely fail in 3.0
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
@@ -1,5 +1,7 @@
|
||||
describe("Clock", function() {
|
||||
|
||||
var NODE_JS = typeof process !== 'undefined' && process.versions && typeof process.versions.node === 'string';
|
||||
|
||||
it("does not replace setTimeout until it is installed", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
@@ -294,13 +296,19 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeout = new clock.FakeTimeout();
|
||||
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn, 0, 'a', 'b');
|
||||
|
||||
expect(fakeSetTimeout).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
|
||||
|
||||
if (!NODE_JS) {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
|
||||
} else {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], false, timeout);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns an id for the delayed function", function() {
|
||||
@@ -312,12 +320,16 @@ describe("Clock", function() {
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeoutId;
|
||||
timeout;
|
||||
|
||||
clock.install();
|
||||
timeoutId = clock.setTimeout(delayedFn, 0);
|
||||
timeout = clock.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(timeoutId).toEqual(123);
|
||||
if (!NODE_JS) {
|
||||
expect(timeout).toEqual(123);
|
||||
} else {
|
||||
expect(timeout.constructor.name).toEqual('FakeTimeout');
|
||||
}
|
||||
});
|
||||
|
||||
it("clears the scheduled function with the scheduler", function() {
|
||||
@@ -342,13 +354,19 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setInterval: fakeSetInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeout = new clock.FakeTimeout;
|
||||
|
||||
clock.install();
|
||||
clock.setInterval(delayedFn, 0, 'a', 'b');
|
||||
|
||||
expect(fakeSetInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
|
||||
|
||||
if (!NODE_JS) {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
|
||||
} else {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true, timeout);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns an id for the delayed function", function() {
|
||||
@@ -360,12 +378,16 @@ describe("Clock", function() {
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
intervalId;
|
||||
interval;
|
||||
|
||||
clock.install();
|
||||
intervalId = clock.setInterval(delayedFn, 0);
|
||||
interval = clock.setInterval(delayedFn, 0);
|
||||
|
||||
expect(intervalId).toEqual(123);
|
||||
if (!NODE_JS) {
|
||||
expect(interval).toEqual(123);
|
||||
} else {
|
||||
expect(interval.constructor.name).toEqual('FakeTimeout');
|
||||
}
|
||||
});
|
||||
|
||||
it("clears the scheduled function with the scheduler", function() {
|
||||
@@ -401,7 +423,8 @@ describe("Clock", function() {
|
||||
setInterval: fakeSetInterval
|
||||
},
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeout = new clock.FakeTimeout();
|
||||
|
||||
fakeSetTimeout.apply = null;
|
||||
fakeSetInterval.apply = null;
|
||||
@@ -409,13 +432,25 @@ describe("Clock", function() {
|
||||
clock.install();
|
||||
|
||||
clock.setTimeout(fn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(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);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true);
|
||||
|
||||
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();
|
||||
@@ -679,4 +714,41 @@ describe("Clock (acceptance)", function() {
|
||||
|
||||
expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]);
|
||||
})
|
||||
|
||||
it('correctly clears a scheduled timeout while the Clock is advancing', function () {
|
||||
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
global = {Date: Date, setTimeout: undefined},
|
||||
mockDate = new jasmineUnderTest.MockDate(global),
|
||||
clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
var timerId2;
|
||||
|
||||
global.setTimeout(function () {
|
||||
global.clearTimeout(timerId2);
|
||||
}, 100);
|
||||
|
||||
timerId2 = global.setTimeout(fail, 100);
|
||||
|
||||
clock.tick(100);
|
||||
});
|
||||
|
||||
it('correctly clears a scheduled interval while the Clock is advancing', function () {
|
||||
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
global = {Date: Date, setTimeout: undefined},
|
||||
mockDate = new jasmineUnderTest.MockDate(global),
|
||||
clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
var timerId2;
|
||||
var timerId1 = global.setInterval(function () {
|
||||
global.clearInterval(timerId2);
|
||||
}, 100);
|
||||
|
||||
timerId2 = global.setInterval(fail, 100);
|
||||
|
||||
clock.tick(400);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -216,21 +216,23 @@ describe("DelayedFunctionScheduler", function() {
|
||||
|
||||
it("removes functions during a tick that runs the function", function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
spy = jasmine.createSpy('fn'),
|
||||
spyAndRemove = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
|
||||
scheduler.scheduleFunction(function () {
|
||||
spyAndRemove.and.callFake(function() {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, 2 * fnDelay);
|
||||
});
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
scheduler.scheduleFunction(spyAndRemove, fnDelay);
|
||||
|
||||
scheduler.tick(3 * fnDelay);
|
||||
timeoutKey = scheduler.scheduleFunction(spy, fnDelay, [], true);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(fn.calls.count()).toBe(2);
|
||||
scheduler.tick(2 * fnDelay);
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
expect(spyAndRemove).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("removes functions during the first tick that runs the function", function() {
|
||||
@@ -252,6 +254,22 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it("does not remove a function that hasn't been added yet", function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
scheduler.removeFunctionWithId('foo');
|
||||
scheduler.scheduleFunction(fn, fnDelay, [], false, 'foo');
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(fnDelay + 1);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("updates the mockDate per scheduled time", function () {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
tickDate = jasmine.createSpy('tickDate');
|
||||
|
||||
@@ -17,7 +17,10 @@ describe("jasmineUnderTest.pp", function () {
|
||||
describe('stringify sets', function() {
|
||||
it("should stringify sets properly", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
expect(jasmineUnderTest.pp(new Set([1, 2]))).toEqual("Set( 1, 2 )");
|
||||
var set = new Set();
|
||||
set.add(1);
|
||||
set.add(2);
|
||||
expect(jasmineUnderTest.pp(set)).toEqual("Set( 1, 2 )");
|
||||
});
|
||||
|
||||
it("should truncate sets with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
@@ -26,7 +29,11 @@ describe("jasmineUnderTest.pp", function () {
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(jasmineUnderTest.pp(new Set(["a", "b", "c"]))).toEqual("Set( 'a', 'b', ... )");
|
||||
var set = new Set();
|
||||
set.add('a');
|
||||
set.add('b');
|
||||
set.add('c');
|
||||
expect(jasmineUnderTest.pp(set)).toEqual("Set( 'a', 'b', ... )");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
|
||||
}
|
||||
@@ -36,7 +43,9 @@ describe("jasmineUnderTest.pp", function () {
|
||||
describe('stringify maps', function() {
|
||||
it("should stringify maps properly", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
expect(jasmineUnderTest.pp(new Map([[1, 2]]))).toEqual("Map( [ 1, 2 ] )");
|
||||
var map = new Map();
|
||||
map.set(1,2);
|
||||
expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 1, 2 ] )");
|
||||
});
|
||||
|
||||
it("should truncate maps with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
@@ -45,7 +54,11 @@ describe("jasmineUnderTest.pp", function () {
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(jasmineUnderTest.pp(new Map([["a", 1], ["b", 2], ["c", 3]]))).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )");
|
||||
var map = new Map();
|
||||
map.set("a",1);
|
||||
map.set("b",2);
|
||||
map.set("c",3);
|
||||
expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
|
||||
}
|
||||
@@ -120,15 +133,50 @@ describe("jasmineUnderTest.pp", function () {
|
||||
});
|
||||
|
||||
it("should truncate objects with too many keys", function () {
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var long = {a: 1, b: 2, c: 3};
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var long = {a: 1, b: 2, c: 3};
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(jasmineUnderTest.pp(long)).toEqual("Object({ a: 1, b: 2, ... })");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(jasmineUnderTest.pp(long)).toEqual("Object({ a: 1, b: 2, ... })");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
});
|
||||
|
||||
function withMaxChars(maxChars, fn) {
|
||||
var originalMaxChars = jasmineUnderTest.MAX_PRETTY_PRINT_CHARS;
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = maxChars;
|
||||
fn();
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = originalMaxChars;
|
||||
}
|
||||
}
|
||||
|
||||
it("should truncate outputs that are too long", function() {
|
||||
var big = [
|
||||
{ a: 1, b: "a long string" },
|
||||
{}
|
||||
];
|
||||
|
||||
withMaxChars(34, function() {
|
||||
expect(jasmineUnderTest.pp(big)).toEqual("[ Object({ a: 1, b: 'a long st ...");
|
||||
});
|
||||
});
|
||||
|
||||
it("should not serialize more objects after hitting MAX_PRETTY_PRINT_CHARS", function() {
|
||||
var a = { jasmineToString: function() { return 'object a'; } },
|
||||
b = { jasmineToString: function() { return 'object b'; } },
|
||||
c = { jasmineToString: jasmine.createSpy('c jasmineToString').and.returnValue('') },
|
||||
d = { jasmineToString: jasmine.createSpy('d jasmineToString').and.returnValue('') };
|
||||
|
||||
withMaxChars(30, function() {
|
||||
jasmineUnderTest.pp([{a: a, b: b, c: c}, d]);
|
||||
expect(c.jasmineToString).not.toHaveBeenCalled();
|
||||
expect(d.jasmineToString).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("should print 'null' as the constructor of an object with its own constructor property", function() {
|
||||
@@ -216,9 +264,9 @@ describe("jasmineUnderTest.pp", function () {
|
||||
|
||||
it("should stringify spy objects properly", function() {
|
||||
var TestObject = {
|
||||
someFunction: function() {}
|
||||
},
|
||||
env = new jasmineUnderTest.Env();
|
||||
someFunction: function() {}
|
||||
},
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() {return [];}});
|
||||
|
||||
|
||||
@@ -375,27 +375,30 @@ describe("QueueRunner", function() {
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("fails the function when the promise is rejected", function() {
|
||||
it("handles a rejected promise like an unhandled exception", function() {
|
||||
var promise = new StubPromise(),
|
||||
queueableFn1 = { fn: function() {
|
||||
setTimeout(function() { promise.rejectHandler('foo'); }, 100);
|
||||
setTimeout(function() {
|
||||
promise.rejectHandler('foo')
|
||||
}, 100);
|
||||
return promise;
|
||||
} },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
fail: failFn
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(onExceptionCallback).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(failFn).toHaveBeenCalledWith('foo');
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith('foo');
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -222,6 +222,7 @@ describe("Spec", function() {
|
||||
fullName: 'a suite with a spec',
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
});
|
||||
});
|
||||
|
||||
@@ -287,6 +287,24 @@ describe("SpyRegistry", function() {
|
||||
|
||||
expect(jasmineUnderTest.isSpy(subject.spiedFunc)).toBe(false);
|
||||
});
|
||||
|
||||
it("restores window.onerror by overwriting, not deleting", function() {
|
||||
function FakeWindow() {
|
||||
}
|
||||
FakeWindow.prototype.onerror = function() {};
|
||||
|
||||
var spies = [],
|
||||
global = new FakeWindow(),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
global: global
|
||||
});
|
||||
|
||||
spyRegistry.spyOn(global, 'onerror');
|
||||
spyRegistry.clearSpies();
|
||||
expect(global.onerror).toBe(FakeWindow.prototype.onerror);
|
||||
expect(global.hasOwnProperty('onerror')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('spying on properties', function() {
|
||||
|
||||
@@ -92,12 +92,35 @@ describe("SpyStrategy", function() {
|
||||
expect(returnValue).toEqual(67);
|
||||
});
|
||||
|
||||
it("allows a fake async function to be called instead", function(done) {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
fakeFn = jasmine.createSpy("fake").and.callFake(eval("async () => { return 67; }")),
|
||||
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
|
||||
returnValue;
|
||||
|
||||
spyStrategy.callFake(fakeFn);
|
||||
spyStrategy.exec().then(function (returnValue) {
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
expect(fakeFn).toHaveBeenCalled();
|
||||
expect(returnValue).toEqual(67);
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
done.fail(err);
|
||||
})
|
||||
});
|
||||
|
||||
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}),
|
||||
invalidFakes = [5, 'foo', {}, true, false, null, void 0, new Date(), /.*/];
|
||||
|
||||
spyOn(jasmineUnderTest, 'isFunction_').and.returnValue(false);
|
||||
spyOn(jasmineUnderTest, 'isAsyncFunction_').and.returnValue(false);
|
||||
|
||||
expect(function () {
|
||||
spyStrategy.callFake(function() {});
|
||||
}).toThrowError(/^Argument passed to callFake should be a function, got/);
|
||||
|
||||
expect(function () {
|
||||
spyStrategy.callFake(function() {});
|
||||
|
||||
@@ -29,6 +29,38 @@ describe("Any", function() {
|
||||
expect(any.asymmetricMatch(true)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Map", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var any = new jasmineUnderTest.Any(Map);
|
||||
|
||||
expect(any.asymmetricMatch(new Map())).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Set", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var any = new jasmineUnderTest.Any(Set);
|
||||
|
||||
expect(any.asymmetricMatch(new Set())).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a TypedArray", function() {
|
||||
jasmine.getEnv().requireFunctioningTypedArrays();
|
||||
|
||||
var any = new jasmineUnderTest.Any(Uint32Array);
|
||||
|
||||
expect(any.asymmetricMatch(new Uint32Array([]))).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Symbol", function() {
|
||||
jasmine.getEnv().requireFunctioningSymbols();
|
||||
|
||||
var any = new jasmineUnderTest.Any(Symbol);
|
||||
|
||||
expect(any.asymmetricMatch(Symbol())).toBe(true);
|
||||
});
|
||||
|
||||
it("matches another constructed object", function() {
|
||||
var Thing = function() {},
|
||||
any = new jasmineUnderTest.Any(Thing);
|
||||
|
||||
@@ -23,6 +23,38 @@ describe("Anything", function() {
|
||||
expect(anything.asymmetricMatch([1,2,3])).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Map", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var anything = new jasmineUnderTest.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch(new Map())).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Set", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var anything = new jasmineUnderTest.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch(new Set())).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a TypedArray", function() {
|
||||
jasmine.getEnv().requireFunctioningTypedArrays();
|
||||
|
||||
var anything = new jasmineUnderTest.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Symbol", function() {
|
||||
jasmine.getEnv().requireFunctioningSymbols();
|
||||
|
||||
var anything = new jasmineUnderTest.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch(Symbol())).toBe(true);
|
||||
});
|
||||
|
||||
it("doesn't match undefined", function() {
|
||||
var anything = new jasmineUnderTest.Anything();
|
||||
|
||||
|
||||
@@ -1485,6 +1485,7 @@ describe("Env integration", function() {
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var specStatus = reporter.specDone.calls.argsFor(0)[0];
|
||||
|
||||
expect(specStatus.status).toBe('pending');
|
||||
expect(specStatus.pendingReason).toBe('with a message');
|
||||
|
||||
done();
|
||||
@@ -1499,6 +1500,45 @@ describe("Env integration", function() {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should report pending spec messages from promise-returning functions', function(done) {
|
||||
function StubPromise(fn) {
|
||||
try {
|
||||
fn();
|
||||
} catch (e) {
|
||||
this.exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
StubPromise.prototype.then = function(resolve, reject) {
|
||||
reject(this.exception);
|
||||
};
|
||||
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'specDone',
|
||||
'jasmineDone'
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var specStatus = reporter.specDone.calls.argsFor(0)[0];
|
||||
|
||||
expect(specStatus.status).toBe('pending');
|
||||
expect(specStatus.pendingReason).toBe('with a message');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.it('will be pending', function() {
|
||||
return new StubPromise(function() {
|
||||
env.pending('with a message');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should report using fallback reporter', function(done) {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
@@ -1903,4 +1943,108 @@ describe("Env integration", function() {
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should throw on suites/specs/befores/afters nested in methods other than \'describe\'', function(done) {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var msg = /\'.*\' should only be used in \'describe\' function/;
|
||||
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('suite describe', [msg]);
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('suite xdescribe', [msg]);
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('suite fdescribe', [msg]);
|
||||
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('spec it', [msg]);
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('spec xit', [msg]);
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('spec fit', [msg]);
|
||||
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('beforeAll spec', [msg]);
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('beforeEach spec', [msg]);
|
||||
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForRunnable('afterAll', [msg]);
|
||||
expect(reporter.specDone).toHaveFailedExpecationsForRunnable('afterEach spec', [msg]);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('suite', function() {
|
||||
env.it('describe', function() { env.describe('inner suite', function() {}); });
|
||||
env.it('xdescribe', function() { env.xdescribe('inner suite', function() {}); });
|
||||
env.it('fdescribe', function() { env.fdescribe('inner suite', function() {}); });
|
||||
});
|
||||
|
||||
env.describe('spec', function() {
|
||||
env.it('it', function() { env.it('inner spec', function() {}); });
|
||||
env.it('xit', function() { env.xit('inner spec', function() {}); });
|
||||
env.it('fit', function() { env.fit('inner spec', function() {}); });
|
||||
});
|
||||
|
||||
env.describe('beforeAll', function() {
|
||||
env.beforeAll(function() { env.beforeAll(function() {}); });
|
||||
env.it('spec', function() {});
|
||||
});
|
||||
|
||||
env.describe('beforeEach', function() {
|
||||
env.beforeEach(function() { env.beforeEach(function() {}); });
|
||||
env.it('spec', function() {});
|
||||
});
|
||||
|
||||
env.describe('afterAll', function() {
|
||||
env.afterAll(function() { env.afterAll(function() {}); });
|
||||
env.it('spec', function() {});
|
||||
});
|
||||
|
||||
env.describe('afterEach', function() {
|
||||
env.afterEach(function() { env.afterEach(function() {}); });
|
||||
env.it('spec', function() {});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should report deprecation warnings on the correct specs and suites', function(done) {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function(result) {
|
||||
expect(result.deprecationWarnings).toEqual([
|
||||
jasmine.objectContaining({ message: 'top level deprecation' })
|
||||
]);
|
||||
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
fullName: 'suite',
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({ message: 'suite level deprecation' })
|
||||
]
|
||||
}));
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
fullName: 'suite spec',
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({ message: 'spec level deprecation' })
|
||||
]
|
||||
}));
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.deprecated('top level deprecation');
|
||||
|
||||
env.describe('suite', function() {
|
||||
env.beforeAll(function() {
|
||||
env.deprecated('suite level deprecation');
|
||||
});
|
||||
|
||||
env.it('spec', function() {
|
||||
env.deprecated('spec level deprecation');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("fails for Arrays whose contents are equivalent, but have differing properties", function() {
|
||||
var one = [1,2,3],
|
||||
two = [1,2,3];
|
||||
two = [1,2,3];
|
||||
|
||||
one.foo = 'bar';
|
||||
two.foo = 'baz';
|
||||
@@ -81,7 +81,7 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes for Arrays with equivalent contents and properties", function() {
|
||||
var one = [1,2,3],
|
||||
two = [1,2,3];
|
||||
two = [1,2,3];
|
||||
|
||||
one.foo = 'bar';
|
||||
two.foo = 'bar';
|
||||
@@ -122,7 +122,7 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes for Objects that are equivalent (with cycles)", function() {
|
||||
var actual = { a: "foo" },
|
||||
expected = { a: "foo" };
|
||||
expected = { a: "foo" };
|
||||
|
||||
actual.b = actual;
|
||||
expected.b = actual;
|
||||
@@ -166,6 +166,16 @@ describe("matchersUtil", function() {
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes for equivalent Promises (GitHub issue #1314)", function() {
|
||||
if (typeof Promise === 'undefined') { return; }
|
||||
|
||||
var p1 = new Promise(function () {}),
|
||||
p2 = new Promise(function () {});
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(p1, p1)).toBe(true);
|
||||
expect(jasmineUnderTest.matchersUtil.equals(p1, p2)).toBe(false);
|
||||
});
|
||||
|
||||
describe("when running in a browser", function() {
|
||||
function isNotRunningInBrowser() {
|
||||
@@ -332,7 +342,7 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes for an asymmetric equality tester that returns true when a custom equality tester return false", function() {
|
||||
var asymmetricTester = { asymmetricMatch: function(other) { return true; } },
|
||||
symmetricTester = function(a, b) { return false; };
|
||||
symmetricTester = function(a, b) { return false; };
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true);
|
||||
expect(jasmineUnderTest.matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true);
|
||||
@@ -350,7 +360,7 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes when an Any is compared to an Any that checks for the same type", function() {
|
||||
var any1 = new jasmineUnderTest.Any(Function),
|
||||
any2 = new jasmineUnderTest.Any(Function);
|
||||
any2 = new jasmineUnderTest.Any(Function);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(any1, any2)).toBe(true);
|
||||
});
|
||||
@@ -359,7 +369,7 @@ describe("matchersUtil", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var objA = Object.create(null),
|
||||
objB = Object.create(null);
|
||||
objB = Object.create(null);
|
||||
|
||||
objA.name = 'test';
|
||||
objB.name = 'test';
|
||||
@@ -371,7 +381,7 @@ describe("matchersUtil", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var objA = Object.create(null),
|
||||
objB = Object.create(null);
|
||||
objB = Object.create(null);
|
||||
|
||||
objA.name = 'test';
|
||||
objB.test = 'name';
|
||||
@@ -386,31 +396,94 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes when comparing identical sets", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var setA = new Set([6, 5]);
|
||||
|
||||
var setA = new Set();
|
||||
setA.add(6);
|
||||
setA.add(5);
|
||||
var setB = new Set();
|
||||
setB.add(6);
|
||||
setB.add(5);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when comparing identical sets with different insertion order", function() {
|
||||
it("passes when comparing identical sets with different insertion order and simple elements", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var setA = new Set([3, 6]);
|
||||
var setB = new Set([6, 3]);
|
||||
|
||||
var setA = new Set();
|
||||
setA.add(3);
|
||||
setA.add(6);
|
||||
var setB = new Set();
|
||||
setB.add(6);
|
||||
setB.add(3);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when comparing identical sets with different insertion order and complex elements 1", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var setA1 = new Set();
|
||||
setA1.add(['a',3]);
|
||||
setA1.add([6,1]);
|
||||
var setA2 = new Set();
|
||||
setA1.add(['y',3]);
|
||||
setA1.add([6,1]);
|
||||
var setA = new Set();
|
||||
setA.add(setA1);
|
||||
setA.add(setA2);
|
||||
|
||||
|
||||
var setB1 = new Set();
|
||||
setB1.add([6,1]);
|
||||
setB1.add(['a',3]);
|
||||
var setB2 = new Set();
|
||||
setB1.add([6,1]);
|
||||
setB1.add(['y',3]);
|
||||
var setB = new Set();
|
||||
setB.add(setB1);
|
||||
setB.add(setB2);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when comparing identical sets with different insertion order and complex elements 2", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var setA = new Set();
|
||||
setA.add([[1,2], [3,4]]);
|
||||
setA.add([[5,6], [7,8]]);
|
||||
var setB = new Set();
|
||||
setB.add([[5,6], [7,8]]);
|
||||
setB.add([[1,2], [3,4]]);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for sets with different elements", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var setA = new Set([6, 3, 5]);
|
||||
var setB = new Set([6, 4, 5]);
|
||||
var setA = new Set();
|
||||
setA.add(6);
|
||||
setA.add(3);
|
||||
setA.add(5);
|
||||
var setB = new Set();
|
||||
setB.add(6);
|
||||
setB.add(4);
|
||||
setB.add(5);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false);
|
||||
});
|
||||
|
||||
it("fails for sets of different size", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var setA = new Set([6, 3]);
|
||||
var setB = new Set([6, 4, 5]);
|
||||
var setA = new Set();
|
||||
setA.add(6);
|
||||
setA.add(3);
|
||||
var setB = new Set();
|
||||
setB.add(6);
|
||||
setB.add(4);
|
||||
setB.add(5);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false);
|
||||
});
|
||||
|
||||
@@ -421,7 +494,8 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes when comparing identical maps", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var mapA = new Map([[6, 5]]);
|
||||
var mapA = new Map();
|
||||
mapA.set(6, 5);
|
||||
var mapB = new Map();
|
||||
mapB.set(6, 5);
|
||||
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true);
|
||||
@@ -429,22 +503,34 @@ describe("matchersUtil", function() {
|
||||
|
||||
it("passes when comparing identical maps with different insertion order", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var mapA = new Map([['a', 3], [6, 1]]);
|
||||
var mapB = new Map([[6, 1], ['a', 3]]);
|
||||
var mapA = new Map();
|
||||
mapA.set("a", 3);
|
||||
mapA.set(6, 1);
|
||||
var mapB = new Map();
|
||||
mapB.set(6, 1);
|
||||
mapB.set("a", 3);
|
||||
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for maps with different elements", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var mapA = new Map([[6, 3], [5, 1]]);
|
||||
var mapB = new Map([[6, 4], [5, 1]]);
|
||||
var mapA = new Map();
|
||||
mapA.set(6, 3);
|
||||
mapA.set(5, 1);
|
||||
var mapB = new Map();
|
||||
mapB.set(6, 4);
|
||||
mapB.set(5, 1);
|
||||
|
||||
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false);
|
||||
});
|
||||
|
||||
it("fails for maps of different size", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var mapA = new Map([[6, 3]]);
|
||||
var mapB = new Map([[6, 4], [5, 1]]);
|
||||
var mapA = new Map();
|
||||
mapA.set(6, 3);
|
||||
var mapB = new Map();
|
||||
mapB.set(6, 4);
|
||||
mapB.set(5, 1);
|
||||
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false);
|
||||
});
|
||||
|
||||
@@ -461,28 +547,28 @@ describe("matchersUtil", function() {
|
||||
Object.defineProperty(Array.prototype, 'findIndex', {
|
||||
enumerable: true,
|
||||
value: function (predicate) {
|
||||
if (this === null) {
|
||||
throw new TypeError('Array.prototype.findIndex called on null or undefined');
|
||||
}
|
||||
if (this === null) {
|
||||
throw new TypeError('Array.prototype.findIndex called on null or undefined');
|
||||
}
|
||||
|
||||
if (typeof predicate !== 'function') {
|
||||
throw new TypeError('predicate must be a function');
|
||||
}
|
||||
if (typeof predicate !== 'function') {
|
||||
throw new TypeError('predicate must be a function');
|
||||
}
|
||||
|
||||
var list = Object(this);
|
||||
var length = list.length >>> 0;
|
||||
var thisArg = arguments[1];
|
||||
var value;
|
||||
var list = Object(this);
|
||||
var length = list.length >>> 0;
|
||||
var thisArg = arguments[1];
|
||||
var value;
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
value = list[i];
|
||||
if (predicate.call(thisArg, value, i, list)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < length; i++) {
|
||||
value = list[i];
|
||||
if (predicate.call(thisArg, value, i, list)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -374,9 +374,11 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Sets", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var actual = new Set([1]),
|
||||
expected = new Set([2]),
|
||||
message = 'Expected Set( 1 ) to equal Set( 2 ).';
|
||||
var actual = new Set();
|
||||
actual.add(1);
|
||||
var expected = new Set();
|
||||
expected.add(2);
|
||||
var message = 'Expected Set( 1 ) to equal Set( 2 ).';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -384,9 +386,11 @@ describe("toEqual", function() {
|
||||
it("reports deep mismatches within Sets", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var actual = new Set([{x: 1}]),
|
||||
expected = new Set([{x: 2}]),
|
||||
message = 'Expected Set( Object({ x: 1 }) ) to equal Set( Object({ x: 2 }) ).';
|
||||
var actual = new Set();
|
||||
actual.add({x: 1});
|
||||
var expected = new Set();
|
||||
expected.add({x: 2});
|
||||
var message = 'Expected Set( Object({ x: 1 }) ) to equal Set( Object({ x: 2 }) ).';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -394,9 +398,14 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Sets nested in objects", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var actual = {sets: [new Set([1])]},
|
||||
expected = {sets: [new Set([2])]},
|
||||
message = "Expected $.sets[0] = Set( 1 ) to equal Set( 2 ).";
|
||||
var actualSet = new Set();
|
||||
actualSet.add(1);
|
||||
var expectedSet = new Set();
|
||||
expectedSet.add(2);
|
||||
|
||||
var actual = { sets: [actualSet] };
|
||||
var expected = { sets: [expectedSet] };
|
||||
var message = "Expected $.sets[0] = Set( 1 ) to equal Set( 2 ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -404,9 +413,12 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Sets of different lengths", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
var actual = new Set([1, 2]),
|
||||
expected = new Set([2]),
|
||||
message = 'Expected Set( 1, 2 ) to equal Set( 2 ).';
|
||||
var actual = new Set();
|
||||
actual.add(1);
|
||||
actual.add(2);
|
||||
var expected = new Set();
|
||||
expected.add(2);
|
||||
var message = 'Expected Set( 1, 2 ) to equal Set( 2 ).';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -415,9 +427,13 @@ describe("toEqual", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
// Use 'duplicate' object in actual so sizes match
|
||||
var actual = new Set([{x: 1}, {x: 1}]),
|
||||
expected = new Set([{x: 1}, {x: 2}]),
|
||||
message = 'Expected Set( Object({ x: 1 }), Object({ x: 1 }) ) to equal Set( Object({ x: 1 }), Object({ x: 2 }) ).';
|
||||
var actual = new Set();
|
||||
actual.add({x: 1});
|
||||
actual.add({x: 1});
|
||||
var expected = new Set();
|
||||
expected.add({x: 1});
|
||||
expected.add({x: 2});
|
||||
var message = 'Expected Set( Object({ x: 1 }), Object({ x: 1 }) ) to equal Set( Object({ x: 1 }), Object({ x: 2 }) ).';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -426,9 +442,13 @@ describe("toEqual", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
|
||||
// Use 'duplicate' object in expected so sizes match
|
||||
var actual = new Set([{x: 1}, {x: 2}]),
|
||||
expected = new Set([{x: 1}, {x: 1}]),
|
||||
message = 'Expected Set( Object({ x: 1 }), Object({ x: 2 }) ) to equal Set( Object({ x: 1 }), Object({ x: 1 }) ).';
|
||||
var actual = new Set();
|
||||
actual.add({x: 1});
|
||||
actual.add({x: 2});
|
||||
var expected = new Set();
|
||||
expected.add({x: 1});
|
||||
expected.add({x: 1});
|
||||
var message = 'Expected Set( Object({ x: 1 }), Object({ x: 2 }) ) to equal Set( Object({ x: 1 }), Object({ x: 1 }) ).';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -436,11 +456,13 @@ describe("toEqual", function() {
|
||||
// == Maps ==
|
||||
|
||||
it("does not report mismatches between deep equal Maps", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
// values are the same but with different object identity
|
||||
var actual = new Map([['a', {x: 1}]]),
|
||||
expected = new Map([['a', {x: 1}]]);
|
||||
var actual = new Map();
|
||||
actual.set('a',{x:1});
|
||||
var expected = new Map();
|
||||
expected.set('a',{x:1});
|
||||
|
||||
expect(compareEquals(actual, expected).pass).toBe(true);
|
||||
});
|
||||
@@ -448,9 +470,11 @@ describe("toEqual", function() {
|
||||
it("reports deep mismatches within Maps", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var actual = new Map([['a', {x: 1}]]),
|
||||
expected = new Map([['a', {x: 2}]]),
|
||||
message = "Expected Map( [ 'a', Object({ x: 1 }) ] ) to equal Map( [ 'a', Object({ x: 2 }) ] ).";
|
||||
var actual = new Map();
|
||||
actual.set('a',{x:1});
|
||||
var expected = new Map();
|
||||
expected.set('a',{x:2});
|
||||
var message = "Expected Map( [ 'a', Object({ x: 1 }) ] ) to equal Map( [ 'a', Object({ x: 2 }) ] ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -458,9 +482,12 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Maps nested in objects", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var actual = {Maps: [new Map([['a', 1]])]},
|
||||
expected = {Maps: [new Map([['a', 2]])]},
|
||||
message = "Expected $.Maps[0] = Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ] ).";
|
||||
var actual = {Maps:[new Map()]};
|
||||
actual.Maps[0].set('a',1);
|
||||
var expected = {Maps:[new Map()]};
|
||||
expected.Maps[0].set('a',2);
|
||||
|
||||
var message = "Expected $.Maps[0] = Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ] ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -468,9 +495,12 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Maps of different lengths", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var actual = new Map([['a', 1]]),
|
||||
expected = new Map([['a', 2], ['b', 1]]),
|
||||
message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ], [ 'b', 1 ] ).";
|
||||
var actual = new Map();
|
||||
actual.set('a',1);
|
||||
var expected = new Map();
|
||||
expected.set('a',2);
|
||||
expected.set('b',1);
|
||||
var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ], [ 'b', 1 ] ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
@@ -478,18 +508,22 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Maps with equal values but differing keys", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var actual = new Map([['a', 1]]),
|
||||
expected = new Map([['b', 1]]),
|
||||
message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'b', 1 ] ).";
|
||||
var actual = new Map();
|
||||
actual.set('a',1);
|
||||
var expected = new Map();
|
||||
expected.set('b',1);
|
||||
var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'b', 1 ] ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it("does not report mismatches between Maps with keys with same object identity", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var key = {x: 1},
|
||||
actual = new Map([[key, 2]]),
|
||||
expected = new Map([[key, 2]]);
|
||||
var key = {x: 1};
|
||||
var actual = new Map();
|
||||
actual.set(key,2);
|
||||
var expected = new Map();
|
||||
expected.set(key,2);
|
||||
|
||||
expect(compareEquals(actual, expected).pass).toBe(true);
|
||||
});
|
||||
@@ -497,13 +531,64 @@ describe("toEqual", function() {
|
||||
it("reports mismatches between Maps with identical keys with different object identity", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var actual = new Map([[{x: 1}, 2]]),
|
||||
expected = new Map([[{x: 1}, 2]]),
|
||||
message = "Expected Map( [ Object({ x: 1 }), 2 ] ) to equal Map( [ Object({ x: 1 }), 2 ] ).";
|
||||
var actual = new Map();
|
||||
actual.set({x:1},2);
|
||||
var expected = new Map();
|
||||
expected.set({x:1},2);
|
||||
var message = "Expected Map( [ Object({ x: 1 }), 2 ] ) to equal Map( [ Object({ x: 1 }), 2 ] ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it("does not report mismatches when comparing Map key to jasmine.anything()", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
|
||||
var actual = new Map();
|
||||
actual.set('a',1);
|
||||
var expected = new Map();
|
||||
expected.set(jasmineUnderTest.anything(),1);
|
||||
|
||||
expect(compareEquals(actual, expected).pass).toBe(true);
|
||||
});
|
||||
|
||||
it("does not report mismatches when comparing Maps with the same symbol keys", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
jasmine.getEnv().requireFunctioningSymbols();
|
||||
|
||||
var key = Symbol();
|
||||
var actual = new Map();
|
||||
actual.set(key,1);
|
||||
var expected = new Map();
|
||||
expected.set(key,1);
|
||||
|
||||
expect(compareEquals(actual, expected).pass).toBe(true);
|
||||
});
|
||||
|
||||
it("reports mismatches between Maps with different symbol keys", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
jasmine.getEnv().requireFunctioningSymbols();
|
||||
|
||||
var actual = new Map();
|
||||
actual.set(Symbol(),1);
|
||||
var expected = new Map();
|
||||
expected.set(Symbol(),1);
|
||||
var message = "Expected Map( [ Symbol(), 1 ] ) to equal Map( [ Symbol(), 1 ] ).";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toBe(message);
|
||||
});
|
||||
|
||||
it("does not report mismatches when comparing Map symbol key to jasmine.anything()", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
jasmine.getEnv().requireFunctioningSymbols();
|
||||
|
||||
var actual = new Map();
|
||||
actual.set(Symbol(),1);
|
||||
var expected = new Map();
|
||||
expected.set(jasmineUnderTest.anything(),1);
|
||||
|
||||
expect(compareEquals(actual, expected).pass).toBe(true);
|
||||
});
|
||||
|
||||
function isNotRunningInBrowser() {
|
||||
return typeof document === 'undefined'
|
||||
}
|
||||
|
||||
@@ -3,10 +3,25 @@
|
||||
if (typeof Map === 'undefined') { return false; }
|
||||
|
||||
try {
|
||||
var s = new Map([['a', 4]]);
|
||||
if (s.size !== 1) { return false; }
|
||||
if (s.keys().next().value !== 'a') { return false; }
|
||||
if (s.values().next().value !== 4) { return false; }
|
||||
var s = new Map();
|
||||
s.set('a',1);
|
||||
s.set('b',2);
|
||||
|
||||
if (s.size !== 2) { return false; }
|
||||
if (s.has('a') !== true) { return false; }
|
||||
|
||||
var iterations = 0;
|
||||
var ifForEachWorking = true;
|
||||
s.forEach(function(value, key, map) {
|
||||
ifForEachWorking = ifForEachWorking && map === s;
|
||||
if (key==='a') {
|
||||
ifForEachWorking = ifForEachWorking && value===1;
|
||||
}
|
||||
iterations++;
|
||||
});
|
||||
if (iterations !== 2) { return false; }
|
||||
if (ifForEachWorking !== true) { return false; }
|
||||
|
||||
return true;
|
||||
} catch(e) {
|
||||
return false;
|
||||
|
||||
@@ -3,9 +3,29 @@
|
||||
if (typeof Set === 'undefined') { return false; }
|
||||
|
||||
try {
|
||||
var s = new Set([4]);
|
||||
if (s.size !== 1) { return false; }
|
||||
if (s.values().next().value !== 4) { return false; }
|
||||
var s = new Set();
|
||||
s.add(1);
|
||||
s.add(2);
|
||||
|
||||
if (s.size !== 2) { return false; }
|
||||
if (s.has(1) !== true) { return false; }
|
||||
|
||||
var iterations = 0;
|
||||
var isForEachWorking = true;
|
||||
s.forEach(function(value, key, set) {
|
||||
isForEachWorking = isForEachWorking && set === s;
|
||||
|
||||
if (iterations===0) {
|
||||
isForEachWorking = isForEachWorking && (key===value) && value===1;
|
||||
} else if (iterations===1) {
|
||||
isForEachWorking = isForEachWorking && (key===value) && value===2;
|
||||
}
|
||||
|
||||
iterations++;
|
||||
});
|
||||
if (iterations !== 2) { return false; }
|
||||
if (isForEachWorking !== true) { return false; }
|
||||
|
||||
return true;
|
||||
} catch(e) {
|
||||
return false;
|
||||
|
||||
28
spec/helpers/checkForSymbol.js
Normal file
28
spec/helpers/checkForSymbol.js
Normal file
@@ -0,0 +1,28 @@
|
||||
(function(env) {
|
||||
function hasFunctioningSymbols() {
|
||||
if (typeof Symbol === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
var s1 = Symbol();
|
||||
var s2 = Symbol();
|
||||
if (typeof s1 !== 'symbol') {
|
||||
return false;
|
||||
}
|
||||
if (s1 === s2) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
env.requireFunctioningSymbols = function() {
|
||||
if (!hasFunctioningSymbols()) {
|
||||
env.pending("Browser has incomplete or missing support for Symbols");
|
||||
}
|
||||
};
|
||||
|
||||
})(jasmine.getEnv());
|
||||
@@ -208,8 +208,49 @@ describe("New HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there are deprecation warnings', function() {
|
||||
it('displays the messages 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.specDone({
|
||||
status: 'passed',
|
||||
deprecationWarnings: [{ message: 'spec deprecation' }],
|
||||
failedExpectations: [],
|
||||
passedExpectations: []
|
||||
});
|
||||
reporter.suiteDone({
|
||||
status: 'passed',
|
||||
deprecationWarnings: [{ message: 'suite deprecation' }],
|
||||
failedExpectations: []
|
||||
});
|
||||
reporter.jasmineDone({
|
||||
deprecationWarnings: [{ message: 'global deprecation' }],
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(4);
|
||||
expect(alertBars[1].innerHTML).toMatch(/spec deprecation/);
|
||||
expect(alertBars[1].getAttribute("class")).toEqual('jasmine-bar jasmine-warning');
|
||||
expect(alertBars[2].innerHTML).toMatch(/suite deprecation/);
|
||||
expect(alertBars[3].innerHTML).toMatch(/global deprecation/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when Jasmine is done", function() {
|
||||
it("adds EMPTY to the link title of specs that have no expectations", function() {
|
||||
it("adds a warning to the link title of specs that have no expectations", function() {
|
||||
if (!window.console) {
|
||||
window.console = { error: function(){} };
|
||||
}
|
||||
@@ -228,7 +269,7 @@ describe("New HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
reporter.jasmineStarted({});
|
||||
reporter.suiteStarted({id: 1});
|
||||
reporter.specStarted({id: 1, status: 'passed', passedExpectations: [], failedExpectations: []});
|
||||
reporter.specStarted({id: 1, passedExpectations: [], failedExpectations: []});
|
||||
reporter.specDone({
|
||||
id: 1,
|
||||
status: 'passed',
|
||||
|
||||
34
spec/html/SpyRegistryHtmlSpec.js
Normal file
34
spec/html/SpyRegistryHtmlSpec.js
Normal file
@@ -0,0 +1,34 @@
|
||||
describe('Spy Registry browser-specific behavior', function() {
|
||||
it('can spy on and unspy window.onerror', function() {
|
||||
requireWriteableOnerror();
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() { return spies; },
|
||||
global: window
|
||||
}),
|
||||
originalHandler = window.onerror;
|
||||
|
||||
try {
|
||||
spyRegistry.spyOn(window, 'onerror');
|
||||
spyRegistry.clearSpies();
|
||||
expect(window.onerror).toBe(originalHandler);
|
||||
} finally {
|
||||
window.onerror = originalHandler;
|
||||
}
|
||||
});
|
||||
|
||||
function requireWriteableOnerror() {
|
||||
var descriptor;
|
||||
|
||||
try {
|
||||
descriptor = Object.getOwnPropertyDescriptor(window, 'onerror');
|
||||
} catch(e) {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
}
|
||||
|
||||
if (descriptor && !(descriptor.writable || descriptor.set)) {
|
||||
pending('Browser declares window.onerror to be readonly');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -7,8 +7,9 @@
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/asyncAwait.js",
|
||||
"helpers/checkForSet.js",
|
||||
"helpers/checkForMap.js",
|
||||
"helpers/checkForSet.js",
|
||||
"helpers/checkForSymbol.js",
|
||||
"helpers/checkForTypedArrays.js",
|
||||
"helpers/nodeDefineJasmineUnderTest.js"
|
||||
],
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
src_dir:
|
||||
- 'src'
|
||||
src_files:
|
||||
- 'core/requireCore.js'
|
||||
- 'core/base.js'
|
||||
- 'core/util.js'
|
||||
#end of known dependencies
|
||||
@@ -18,8 +19,9 @@ stylesheets:
|
||||
helpers:
|
||||
- 'helpers/asyncAwait.js'
|
||||
- 'helpers/BrowserFlags.js'
|
||||
- 'helpers/checkForSet.js'
|
||||
- 'helpers/checkForMap.js'
|
||||
- 'helpers/checkForSet.js'
|
||||
- 'helpers/checkForSymbol.js'
|
||||
- 'helpers/checkForTypedArrays.js'
|
||||
- 'helpers/defineJasmineUnderTest.js'
|
||||
spec_files:
|
||||
|
||||
@@ -7,25 +7,9 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
var calls = [];
|
||||
var opts = {};
|
||||
|
||||
function argCloner(context) {
|
||||
var clonedArgs = [];
|
||||
var argsAsArray = j$.util.argsToArray(context.args);
|
||||
for(var i = 0; i < argsAsArray.length; i++) {
|
||||
var str = Object.prototype.toString.apply(argsAsArray[i]),
|
||||
primitives = /^\[object (Boolean|String|RegExp|Number)/;
|
||||
|
||||
if (argsAsArray[i] == null || str.match(primitives)) {
|
||||
clonedArgs.push(argsAsArray[i]);
|
||||
} else {
|
||||
clonedArgs.push(j$.util.clone(argsAsArray[i]));
|
||||
}
|
||||
}
|
||||
context.args = clonedArgs;
|
||||
}
|
||||
|
||||
this.track = function(context) {
|
||||
if(opts.cloneArgs) {
|
||||
argCloner(context);
|
||||
context.args = j$.util.cloneArgs(context.args);
|
||||
}
|
||||
calls.push(context);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
getJasmineRequireObj().Clock = function() {
|
||||
|
||||
var NODE_JS = typeof process !== 'undefined' && process.versions && typeof process.versions.node === 'string';
|
||||
|
||||
/**
|
||||
* _Note:_ Do not construct this directly, Jasmine will make one during booting. You can get the current clock with {@link jasmine.clock}.
|
||||
* @class Clock
|
||||
@@ -22,6 +25,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
delayedFunctionScheduler,
|
||||
timer;
|
||||
|
||||
self.FakeTimeout = FakeTimeout;
|
||||
|
||||
/**
|
||||
* Install the mock clock over the built-in methods.
|
||||
@@ -145,7 +149,15 @@ getJasmineRequireObj().Clock = function() {
|
||||
}
|
||||
|
||||
function setTimeout(fn, delay) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
|
||||
if (!NODE_JS) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
|
||||
}
|
||||
|
||||
var timeout = new FakeTimeout();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2), false, timeout);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
function clearTimeout(id) {
|
||||
@@ -153,7 +165,15 @@ getJasmineRequireObj().Clock = function() {
|
||||
}
|
||||
|
||||
function setInterval(fn, interval) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
|
||||
if (!NODE_JS) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
|
||||
}
|
||||
|
||||
var timeout = new FakeTimeout();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true, timeout);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
function clearInterval(id) {
|
||||
@@ -165,5 +185,18 @@ getJasmineRequireObj().Clock = function() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks Node.js Timeout class
|
||||
*/
|
||||
function FakeTimeout() {}
|
||||
|
||||
FakeTimeout.prototype.ref = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
FakeTimeout.prototype.unref = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
return Clock;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
function DelayedFunctionScheduler() {
|
||||
var self = this;
|
||||
var scheduledLookup = [];
|
||||
var scheduledFunctions = {};
|
||||
var currentTime = 0;
|
||||
var delayedFnCount = 0;
|
||||
var deletedKeys = [];
|
||||
|
||||
self.tick = function(millis, tickDate) {
|
||||
millis = millis || 0;
|
||||
@@ -51,6 +52,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
};
|
||||
|
||||
self.removeFunctionWithId = function(timeoutKey) {
|
||||
deletedKeys.push(timeoutKey);
|
||||
|
||||
for (var runAtMillis in scheduledFunctions) {
|
||||
var funcs = scheduledFunctions[runAtMillis];
|
||||
var i = indexOfFirstToPass(funcs, function (func) {
|
||||
@@ -121,12 +124,14 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
}
|
||||
|
||||
do {
|
||||
deletedKeys = [];
|
||||
var newCurrentTime = scheduledLookup.shift();
|
||||
tickDate(newCurrentTime - currentTime);
|
||||
|
||||
currentTime = newCurrentTime;
|
||||
|
||||
var funcsToRun = scheduledFunctions[currentTime];
|
||||
|
||||
delete scheduledFunctions[currentTime];
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
@@ -136,6 +141,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
});
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) {
|
||||
// skip a timeoutKey deleted whilst we were running
|
||||
return;
|
||||
}
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
});
|
||||
} while (scheduledLookup.length > 0 &&
|
||||
|
||||
@@ -11,6 +11,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var self = this;
|
||||
var global = options.global || j$.getGlobal();
|
||||
|
||||
var hasExecuted = false;
|
||||
|
||||
var totalSpecsDefined = 0;
|
||||
|
||||
var catchExceptions = true;
|
||||
@@ -197,6 +199,9 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
// 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;
|
||||
};
|
||||
|
||||
@@ -234,6 +239,14 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
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;
|
||||
@@ -241,6 +254,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
options.fail = self.fail;
|
||||
options.globalErrors = globalErrors;
|
||||
options.completeOnFirstError = throwOnExpectationFailure && options.isLeaf;
|
||||
options.deprecated = self.deprecated;
|
||||
|
||||
new j$.QueueRunner(options).execute();
|
||||
};
|
||||
@@ -260,6 +274,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
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) {
|
||||
runnablesToRun = focusedRunnables;
|
||||
@@ -326,10 +346,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @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
|
||||
failedExpectations: topSuite.result.failedExpectations,
|
||||
deprecationWarnings: topSuite.result.deprecationWarnings
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -384,6 +406,13 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
function ensureIsNotNested(method) {
|
||||
var runnable = currentRunnable();
|
||||
if (runnable !== null && runnable !== undefined) {
|
||||
throw new Error('\'' + method + '\' should only be used in \'describe\' function');
|
||||
}
|
||||
}
|
||||
|
||||
var suiteFactory = function(description) {
|
||||
var suite = new j$.Suite({
|
||||
env: self,
|
||||
@@ -399,6 +428,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.describe = function(description, specDefinitions) {
|
||||
ensureIsNotNested('describe');
|
||||
ensureIsFunction(specDefinitions, 'describe');
|
||||
var suite = suiteFactory(description);
|
||||
if (specDefinitions.length > 0) {
|
||||
@@ -412,6 +442,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.xdescribe = function(description, specDefinitions) {
|
||||
ensureIsNotNested('xdescribe');
|
||||
ensureIsFunction(specDefinitions, 'xdescribe');
|
||||
var suite = suiteFactory(description);
|
||||
suite.pend();
|
||||
@@ -422,6 +453,8 @@ 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);
|
||||
suite.isFocused = true;
|
||||
@@ -519,6 +552,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.it = function(description, fn, timeout) {
|
||||
ensureIsNotNested('it');
|
||||
// it() sometimes doesn't have a fn argument, so only check the type if
|
||||
// it's given.
|
||||
if (arguments.length > 1 && typeof fn !== 'undefined') {
|
||||
@@ -533,6 +567,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.xit = function(description, fn, timeout) {
|
||||
ensureIsNotNested('xit');
|
||||
// xit(), like it(), doesn't always have a fn argument, so only check the
|
||||
// type when needed.
|
||||
if (arguments.length > 1 && typeof fn !== 'undefined') {
|
||||
@@ -544,6 +579,8 @@ 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);
|
||||
currentDeclarationSuite.addChild(spec);
|
||||
@@ -561,6 +598,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||
ensureIsNotNested('beforeEach');
|
||||
ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
|
||||
currentDeclarationSuite.beforeEach({
|
||||
fn: beforeEachFunction,
|
||||
@@ -569,6 +607,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.beforeAll = function(beforeAllFunction, timeout) {
|
||||
ensureIsNotNested('beforeAll');
|
||||
ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');
|
||||
currentDeclarationSuite.beforeAll({
|
||||
fn: beforeAllFunction,
|
||||
@@ -577,6 +616,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.afterEach = function(afterEachFunction, timeout) {
|
||||
ensureIsNotNested('afterEach');
|
||||
ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');
|
||||
afterEachFunction.isCleanup = true;
|
||||
currentDeclarationSuite.afterEach({
|
||||
@@ -586,6 +626,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.afterAll = function(afterAllFunction, timeout) {
|
||||
ensureIsNotNested('afterAll');
|
||||
ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');
|
||||
currentDeclarationSuite.afterAll({
|
||||
fn: afterAllFunction,
|
||||
|
||||
@@ -3,6 +3,8 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
function PrettyPrinter() {
|
||||
this.ppNestLevel_ = 0;
|
||||
this.seen = [];
|
||||
this.length = 0;
|
||||
this.stringParts = [];
|
||||
}
|
||||
|
||||
function hasCustomToString(value) {
|
||||
@@ -36,9 +38,9 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.emitScalar('HTMLNode');
|
||||
} else if (value instanceof Date) {
|
||||
this.emitScalar('Date(' + value + ')');
|
||||
} else if (j$.getType_(value) == '[object Set]') {
|
||||
} else if (j$.isSet(value)) {
|
||||
this.emitSet(value);
|
||||
} else if (j$.getType_(value) == '[object Map]') {
|
||||
} else if (j$.isMap(value)) {
|
||||
this.emitMap(value);
|
||||
} else if (j$.isTypedArray_(value)) {
|
||||
this.emitTypedArray(value);
|
||||
@@ -57,6 +59,10 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
} else {
|
||||
this.emitScalar(value.toString());
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
this.ppNestLevel_--;
|
||||
}
|
||||
@@ -82,30 +88,15 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
return objKeys.length > length;
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitSet = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitMap = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;
|
||||
PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;
|
||||
|
||||
function StringPrettyPrinter() {
|
||||
PrettyPrinter.call(this);
|
||||
|
||||
this.stringParts = [];
|
||||
}
|
||||
|
||||
j$.util.inherit(StringPrettyPrinter, PrettyPrinter);
|
||||
|
||||
StringPrettyPrinter.prototype.emitScalar = function(value) {
|
||||
PrettyPrinter.prototype.emitScalar = function(value) {
|
||||
this.append(value);
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitString = function(value) {
|
||||
PrettyPrinter.prototype.emitString = function(value) {
|
||||
this.append('\'' + value + '\'');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitArray = function(array) {
|
||||
PrettyPrinter.prototype.emitArray = function(array) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Array');
|
||||
return;
|
||||
@@ -139,47 +130,57 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(' ]');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitSet = function(set) {
|
||||
PrettyPrinter.prototype.emitSet = function(set) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Set');
|
||||
return;
|
||||
}
|
||||
this.append('Set( ');
|
||||
var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var iter = set.values();
|
||||
for (var i = 0; i < size; i++) {
|
||||
var i = 0;
|
||||
set.forEach( function( value, key ) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(iter.next().value);
|
||||
}
|
||||
this.format(value);
|
||||
|
||||
i++;
|
||||
}, this );
|
||||
if (set.size > size){
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitMap = function(map) {
|
||||
PrettyPrinter.prototype.emitMap = function(map) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Map');
|
||||
return;
|
||||
}
|
||||
this.append('Map( ');
|
||||
var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var iter = map.entries();
|
||||
for (var i = 0; i < size; i++) {
|
||||
var i = 0;
|
||||
map.forEach( function( value, key ) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(iter.next().value);
|
||||
}
|
||||
this.format([key,value]);
|
||||
|
||||
i++;
|
||||
}, this );
|
||||
if (map.size > size){
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitObject = function(obj) {
|
||||
PrettyPrinter.prototype.emitObject = function(obj) {
|
||||
var ctor = obj.constructor,
|
||||
constructorName;
|
||||
|
||||
@@ -212,7 +213,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(' })');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitTypedArray = function(arr) {
|
||||
PrettyPrinter.prototype.emitTypedArray = function(arr) {
|
||||
var constructorName = j$.fnNameFor(arr.constructor),
|
||||
limitedArray = Array.prototype.slice.call(arr, 0, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH),
|
||||
itemsString = Array.prototype.join.call(limitedArray, ', ');
|
||||
@@ -224,7 +225,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(constructorName + ' [ ' + itemsString + ' ]');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
this.append(property);
|
||||
this.append(': ');
|
||||
if (isGetter) {
|
||||
@@ -234,10 +235,33 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.append = function(value) {
|
||||
this.stringParts.push(value);
|
||||
PrettyPrinter.prototype.append = function(value) {
|
||||
var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);
|
||||
this.length += result.value.length;
|
||||
this.stringParts.push(result.value);
|
||||
|
||||
if (result.truncated) {
|
||||
throw new MaxCharsReachedError();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function truncate(s, maxlen) {
|
||||
if (s.length <= maxlen) {
|
||||
return { value: s, truncated: false };
|
||||
}
|
||||
|
||||
s = s.substring(0, maxlen - 4) + ' ...';
|
||||
return { value: s, truncated: true };
|
||||
}
|
||||
|
||||
function MaxCharsReachedError() {
|
||||
this.message = 'Exceeded ' + j$.MAX_PRETTY_PRINT_CHARS +
|
||||
' characters while pretty-printing a value';
|
||||
}
|
||||
|
||||
MaxCharsReachedError.prototype = new Error();
|
||||
|
||||
function keys(obj, isArray) {
|
||||
var allKeys = Object.keys ? Object.keys(obj) :
|
||||
(function(o) {
|
||||
@@ -268,8 +292,8 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
return extraKeys;
|
||||
}
|
||||
return function(value) {
|
||||
var stringPrettyPrinter = new StringPrettyPrinter();
|
||||
stringPrettyPrinter.format(value);
|
||||
return stringPrettyPrinter.stringParts.join('');
|
||||
var prettyPrinter = new PrettyPrinter();
|
||||
prettyPrinter.format(value);
|
||||
return prettyPrinter.stringParts.join('');
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
return function() {
|
||||
if (!called) {
|
||||
called = true;
|
||||
fn();
|
||||
fn.apply(null, arguments);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -24,6 +24,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.fail = attrs.fail || function() {};
|
||||
this.globalErrors = attrs.globalErrors || { pushListener: function() {}, popListener: function() {} };
|
||||
this.completeOnFirstError = !!attrs.completeOnFirstError;
|
||||
this.deprecated = attrs.deprecated;
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
@@ -83,9 +84,13 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
clearTimeout(timeoutId);
|
||||
self.globalErrors.popListener(handleError);
|
||||
}),
|
||||
next = once(function () {
|
||||
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);
|
||||
@@ -125,7 +130,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
var maybeThenable = queueableFn.fn.call(self.userContext);
|
||||
|
||||
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
|
||||
maybeThenable.then(next, next.fail);
|
||||
maybeThenable.then(next, onPromiseRejection);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
@@ -147,6 +152,11 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
errored = true;
|
||||
}
|
||||
|
||||
function onPromiseRejection(e) {
|
||||
onException(e);
|
||||
next();
|
||||
}
|
||||
|
||||
function handleException(e, queueableFn) {
|
||||
onException(e);
|
||||
if (!self.catchException(e)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
getJasmineRequireObj().ReportDispatcher = function() {
|
||||
getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
function ReportDispatcher(methods) {
|
||||
|
||||
var dispatchedMethods = methods || [];
|
||||
@@ -36,7 +36,7 @@ getJasmineRequireObj().ReportDispatcher = function() {
|
||||
for (var i = 0; i < reporters.length; i++) {
|
||||
var reporter = reporters[i];
|
||||
if (reporter[method]) {
|
||||
reporter[method].apply(reporter, args);
|
||||
reporter[method].apply(reporter, j$.util.cloneArgs(args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @property {String} fullName - The full description including all ancestors of this spec.
|
||||
* @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
|
||||
* @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
|
||||
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
|
||||
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
|
||||
*/
|
||||
@@ -34,6 +35,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
};
|
||||
}
|
||||
@@ -149,6 +151,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
|
||||
Spec.prototype.addDeprecationWarning = function(msg) {
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
|
||||
};
|
||||
|
||||
var extractCustomPendingMessage = function(e) {
|
||||
var fullMessage = e.toString(),
|
||||
boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
|
||||
|
||||
@@ -4,6 +4,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
|
||||
function SpyRegistry(options) {
|
||||
options = options || {};
|
||||
var global = options.global || j$.getGlobal();
|
||||
var currentSpies = options.currentSpies || function() { return []; };
|
||||
|
||||
this.allowRespy = function(allow){
|
||||
@@ -47,7 +48,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
spiedMethod = j$.createSpy(methodName, originalMethod),
|
||||
restoreStrategy;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(obj, methodName)) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, methodName) || (obj === global && methodName === 'onerror')) {
|
||||
restoreStrategy = function() {
|
||||
obj[methodName] = originalMethod;
|
||||
};
|
||||
|
||||
@@ -88,7 +88,7 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
* @param {Function} fn The function to invoke with the passed parameters.
|
||||
*/
|
||||
this.callFake = function(fn) {
|
||||
if(!j$.isFunction_(fn)) {
|
||||
if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
|
||||
throw new Error('Argument passed to callFake should be a function, got ' + fn);
|
||||
}
|
||||
plan = fn;
|
||||
|
||||
@@ -21,13 +21,15 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @property {String} description - The description text passed to the {@link describe} that made this suite.
|
||||
* @property {String} fullName - The full description including all ancestors of this suite.
|
||||
* @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
|
||||
* @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
description: this.description,
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: []
|
||||
failedExpectations: [],
|
||||
deprecationWarnings: []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -147,6 +149,10 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.addDeprecationWarning = function(msg) {
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
|
||||
};
|
||||
|
||||
function isAfterAll(children) {
|
||||
return children && children[0].result.status;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ getJasmineRequireObj().Any = function(j$) {
|
||||
}
|
||||
|
||||
if (this.expectedObject == Object) {
|
||||
if (other === null) {
|
||||
j$.getEnv().deprecated('jasmine.Any(Object) will no longer match null in Jasmine 3.0');
|
||||
}
|
||||
return typeof other == 'object';
|
||||
}
|
||||
|
||||
@@ -31,6 +34,12 @@ getJasmineRequireObj().Any = function(j$) {
|
||||
return typeof other == 'boolean';
|
||||
}
|
||||
|
||||
/* jshint -W122 */
|
||||
if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) {
|
||||
return typeof other == 'symbol';
|
||||
}
|
||||
/* jshint +W122 */
|
||||
|
||||
return other instanceof this.expectedObject;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,14 +8,20 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Set this to a lower value to speed up pretty printing if you have large objects.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_DEPTH
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 40;
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 8;
|
||||
/**
|
||||
* Maximum number of array elements to display when pretty printing objects.
|
||||
* This will also limit the number of keys and values displayed for an object.
|
||||
* Elements past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100;
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
|
||||
/**
|
||||
* Maximum number of charasters to display when pretty printing objects.
|
||||
* Characters past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_CHARS
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_CHARS = 1000;
|
||||
/**
|
||||
* Default number of milliseconds Jasmine will wait for an asynchronous spec to complete.
|
||||
* @name jasmine.DEFAULT_TIMEOUT_INTERVAL
|
||||
@@ -87,6 +93,18 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return obj.nodeType > 0;
|
||||
};
|
||||
|
||||
j$.isMap = function(obj) {
|
||||
return typeof jasmineGlobal.Map !== 'undefined' && obj.constructor === jasmineGlobal.Map;
|
||||
};
|
||||
|
||||
j$.isSet = function(obj) {
|
||||
return typeof jasmineGlobal.Set !== 'undefined' && obj.constructor === jasmineGlobal.Set;
|
||||
};
|
||||
|
||||
j$.isPromise = function(obj) {
|
||||
return typeof jasmineGlobal.Promise !== 'undefined' && obj.constructor === jasmineGlobal.Promise;
|
||||
};
|
||||
|
||||
j$.fnNameFor = function(func) {
|
||||
if (func.name) {
|
||||
return func.name;
|
||||
|
||||
@@ -214,6 +214,12 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aIsPromise = j$.isPromise(a);
|
||||
var bIsPromise = j$.isPromise(b);
|
||||
if (aIsPromise && bIsPromise) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
var length = aStack.length;
|
||||
@@ -247,22 +253,46 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
} else if (className == '[object Map]') {
|
||||
} else if (j$.isMap(a) && j$.isMap(b)) {
|
||||
if (a.size != b.size) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
|
||||
// For both sets of keys, check they map to equal values in both maps
|
||||
var mapKeys = [a.keys(), b.keys()];
|
||||
var mapIter, mapKeyIt, mapKey;
|
||||
var keysA = [];
|
||||
var keysB = [];
|
||||
a.forEach( function( valueA, keyA ) {
|
||||
keysA.push( keyA );
|
||||
});
|
||||
b.forEach( function( valueB, keyB ) {
|
||||
keysB.push( keyB );
|
||||
});
|
||||
|
||||
// For both sets of keys, check they map to equal values in both maps.
|
||||
// Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys.
|
||||
var mapKeys = [keysA, keysB];
|
||||
var cmpKeys = [keysB, keysA];
|
||||
var mapIter, mapKey, mapValueA, mapValueB;
|
||||
var cmpIter, cmpKey;
|
||||
for (i = 0; result && i < mapKeys.length; i++) {
|
||||
mapIter = mapKeys[i];
|
||||
mapKeyIt = mapIter.next();
|
||||
while (result && !mapKeyIt.done) {
|
||||
mapKey = mapKeyIt.value;
|
||||
result = eq(a.get(mapKey), b.get(mapKey), aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
mapKeyIt = mapIter.next();
|
||||
cmpIter = cmpKeys[i];
|
||||
|
||||
for (var j = 0; result && j < mapIter.length; j++) {
|
||||
mapKey = mapIter[j];
|
||||
cmpKey = cmpIter[j];
|
||||
mapValueA = a.get(mapKey);
|
||||
|
||||
// Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches,
|
||||
// otherwise explicitly look up the mapKey in the other Map since we want keys with unique
|
||||
// obj identity (that are otherwise equal) to not match.
|
||||
if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) &&
|
||||
eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) {
|
||||
mapValueB = b.get(cmpKey);
|
||||
} else {
|
||||
mapValueB = b.get(mapKey);
|
||||
}
|
||||
result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,36 +300,49 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
} else if (className == '[object Set]') {
|
||||
} else if (j$.isSet(a) && j$.isSet(b)) {
|
||||
if (a.size != b.size) {
|
||||
diffBuilder.record(a, b);
|
||||
return false;
|
||||
}
|
||||
|
||||
var valuesA = [];
|
||||
a.forEach( function( valueA ) {
|
||||
valuesA.push( valueA );
|
||||
});
|
||||
var valuesB = [];
|
||||
b.forEach( function( valueB ) {
|
||||
valuesB.push( valueB );
|
||||
});
|
||||
|
||||
// For both sets, check they are all contained in the other set
|
||||
var setPairs = [[a, b], [b, a]];
|
||||
var baseIter, baseValueIt, baseValue;
|
||||
var otherSet, otherIter, otherValueIt, otherValue, found;
|
||||
var setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
|
||||
var stackPairs = [[aStack, bStack], [bStack, aStack]];
|
||||
var baseValues, baseValue, baseStack;
|
||||
var otherValues, otherValue, otherStack;
|
||||
var found;
|
||||
var prevStackSize;
|
||||
for (i = 0; result && i < setPairs.length; i++) {
|
||||
baseIter = setPairs[i][0].values();
|
||||
otherSet = setPairs[i][1];
|
||||
baseValues = setPairs[i][0];
|
||||
otherValues = setPairs[i][1];
|
||||
baseStack = stackPairs[i][0];
|
||||
otherStack = stackPairs[i][1];
|
||||
// For each value in the base set...
|
||||
baseValueIt = baseIter.next();
|
||||
while (result && !baseValueIt.done) {
|
||||
baseValue = baseValueIt.value;
|
||||
for (var k = 0; result && k < baseValues.length; k++) {
|
||||
baseValue = baseValues[k];
|
||||
found = false;
|
||||
// ... test that it is present in the other set
|
||||
otherIter = otherSet.values();
|
||||
otherValueIt = otherIter.next();
|
||||
// Optimisation: start looking for value by object identity
|
||||
found = otherSet.has(baseValue);
|
||||
// If not found, compare by value equality
|
||||
while (!found && !otherValueIt.done) {
|
||||
otherValue = otherValueIt.value;
|
||||
found = eq(baseValue, otherValue, aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
otherValueIt = otherIter.next();
|
||||
for (var l = 0; !found && l < otherValues.length; l++) {
|
||||
otherValue = otherValues[l];
|
||||
prevStackSize = baseStack.length;
|
||||
// compare by value equality
|
||||
found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder());
|
||||
if (!found && prevStackSize !== baseStack.length) {
|
||||
baseStack.splice(prevStackSize);
|
||||
otherStack.splice(prevStackSize);
|
||||
}
|
||||
}
|
||||
result = result && found;
|
||||
baseValueIt = baseIter.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
|
||||
jasmineGlobal = window;
|
||||
}
|
||||
jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {};
|
||||
jasmineRequire = jasmineGlobal.jasmineRequire = {};
|
||||
}
|
||||
|
||||
function getJasmineRequire() {
|
||||
@@ -23,7 +23,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
var j$ = {};
|
||||
|
||||
jRequire.base(j$, jasmineGlobal);
|
||||
j$.util = jRequire.util();
|
||||
j$.util = jRequire.util(j$);
|
||||
j$.errors = jRequire.errors();
|
||||
j$.formatErrorMsg = jRequire.formatErrorMsg();
|
||||
j$.Any = jRequire.Any(j$);
|
||||
@@ -32,7 +32,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.MockDate = jRequire.MockDate();
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter();
|
||||
j$.Expectation = jRequire.Expectation();
|
||||
@@ -44,7 +44,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$);
|
||||
j$.pp = jRequire.pp(j$);
|
||||
j$.QueueRunner = jRequire.QueueRunner(j$);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher();
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.Spy = jRequire.Spy(j$);
|
||||
j$.SpyRegistry = jRequire.SpyRegistry(j$);
|
||||
|
||||
@@ -197,7 +197,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Install a spy on a property onto an existing object.
|
||||
* Install a spy on a property installed with `Object.defineProperty` onto an existing object.
|
||||
* @name spyOnProperty
|
||||
* @function
|
||||
* @global
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
getJasmineRequireObj().util = function() {
|
||||
getJasmineRequireObj().util = function(j$) {
|
||||
|
||||
var util = {};
|
||||
|
||||
@@ -55,6 +55,23 @@ getJasmineRequireObj().util = function() {
|
||||
return cloned;
|
||||
};
|
||||
|
||||
util.cloneArgs = function(args) {
|
||||
var clonedArgs = [];
|
||||
var argsAsArray = j$.util.argsToArray(args);
|
||||
for(var i = 0; i < argsAsArray.length; i++) {
|
||||
var str = Object.prototype.toString.apply(argsAsArray[i]),
|
||||
primitives = /^\[object (Boolean|String|RegExp|Number)/;
|
||||
|
||||
// All falsey values are either primitives, `null`, or `undefined.
|
||||
if (!argsAsArray[i] || str.match(primitives)) {
|
||||
clonedArgs.push(argsAsArray[i]);
|
||||
} else {
|
||||
clonedArgs.push(j$.util.clone(argsAsArray[i]));
|
||||
}
|
||||
}
|
||||
return clonedArgs;
|
||||
};
|
||||
|
||||
util.getPropertyDescriptor = function(obj, methodName) {
|
||||
var descriptor,
|
||||
proto = obj;
|
||||
|
||||
@@ -5,6 +5,46 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
|
||||
function ResultsStateBuilder() {
|
||||
this.topResults = new j$.ResultsNode({}, '', null);
|
||||
this.currentParent = this.topResults;
|
||||
this.specsExecuted = 0;
|
||||
this.failureCount = 0;
|
||||
this.pendingSpecCount = 0;
|
||||
}
|
||||
|
||||
ResultsStateBuilder.prototype.suiteStarted = function(result) {
|
||||
this.currentParent.addChild(result, 'suite');
|
||||
this.currentParent = this.currentParent.last();
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.suiteDone = function(result) {
|
||||
if (this.currentParent !== this.topResults) {
|
||||
this.currentParent = this.currentParent.parent;
|
||||
}
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specStarted = function(result) {
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specDone = function(result) {
|
||||
this.currentParent.addChild(result, 'spec');
|
||||
|
||||
if (result.status !== 'disabled') {
|
||||
this.specsExecuted++;
|
||||
}
|
||||
|
||||
if (result.status === 'failed') {
|
||||
this.failureCount++;
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
this.pendingSpecCount++;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
function HtmlReporter(options) {
|
||||
var env = options.env || {},
|
||||
getContainer = options.getContainer,
|
||||
@@ -17,12 +57,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
filterSpecs = options.filterSpecs,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
failedSuites = [],
|
||||
deprecationWarnings = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
@@ -48,12 +86,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
var summary = createDom('div', {className: 'jasmine-summary'});
|
||||
|
||||
var topResults = new j$.ResultsNode({}, '', null),
|
||||
currentParent = topResults;
|
||||
var stateBuilder = new ResultsStateBuilder();
|
||||
|
||||
this.suiteStarted = function(result) {
|
||||
currentParent.addChild(result, 'suite');
|
||||
currentParent = currentParent.last();
|
||||
stateBuilder.suiteStarted(result);
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
@@ -61,27 +97,22 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentParent = currentParent.parent;
|
||||
stateBuilder.suiteDone(result);
|
||||
addDeprecationWarnings(result);
|
||||
};
|
||||
|
||||
this.specStarted = function(result) {
|
||||
currentParent.addChild(result, 'spec');
|
||||
stateBuilder.specStarted(result);
|
||||
};
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
stateBuilder.specDone(result);
|
||||
|
||||
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
|
||||
console.error('Spec \'' + result.fullName + '\' has no expectations.');
|
||||
}
|
||||
|
||||
if (result.status != 'disabled') {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
if (!symbols){
|
||||
symbols = find('.jasmine-symbol-summary');
|
||||
}
|
||||
@@ -94,8 +125,6 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
));
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
@@ -114,9 +143,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingSpecCount++;
|
||||
}
|
||||
addDeprecationWarnings(result);
|
||||
};
|
||||
|
||||
this.jasmineDone = function(doneResult) {
|
||||
@@ -179,8 +206,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
if (stateBuilder.specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + stateBuilder.specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
var skippedLink = addToExistingQueryString('spec', '');
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
|
||||
@@ -192,9 +219,9 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
|
||||
statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
statusBarMessage += pluralize('spec', stateBuilder.specsExecuted) + ', ' + pluralize('failure', stateBuilder.failureCount);
|
||||
if (stateBuilder.pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', stateBuilder.pendingSpecCount); }
|
||||
statusBarClassName += (stateBuilder.failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
} else {
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
@@ -226,10 +253,18 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
|
||||
}
|
||||
|
||||
addDeprecationWarnings(doneResult);
|
||||
|
||||
var warningBarClassName = 'jasmine-bar jasmine-warning';
|
||||
for(i = 0; i < deprecationWarnings.length; i++) {
|
||||
var warning = deprecationWarnings[i];
|
||||
alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning));
|
||||
}
|
||||
|
||||
var results = find('.jasmine-results');
|
||||
results.appendChild(summary);
|
||||
|
||||
summaryList(topResults, summary);
|
||||
summaryList(stateBuilder.topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
@@ -300,6 +335,17 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
return this;
|
||||
|
||||
function addDeprecationWarnings(result) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for(var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
var warning = result.deprecationWarnings[i].message;
|
||||
if (!j$.util.arrayContains(warning)) {
|
||||
deprecationWarnings.push(warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
|
||||
@@ -216,6 +216,11 @@ body {
|
||||
background-color: $failing-color;
|
||||
}
|
||||
|
||||
&.jasmine-warning {
|
||||
background-color: $pending-color;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
&.jasmine-menu {
|
||||
background-color: #fff;
|
||||
color: $faint-text-color;
|
||||
|
||||
@@ -4,7 +4,7 @@ rm -rf ~/.nvm
|
||||
git clone https://github.com/creationix/nvm.git ~/.nvm
|
||||
(cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`)
|
||||
source ~/.nvm/nvm.sh
|
||||
nvm install v0.12.18
|
||||
nvm install ${1:-"v0.12.18"}
|
||||
|
||||
npm install
|
||||
npm test
|
||||
|
||||
Reference in New Issue
Block a user