Merge branch 'main' into 3.99

This commit is contained in:
Steve Gravrock
2020-09-14 18:39:32 -07:00
82 changed files with 2725 additions and 1286 deletions

View File

@@ -17,7 +17,7 @@ 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 # Fetch changes not present in your local repository
git merge upstream/master # Sync local master with upstream repository
git merge upstream/main # Sync local main 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
@@ -121,7 +121,7 @@ The easiest way to run the tests in **Internet Explorer** is to run a VM that ha
1. Build `jasmine.js` with `npm run build` and run all specs again - this ensures that your changes self-test well
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
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into main
Note that we use Travis for Continuous Integration. We only accept green pull requests.

View File

@@ -1,8 +1,5 @@
language: node_js
node_js:
- "10"
- "8"
- "12"
node_js: 10
script: $TEST_COMMAND
@@ -10,15 +7,17 @@ env:
global:
- USE_SAUCE=true
- TEST_COMMAND="bash travis-core-script.sh"
- JASMINE_LONG_PROPERTY_TESTS="y"
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
matrix:
- TEST_COMMAND="npm test"
matrix:
include:
- node_js: "10"
env: JASMINE_LONG_PROPERTY_TESTS="y" TEST_COMMAND="npm test"
- node_js: "12"
env: TEST_COMMAND="npm test"
- node_js: "8"
env: TEST_COMMAND="npm test"
- env: JASMINE_BROWSER="internet explorer" SAUCE_BROWSER_VERSION=11 SAUCE_OS="Windows 8.1"
if: type != pull_request
addons:

View File

@@ -1,6 +1,6 @@
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/main/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=master)](https://travis-ci.org/jasmine/jasmine)
[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=main)](https://travis-ci.org/jasmine/jasmine)
[![Open Source Helpers](https://www.codetriage.com/jasmine/jasmine/badges/users.svg)](https://www.codetriage.com/jasmine/jasmine)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine?ref=badge_shield)
@@ -9,59 +9,70 @@
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
For a quick start guide of Jasmine, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html)
For a quick start guide of Jasmine, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html).
Upgrading from Jasmine 2.x? Check out the [3.0 release notes](https://github.com/jasmine/jasmine/blob/v3.0.0/release_notes/3.0.md) for a list of what's new (including breaking changes).
## Contributing
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/.github/CONTRIBUTING.md)
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md).
## Installation
For the Jasmine NPM module:<br>
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm)
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm).
For the Jasmine Ruby Gem:<br>
[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem)
[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem).
For the Jasmine Python Egg:<br>
[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py)
[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py).
For the Jasmine headless browser gulp plugin:<br>
[https://github.com/jasmine/gulp-jasmine-browser](https://github.com/jasmine/gulp-jasmine-browser)
[https://github.com/jasmine/gulp-jasmine-browser](https://github.com/jasmine/gulp-jasmine-browser).
To install Jasmine standalone on your local box (where **_{#.#.#}_** below is substituted by the release number downloaded):
* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases)
* Create a Jasmine directory in your project - `mkdir my-project/jasmine`
* Move the dist to your project directory - `mv jasmine/dist/jasmine-standalone-{#.#.#}.zip my-project/jasmine`
* Change directory - `cd my-project/jasmine`
* Unzip the dist - `unzip jasmine-standalone-{#.#.#}.zip`
* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases).
* Create a Jasmine directory in your project. - `mkdir my-project/jasmine`
* Move the dist to your project directory. - `mv jasmine/dist/jasmine-standalone-{#.#.#}.zip my-project/jasmine`
* Change directory. - `cd my-project/jasmine`
* Unzip the dist. - `unzip jasmine-standalone-{#.#.#}.zip`
Add the following to your HTML file:
```html
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-{#.#.#}/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-{#.#.#}/jasmine.css">
<link rel="shortcut icon" type="image/png" href="lib/jasmine-{#.#.#}/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-{#.#.#}/jasmine.css">
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/boot.js"></script>
<script type="text/javascript" src="lib/jasmine-{#.#.#}/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-{#.#.#}/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-{#.#.#}/boot.js"></script>
```
## Supported environments
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, Microsoft Edge, and new Internet Explorer) as well as nodejs. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, Microsoft Edge, and Internet Explorer) as well as nodejs.
[![Sauce Test Status](https://saucelabs.com/browser-matrix/jasmine-js.svg)](https://saucelabs.com/u/jasmine-js)
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 8, 10, 12 |
| Safari | 8-13 |
| Chrome | Evergreen |
| Firefox | Evergreen, 68 |
| Edge | Evergreen |
| Internet Explorer | 10, 11 |
For evergreen browsers, each version of Jasmine is tested against the version of the browser that is available to us
at the time of release. Other browsers, as well as older & newer versions of some supported browsers, are likely to work.
However, Jasmine isn't tested against them and they aren't actively supported.
## Support
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com)
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js).
* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com).
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606).
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD).
## Maintainers

View File

@@ -7,7 +7,7 @@ Follow the instructions in `CONTRIBUTING.md` during development.
### Git Rules
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`.
Please attempt to keep commits to `main` 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 `main`.
### Version
@@ -29,29 +29,32 @@ When jasmine-core revs its major or minor version, the binding libraries should
When ready to release - specs are all green and the stories are done:
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly
1. Update the version in `package.json` to a release candidate
1. Update any links or top-level landing page for the Github Pages
1. Update the version in `package.json`
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
### Commit and push core changes
1. Commit release notes and version changes (jasmine.js, version.rb, package.json)
1. Push
1. Wait for Travis to go green
### Build standalone distribution
1. Build the standalone distribution with `grunt buildStandaloneDist`
### Release the Python egg
### Release the core Ruby gem
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release. See below.
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
### Release the core Python egg
Install [twine](https://github.com/pypa/twine)
1. `python setup.py sdist`
1. `twine upload dist/jasmine-core-<version>.tar.gz` You will need pypi credentials to upload the egg.
### Release the Ruby gem
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile.
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release.
1. Push these changes to GitHub and verify that this SHA is green
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
### Release the NPM
### Release the core NPM module
1. `npm adduser` to save your credentials locally
1. `npm publish .` to publish what's in `package.json`
@@ -60,15 +63,35 @@ Install [twine](https://github.com/pypa/twine)
Probably only need to do this when releasing a minor version, and not a patch version.
1. `cp -R edge ${version}` to copy the current edge docs to the new version
1. Add a link to the new version in `index.html`
1. `rake update_edge_jasmine`
1. `npm run jsdoc`
1. `rake release[${version}]` to copy the current edge docs to the new version
1. Commit and push.
### Release the binding libraries
#### NPM
1. Create release notes using Anchorman as above
1. In `package.json`, update both the package version and the jasmine-core dependency version
1. Commit and push.
1. Wait for Travis to go green again.
1. `grunt release `
1. `npm publish .`
#### Gem
1. Create release notes using Anchorman as above
1. Update the version number in `lib/jasmine/version.rb`.
1. Update the jasmine-core dependency version in `jasmine.gemspec`.
1. Commit and push.
1. Wait for Travis to go green again.
1. `rake release`
### Finally
1. Visit the [Releases page for Jasmine](https://github.com/jasmine/jasmine/releases), find the tag just pushed.
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
1. If it is a pre-release, mark it as such.
1. Attach the standalone zipfile
There should be a post to Pivotal Labs blog and a tweet to that link.
For each of the above GitHub repos:
1. Visit the releases page and find the tag just published.
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
1. If it is a pre-release, mark it as such.
1. For core, attach the standalone zipfile.

View File

@@ -31,13 +31,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function() {
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
/**
* ## Require &amp; Instantiate
*
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
*/
window.jasmine = jasmineRequire.core(jasmineRequire);
var jasmine = jasmineRequire.core(jasmineRequire),
global = jasmine.getGlobal();
global.jasmine = jasmine;
/**
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
@@ -59,7 +62,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/**
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
*/
extend(window, jasmineInterface);
extend(global, jasmineInterface);
/**
* ## Runner Parameters

View File

@@ -9,13 +9,16 @@
*/
(function() {
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
/**
* ## Require &amp; Instantiate
*
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
*/
window.jasmine = jasmineRequire.core(jasmineRequire);
var jasmine = jasmineRequire.core(jasmineRequire),
global = jasmine.getGlobal();
global.jasmine = jasmine;
/**
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
@@ -37,7 +40,7 @@
/**
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
*/
extend(window, jasmineInterface);
extend(global, jasmineInterface);
/**
* ## Runner Parameters

View File

@@ -19,4 +19,4 @@ Player.prototype.resume = function() {
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
};

View File

@@ -4,4 +4,4 @@ function Song() {
Song.prototype.persistFavoriteStatus = function(value) {
// something complicated
throw new Error("not yet implemented");
};
};

View File

@@ -20,6 +20,8 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
jasmineRequire.html = function(j$) {
j$.ResultsNode = jasmineRequire.ResultsNode();
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
@@ -130,7 +132,7 @@ jasmineRequire.HtmlReporter = function(j$) {
if (result.status === 'failed') {
failures.push(failureDom(result));
}
addDeprecationWarnings(result);
addDeprecationWarnings(result, 'suite');
};
this.specStarted = function(result) {
@@ -166,7 +168,7 @@ jasmineRequire.HtmlReporter = function(j$) {
failures.push(failureDom(result));
}
addDeprecationWarnings(result);
addDeprecationWarnings(result, 'spec');
};
this.displaySpecInCorrectFormat = function(result) {
@@ -305,14 +307,27 @@ jasmineRequire.HtmlReporter = function(j$) {
addDeprecationWarnings(doneResult);
var warningBarClassName = 'jasmine-bar jasmine-warning';
for (i = 0; i < deprecationWarnings.length; i++) {
var warning = deprecationWarnings[i];
var context;
switch (deprecationWarnings[i].runnableType) {
case 'spec':
context = '(in spec: ' + deprecationWarnings[i].runnableName + ')';
break;
case 'suite':
context = '(in suite: ' + deprecationWarnings[i].runnableName + ')';
break;
default:
context = '';
}
alert.appendChild(
createDom(
'span',
{ className: warningBarClassName },
'DEPRECATION: ' + warning
{ className: 'jasmine-bar jasmine-warning' },
'DEPRECATION: ' + deprecationWarnings[i].message,
createDom('br'),
context
)
);
}
@@ -350,9 +365,11 @@ jasmineRequire.HtmlReporter = function(j$) {
find('.jasmine-failures-menu').onclick = function() {
setMenuModeTo('jasmine-failure-list');
return false;
};
find('.jasmine-spec-list-menu').onclick = function() {
setMenuModeTo('jasmine-spec-list');
return false;
};
setMenuModeTo('jasmine-failure-list');
@@ -621,12 +638,16 @@ jasmineRequire.HtmlReporter = function(j$) {
return addToExistingQueryString('spec', els.join(' '));
}
function addDeprecationWarnings(result) {
function addDeprecationWarnings(result, runnableType) {
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);
deprecationWarnings.push({
message: warning,
runnableName: result.fullName,
runnableType: runnableType
});
}
}
}

View File

@@ -71,7 +71,6 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.Expector = jRequire.Expector(j$);
j$.Expectation = jRequire.Expectation(j$);
j$.buildExpectationResult = jRequire.buildExpectationResult(j$);
j$.noopTimer = jRequire.noopTimer();
j$.JsApiReporter = jRequire.JsApiReporter(j$);
j$.asymmetricEqualityTesterArgCompatShim = jRequire.asymmetricEqualityTesterArgCompatShim(
j$
@@ -168,8 +167,10 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
'toBeUndefined',
'toContain',
'toEqual',
'toHaveSize',
'toHaveBeenCalled',
'toHaveBeenCalledBefore',
'toHaveBeenCalledOnceWith',
'toHaveBeenCalledTimes',
'toHaveBeenCalledWith',
'toHaveClass',
@@ -266,6 +267,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
return j$.isA_('AsyncFunction', value);
};
j$.isGeneratorFunction_ = function(value) {
return j$.isA_('GeneratorFunction', value);
};
j$.isTypedArray_ = function(value) {
return (
j$.isA_('Float32Array', value) ||
@@ -338,6 +343,24 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
);
};
j$.isWeakMap = function(obj) {
return (
obj !== null &&
typeof obj !== 'undefined' &&
typeof jasmineGlobal.WeakMap !== 'undefined' &&
obj.constructor === jasmineGlobal.WeakMap
);
};
j$.isDataView = function(obj) {
return (
obj !== null &&
typeof obj !== 'undefined' &&
typeof jasmineGlobal.DataView !== 'undefined' &&
obj.constructor === jasmineGlobal.DataView
);
};
j$.isPromise = function(obj) {
return (
typeof jasmineGlobal.Promise !== 'undefined' &&
@@ -704,7 +727,7 @@ getJasmineRequireObj().Spec = function(j$) {
return true;
};
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
this.timer = attrs.timer || j$.noopTimer;
this.timer = attrs.timer || new j$.Timer();
if (!this.queueableFn.fn) {
this.pend();
@@ -721,6 +744,7 @@ getJasmineRequireObj().Spec = function(j$) {
* @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.
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
*/
this.result = {
id: this.id,
@@ -730,7 +754,8 @@ getJasmineRequireObj().Spec = function(j$) {
passedExpectations: [],
deprecationWarnings: [],
pendingReason: '',
duration: null
duration: null,
properties: null
};
}
@@ -747,6 +772,11 @@ getJasmineRequireObj().Spec = function(j$) {
}
};
Spec.prototype.setSpecProperty = function(key, value) {
this.result.properties = this.result.properties || {};
this.result.properties[key] = value;
};
Spec.prototype.expect = function(actual) {
return this.expectationFactory(actual, this);
};
@@ -769,6 +799,7 @@ getJasmineRequireObj().Spec = function(j$) {
fn: function(done) {
self.queueableFn.fn = null;
self.result.status = self.status(excluded, failSpecWithNoExp);
self.result.duration = self.timer.elapsed();
self.resultCallback(self.result, done);
}
};
@@ -784,7 +815,6 @@ getJasmineRequireObj().Spec = function(j$) {
self.onException.apply(self, arguments);
},
onComplete: function() {
self.result.duration = self.timer.elapsed();
onComplete(
self.result.status === 'failed' &&
new j$.StopExecutionError('spec failed')
@@ -1569,12 +1599,22 @@ getJasmineRequireObj().Env = function(j$) {
this.deprecated = function(deprecation) {
var runnable = currentRunnable() || topSuite;
var context;
if (runnable === topSuite) {
context = '';
} else if (runnable === currentSuite()) {
context = ' (in suite: ' + runnable.getFullName() + ')';
} else {
context = ' (in spec: ' + runnable.getFullName() + ')';
}
runnable.addDeprecationWarning(deprecation);
if (
typeof console !== 'undefined' &&
typeof console.error === 'function'
) {
console.error('DEPRECATION:', deprecation);
console.error('DEPRECATION: ' + deprecation + context);
}
};
@@ -1716,7 +1756,8 @@ getJasmineRequireObj().Env = function(j$) {
queueRunnerFactory
);
this.execute = function(runnablesToRun) {
// Both params are optional.
this.execute = function(runnablesToRun, onComplete) {
installGlobalErrors();
if (!runnablesToRun) {
@@ -1824,7 +1865,11 @@ getJasmineRequireObj().Env = function(j$) {
failedExpectations: topSuite.result.failedExpectations,
deprecationWarnings: topSuite.result.deprecationWarnings
},
function() {}
function() {
if (onComplete) {
onComplete();
}
}
);
});
}
@@ -1963,6 +2008,7 @@ getJasmineRequireObj().Env = function(j$) {
id: getNextSuiteId(),
description: description,
parentSuite: currentDeclarationSuite,
timer: new j$.Timer(),
expectationFactory: expectationFactory,
asyncExpectationFactory: suiteAsyncExpectationFactory,
expectationResultFactory: expectationResultFactory,
@@ -2141,6 +2187,40 @@ getJasmineRequireObj().Env = function(j$) {
return spec;
};
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}
* @name Env#setSpecProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
this.setSpecProperty = function(key, value) {
if (!currentRunnable() || currentRunnable() == currentSuite()) {
throw new Error(
"'setSpecProperty' was used when there was no current spec"
);
}
currentRunnable().setSpecProperty(key, value);
};
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}
* @name Env#setSuiteProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
this.setSuiteProperty = function(key, value) {
if (!currentSuite()) {
throw new Error(
"'setSuiteProperty' was used when there was no current suite"
);
}
currentSuite().setSuiteProperty(key, value);
};
this.expect = function(actual) {
if (!currentRunnable()) {
throw new Error(
@@ -2258,7 +2338,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
* @hideconstructor
*/
function JsApiReporter(options) {
var timer = options.timer || j$.noopTimer,
var timer = options.timer || new j$.Timer(),
status = 'loaded';
this.started = false;
@@ -2837,7 +2917,9 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
for (i = 0; i < props.length; i++) {
k = props[i];
if (k !== 'length') {
// Skip length (dealt with above), and anything that collides with
// MatchesUtil e.g. an Array.prototype.contains method added by user code
if (k !== 'length' && !self[k]) {
copyAndDeprecate(self, Array.prototype, k);
}
}
@@ -2868,7 +2950,7 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
});
}
props = Object.getOwnPropertyDescriptors(Array.prototype);
props = Object.getOwnPropertyDescriptors(Array.prototype); // eslint-disable-line compat/compat
a = [];
for (k in props) {
@@ -4151,7 +4233,17 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
handlers.push(listener);
};
this.popListener = function popListener() {
this.popListener = function popListener(listener) {
if (!listener) {
throw new Error('popListener expects a listener');
}
if (listener !== handlers[handlers.length - 1]) {
throw new Error(
'popListener was passed a different listener than the current one'
);
}
handlers.pop();
};
}
@@ -4159,6 +4251,33 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
return GlobalErrors;
};
/* eslint-disable compat/compat */
getJasmineRequireObj().toBePending = function(j$) {
/**
* Expect a promise to be pending, i.e. the promise is neither resolved nor rejected.
* @function
* @async
* @name async-matchers#toBePending
* @since 3.6
* @example
* await expectAsync(aPromise).toBePending();
*/
return function toBePending() {
return {
compare: function(actual) {
if (!j$.isPromiseLike(actual)) {
throw new Error('Expected toBePending to be called on a promise.');
}
var want = {};
return Promise.race([actual, Promise.resolve(want)]).then(
function(got) { return {pass: want === got}; },
function() { return {pass: false}; }
);
}
};
};
};
getJasmineRequireObj().toBeRejected = function(j$) {
/**
* Expect a promise to be rejected.
@@ -4490,12 +4609,7 @@ getJasmineRequireObj().DiffBuilder = function (j$) {
};
function dereferencePath(objectPath, actual, expected, pp) {
var i, asymmetricResult
for (i = 0; i < objectPath.components.length; i++) {
actual = actual[objectPath.components[i]];
expected = expected[objectPath.components[i]];
function handleAsymmetricExpected() {
if (j$.isAsymmetricEqualityTester_(expected) && j$.isFunction_(expected.valuesForDiff_)) {
var asymmetricResult = expected.valuesForDiff_(actual, pp);
expected = asymmetricResult.self;
@@ -4503,6 +4617,15 @@ getJasmineRequireObj().DiffBuilder = function (j$) {
}
}
var i;
handleAsymmetricExpected();
for (i = 0; i < objectPath.components.length; i++) {
actual = actual[objectPath.components[i]];
expected = expected[objectPath.components[i]];
handleAsymmetricExpected();
}
return {actual: actual, expected: expected};
}
@@ -4513,7 +4636,6 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* _Note:_ Do not construct this directly. Jasmine will construct one and
* pass it to matchers and asymmetric equality testers.
* @name MatchersUtil
* @since 2.0.0
* @classdesc Utilities for use in implementing matchers
* @constructor
*/
@@ -4525,6 +4647,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* taking into account the current set of custom value formatters.
* @function
* @name MatchersUtil#pp
* @since 3.6.0
* @param {*} value The value to pretty-print
* @return {string} The pretty-printed value
*/
@@ -4536,6 +4659,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* logic as {@link MatchersUtil#equals}.
* @function
* @name MatchersUtil#contains
* @since 2.0.0
* @param {*} haystack The collection to search
* @param {*} needle The value to search for
* @param [customTesters] An array of custom equality testers. Deprecated.
@@ -4635,6 +4759,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* Determines whether two values are deeply equal to each other.
* @function
* @name MatchersUtil#equals
* @since 2.0.0
* @param {*} a The first value to compare
* @param {*} b The second value to compare
* @param [customTesters] An array of custom equality testers. Deprecated.
@@ -5208,6 +5333,7 @@ getJasmineRequireObj().ObjectPath = function(j$) {
getJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) {
var availableMatchers = [
'toBePending',
'toBeResolved',
'toBeRejected',
'toBeResolvedTo',
@@ -5837,6 +5963,76 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
return toHaveBeenCalledBefore;
};
getJasmineRequireObj().toHaveBeenCalledOnceWith = function (j$) {
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledOnceWith>', 'expect(<spyObj>).toHaveBeenCalledOnceWith(...arguments)');
/**
* {@link expect} the actual (a {@link Spy}) to have been called exactly once, and exactly with the particular arguments.
* @function
* @name matchers#toHaveBeenCalledOnceWith
* @since 3.6.0
* @param {...Object} - The arguments to look for
* @example
* expect(mySpy).toHaveBeenCalledOnceWith('foo', 'bar', 2);
*/
function toHaveBeenCalledOnceWith(util) {
return {
compare: function () {
var args = Array.prototype.slice.call(arguments, 0),
actual = args[0],
expectedArgs = args.slice(1);
if (!j$.isSpy(actual)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + util.pp(actual) + '.'));
}
var prettyPrintedCalls = actual.calls.allArgs().map(function (argsForCall) {
return ' ' + util.pp(argsForCall);
});
if (actual.calls.count() === 1 && util.contains(actual.calls.allArgs(), expectedArgs)) {
return {
pass: true,
message: 'Expected spy ' + actual.and.identity + ' to have been called 0 times, multiple times, or once, but with arguments different from:\n'
+ ' ' + util.pp(expectedArgs) + '\n'
+ 'But the actual call was:\n'
+ prettyPrintedCalls.join(',\n') + '.\n\n'
};
}
function getDiffs() {
return actual.calls.allArgs().map(function (argsForCall, callIx) {
var diffBuilder = new j$.DiffBuilder();
util.equals(argsForCall, expectedArgs, diffBuilder);
return diffBuilder.getMessage();
});
}
function butString() {
switch (actual.calls.count()) {
case 0:
return 'But it was never called.\n\n';
case 1:
return 'But the actual call was:\n' + prettyPrintedCalls.join(',\n') + '.\n' + getDiffs().join('\n') + '\n\n';
default:
return 'But the actual calls were:\n' + prettyPrintedCalls.join(',\n') + '.\n\n';
}
}
return {
pass: false,
message: 'Expected spy ' + actual.and.identity + ' to have been called only once, and with given args:\n'
+ ' ' + util.pp(expectedArgs) + '\n'
+ butString()
};
}
};
}
return toHaveBeenCalledOnceWith;
};
getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledTimes>', 'expect(<spyObj>).toHaveBeenCalledTimes(<Number>)');
@@ -5984,6 +6180,49 @@ getJasmineRequireObj().toHaveClass = function(j$) {
return toHaveClass;
};
getJasmineRequireObj().toHaveSize = function(j$) {
/**
* {@link expect} the actual size to be equal to the expected, using array-like length or object keys size.
* @function
* @name matchers#toHaveSize
* @since 3.6.0
* @param {Object} expected - Expected size
* @example
* array = [1,2];
* expect(array).toHaveSize(2);
*/
function toHaveSize() {
return {
compare: function(actual, expected) {
var result = {
pass: false
};
if (j$.isA_('WeakSet', actual) || j$.isWeakMap(actual) || j$.isDataView(actual)) {
throw new Error('Cannot get size of ' + actual + '.');
}
if (j$.isSet(actual) || j$.isMap(actual)) {
result.pass = actual.size === expected;
} else if (isLength(actual.length)) {
result.pass = actual.length === expected;
} else {
result.pass = Object.keys(actual).length === expected;
}
return result;
}
};
}
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; // eslint-disable-line compat/compat
function isLength(value) {
return (typeof value == 'number') && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
return toHaveSize;
};
getJasmineRequireObj().toMatch = function(j$) {
var getErrorMsg = j$.formatErrorMsg('<toMatch>', 'expect(<expectation>).toMatch(<string> || <regexp>)');
@@ -6827,6 +7066,8 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
};
getJasmineRequireObj().QueueRunner = function(j$) {
var nextid = 1;
function StopExecutionError() {}
StopExecutionError.prototype = new Error();
j$.StopExecutionError = StopExecutionError;
@@ -6846,6 +7087,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
function emptyFn() {}
function QueueRunner(attrs) {
this.id_ = nextid++;
var queueableFns = attrs.queueableFns || [];
this.queueableFns = queueableFns.concat(attrs.cleanupFns || []);
this.firstCleanupIx = queueableFns.length;
@@ -6948,7 +7190,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}),
errored = false,
queueableFn = self.queueableFns[iterativeIndex],
timeoutId;
timeoutId,
maybeThenable;
next.fail = function nextFail() {
self.fail.apply(null, arguments);
@@ -6976,7 +7219,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
if (queueableFn.fn.length === 0) {
var maybeThenable = queueableFn.fn.call(self.userContext);
maybeThenable = queueableFn.fn.call(self.userContext);
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
maybeThenable.then(next, onPromiseRejection);
@@ -6984,7 +7227,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
return { completedSynchronously: false };
}
} else {
queueableFn.fn.call(self.userContext, next);
maybeThenable = queueableFn.fn.call(self.userContext, next);
this.diagnoseConflictingAsync_(queueableFn.fn, maybeThenable);
completedSynchronously = false;
return { completedSynchronously: false };
}
@@ -7037,6 +7281,29 @@ getJasmineRequireObj().QueueRunner = function(j$) {
});
};
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
if (retval && j$.isFunction_(retval.then)) {
// Issue a warning that matches the user's code
if (j$.isAsyncFunction_(fn)) {
this.deprecated(
'An asynchronous before/it/after ' +
'function was defined with the async keyword but also took a ' +
'done callback. This is not supported and will stop working in' +
' the future. Either remove the done callback (recommended) or ' +
'remove the async keyword.'
);
} else {
this.deprecated(
'An asynchronous before/it/after ' +
'function took a done callback but also returned a promise. ' +
'This is not supported and will stop working in the future. ' +
'Either remove the done callback (recommended) or change the ' +
'function to not return a promise.'
);
}
}
};
return QueueRunner;
};
@@ -7285,6 +7552,30 @@ getJasmineRequireObj().interface = function(jasmine, env) {
return env.afterAll.apply(env, arguments);
},
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}
* @name setSpecProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
setSpecProperty: function(key, value) {
return env.setSpecProperty(key, value);
},
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}
* @name setSuiteProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
setSuiteProperty: function(key, value) {
return env.setSuiteProperty(key, value);
},
/**
* Create an expectation for a spec.
* @name expect
@@ -7444,7 +7735,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 3.6.0
* @function
* @param {Function} formatter - A function which takes a value to format and returns a string if it knows how to format it, and `undefined` otherwise.
* @see custom_object_formatter
* @see custom_object_formatters
*/
jasmine.addCustomObjectFormatter = function(formatter) {
return env.addCustomObjectFormatter(formatter);
@@ -8182,10 +8473,10 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
* @name SpyStrategy#throwError
* @since 2.0.0
* @function
* @param {Error|String} something Thing to throw
* @param {Error|Object|String} something Thing to throw
*/
SpyStrategy.prototype.throwError = function(something) {
var error = something instanceof Error ? something : new Error(something);
var error = j$.isString_(something) ? new Error(something) : something;
this.plan = function() {
throw error;
};
@@ -8200,7 +8491,13 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
* @param {Function} fn The function to invoke with the passed parameters.
*/
SpyStrategy.prototype.callFake = function(fn) {
if (!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
if (
!(
j$.isFunction_(fn) ||
j$.isAsyncFunction_(fn) ||
j$.isGeneratorFunction_(fn)
)
) {
throw new Error(
'Argument passed to callFake should be a function, got ' + fn
);
@@ -8368,7 +8665,7 @@ getJasmineRequireObj().Suite = function(j$) {
this.beforeAllFns = [];
this.afterAllFns = [];
this.timer = attrs.timer || j$.noopTimer;
this.timer = attrs.timer || new j$.Timer();
this.children = [];
@@ -8381,6 +8678,7 @@ getJasmineRequireObj().Suite = function(j$) {
* @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.
* @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty}
*/
this.result = {
id: this.id,
@@ -8388,10 +8686,16 @@ getJasmineRequireObj().Suite = function(j$) {
fullName: this.getFullName(),
failedExpectations: [],
deprecationWarnings: [],
duration: null
duration: null,
properties: null
};
}
Suite.prototype.setSuiteProperty = function(key, value) {
this.result.properties = this.result.properties || {};
this.result.properties[key] = value;
};
Suite.prototype.expect = function(actual) {
return this.expectationFactory(actual, this);
};
@@ -8571,15 +8875,6 @@ getJasmineRequireObj().Timer = function() {
return Timer;
};
getJasmineRequireObj().noopTimer = function() {
return {
start: function() {},
elapsed: function() {
return 0;
}
};
};
getJasmineRequireObj().TreeProcessor = function() {
function TreeProcessor(attrs) {
var tree = attrs.tree,
@@ -8855,5 +9150,5 @@ getJasmineRequireObj().UserContext = function(j$) {
};
getJasmineRequireObj().version = function() {
return '3.5.0';
return '3.6.0';
};

View File

@@ -4,6 +4,6 @@
#
module Jasmine
module Core
VERSION = "3.5.0"
VERSION = "3.6.0"
end
end

View File

@@ -1,7 +1,7 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "3.5.0",
"version": "3.6.0",
"repository": {
"type": "git",
"url": "https://github.com/jasmine/jasmine.git"
@@ -13,7 +13,7 @@
"bdd"
],
"scripts": {
"posttest": "eslint src/**/*.js spec/**/*.js && prettier --check src/**/*.js spec/**/*.js",
"posttest": "eslint \"src/**/*.js\" \"spec/**/*.js\" && prettier --check src/**/*.js spec/**/*.js",
"test": "grunt --stack execSpecsInNode",
"cleanup": "prettier --write src/**/*.js spec/**/*.js",
"build": "grunt buildDistribution",
@@ -28,7 +28,8 @@
"devDependencies": {
"acorn": "^6.0.0",
"ejs": "^2.5.5",
"eslint": "^5.16.0",
"eslint": "^6.8.0",
"eslint-plugin-compat": "^3.8.0",
"express": "^4.16.4",
"fast-check": "^1.21.0",
"fast-glob": "^2.2.6",
@@ -39,7 +40,7 @@
"grunt-css-url-embed": "^1.11.1",
"grunt-sass": "^3.0.2",
"jasmine": "^3.4.0",
"jasmine-browser-runner": "0.3.0",
"jasmine-browser-runner": "^0.4.0",
"jsdom": "^15.0.0",
"load-grunt-tasks": "^4.0.0",
"node-sass": "^4.11.0",
@@ -52,6 +53,12 @@
"singleQuote": true
},
"eslintConfig": {
"extends": [
"plugin:compat/recommended"
],
"parserOptions": {
"ecmaVersion": 5
},
"rules": {
"quotes": [
"error",
@@ -67,10 +74,6 @@
}
],
"block-spacing": "error",
"comma-dangle": [
"error",
"never"
],
"func-call-spacing": [
"error",
"never"
@@ -85,5 +88,13 @@
],
"space-before-blocks": "error"
}
}
},
"browserslist": [
"Safari >= 8",
"last 2 Chrome versions",
"last 2 Firefox versions",
"Firefox 68",
"last 2 Edge versions",
"IE >= 10"
]
}

146
release_notes/3.6.0.md Normal file
View File

@@ -0,0 +1,146 @@
# Jasmine Core 3.6 Release Notes
## Summary
This is a maintenance release of Jasmine with a number of new features and fixes.
## Highlights
* Added support for custom object formatters
* Allows customizing how an object is stringified in matcher failure messages
* [Tutorial](https://jasmine.github.io/tutorials/custom_object_formatter)
* [API reference](https://jasmine.github.io/api/3.6/jasmine.html#.addCustomObjectFormatter)
* Don't require matchers and asymmetric equality testers to pass custom object formatters back to Jasmine
- Supports custom object formatters.
- Makes it easier to write high quality matchers and asymmetric equality testers.
- The old API will still work until 4.0.
* Properly import jasmineRequire object before using
- Improves compatibility with Webpack
- Merges [#1766](https://github.com/jasmine/jasmine/pull/1766) from @amilligan
* Added a toHaveBeenCalledOnceWith matcher
- Merges [#1801](https://github.com/jasmine/jasmine/pull/1801) from @Maximaximum
- Fixes [#1717](https://github.com/jasmine/jasmine/issues/1717)
* Added a toHaveSize matcher
- Merges [#1796](https://github.com/jasmine/jasmine/pull/1796) from @wokier
* Added a toBePending async matcher
- Merges [#1808](https://github.com/jasmine/jasmine/pull/1808) from @DCtheTall
- Fixes [#1803](https://github.com/jasmine/jasmine/issues/1803)
* Added support for user-defined spec/suite properties
- Allows specs/suites to pass data to custom reporters
- Merges [#1763](https://github.com/jasmine/jasmine/pull/1763) from @johnjbarton
* Route unhandled promise rejections to onerror
- Merges [#1778](https://github.com/jasmine/jasmine/pull/1778) from @johnjbarton
- Fixes [#1777](https://github.com/jasmine/jasmine/issues/1777)
## Internal notes
* Use a version of eslint that works on Node 8
* Check for syntax and standard library objects that don't work in IE
* Run eslint against all files
* Add Additional Test for equals Matcher
- Merges [#1829](https://github.com/jasmine/jasmine/pull/1829) from @tobiasschweizer
- Fixes [#1821](https://github.com/jasmine/jasmine/issues/1821)
* Depend on head of jasmine-browser to fix IE failures in CI
* Fixed test failure in Firefox 74
* Added test for resolveTo/rejectWith with empty parameters
- Merges [#1802](https://github.com/jasmine/jasmine/pull/1802) from @chivesrs
* Removed unnecessary uses of new in tests
* Realigned the browser testing matrix to match current reality
- Use Windows instead of Linux so we can get current browsers from Sauce.
- Test against the version of Firefox that corresponds to ESR as well as
latest.
- Test the latest Edge rather than a specific older version.
- Test Safari 8 and 13 instead of 8, 9 and 10. What works in those versions
is likely to work in the ones in between.
* Don't leak global error handlers between Jasmine's own tests
* Added basic property tests for matchersUtil.equals
* Added integration tests for existing matcher interfaces
* Added integration tests for asymmetric equality testers
* Test IE before other browsers on Travis
## Other Changes
* Show diffs involving root-level asymmetric equality testers
- Fixes [#1831](https://github.com/jasmine/jasmine/issues/1831)
* Fixed references to master in docs
* Allow spy throwError to throw an Object
- Merges [#1822](https://github.com/jasmine/jasmine/pull/1822) from @terencehonles
* Added missing periods to README
- Merges [#1828](https://github.com/jasmine/jasmine/pull/1828) from @dirkpuge
* Expose setSpec/SuiteProperty on interface
- Merges [#1820](https://github.com/jasmine/jasmine/pull/1820) from @johnjbarton
* Prevent undesired reloads when karma-jasmine-html-reporter is used
- Merges [#1807](https://github.com/jasmine/jasmine/pull/1807) from @parloti
- Fixes [#1775](https://github.com/jasmine/jasmine/issues/1775)
* Correctly report spec and suite duration
- Fixes [#1676](https://github.com/jasmine/jasmine/issues/1676).
* Added jsdocs for MatchersUtil
* Allow the .callThrough spy strategy to call constructor functions without errors
- Merges [#1782](https://github.com/jasmine/jasmine/pull/1782) from @enelson
- Fixes [#1760](https://github.com/jasmine/jasmine/issues/1760)
* Inject a per-runable pretty printer into MatchersUtil
- Supports custom object formatters
* Include stack traces in unhandled promise rejection messages
* Describe the naming for the function it
- Merges [#1772](https://github.com/jasmine/jasmine/pull/1772) from @johnlinp
* Correctly extract error messages from stack traces that don't start with `Error`
- Merges [#1776](https://github.com/jasmine/jasmine/pull/1776) from @vhermannitk
- Fixes [#1771](https://github.com/jasmine/jasmine/issues/1771)
* Fixed objectContaining to not match when the expected is the empty object and the actual is a non-object
* Fixed toEqual(0, Number.MIN_VALUE) to fail instead of passing
- Merges [#1764](https://github.com/jasmine/jasmine/pull/1764) from @dubzzz
* Fixed comparison between ObjectContaining and non-objects on IE
* Provide better diffs for object graphs that include `objectContaining`
* Indent multiline failure messages in the output of `withContext`
* This makes it easier to see where each failure message begins and ends.
* Report async expectations that complete after the runable completes
- See [#1752](https://github.com/jasmine/jasmine/issues/1752).
* Treat NodeJS assertion failures as expectation failures
- Merges [#1678](https://github.com/jasmine/jasmine/pull/1678) from @apla
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

17
spec/.eslintrc.js Normal file
View File

@@ -0,0 +1,17 @@
module.exports = {
"ignorePatterns": [
"support/ci.js",
"support/jasmine-browser.js"
],
rules: {
// Relax rules for now to allow for the quirks of the test suite
// TODO: We should probably remove these & fix the resulting errors
"quotes": "off",
"semi": "off",
"key-spacing": "off",
"space-before-blocks": "off",
"no-unused-vars": "off",
"no-trailing-spaces": "off",
"block-spacing": "off",
}
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('AsyncExpectation', function() {
beforeEach(function() {
jasmineUnderTest.Expectation.addAsyncCoreMatchers(

View File

@@ -401,20 +401,16 @@ describe('Env', function() {
expectationFactory('actual', specInstance);
});
env.addReporter({
jasmineDone: function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
}
env.execute(null, function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
});
env.execute();
});
it('creates an asyncExpectationFactory that uses the current custom equality testers and object formatters', function(done) {
@@ -438,19 +434,15 @@ describe('Env', function() {
asyncExpectationFactory('actual', specInstance);
});
env.addReporter({
jasmineDone: function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
}
env.execute(null, function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
});
env.execute();
});
});

View File

@@ -29,8 +29,7 @@ describe('Exceptions:', function() {
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
env.execute(null, expectations);
});
it('should handle exceptions thrown directly in top-level describe blocks and continue', function(done) {
@@ -53,7 +52,6 @@ describe('Exceptions:', function() {
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
env.execute(null, expectations);
});
});

View File

@@ -58,7 +58,7 @@ describe('GlobalErrors', function() {
errors.pushListener(handler1);
errors.pushListener(handler2);
errors.popListener();
errors.popListener(handler2);
fakeGlobal.onerror('foo');
@@ -66,6 +66,23 @@ describe('GlobalErrors', function() {
expect(handler2).not.toHaveBeenCalled();
});
it('throws when no listener is passed to #popListener', function() {
var errors = new jasmineUnderTest.GlobalErrors({});
expect(function() {
errors.popListener();
}).toThrowError('popListener expects a listener');
});
it('throws when the argument to #popListener is not the current listener', function() {
var errors = new jasmineUnderTest.GlobalErrors({});
errors.pushListener(function() {});
expect(function() {
errors.popListener(function() {});
}).toThrowError(
'popListener was passed a different listener than the current one'
);
});
it('uninstalls itself, putting back a previous callback', function() {
var originalCallback = jasmine.createSpy('error'),
fakeGlobal = { onerror: originalCallback },

View File

@@ -19,7 +19,7 @@ describe('PrettyPrinter', function() {
describe('stringify sets', function() {
it('should stringify sets properly', function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set();
var set = new Set(); // eslint-disable-line compat/compat
set.add(1);
set.add(2);
var pp = jasmineUnderTest.makePrettyPrinter();
@@ -32,7 +32,7 @@ describe('PrettyPrinter', function() {
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
var set = new Set();
var set = new Set(); // eslint-disable-line compat/compat
set.add('a');
set.add('b');
set.add('c');
@@ -47,7 +47,7 @@ describe('PrettyPrinter', function() {
describe('stringify maps', function() {
it('should stringify maps properly', function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map();
var map = new Map(); // eslint-disable-line compat/compat
map.set(1, 2);
var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(map)).toEqual('Map( [ 1, 2 ] )');
@@ -59,7 +59,7 @@ describe('PrettyPrinter', function() {
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
var map = new Map();
var map = new Map(); // eslint-disable-line compat/compat
map.set('a', 1);
map.set('b', 2);
map.set('c', 3);

View File

@@ -512,6 +512,50 @@ describe('QueueRunner', function() {
expect(onExceptionCallback).toHaveBeenCalledWith('foo');
expect(queueableFn2.fn).toHaveBeenCalled();
});
it('issues a deprecation if the function also takes a parameter', function() {
var queueableFn = {
fn: function(done) {
return new StubPromise();
}
},
deprecated = jasmine.createSpy('deprecated'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
deprecated: deprecated
}),
env = jasmineUnderTest.getEnv();
queueRunner.execute();
expect(deprecated).toHaveBeenCalledWith(
'An asynchronous ' +
'before/it/after function took a done callback but also returned a ' +
'promise. This is not supported and will stop working in the future. ' +
'Either remove the done callback (recommended) or change the function ' +
'to not return a promise.'
);
});
it('issues a more specific deprecation if the function is `async`', function() {
jasmine.getEnv().requireAsyncAwait();
eval('var fn = async function(done){};');
var deprecated = jasmine.createSpy('deprecated'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [{ fn: fn }],
deprecated: deprecated
});
queueRunner.execute();
expect(deprecated).toHaveBeenCalledWith(
'An asynchronous ' +
'before/it/after function was defined with the async keyword but ' +
'also took a done callback. This is not supported and will stop ' +
'working in the future. Either remove the done callback ' +
'(recommended) or remove the async keyword.'
);
});
});
it('passes the error instance to exception handlers in HTML browsers', function() {

View File

@@ -227,7 +227,8 @@ describe('Spec', function() {
passedExpectations: [],
deprecationWarnings: [],
pendingReason: '',
duration: null
duration: jasmine.any(Number),
properties: null
},
'things'
);
@@ -273,8 +274,34 @@ describe('Spec', function() {
});
it('should report the duration of the test', function() {
var timer = jasmine.createSpyObj('timer', { start: null, elapsed: 77000 }),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: jasmine.createSpy('spec body') },
catchExceptions: function() {
return false;
},
resultCallback: function(result) {
duration = result.duration;
},
queueRunnerFactory: function(config) {
config.queueableFns.forEach(function(qf) {
qf.fn();
});
config.cleanupFns.forEach(function(qf) {
qf.fn();
});
config.onComplete();
},
timer: timer
}),
duration = undefined;
spec.execute(function() {});
expect(duration).toBe(77000);
});
it('should report properties set during the test', function() {
var done = jasmine.createSpy('done callback'),
timer = jasmine.createSpyObj('timer', { start: null, elapsed: 77000 }),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: jasmine.createSpy('spec body') },
catchExceptions: function() {
@@ -283,11 +310,11 @@ describe('Spec', function() {
resultCallback: function() {},
queueRunnerFactory: function(attrs) {
attrs.onComplete();
},
timer: timer
}
});
spec.setSpecProperty('a', 4);
spec.execute(done);
expect(spec.result.duration).toBe(77000);
expect(spec.result.properties).toEqual({ a: 4 });
});
it('#status returns passing by default', function() {

View File

@@ -70,7 +70,7 @@ describe('SpyStrategy', function() {
expect(originalFn).not.toHaveBeenCalled();
});
it('allows a non-Error to be thrown, wrapping it into an exception when executed', function() {
it('allows a string to be thrown, wrapping it into an exception when executed', function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: originalFn });
@@ -82,6 +82,18 @@ describe('SpyStrategy', function() {
expect(originalFn).not.toHaveBeenCalled();
});
it('allows a non-Error to be thrown when executed', function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: originalFn });
spyStrategy.throwError({ code: 'ESRCH' });
expect(function() {
spyStrategy.exec();
}).toThrow({ code: 'ESRCH' });
expect(originalFn).not.toHaveBeenCalled();
});
it('allows a fake function to be called instead', function() {
var originalFn = jasmine.createSpy('original'),
fakeFn = jasmine.createSpy('fake').and.returnValue(67),
@@ -140,6 +152,28 @@ describe('SpyStrategy', function() {
.catch(done.fail);
});
it('allows an empty resolved promise to be returned', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
});
spyStrategy.resolveTo();
spyStrategy
.exec()
.then(function(returnValue) {
expect(returnValue).toBe();
done();
})
.catch(done.fail);
});
it('fails if promises are not available', function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: originalFn });
@@ -176,6 +210,29 @@ describe('SpyStrategy', function() {
.catch(done.fail);
});
it('allows an empty rejected promise to be returned', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
});
spyStrategy.rejectWith();
spyStrategy
.exec()
.then(done.fail)
.catch(function(error) {
expect(error).toBe();
done();
})
.catch(done.fail);
});
it('allows a non-Error to be rejected', function(done) {
jasmine.getEnv().requirePromises();
@@ -277,6 +334,17 @@ describe('SpyStrategy', function() {
}).toThrowError(/^Argument passed to callFake should be a function, got/);
});
it('allows generator functions to be passed to callFake strategy', function() {
jasmine.getEnv().requireGeneratorFunctions();
var generator = jasmine.getEnv().makeGeneratorFunction('yield "ok";'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: function() {} });
spyStrategy.callFake(generator);
expect(spyStrategy.exec().next().value).toEqual('ok');
});
it('allows a return to plan stubbing after another strategy', function() {
var originalFn = jasmine.createSpy('original'),
fakeFn = jasmine.createSpy('fake').and.returnValue(67),

View File

@@ -40,7 +40,7 @@ describe('jasmineUnderTest.util', function() {
beforeEach(function() {
jasmine.getEnv().requirePromises();
mockNativePromise = new Promise(function(res, rej) {});
mockNativePromise = new Promise(function(res, rej) {}); // eslint-disable-line compat/compat
mockPromiseLikeObject = new mockPromiseLike();
});

View File

@@ -63,7 +63,6 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
it('provides and deprecates properties of Array.prototype', function() {
var keys = [
'concat',
'constructor',
'every',
'filter',
'forEach',
@@ -82,8 +81,6 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
'some',
'sort',
'splice',
'toLocaleString',
'toString',
'unshift'
],
optionalKeys = [
@@ -142,4 +139,46 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
expect(deprecated).not.toHaveBeenCalled();
});
describe('When Array.prototype additions collide with MatchersUtil methods', function() {
function keys() {
return [
'contains',
'buildFailureMessage',
'asymmetricDiff_',
'asymmetricMatch_',
'equals',
'eq_'
];
}
beforeEach(function() {
keys().forEach(function(k) {
expect(Array.prototype[k])
.withContext('Array.prototype already had ' + k)
.toBeUndefined();
Array.prototype[k] = function() {};
});
});
afterEach(function() {
keys().forEach(function(k) {
delete Array.prototype[k];
});
});
it('uses the MatchersUtil methods', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({}),
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim(
matchersUtil,
[]
);
keys().forEach(function(k) {
expect(shim[k])
.withContext(k + ' was overwritten')
.toBe(jasmineUnderTest.MatchersUtil.prototype[k]);
});
});
});
});

View File

@@ -34,7 +34,7 @@ describe("Any", function() {
var any = new jasmineUnderTest.Any(Map);
expect(any.asymmetricMatch(new Map())).toBe(true);
expect(any.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
});
it("matches a Set", function() {
@@ -42,23 +42,23 @@ describe("Any", function() {
var any = new jasmineUnderTest.Any(Set);
expect(any.asymmetricMatch(new Set())).toBe(true);
expect(any.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
});
it("matches a TypedArray", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
var any = new jasmineUnderTest.Any(Uint32Array);
var any = new jasmineUnderTest.Any(Uint32Array); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(new Uint32Array([]))).toBe(true);
expect(any.asymmetricMatch(new Uint32Array([]))).toBe(true); // eslint-disable-line compat/compat
});
it("matches a Symbol", function() {
jasmine.getEnv().requireFunctioningSymbols();
var any = new jasmineUnderTest.Any(Symbol);
var any = new jasmineUnderTest.Any(Symbol); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(Symbol())).toBe(true);
expect(any.asymmetricMatch(Symbol())).toBe(true); // eslint-disable-line compat/compat
});
it("matches another constructed object", function() {

View File

@@ -28,7 +28,7 @@ describe("Anything", function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Map())).toBe(true);
expect(anything.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
});
it("matches a Set", function() {
@@ -36,7 +36,7 @@ describe("Anything", function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Set())).toBe(true);
expect(anything.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
});
it("matches a TypedArray", function() {
@@ -44,7 +44,7 @@ describe("Anything", function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true);
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true); // eslint-disable-line compat/compat
});
it("matches a Symbol", function() {
@@ -52,7 +52,7 @@ describe("Anything", function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(Symbol())).toBe(true);
expect(anything.asymmetricMatch(Symbol())).toBe(true); // eslint-disable-line compat/compat
});
it("doesn't match undefined", function() {

View File

@@ -24,20 +24,20 @@ describe("Empty", function () {
it("matches an empty map", function () {
jasmine.getEnv().requireFunctioningMaps();
var empty = new jasmineUnderTest.Empty();
var fullMap = new Map();
var fullMap = new Map(); // eslint-disable-line compat/compat
fullMap.set('thing', 2);
expect(empty.asymmetricMatch(new Map())).toBe(true);
expect(empty.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(fullMap)).toBe(false);
});
it("matches an empty set", function () {
jasmine.getEnv().requireFunctioningSets();
var empty = new jasmineUnderTest.Empty();
var fullSet = new Set();
var fullSet = new Set(); // eslint-disable-line compat/compat
fullSet.add(3);
expect(empty.asymmetricMatch(new Set())).toBe(true);
expect(empty.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(fullSet)).toBe(false);
});
@@ -45,7 +45,7 @@ describe("Empty", function () {
jasmine.getEnv().requireFunctioningTypedArrays();
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch(new Int16Array())).toBe(true);
expect(empty.asymmetricMatch(new Int16Array([1,2]))).toBe(false);
expect(empty.asymmetricMatch(new Int16Array())).toBe(true); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(new Int16Array([1,2]))).toBe(false); // eslint-disable-line compat/compat
});
});

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('MapContaining', function() {
function MapI(iterable) { // for IE11
var map = new Map();

View File

@@ -24,9 +24,9 @@ describe("NotEmpty", function () {
it("matches a non empty map", function () {
jasmine.getEnv().requireFunctioningMaps();
var notEmpty = new jasmineUnderTest.NotEmpty();
var fullMap = new Map();
var fullMap = new Map(); // eslint-disable-line compat/compat
fullMap.set('one', 1);
var emptyMap = new Map();
var emptyMap = new Map(); // eslint-disable-line compat/compat
expect(notEmpty.asymmetricMatch(fullMap)).toBe(true);
expect(notEmpty.asymmetricMatch(emptyMap)).toBe(false);
@@ -35,9 +35,9 @@ describe("NotEmpty", function () {
it("matches a non empty set", function () {
jasmine.getEnv().requireFunctioningSets();
var notEmpty = new jasmineUnderTest.NotEmpty();
var filledSet = new Set();
var filledSet = new Set(); // eslint-disable-line compat/compat
filledSet.add(1);
var emptySet = new Set();
var emptySet = new Set(); // eslint-disable-line compat/compat
expect(notEmpty.asymmetricMatch(filledSet)).toBe(true);
expect(notEmpty.asymmetricMatch(emptySet)).toBe(false);
@@ -47,7 +47,7 @@ describe("NotEmpty", function () {
jasmine.getEnv().requireFunctioningTypedArrays();
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch(new Int16Array([1,2,3]))).toBe(true);
expect(notEmpty.asymmetricMatch(new Int16Array())).toBe(false);
expect(notEmpty.asymmetricMatch(new Int16Array([1,2,3]))).toBe(true); // eslint-disable-line compat/compat
expect(notEmpty.asymmetricMatch(new Int16Array())).toBe(false); // eslint-disable-line compat/compat
});
});

View File

@@ -149,7 +149,7 @@ describe("ObjectContaining", function() {
});
});
it("includes keys that are present in only sample", function() {
it("includes keys that are present only in sample", function() {
var sample = {a: 1, b: 2},
other = {a: 3},
containing = new jasmineUnderTest.ObjectContaining(sample),

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('SetContaining', function() {
function SetI(iterable) { // for IE11
var set = new Set();

View File

@@ -51,4 +51,15 @@ describe('base helpers', function() {
expect(jasmineUnderTest.isAsymmetricEqualityTester_(obj)).toBe(true);
});
});
describe('isSet', function() {
it('returns true when the object is a Set', function() {
jasmine.getEnv().requireFunctioningSets();
expect(jasmineUnderTest.isSet(new Set())).toBe(true); // eslint-disable-line compat/compat
});
it('returns false when the object is not a Set', function() {
expect(jasmineUnderTest.isSet({})).toBe(false);
});
});
});

View File

@@ -19,8 +19,8 @@ describe('Asymmetric equality testers (Integration)', function () {
.toBeUndefined();
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({specDone: specExpectations});
env.execute(null, done);
});
}
@@ -43,8 +43,8 @@ describe('Asymmetric equality testers (Integration)', function () {
.not.toEqual('');
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({specDone: specExpectations});
env.execute(null, done);
});
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('Custom Async Matchers (Integration)', function() {
var env;
@@ -27,8 +28,8 @@ describe('Custom Async Matchers (Integration)', function() {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it('uses the negative compare function for a negative comparison, if provided', function(done) {
@@ -51,8 +52,8 @@ describe('Custom Async Matchers (Integration)', function() {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it('generates messages with the same rules as built in matchers absent a custom message', function(done) {
@@ -76,8 +77,8 @@ describe('Custom Async Matchers (Integration)', function() {
expect(result.failedExpectations[0].message).toEqual("Expected 'a' to be real.");
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("passes the jasmine utility to the matcher factory", function (done) {
@@ -106,8 +107,8 @@ describe('Custom Async Matchers (Integration)', function() {
);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
// TODO: remove this in the next major release.
@@ -177,8 +178,8 @@ describe('Custom Async Matchers (Integration)', function() {
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it('logs a deprecation once per matcher if the matcher factory takes two arguments', function (done) {

View File

@@ -37,9 +37,9 @@ describe("Custom Matchers (Integration)", function () {
expect(firstSpecResult.failedExpectations[0].message).toEqual("matcherForSpec: actual: zzz; expected: yyy");
done();
};
env.addReporter({ specDone:specDoneSpy, jasmineDone: expectations});
env.addReporter({ specDone:specDoneSpy });
env.execute();
env.execute(null, expectations);
});
it("passes the spec if the custom matcher passes", function(done) {
@@ -57,8 +57,8 @@ describe("Custom Matchers (Integration)", function () {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers", function(done) {
@@ -81,8 +81,8 @@ describe("Custom Matchers (Integration)", function () {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("supports asymmetric equality testers that take a list of custom equality testers", function(done) {
@@ -112,8 +112,8 @@ describe("Custom Matchers (Integration)", function () {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("displays an appropriate failure message if a custom equality matcher fails", function(done) {
@@ -139,8 +139,8 @@ describe("Custom Matchers (Integration)", function () {
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("uses the negative compare function for a negative comparison, if provided", function(done) {
@@ -161,8 +161,8 @@ describe("Custom Matchers (Integration)", function () {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("generates messages with the same rules as built in matchers absent a custom message", function(done) {
@@ -184,8 +184,8 @@ describe("Custom Matchers (Integration)", function () {
expect(result.failedExpectations[0].message).toEqual("Expected 'a' to be real.");
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("passes the expected and actual arguments to the comparison function", function(done) {
@@ -209,8 +209,8 @@ describe("Custom Matchers (Integration)", function () {
expect(argumentSpy).toHaveBeenCalledWith(true, "arg1", "arg2");
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("passes the jasmine utility to the matcher factory", function (done) {
@@ -237,8 +237,8 @@ describe("Custom Matchers (Integration)", function () {
);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
// TODO: remove this in the next major release.
@@ -306,8 +306,8 @@ describe("Custom Matchers (Integration)", function () {
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({specDone: specExpectations});
env.execute(null, done);
});
it('logs a deprecation once per matcher if the matcher factory takes two arguments', function(done) {

View File

@@ -25,9 +25,9 @@ describe("Custom object formatters", function() {
expect(specResults[1].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.addReporter({ specDone:specDone });
env.execute();
env.execute(null, expectations);
});
it("scopes custom object formatters to a suite", function(done) {
@@ -54,9 +54,9 @@ describe("Custom object formatters", function() {
expect(specResults[1].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.addReporter({ specDone:specDone });
env.execute();
env.execute(null, expectations);
});
it("throws an exception if you try to add a custom object formatter outside a runable", function() {

View File

@@ -15,6 +15,7 @@ describe('Custom Spy Strategies (Integration)', function() {
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
var jasmineDone = jasmine.createSpy('jasmineDone');
env.describe('suite defining a custom spy strategy', function() {
env.beforeEach(function() {
@@ -33,13 +34,14 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('allows adding more strategies local to a spec', function(done) {
@@ -47,6 +49,7 @@ describe('Custom Spy Strategies (Integration)', function() {
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
var jasmineDone = jasmine.createSpy('jasmineDone');
env.it('spec defining a custom spy strategy', function() {
env.addSpyStrategy('frobnicate', strategy);
@@ -60,13 +63,14 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('allows using custom strategies on a per-argument basis', function(done) {
@@ -74,6 +78,7 @@ describe('Custom Spy Strategies (Integration)', function() {
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
var jasmineDone = jasmine.createSpy('jasmineDone');
env.it('spec defining a custom spy strategy', function() {
env.addSpyStrategy('frobnicate', strategy);
@@ -91,13 +96,14 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('allows multiple custom strategies to be used', function(done) {
@@ -105,7 +111,9 @@ describe('Custom Spy Strategies (Integration)', function() {
strategy1 = jasmine.createSpy('strat 1').and.returnValue(plan1),
plan2 = jasmine.createSpy('plan 2').and.returnValue(24),
strategy2 = jasmine.createSpy('strat 2').and.returnValue(plan2),
specDone = jasmine.createSpy('specDone');
specDone = jasmine.createSpy('specDone'),
jasmineDone = jasmine.createSpy('jasmineDone');
env.beforeEach(function() {
env.addSpyStrategy('frobnicate', strategy1);
@@ -130,13 +138,14 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(plan2).toHaveBeenCalled();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
expect(specDone.calls.count()).toBe(2);
done();
}
env.addReporter({ jasmineDone: jasmineDone, specDone: specDone });
env.execute();
env.execute(null, expectations);
});
});

View File

@@ -29,13 +29,15 @@ describe('Default Spy Strategy (Integration)', function() {
expect(spy()).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
var jasmineDone = jasmine.createSpy('jasmineDone');
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('uses the default spy strategy defined when the spy is created', function (done) {
@@ -61,12 +63,14 @@ describe('Default Spy Strategy (Integration)', function() {
expect(d.and.isConfigured()).toBe(false);
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
var jasmineDone = jasmine.createSpy('jasmineDone');
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -28,8 +28,8 @@ describe('Matchers (Integration)', function() {
.toBeUndefined();
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -47,12 +47,15 @@ describe('Matchers (Integration)', function() {
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown error rather than a matcher failure')
.not.toMatch(/^Error: /);
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown type error rather than a matcher failure')
.not.toMatch(/^TypeError: /);
expect(result.failedExpectations[0].matcherName).withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -72,8 +75,8 @@ describe('Matchers (Integration)', function() {
.toEqual(config.expectedMessage);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -98,8 +101,8 @@ describe('Matchers (Integration)', function() {
.toBeUndefined();
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -123,8 +126,8 @@ describe('Matchers (Integration)', function() {
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -146,8 +149,8 @@ describe('Matchers (Integration)', function() {
.toEqual(config.expectedMessage);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -332,11 +335,11 @@ describe('Matchers (Integration)', function() {
describe('toBeResolved', function() {
verifyPassesAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeResolved();
return env.expectAsync(Promise.resolve()).toBeResolved(); // eslint-disable-line compat/compat
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.reject()).toBeResolved();
return env.expectAsync(Promise.reject()).toBeResolved(); // eslint-disable-line compat/compat
});
});
@@ -345,11 +348,11 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
return env.expectAsync(Promise.resolve('5')).toBeResolvedTo(5);
return env.expectAsync(Promise.resolve('5')).toBeResolvedTo(5); // eslint-disable-line compat/compat
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar');
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar'); // eslint-disable-line compat/compat
});
verifyFailsWithCustomObjectFormattersAsync({
@@ -357,7 +360,7 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y');
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y'); // eslint-disable-line compat/compat
},
expectedMessage: 'Expected a promise to be resolved to |y| ' +
'but it was resolved to |x|.'
@@ -366,11 +369,11 @@ describe('Matchers (Integration)', function() {
describe('toBeRejected', function() {
verifyPassesAsync(function(env) {
return env.expectAsync(Promise.reject('nope')).toBeRejected();
return env.expectAsync(Promise.reject('nope')).toBeRejected(); // eslint-disable-line compat/compat
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejected();
return env.expectAsync(Promise.resolve()).toBeRejected(); // eslint-disable-line compat/compat
});
});
@@ -379,11 +382,11 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
return env.expectAsync(Promise.reject('5')).toBeRejectedWith(5);
return env.expectAsync(Promise.reject('5')).toBeRejectedWith(5); // eslint-disable-line compat/compat
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope');
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope'); // eslint-disable-line compat/compat
});
verifyFailsWithCustomObjectFormattersAsync({
@@ -391,7 +394,7 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y');
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y'); // eslint-disable-line compat/compat
},
expectedMessage: 'Expected a promise to be rejected with |y| ' +
'but it was rejected with |x|.'
@@ -400,11 +403,11 @@ describe('Matchers (Integration)', function() {
describe('toBeRejectedWithError', function() {
verifyPassesAsync(function(env) {
return env.expectAsync(Promise.reject(new Error())).toBeRejectedWithError(Error);
return env.expectAsync(Promise.reject(new Error())).toBeRejectedWithError(Error); // eslint-disable-line compat/compat
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error);
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error); // eslint-disable-line compat/compat
});
verifyFailsWithCustomObjectFormattersAsync({
@@ -412,7 +415,7 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('foo')).toBeRejectedWithError('foo');
return env.expectAsync(Promise.reject('foo')).toBeRejectedWithError('foo'); // eslint-disable-line compat/compat
},
expectedMessage: 'Expected a promise to be rejected with Error: |foo| ' +
'but it was rejected with |foo|.'
@@ -477,9 +480,9 @@ describe('Matchers (Integration)', function() {
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
if (val === 5) {
return "five"
return 'five';
} else if (val === 4) {
return "four"
return 'four';
}
},
expectations: function(env) {
@@ -489,6 +492,16 @@ describe('Matchers (Integration)', function() {
});
});
describe('toHaveSize', function() {
verifyPasses(function(env) {
env.expect(['a','b']).toHaveSize(2);
});
verifyFails(function(env) {
env.expect(['a','b']).toHaveSize(1);
});
});
describe('toHaveBeenCalled', function() {
verifyPasses(function(env) {
var spy = env.createSpy('spy');
@@ -560,6 +573,22 @@ describe('Matchers (Integration)', function() {
});
});
describe('toHaveBeenCalledOnceWith', function() {
verifyPasses(function(env) {
var spy = env.createSpy();
spy('5', 3);
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect(spy).toHaveBeenCalledOnceWith(5, 3);
});
verifyFails(function(env) {
var spy = env.createSpy();
env.expect(spy).toHaveBeenCalledOnceWith(5, 3);
});
});
describe('toHaveClass', function() {
beforeEach(function() {
this.domHelpers = jasmine.getEnv().domHelpers();

View File

@@ -66,17 +66,14 @@ describe("spec running", function () {
expect(bar).toEqual(0);
expect(baz).toEqual(0);
expect(quux).toEqual(0);
var assertions = function() {
env.execute(null, function() {
expect(foo).toEqual(1);
expect(bar).toEqual(1);
expect(baz).toEqual(1);
expect(quux).toEqual(1);
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
});
it("should permit nested describes", function(done) {
@@ -136,7 +133,7 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = [
"topSuite beforeEach",
"outer beforeEach",
@@ -168,11 +165,7 @@ describe("spec running", function () {
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("should run multiple befores and afters ordered so functions declared later are treated as more specific", function(done) {
@@ -232,7 +225,7 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = [
"runner beforeAll1",
"runner beforeAll2",
@@ -250,11 +243,7 @@ describe("spec running", function () {
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it('should run beforeAlls before beforeEachs and afterAlls after afterEachs', function(done) {
@@ -298,7 +287,7 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = [
"runner beforeAll",
"inner beforeAll",
@@ -312,10 +301,7 @@ describe("spec running", function () {
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it('should run beforeAlls and afterAlls in the order declared when runnablesToRun is provided', function(done) {
@@ -365,7 +351,7 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute([spec2.id, spec.id], function() {
var expected = [
"runner beforeAll",
"inner beforeAll",
@@ -385,10 +371,7 @@ describe("spec running", function () {
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute([spec2.id, spec.id]);
});
});
it('only runs *Alls once in a focused suite', function(done){
@@ -406,13 +389,10 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual(['beforeAll', 'spec', 'afterAll']);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
describe('focused runnables', function() {
@@ -435,7 +415,7 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = [
'beforeAll',
'beforeEach',
@@ -449,10 +429,7 @@ describe("spec running", function () {
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it('focused specs in focused suites cause non-focused siblings to not run', function(done){
@@ -467,14 +444,11 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = ['focused spec'];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it('focused suites in focused suites cause non-focused siblings to not run', function(done){
@@ -491,14 +465,11 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = ['inner spec'];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it('focused runnables unfocus ancestor focused suites', function(done) {
@@ -515,14 +486,11 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = ['focused spec'];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
});
@@ -534,14 +502,10 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
expect(specInADisabledSuite).not.toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("shouldn't run before/after functions in disabled suites", function(done) {
@@ -556,14 +520,10 @@ describe("spec running", function () {
env.it('spec inside a disabled suite', shouldNotRun);
});
var assertions = function() {
env.execute(null, function() {
expect(shouldNotRun).not.toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("should allow top level suites to be disabled", function(done) {
@@ -577,15 +537,11 @@ describe("spec running", function () {
env.it('another spec', otherSpec);
});
var assertions = function() {
env.execute(null, function() {
expect(specInADisabledSuite).not.toHaveBeenCalled();
expect(otherSpec).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("should set all pending specs to pending when a suite is run", function(done) {
@@ -594,31 +550,20 @@ describe("spec running", function () {
pendingSpec = env.it("I am a pending spec");
});
var assertions = function() {
env.execute(null, function() {
expect(pendingSpec.status()).toBe("pending");
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("should recover gracefully when there are errors in describe functions", function(done) {
var specs = [],
reporter = jasmine.createSpyObj(['specDone', 'suiteDone', 'jasmineDone']);
reporter = jasmine.createSpyObj(['specDone', 'suiteDone']);
reporter.specDone.and.callFake(function(result) {
specs.push(result.fullName);
});
reporter.jasmineDone.and.callFake(function() {
expect(specs).toEqual(['outer1 inner1 should thingy', 'outer1 inner2 should other thingy', 'outer2 should xxx']);
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1 inner1', [/inner error/]);
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1', [/outer error/]);
done();
});
expect(function() {
env.describe("outer1", function() {
env.describe("inner1", function() {
@@ -647,7 +592,12 @@ describe("spec running", function () {
});
env.addReporter(reporter);
env.execute();
env.execute(null, function() {
expect(specs).toEqual(['outer1 inner1 should thingy', 'outer1 inner2 should other thingy', 'outer2 should xxx']);
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1 inner1', [/inner error/]);
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1', [/outer error/]);
done();
});
});
it("re-enters suites that have no *Alls", function(done) {
@@ -668,14 +618,10 @@ describe("spec running", function () {
actions.push("spec3");
});
env.addReporter({
jasmineDone: function() {
expect(actions).toEqual(["spec2", "spec3", "spec1"]);
done();
}
env.execute([spec2.id, spec3.id, spec1.id], function() {
expect(actions).toEqual(["spec2", "spec3", "spec1"]);
done();
});
env.execute([spec2.id, spec3.id, spec1.id]);
});
it("refuses to re-enter suites with a beforeAll", function() {
@@ -698,16 +644,10 @@ describe("spec running", function () {
actions.push("spec3");
});
env.addReporter({
jasmineDone: function() {
expect(actions).toEqual([]);
done();
}
});
expect(function() {
env.execute([spec2.id, spec3.id, spec1.id]);
}).toThrowError(/beforeAll/);
expect(actions).toEqual([]);
});
it("refuses to re-enter suites with a afterAll", function() {
@@ -730,16 +670,10 @@ describe("spec running", function () {
actions.push("spec3");
});
env.addReporter({
jasmineDone: function() {
expect(actions).toEqual([]);
done();
}
});
expect(function() {
env.execute([spec2.id, spec3.id, spec1.id]);
}).toThrowError(/afterAll/);
expect(actions).toEqual([]);
});
it("should run the tests in a consistent order when a seed is supplied", function(done) {
@@ -800,7 +734,7 @@ describe("spec running", function () {
});
});
var assertions = function() {
env.execute(null, function() {
var expected = [
'topSuite beforeEach',
'outer beforeEach',
@@ -832,11 +766,7 @@ describe("spec running", function () {
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
describe("When throwOnExpectationFailure is set", function() {
@@ -870,18 +800,14 @@ describe("spec running", function () {
env.configure({oneFailurePerSpec: true});
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual([
'outer beforeEach',
'inner afterEach',
'outer afterEach'
]);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("skips to cleanup functions after done.fail is called", function(done) {
@@ -905,17 +831,13 @@ describe("spec running", function () {
env.configure({oneFailurePerSpec: true});
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual([
'beforeEach',
'afterEach'
]);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("skips to cleanup functions when an async function times out", function(done) {
@@ -937,17 +859,13 @@ describe("spec running", function () {
env.configure({oneFailurePerSpec: true});
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual([
'beforeEach',
'afterEach'
]);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("skips to cleanup functions after an error with deprecations", function(done) {
@@ -982,7 +900,7 @@ describe("spec running", function () {
env.throwOnExpectationFailure(true);
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual([
'outer beforeEach',
'inner afterEach',
@@ -990,11 +908,7 @@ describe("spec running", function () {
]);
expect(env.deprecated).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("skips to cleanup functions after done.fail is called with deprecations", function(done) {
@@ -1020,18 +934,14 @@ describe("spec running", function () {
env.throwOnExpectationFailure(true);
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual([
'beforeEach',
'afterEach'
]);
expect(env.deprecated).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("skips to cleanup functions when an async function times out with deprecations", function(done) {
@@ -1055,18 +965,14 @@ describe("spec running", function () {
env.throwOnExpectationFailure(true);
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual([
'beforeEach',
'afterEach'
]);
expect(env.deprecated).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
});
@@ -1089,13 +995,10 @@ describe("spec running", function () {
env.configure({random: false, failFast: true});
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual(['fails']);
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
});
it("does not run further specs when one fails when configured with deprecated option", function(done) {
@@ -1119,14 +1022,11 @@ describe("spec running", function () {
env.configure({random: false});
env.stopOnSpecFailure(true);
var assertions = function() {
env.execute(null, function() {
expect(actions).toEqual(['fails']);
expect(env.deprecated).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
});
});
});

View File

@@ -133,4 +133,50 @@ describe("DiffBuilder", function () {
expect(diffBuilder.getMessage()).toEqual(expectedMsg);
});
it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ at the root', function() {
var prettyPrinter = jasmineUnderTest.makePrettyPrinter([]),
diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter}),
expectedMsg = 'Expected $.foo = 1 to equal 2.\n' +
"Expected $.baz = undefined to equal 3.";
diffBuilder.setRoots(
{foo: 1, bar: 2},
jasmine.objectContaining({foo: 2, baz: 3})
);
diffBuilder.withPath('foo', function() {
diffBuilder.recordMismatch();
});
diffBuilder.withPath('baz', function() {
diffBuilder.recordMismatch();
});
expect(diffBuilder.getMessage()).toEqual(expectedMsg);
});
it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ below the root', function() {
var prettyPrinter = jasmineUnderTest.makePrettyPrinter([]),
diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter}),
expectedMsg = 'Expected $.x.foo = 1 to equal 2.\n' +
"Expected $.x.baz = undefined to equal 3.";
diffBuilder.setRoots(
{x: {foo: 1, bar: 2}},
{x: jasmine.objectContaining({foo: 2, baz: 3})}
);
diffBuilder.withPath('x', function() {
diffBuilder.withPath('foo', function () {
diffBuilder.recordMismatch();
});
diffBuilder.withPath('baz', function () {
diffBuilder.recordMismatch();
});
});
expect(diffBuilder.getMessage()).toEqual(expectedMsg);
});
});

View File

@@ -0,0 +1,52 @@
/* eslint-disable compat/compat */
describe('toBePending', function() {
it('passes if the actual promise is pending', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = new Promise(function() {});
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
});
});
it('fails if the actual promise is resolved', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = Promise.resolve();
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: false}));
});
});
it('fails if the actual promise is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = Promise.reject(new Error('promise was rejected'));
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: false}));
});
});
it('fails if actual is not a promise', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = 'not a promise';
function f() {
return matcher.compare(actual);
}
expect(f).toThrowError(
'Expected toBePending to be called on a promise.'
);
});
});

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('toBeRejected', function() {
it('passes if the actual is rejected', function() {
jasmine.getEnv().requirePromises();

View File

@@ -1,8 +1,9 @@
/* eslint-disable compat/compat */
describe('#toBeRejectedWithError', function () {
it('passes when Error type matches', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new TypeError('foo'));
@@ -17,7 +18,7 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error type and message matches', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new TypeError('foo'));
@@ -32,7 +33,7 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error matches and is exactly Error', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error());
@@ -48,7 +49,7 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error message matches a string', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo'));
@@ -63,7 +64,7 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error message matches a RegExp', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo'));
@@ -78,7 +79,7 @@ describe('#toBeRejectedWithError', function () {
it('passes when Error message is empty', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error());
@@ -93,7 +94,7 @@ describe('#toBeRejectedWithError', function () {
it('passes when no arguments', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error());
@@ -108,7 +109,7 @@ describe('#toBeRejectedWithError', function () {
it('fails when resolved', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.resolve(new Error('foo'));
@@ -123,7 +124,7 @@ describe('#toBeRejectedWithError', function () {
it('fails when rejected with non Error type', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject('foo');
@@ -138,7 +139,7 @@ describe('#toBeRejectedWithError', function () {
it('fails when Error type mismatches', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo'));
@@ -153,7 +154,7 @@ describe('#toBeRejectedWithError', function () {
it('fails when Error message mismatches', function () {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = Promise.reject(new Error('foo'));
@@ -166,7 +167,7 @@ describe('#toBeRejectedWithError', function () {
});
it('fails if actual is not a promise', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
actual = 'not a promise';

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('#toBeRejectedWith', function () {
it('should return true if the promise is rejected with the expected value', function () {
jasmine.getEnv().requirePromises();

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('toBeResolved', function() {
it('passes if the actual is resolved', function() {
jasmine.getEnv().requirePromises();

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
describe('#toBeResolvedTo', function() {
it('passes if the promise is resolved to the expected value', function() {
jasmine.getEnv().requirePromises();
@@ -14,7 +15,7 @@ describe('#toBeResolvedTo', function() {
it('fails if the promise is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec error');
@@ -29,7 +30,7 @@ describe('#toBeResolvedTo', function() {
it('fails if the promise is resolved to a different value', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve({foo: 17});
@@ -44,7 +45,7 @@ describe('#toBeResolvedTo', function() {
it('builds its message correctly when negated', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: new jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve(true);

View File

@@ -112,6 +112,11 @@ describe("matchersUtil", function() {
expect(matchersUtil.equals(123, 456)).toBe(false);
});
it("fails for a Number and a String that have equivalent values", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(123, "123")).toBe(false);
});
it("passes for Dates that are equivalent", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Jan 1, 1970"))).toBe(true);
@@ -280,8 +285,8 @@ describe("matchersUtil", function() {
it("passes for equivalent Promises (GitHub issue #1314)", function() {
if (typeof Promise === 'undefined') { return; }
var p1 = new Promise(function () {}),
p2 = new Promise(function () {}),
var p1 = new Promise(function () {}), // eslint-disable-line compat/compat
p2 = new Promise(function () {}), // eslint-disable-line compat/compat
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(p1, p1)).toBe(true);
@@ -416,10 +421,10 @@ describe("matchersUtil", function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var obj = new Map();
var obj = new Map(); // eslint-disable-line compat/compat
obj.set(1, 2);
obj.set('foo', 'bar');
var containing = new jasmineUnderTest.MapContaining(new Map());
var containing = new jasmineUnderTest.MapContaining(new Map()); // eslint-disable-line compat/compat
containing.sample.set('foo', 'bar');
expect(matchersUtil.equals(obj, containing)).toBe(true);
@@ -430,10 +435,10 @@ describe("matchersUtil", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var obj = new Set();
var obj = new Set(); // eslint-disable-line compat/compat
obj.add(1);
obj.add('foo');
var containing = new jasmineUnderTest.SetContaining(new Set());
var containing = new jasmineUnderTest.SetContaining(new Set()); // eslint-disable-line compat/compat
containing.sample.add(1);
expect(matchersUtil.equals(obj, containing)).toBe(true);
@@ -610,17 +615,17 @@ describe("matchersUtil", function() {
it("passes when comparing two empty sets", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Set(), new Set())).toBe(true);
expect(matchersUtil.equals(new Set(), new Set())).toBe(true); // eslint-disable-line compat/compat
});
it("passes when comparing identical sets", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set();
var setA = new Set(); // eslint-disable-line compat/compat
setA.add(6);
setA.add(5);
var setB = new Set();
var setB = new Set(); // eslint-disable-line compat/compat
setB.add(6);
setB.add(5);
@@ -631,10 +636,10 @@ describe("matchersUtil", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set();
var setA = new Set(); // eslint-disable-line compat/compat
setA.add(3);
setA.add(6);
var setB = new Set();
var setB = new Set(); // eslint-disable-line compat/compat
setB.add(6);
setB.add(3);
@@ -645,24 +650,23 @@ describe("matchersUtil", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA1 = new Set();
var setA1 = new Set(); // eslint-disable-line compat/compat
setA1.add(['a',3]);
setA1.add([6,1]);
var setA2 = new Set();
var setA2 = new Set(); // eslint-disable-line compat/compat
setA1.add(['y',3]);
setA1.add([6,1]);
var setA = new Set();
var setA = new Set(); // eslint-disable-line compat/compat
setA.add(setA1);
setA.add(setA2);
var setB1 = new Set();
var setB1 = new Set(); // eslint-disable-line compat/compat
setB1.add([6,1]);
setB1.add(['a',3]);
var setB2 = new Set();
var setB2 = new Set(); // eslint-disable-line compat/compat
setB1.add([6,1]);
setB1.add(['y',3]);
var setB = new Set();
var setB = new Set(); // eslint-disable-line compat/compat
setB.add(setB1);
setB.add(setB2);
@@ -673,10 +677,10 @@ describe("matchersUtil", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set();
var setA = new Set(); // eslint-disable-line compat/compat
setA.add([[1,2], [3,4]]);
setA.add([[5,6], [7,8]]);
var setB = new Set();
var setB = new Set(); // eslint-disable-line compat/compat
setB.add([[5,6], [7,8]]);
setB.add([[1,2], [3,4]]);
@@ -686,11 +690,11 @@ describe("matchersUtil", function() {
it("fails for sets with different elements", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set();
var setA = new Set(); // eslint-disable-line compat/compat
setA.add(6);
setA.add(3);
setA.add(5);
var setB = new Set();
var setB = new Set(); // eslint-disable-line compat/compat
setB.add(6);
setB.add(4);
setB.add(5);
@@ -701,10 +705,10 @@ describe("matchersUtil", function() {
it("fails for sets of different size", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set();
var setA = new Set(); // eslint-disable-line compat/compat
setA.add(6);
setA.add(3);
var setB = new Set();
var setB = new Set(); // eslint-disable-line compat/compat
setB.add(6);
setB.add(4);
setB.add(5);
@@ -715,15 +719,15 @@ describe("matchersUtil", function() {
it("passes when comparing two empty maps", function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Map(), new Map())).toBe(true);
expect(matchersUtil.equals(new Map(), new Map())).toBe(true); // eslint-disable-line compat/compat
});
it("passes when comparing identical maps", function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map();
var mapA = new Map(); // eslint-disable-line compat/compat
mapA.set(6, 5);
var mapB = new Map();
var mapB = new Map(); // eslint-disable-line compat/compat
mapB.set(6, 5);
expect(matchersUtil.equals(mapA, mapB)).toBe(true);
});
@@ -731,10 +735,10 @@ describe("matchersUtil", function() {
it("passes when comparing identical maps with different insertion order", function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map();
var mapA = new Map(); // eslint-disable-line compat/compat
mapA.set("a", 3);
mapA.set(6, 1);
var mapB = new Map();
var mapB = new Map(); // eslint-disable-line compat/compat
mapB.set(6, 1);
mapB.set("a", 3);
expect(matchersUtil.equals(mapA, mapB)).toBe(true);
@@ -743,10 +747,10 @@ describe("matchersUtil", function() {
it("fails for maps with different elements", function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map();
var mapA = new Map(); // eslint-disable-line compat/compat
mapA.set(6, 3);
mapA.set(5, 1);
var mapB = new Map();
var mapB = new Map(); // eslint-disable-line compat/compat
mapB.set(6, 4);
mapB.set(5, 1);
@@ -756,9 +760,9 @@ describe("matchersUtil", function() {
it("fails for maps of different size", function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map();
var mapA = new Map(); // eslint-disable-line compat/compat
mapA.set(6, 3);
var mapB = new Map();
var mapB = new Map(); // eslint-disable-line compat/compat
mapB.set(6, 4);
mapB.set(5, 1);
expect(matchersUtil.equals(mapA, mapB)).toBe(false);
@@ -829,7 +833,7 @@ describe("matchersUtil", function() {
expect(diffBuilder.setRoots).toHaveBeenCalledWith(actual, expected);
expect(diffBuilder.withPath).toHaveBeenCalledWith('x', jasmine.any(Function));
expect(diffBuilder.recordMismatch). toHaveBeenCalledWith();
expect(diffBuilder.recordMismatch).toHaveBeenCalledWith();
});
it("records both objects when the tester does not implement valuesForDiff", function() {
@@ -846,7 +850,7 @@ describe("matchersUtil", function() {
expect(diffBuilder.setRoots).toHaveBeenCalledWith(actual, expected);
expect(diffBuilder.withPath).toHaveBeenCalledWith('x', jasmine.any(Function));
expect(diffBuilder.recordMismatch). toHaveBeenCalledWith();
expect(diffBuilder.recordMismatch).toHaveBeenCalledWith();
});
});
@@ -981,7 +985,7 @@ describe("matchersUtil", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setItem = {'foo': 'bar'};
var set = new Set();
var set = new Set(); // eslint-disable-line compat/compat
set.add(setItem);
expect(matchersUtil.contains(set, setItem)).toBe(true);
@@ -992,7 +996,7 @@ describe("matchersUtil", function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var set = new Set();
var set = new Set(); // eslint-disable-line compat/compat
set.add({'foo': 'bar'});
expect(matchersUtil.contains(set, {'foo': 'bar'})).toBe(false);

View File

@@ -261,8 +261,8 @@ describe("toEqual", function() {
it("reports mismatches between arrays of different types", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
var actual = new Uint32Array([1, 2, 3]),
expected = new Uint16Array([1, 2, 3]),
var actual = new Uint32Array([1, 2, 3]), // eslint-disable-line compat/compat
expected = new Uint16Array([1, 2, 3]), // eslint-disable-line compat/compat
message = "Expected Uint32Array [ 1, 2, 3 ] to equal Uint16Array [ 1, 2, 3 ].";
expect(compareEquals(actual, expected).message).toEqual(message);
@@ -429,17 +429,30 @@ describe("toEqual", function() {
expect(compareEquals(actual, expected).message).toEqual(message);
});
it("reports mismatches involving objectContaining and an object", function() {
var actual = {x: {a: 1, b: 4, c: 3, extra: 'ignored'}};
var expected = {x: jasmineUnderTest.objectContaining({a: 1, b: 2, c: 3})};
expect(compareEquals(actual, expected).message).toEqual('Expected $.x.b = 4 to equal 2.');
it('reports mismatches between an object and objectContaining', function() {
var actual = {a: 1, b: 4, c: 3, extra: 'ignored'};
var expected = jasmineUnderTest.objectContaining({a: 1, b: 2, c: 3, d: 4});
expect(compareEquals(actual, expected).message)
.toEqual(
'Expected $.b = 4 to equal 2.\n' +
'Expected $.d = undefined to equal 4.'
);
});
it("reports mismatches between a non-object and objectContaining", function() {
var actual = {x: 1};
var expected = {x: jasmineUnderTest.objectContaining({a: 1})};
var actual = 1;
var expected = jasmineUnderTest.objectContaining({a: 1});
expect(compareEquals(actual, expected).message).toEqual(
"Expected $.x = 1 to equal '<jasmine.objectContaining(Object({ a: 1 }))>'."
"Expected 1 to equal '<jasmine.objectContaining(Object({ a: 1 }))>'."
);
});
it("reports mismatches involving a nested objectContaining", function() {
var actual = {x: {a: 1, b: 4, c: 3, extra: 'ignored'}};
var expected = {x: jasmineUnderTest.objectContaining({a: 1, b: 2, c: 3, d: 4})};
expect(compareEquals(actual, expected).message).toEqual(
'Expected $.x.b = 4 to equal 2.\n' +
'Expected $.x.d = undefined to equal 4.'
);
});
@@ -448,9 +461,9 @@ describe("toEqual", function() {
it("reports mismatches between Sets", function() {
jasmine.getEnv().requireFunctioningSets();
var actual = new Set();
var actual = new Set(); // eslint-disable-line compat/compat
actual.add(1);
var expected = new Set();
var expected = new Set(); // eslint-disable-line compat/compat
expected.add(2);
var message = 'Expected Set( 1 ) to equal Set( 2 ).';
@@ -460,9 +473,9 @@ describe("toEqual", function() {
it("reports deep mismatches within Sets", function() {
jasmine.getEnv().requireFunctioningSets();
var actual = new Set();
var actual = new Set(); // eslint-disable-line compat/compat
actual.add({x: 1});
var expected = new Set();
var expected = new Set(); // eslint-disable-line compat/compat
expected.add({x: 2});
var message = 'Expected Set( Object({ x: 1 }) ) to equal Set( Object({ x: 2 }) ).';
@@ -472,9 +485,9 @@ describe("toEqual", function() {
it("reports mismatches between Sets nested in objects", function() {
jasmine.getEnv().requireFunctioningSets();
var actualSet = new Set();
var actualSet = new Set(); // eslint-disable-line compat/compat
actualSet.add(1);
var expectedSet = new Set();
var expectedSet = new Set(); // eslint-disable-line compat/compat
expectedSet.add(2);
var actual = { sets: [actualSet] };
@@ -487,10 +500,10 @@ describe("toEqual", function() {
it("reports mismatches between Sets of different lengths", function() {
jasmine.getEnv().requireFunctioningSets();
var actual = new Set();
var actual = new Set(); // eslint-disable-line compat/compat
actual.add(1);
actual.add(2);
var expected = new Set();
var expected = new Set(); // eslint-disable-line compat/compat
expected.add(2);
var message = 'Expected Set( 1, 2 ) to equal Set( 2 ).';
@@ -501,10 +514,10 @@ describe("toEqual", function() {
jasmine.getEnv().requireFunctioningSets();
// Use 'duplicate' object in actual so sizes match
var actual = new Set();
var actual = new Set(); // eslint-disable-line compat/compat
actual.add({x: 1});
actual.add({x: 1});
var expected = new Set();
var expected = new Set(); // eslint-disable-line compat/compat
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 }) ).';
@@ -516,10 +529,10 @@ describe("toEqual", function() {
jasmine.getEnv().requireFunctioningSets();
// Use 'duplicate' object in expected so sizes match
var actual = new Set();
var actual = new Set(); // eslint-disable-line compat/compat
actual.add({x: 1});
actual.add({x: 2});
var expected = new Set();
var expected = new Set(); // eslint-disable-line compat/compat
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 }) ).';
@@ -533,9 +546,9 @@ describe("toEqual", function() {
jasmine.getEnv().requireFunctioningMaps();
// values are the same but with different object identity
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set('a',{x:1});
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set('a',{x:1});
expect(compareEquals(actual, expected).pass).toBe(true);
@@ -544,9 +557,9 @@ describe("toEqual", function() {
it("reports deep mismatches within Maps", function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set('a',{x:1});
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set('a',{x:2});
var message = "Expected Map( [ 'a', Object({ x: 1 }) ] ) to equal Map( [ 'a', Object({ x: 2 }) ] ).";
@@ -556,9 +569,9 @@ describe("toEqual", function() {
it("reports mismatches between Maps nested in objects", function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = {Maps:[new Map()]};
var actual = {Maps:[new Map()]}; // eslint-disable-line compat/compat
actual.Maps[0].set('a',1);
var expected = {Maps:[new Map()]};
var expected = {Maps:[new Map()]}; // eslint-disable-line compat/compat
expected.Maps[0].set('a',2);
var message = "Expected $.Maps[0] = Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ] ).";
@@ -569,9 +582,9 @@ describe("toEqual", function() {
it("reports mismatches between Maps of different lengths", function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set('a',1);
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set('a',2);
expected.set('b',1);
var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ], [ 'b', 1 ] ).";
@@ -582,9 +595,9 @@ describe("toEqual", function() {
it("reports mismatches between Maps with equal values but differing keys", function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set('a',1);
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set('b',1);
var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'b', 1 ] ).";
@@ -594,9 +607,9 @@ describe("toEqual", function() {
it("does not report mismatches between Maps with keys with same object identity", function() {
jasmine.getEnv().requireFunctioningMaps();
var key = {x: 1};
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set(key,2);
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set(key,2);
expect(compareEquals(actual, expected).pass).toBe(true);
@@ -605,9 +618,9 @@ describe("toEqual", function() {
it("reports mismatches between Maps with identical keys with different object identity", function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set({x:1},2);
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set({x:1},2);
var message = "Expected Map( [ Object({ x: 1 }), 2 ] ) to equal Map( [ Object({ x: 1 }), 2 ] ).";
@@ -617,9 +630,9 @@ describe("toEqual", function() {
it("does not report mismatches when comparing Map key to jasmine.anything()", function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set('a',1);
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set(jasmineUnderTest.anything(),1);
expect(compareEquals(actual, expected).pass).toBe(true);
@@ -629,10 +642,10 @@ describe("toEqual", function() {
jasmine.getEnv().requireFunctioningMaps();
jasmine.getEnv().requireFunctioningSymbols();
var key = Symbol();
var actual = new Map();
var key = Symbol(); // eslint-disable-line compat/compat
var actual = new Map(); // eslint-disable-line compat/compat
actual.set(key,1);
var expected = new Map();
var expected = new Map(); // eslint-disable-line compat/compat
expected.set(key,1);
expect(compareEquals(actual, expected).pass).toBe(true);
@@ -642,10 +655,10 @@ describe("toEqual", function() {
jasmine.getEnv().requireFunctioningMaps();
jasmine.getEnv().requireFunctioningSymbols();
var actual = new Map();
actual.set(Symbol(),1);
var expected = new Map();
expected.set(Symbol(),1);
var actual = new Map(); // eslint-disable-line compat/compat
actual.set(Symbol(),1); // eslint-disable-line compat/compat
var expected = new Map(); // eslint-disable-line compat/compat
expected.set(Symbol(),1); // eslint-disable-line compat/compat
var message = "Expected Map( [ Symbol(), 1 ] ) to equal Map( [ Symbol(), 1 ] ).";
expect(compareEquals(actual, expected).message).toBe(message);
@@ -655,9 +668,9 @@ describe("toEqual", function() {
jasmine.getEnv().requireFunctioningMaps();
jasmine.getEnv().requireFunctioningSymbols();
var actual = new Map();
actual.set(Symbol(),1);
var expected = new Map();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set(Symbol(),1); // eslint-disable-line compat/compat
var expected = new Map(); // eslint-disable-line compat/compat
expected.set(jasmineUnderTest.anything(),1);
expect(compareEquals(actual, expected).pass).toBe(true);

View File

@@ -0,0 +1,95 @@
describe("toHaveBeenCalledOnceWith", function () {
it("passes when the actual was called only once and with matching parameters", function () {
var pp = jasmineUnderTest.makePrettyPrinter(),
util = new jasmineUnderTest.MatchersUtil({ pp: pp }),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(util),
calledSpy = new jasmineUnderTest.Spy('called-spy'),
result;
calledSpy('a', 'b');
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected spy called-spy to have been called 0 times, multiple times, or once, but with arguments different from:\n [ 'a', 'b' ]\nBut the actual call was:\n [ 'a', 'b' ].\n\n");
});
it("supports custom equality testers", function () {
var customEqualityTesters = [function() { return true; }],
matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: customEqualityTesters}),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(matchersUtil),
calledSpy = new jasmineUnderTest.Spy('called-spy'),
result;
calledSpy('a', 'b');
result = matcher.compare(calledSpy, 'a', 'a');
expect(result.pass).toBe(true);
});
it("fails when the actual was never called", function () {
var pp = jasmineUnderTest.makePrettyPrinter(),
util = new jasmineUnderTest.MatchersUtil({ pp: pp }),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(util),
calledSpy = new jasmineUnderTest.Spy('called-spy'),
result;
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected spy called-spy to have been called only once, and with given args:\n [ 'a', 'b' ]\nBut it was never called.\n\n");
});
it("fails when the actual was called once with different parameters", function () {
var pp = jasmineUnderTest.makePrettyPrinter(),
util = new jasmineUnderTest.MatchersUtil({ pp: pp }),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(util),
calledSpy = new jasmineUnderTest.Spy('called-spy'),
result;
calledSpy('a', 'c');
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected spy called-spy to have been called only once, and with given args:\n [ 'a', 'b' ]\nBut the actual call was:\n [ 'a', 'c' ].\nExpected $[1] = 'c' to equal 'b'.\n\n");
});
it("fails when the actual was called multiple times with expected parameters", function () {
var pp = jasmineUnderTest.makePrettyPrinter(),
util = new jasmineUnderTest.MatchersUtil({ pp: pp }),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(util),
calledSpy = new jasmineUnderTest.Spy('called-spy'),
result;
calledSpy('a', 'b');
calledSpy('a', 'b');
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected spy called-spy to have been called only once, and with given args:\n [ 'a', 'b' ]\nBut the actual calls were:\n [ 'a', 'b' ],\n [ 'a', 'b' ].\n\n");
});
it("fails when the actual was called multiple times (one of them - with expected parameters)", function () {
var pp = jasmineUnderTest.makePrettyPrinter(),
util = new jasmineUnderTest.MatchersUtil({ pp: pp }),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(util),
calledSpy = new jasmineUnderTest.Spy('called-spy'),
result;
calledSpy('a', 'b');
calledSpy('a', 'c');
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected spy called-spy to have been called only once, and with given args:\n [ 'a', 'b' ]\nBut the actual calls were:\n [ 'a', 'b' ],\n [ 'a', 'c' ].\n\n");
});
it("throws an exception when the actual is not a spy", function () {
var pp = jasmineUnderTest.makePrettyPrinter(),
util = new jasmineUnderTest.MatchersUtil({ pp: pp }),
matcher = jasmineUnderTest.matchers.toHaveBeenCalledOnceWith(util),
fn = function () { };
expect(function () { matcher.compare(fn) }).toThrowError(/Expected a spy, but got Function./);
});
});

View File

@@ -0,0 +1,138 @@
/* eslint-disable compat/compat */
describe('toHaveSize', function() {
'use strict';
it('passes for an array whose length matches', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare([1, 2], 2);
expect(result.pass).toBe(true);
});
it('fails for an array whose length does not match', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare([1, 2, 3], 2);
expect(result.pass).toBe(false);
});
it('passes for an object with the proper number of keys', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare({a: 1, b: 2}, 2);
expect(result.pass).toBe(true);
});
it('fails for an object with a different number of keys', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare({a: 1, b: 2}, 1);
expect(result.pass).toBe(false);
});
it('passes for an object with an explicit `length` property that matches', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare({a: 1, b: 2, length: 5}, 5);
expect(result.pass).toBe(true);
});
it('fails for an object with an explicit `length` property that does not match', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare({a: 1, b: 2, length: 5}, 1);
expect(result.pass).toBe(false);
});
it('passes for a string whose length matches', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare('ab', 2);
expect(result.pass).toBe(true);
});
it('fails for a string whose length does not match', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare('abc', 2);
expect(result.pass).toBe(false);
});
it('passes for a Map whose length matches', function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map();
map.set('a',1);
map.set('b',2);
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare(map, 2);
expect(result.pass).toBe(true);
});
it('fails for a Map whose length does not match', function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map();
map.set('a',1);
map.set('b',2);
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare(map, 1);
expect(result.pass).toBe(false);
});
it('passes for a Set whose length matches', function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set();
set.add('a');
set.add('b');
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare(set, 2);
expect(result.pass).toBe(true);
});
it('fails for a Set whose length does not match', function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set();
set.add('a');
set.add('b');
var matcher = jasmineUnderTest.matchers.toHaveSize(),
result = matcher.compare(set, 1);
expect(result.pass).toBe(false);
});
it('throws an error for WeakSet', function() {
jasmine.getEnv().requireWeakSets();
var matcher = jasmineUnderTest.matchers.toHaveSize();
expect(function() {
matcher.compare(new WeakSet(), 2);
}).toThrowError('Cannot get size of [object WeakSet].');
});
it('throws an error for WeakMap', function() {
jasmine.getEnv().requireWeakMaps();
var matcher = jasmineUnderTest.matchers.toHaveSize();
expect(function() {
matcher.compare(new WeakMap(), 2);
}).toThrowError(/Cannot get size of \[object (WeakMap|Object)\]\./);
});
it('throws an error for DataView', function() {
var matcher = jasmineUnderTest.matchers.toHaveSize();
expect(function() {
matcher.compare(new DataView(new ArrayBuffer(128)), 2);
}).toThrowError(/Cannot get size of \[object (DataView|Object)\]\./);
});
});

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
(function(env) {
env.hasFunctioningMaps = function() {
if (typeof Map === 'undefined') {
@@ -43,4 +44,10 @@
env.pending('Browser has incomplete or missing support for Maps');
}
};
env.requireWeakMaps = function() {
if (typeof WeakMap === 'undefined') {
env.pending('Browser does not have support for WeakMap');
}
};
})(jasmine.getEnv());

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
(function(env) {
env.hasFunctioningSets = function() {
if (typeof Set === 'undefined') {
@@ -47,4 +48,10 @@
env.pending('Browser has incomplete or missing support for Sets');
}
};
env.requireWeakSets = function() {
if (typeof WeakSet === 'undefined') {
env.pending('Browser does not have support for WeakSet');
}
};
})(jasmine.getEnv());

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
(function(env) {
function hasFunctioningSymbols() {
if (typeof Symbol === 'undefined') {

View File

@@ -1,3 +1,4 @@
/* eslint-disable compat/compat */
(function(env) {
function hasFunctioningTypedArrays() {
if (typeof Uint32Array === 'undefined') {

22
spec/helpers/generator.js Normal file
View File

@@ -0,0 +1,22 @@
(function(env) {
function getGeneratorFuncCtor() {
try {
eval('var func = function*() {}');
} catch (e) {
return null;
}
return Object.getPrototypeOf(func).constructor;
}
env.makeGeneratorFunction = function(text) {
var GeneratorFunction = getGeneratorFuncCtor();
return new GeneratorFunction(text || '');
};
env.requireGeneratorFunctions = function() {
if (!getGeneratorFuncCtor()) {
env.pending('Environment does not support generator functions');
}
};
})(jasmine.getEnv());

View File

@@ -270,12 +270,14 @@ describe('HtmlReporter', function() {
reporter.jasmineStarted({});
reporter.specDone({
status: 'passed',
fullName: 'a spec with a deprecation',
deprecationWarnings: [{ message: 'spec deprecation' }],
failedExpectations: [],
passedExpectations: []
});
reporter.suiteDone({
status: 'passed',
fullName: 'a suite with a deprecation',
deprecationWarnings: [{ message: 'suite deprecation' }],
failedExpectations: []
});
@@ -287,12 +289,17 @@ describe('HtmlReporter', function() {
var alertBars = container.querySelectorAll('.jasmine-alert .jasmine-bar');
expect(alertBars.length).toEqual(4);
expect(alertBars[1].innerHTML).toMatch(/spec deprecation/);
expect(alertBars[1].innerHTML).toMatch(
/spec deprecation.*\(in spec: a spec with a deprecation\)/
);
expect(alertBars[1].getAttribute('class')).toEqual(
'jasmine-bar jasmine-warning'
);
expect(alertBars[2].innerHTML).toMatch(/suite deprecation/);
expect(alertBars[2].innerHTML).toMatch(
/suite deprecation.*\(in suite: a suite with a deprecation\)/
);
expect(alertBars[3].innerHTML).toMatch(/global deprecation/);
expect(alertBars[3].innerHTML).not.toMatch(/in /);
});
});

View File

@@ -31,7 +31,7 @@ describe('PrettyPrinter (HTML Dependent)', function() {
}
// Different versions of FF produce different error messages.
expect(pp(err)).toMatch(
/Not enough arguments|CustomEvent requires at least 1 argument, but only 0 were passed/
/Not enough arguments|CustomEvent.*only 0.*passed/
);
}
});

View File

@@ -18,6 +18,7 @@ module.exports = {
specFiles: ['**/*[Ss]pec.js', '!npmPackage/**/*'],
helpers: [
'helpers/asyncAwait.js',
'helpers/generator.js',
'helpers/BrowserFlags.js',
'helpers/checkForMap.js',
'helpers/checkForSet.js',

View File

@@ -6,6 +6,7 @@
],
"helpers": [
"helpers/asyncAwait.js",
"helpers/generator.js",
"helpers/checkForMap.js",
"helpers/checkForSet.js",
"helpers/checkForSymbol.js",

View File

@@ -620,12 +620,22 @@ getJasmineRequireObj().Env = function(j$) {
this.deprecated = function(deprecation) {
var runnable = currentRunnable() || topSuite;
var context;
if (runnable === topSuite) {
context = '';
} else if (runnable === currentSuite()) {
context = ' (in suite: ' + runnable.getFullName() + ')';
} else {
context = ' (in spec: ' + runnable.getFullName() + ')';
}
runnable.addDeprecationWarning(deprecation);
if (
typeof console !== 'undefined' &&
typeof console.error === 'function'
) {
console.error('DEPRECATION:', deprecation);
console.error('DEPRECATION: ' + deprecation + context);
}
};
@@ -767,7 +777,8 @@ getJasmineRequireObj().Env = function(j$) {
queueRunnerFactory
);
this.execute = function(runnablesToRun) {
// Both params are optional.
this.execute = function(runnablesToRun, onComplete) {
installGlobalErrors();
if (!runnablesToRun) {
@@ -875,7 +886,11 @@ getJasmineRequireObj().Env = function(j$) {
failedExpectations: topSuite.result.failedExpectations,
deprecationWarnings: topSuite.result.deprecationWarnings
},
function() {}
function() {
if (onComplete) {
onComplete();
}
}
);
});
}
@@ -1014,6 +1029,7 @@ getJasmineRequireObj().Env = function(j$) {
id: getNextSuiteId(),
description: description,
parentSuite: currentDeclarationSuite,
timer: new j$.Timer(),
expectationFactory: expectationFactory,
asyncExpectationFactory: suiteAsyncExpectationFactory,
expectationResultFactory: expectationResultFactory,
@@ -1192,6 +1208,40 @@ getJasmineRequireObj().Env = function(j$) {
return spec;
};
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}
* @name Env#setSpecProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
this.setSpecProperty = function(key, value) {
if (!currentRunnable() || currentRunnable() == currentSuite()) {
throw new Error(
"'setSpecProperty' was used when there was no current spec"
);
}
currentRunnable().setSpecProperty(key, value);
};
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}
* @name Env#setSuiteProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
this.setSuiteProperty = function(key, value) {
if (!currentSuite()) {
throw new Error(
"'setSuiteProperty' was used when there was no current suite"
);
}
currentSuite().setSuiteProperty(key, value);
};
this.expect = function(actual) {
if (!currentRunnable()) {
throw new Error(

View File

@@ -96,7 +96,17 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
handlers.push(listener);
};
this.popListener = function popListener() {
this.popListener = function popListener(listener) {
if (!listener) {
throw new Error('popListener expects a listener');
}
if (listener !== handlers[handlers.length - 1]) {
throw new Error(
'popListener was passed a different listener than the current one'
);
}
handlers.pop();
};
}

View File

@@ -6,7 +6,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
* @hideconstructor
*/
function JsApiReporter(options) {
var timer = options.timer || j$.noopTimer,
var timer = options.timer || new j$.Timer(),
status = 'loaded';
this.started = false;

View File

@@ -1,4 +1,6 @@
getJasmineRequireObj().QueueRunner = function(j$) {
var nextid = 1;
function StopExecutionError() {}
StopExecutionError.prototype = new Error();
j$.StopExecutionError = StopExecutionError;
@@ -18,6 +20,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
function emptyFn() {}
function QueueRunner(attrs) {
this.id_ = nextid++;
var queueableFns = attrs.queueableFns || [];
this.queueableFns = queueableFns.concat(attrs.cleanupFns || []);
this.firstCleanupIx = queueableFns.length;
@@ -120,7 +123,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}),
errored = false,
queueableFn = self.queueableFns[iterativeIndex],
timeoutId;
timeoutId,
maybeThenable;
next.fail = function nextFail() {
self.fail.apply(null, arguments);
@@ -148,7 +152,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
try {
if (queueableFn.fn.length === 0) {
var maybeThenable = queueableFn.fn.call(self.userContext);
maybeThenable = queueableFn.fn.call(self.userContext);
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
maybeThenable.then(next, onPromiseRejection);
@@ -156,7 +160,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
return { completedSynchronously: false };
}
} else {
queueableFn.fn.call(self.userContext, next);
maybeThenable = queueableFn.fn.call(self.userContext, next);
this.diagnoseConflictingAsync_(queueableFn.fn, maybeThenable);
completedSynchronously = false;
return { completedSynchronously: false };
}
@@ -209,5 +214,28 @@ getJasmineRequireObj().QueueRunner = function(j$) {
});
};
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
if (retval && j$.isFunction_(retval.then)) {
// Issue a warning that matches the user's code
if (j$.isAsyncFunction_(fn)) {
this.deprecated(
'An asynchronous before/it/after ' +
'function was defined with the async keyword but also took a ' +
'done callback. This is not supported and will stop working in' +
' the future. Either remove the done callback (recommended) or ' +
'remove the async keyword.'
);
} else {
this.deprecated(
'An asynchronous before/it/after ' +
'function took a done callback but also returned a promise. ' +
'This is not supported and will stop working in the future. ' +
'Either remove the done callback (recommended) or change the ' +
'function to not return a promise.'
);
}
}
};
return QueueRunner;
};

View File

@@ -31,7 +31,7 @@ getJasmineRequireObj().Spec = function(j$) {
return true;
};
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
this.timer = attrs.timer || j$.noopTimer;
this.timer = attrs.timer || new j$.Timer();
if (!this.queueableFn.fn) {
this.pend();
@@ -48,6 +48,7 @@ getJasmineRequireObj().Spec = function(j$) {
* @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.
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
*/
this.result = {
id: this.id,
@@ -57,7 +58,8 @@ getJasmineRequireObj().Spec = function(j$) {
passedExpectations: [],
deprecationWarnings: [],
pendingReason: '',
duration: null
duration: null,
properties: null
};
}
@@ -74,6 +76,11 @@ getJasmineRequireObj().Spec = function(j$) {
}
};
Spec.prototype.setSpecProperty = function(key, value) {
this.result.properties = this.result.properties || {};
this.result.properties[key] = value;
};
Spec.prototype.expect = function(actual) {
return this.expectationFactory(actual, this);
};
@@ -96,6 +103,7 @@ getJasmineRequireObj().Spec = function(j$) {
fn: function(done) {
self.queueableFn.fn = null;
self.result.status = self.status(excluded, failSpecWithNoExp);
self.result.duration = self.timer.elapsed();
self.resultCallback(self.result, done);
}
};
@@ -111,7 +119,6 @@ getJasmineRequireObj().Spec = function(j$) {
self.onException.apply(self, arguments);
},
onComplete: function() {
self.result.duration = self.timer.elapsed();
onComplete(
self.result.status === 'failed' &&
new j$.StopExecutionError('spec failed')

View File

@@ -150,10 +150,10 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
* @name SpyStrategy#throwError
* @since 2.0.0
* @function
* @param {Error|String} something Thing to throw
* @param {Error|Object|String} something Thing to throw
*/
SpyStrategy.prototype.throwError = function(something) {
var error = something instanceof Error ? something : new Error(something);
var error = j$.isString_(something) ? new Error(something) : something;
this.plan = function() {
throw error;
};
@@ -168,7 +168,13 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
* @param {Function} fn The function to invoke with the passed parameters.
*/
SpyStrategy.prototype.callFake = function(fn) {
if (!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
if (
!(
j$.isFunction_(fn) ||
j$.isAsyncFunction_(fn) ||
j$.isGeneratorFunction_(fn)
)
) {
throw new Error(
'Argument passed to callFake should be a function, got ' + fn
);

View File

@@ -14,7 +14,7 @@ getJasmineRequireObj().Suite = function(j$) {
this.beforeAllFns = [];
this.afterAllFns = [];
this.timer = attrs.timer || j$.noopTimer;
this.timer = attrs.timer || new j$.Timer();
this.children = [];
@@ -27,6 +27,7 @@ getJasmineRequireObj().Suite = function(j$) {
* @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.
* @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty}
*/
this.result = {
id: this.id,
@@ -34,10 +35,16 @@ getJasmineRequireObj().Suite = function(j$) {
fullName: this.getFullName(),
failedExpectations: [],
deprecationWarnings: [],
duration: null
duration: null,
properties: null
};
}
Suite.prototype.setSuiteProperty = function(key, value) {
this.result.properties = this.result.properties || {};
this.result.properties[key] = value;
};
Suite.prototype.expect = function(actual) {
return this.expectationFactory(actual, this);
};

View File

@@ -22,12 +22,3 @@ getJasmineRequireObj().Timer = function() {
return Timer;
};
getJasmineRequireObj().noopTimer = function() {
return {
start: function() {},
elapsed: function() {
return 0;
}
};
};

View File

@@ -66,7 +66,9 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
for (i = 0; i < props.length; i++) {
k = props[i];
if (k !== 'length') {
// Skip length (dealt with above), and anything that collides with
// MatchesUtil e.g. an Array.prototype.contains method added by user code
if (k !== 'length' && !self[k]) {
copyAndDeprecate(self, Array.prototype, k);
}
}
@@ -97,7 +99,7 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
});
}
props = Object.getOwnPropertyDescriptors(Array.prototype);
props = Object.getOwnPropertyDescriptors(Array.prototype); // eslint-disable-line compat/compat
a = [];
for (k in props) {

View File

@@ -76,6 +76,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
return j$.isA_('AsyncFunction', value);
};
j$.isGeneratorFunction_ = function(value) {
return j$.isA_('GeneratorFunction', value);
};
j$.isTypedArray_ = function(value) {
return (
j$.isA_('Float32Array', value) ||
@@ -148,6 +152,24 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
);
};
j$.isWeakMap = function(obj) {
return (
obj !== null &&
typeof obj !== 'undefined' &&
typeof jasmineGlobal.WeakMap !== 'undefined' &&
obj.constructor === jasmineGlobal.WeakMap
);
};
j$.isDataView = function(obj) {
return (
obj !== null &&
typeof obj !== 'undefined' &&
typeof jasmineGlobal.DataView !== 'undefined' &&
obj.constructor === jasmineGlobal.DataView
);
};
j$.isPromise = function(obj) {
return (
typeof jasmineGlobal.Promise !== 'undefined' &&

View File

@@ -72,12 +72,7 @@ getJasmineRequireObj().DiffBuilder = function (j$) {
};
function dereferencePath(objectPath, actual, expected, pp) {
var i, asymmetricResult
for (i = 0; i < objectPath.components.length; i++) {
actual = actual[objectPath.components[i]];
expected = expected[objectPath.components[i]];
function handleAsymmetricExpected() {
if (j$.isAsymmetricEqualityTester_(expected) && j$.isFunction_(expected.valuesForDiff_)) {
var asymmetricResult = expected.valuesForDiff_(actual, pp);
expected = asymmetricResult.self;
@@ -85,6 +80,15 @@ getJasmineRequireObj().DiffBuilder = function (j$) {
}
}
var i;
handleAsymmetricExpected();
for (i = 0; i < objectPath.components.length; i++) {
actual = actual[objectPath.components[i]];
expected = expected[objectPath.components[i]];
handleAsymmetricExpected();
}
return {actual: actual, expected: expected};
}

View File

@@ -0,0 +1,26 @@
/* eslint-disable compat/compat */
getJasmineRequireObj().toBePending = function(j$) {
/**
* Expect a promise to be pending, i.e. the promise is neither resolved nor rejected.
* @function
* @async
* @name async-matchers#toBePending
* @since 3.6
* @example
* await expectAsync(aPromise).toBePending();
*/
return function toBePending() {
return {
compare: function(actual) {
if (!j$.isPromiseLike(actual)) {
throw new Error('Expected toBePending to be called on a promise.');
}
var want = {};
return Promise.race([actual, Promise.resolve(want)]).then(
function(got) { return {pass: want === got}; },
function() { return {pass: false}; }
);
}
};
};
};

View File

@@ -3,7 +3,6 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* _Note:_ Do not construct this directly. Jasmine will construct one and
* pass it to matchers and asymmetric equality testers.
* @name MatchersUtil
* @since 2.0.0
* @classdesc Utilities for use in implementing matchers
* @constructor
*/
@@ -15,6 +14,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* taking into account the current set of custom value formatters.
* @function
* @name MatchersUtil#pp
* @since 3.6.0
* @param {*} value The value to pretty-print
* @return {string} The pretty-printed value
*/
@@ -26,6 +26,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* logic as {@link MatchersUtil#equals}.
* @function
* @name MatchersUtil#contains
* @since 2.0.0
* @param {*} haystack The collection to search
* @param {*} needle The value to search for
* @param [customTesters] An array of custom equality testers. Deprecated.
@@ -125,6 +126,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
* Determines whether two values are deeply equal to each other.
* @function
* @name MatchersUtil#equals
* @since 2.0.0
* @param {*} a The first value to compare
* @param {*} b The second value to compare
* @param [customTesters] An array of custom equality testers. Deprecated.

View File

@@ -1,5 +1,6 @@
getJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) {
var availableMatchers = [
'toBePending',
'toBeResolved',
'toBeRejected',
'toBeResolvedTo',

View File

@@ -20,8 +20,10 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
'toBeUndefined',
'toContain',
'toEqual',
'toHaveSize',
'toHaveBeenCalled',
'toHaveBeenCalledBefore',
'toHaveBeenCalledOnceWith',
'toHaveBeenCalledTimes',
'toHaveBeenCalledWith',
'toHaveClass',

View File

@@ -0,0 +1,69 @@
getJasmineRequireObj().toHaveBeenCalledOnceWith = function (j$) {
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledOnceWith>', 'expect(<spyObj>).toHaveBeenCalledOnceWith(...arguments)');
/**
* {@link expect} the actual (a {@link Spy}) to have been called exactly once, and exactly with the particular arguments.
* @function
* @name matchers#toHaveBeenCalledOnceWith
* @since 3.6.0
* @param {...Object} - The arguments to look for
* @example
* expect(mySpy).toHaveBeenCalledOnceWith('foo', 'bar', 2);
*/
function toHaveBeenCalledOnceWith(util) {
return {
compare: function () {
var args = Array.prototype.slice.call(arguments, 0),
actual = args[0],
expectedArgs = args.slice(1);
if (!j$.isSpy(actual)) {
throw new Error(getErrorMsg('Expected a spy, but got ' + util.pp(actual) + '.'));
}
var prettyPrintedCalls = actual.calls.allArgs().map(function (argsForCall) {
return ' ' + util.pp(argsForCall);
});
if (actual.calls.count() === 1 && util.contains(actual.calls.allArgs(), expectedArgs)) {
return {
pass: true,
message: 'Expected spy ' + actual.and.identity + ' to have been called 0 times, multiple times, or once, but with arguments different from:\n'
+ ' ' + util.pp(expectedArgs) + '\n'
+ 'But the actual call was:\n'
+ prettyPrintedCalls.join(',\n') + '.\n\n'
};
}
function getDiffs() {
return actual.calls.allArgs().map(function (argsForCall, callIx) {
var diffBuilder = new j$.DiffBuilder();
util.equals(argsForCall, expectedArgs, diffBuilder);
return diffBuilder.getMessage();
});
}
function butString() {
switch (actual.calls.count()) {
case 0:
return 'But it was never called.\n\n';
case 1:
return 'But the actual call was:\n' + prettyPrintedCalls.join(',\n') + '.\n' + getDiffs().join('\n') + '\n\n';
default:
return 'But the actual calls were:\n' + prettyPrintedCalls.join(',\n') + '.\n\n';
}
}
return {
pass: false,
message: 'Expected spy ' + actual.and.identity + ' to have been called only once, and with given args:\n'
+ ' ' + util.pp(expectedArgs) + '\n'
+ butString()
};
}
};
}
return toHaveBeenCalledOnceWith;
};

View File

@@ -0,0 +1,42 @@
getJasmineRequireObj().toHaveSize = function(j$) {
/**
* {@link expect} the actual size to be equal to the expected, using array-like length or object keys size.
* @function
* @name matchers#toHaveSize
* @since 3.6.0
* @param {Object} expected - Expected size
* @example
* array = [1,2];
* expect(array).toHaveSize(2);
*/
function toHaveSize() {
return {
compare: function(actual, expected) {
var result = {
pass: false
};
if (j$.isA_('WeakSet', actual) || j$.isWeakMap(actual) || j$.isDataView(actual)) {
throw new Error('Cannot get size of ' + actual + '.');
}
if (j$.isSet(actual) || j$.isMap(actual)) {
result.pass = actual.size === expected;
} else if (isLength(actual.length)) {
result.pass = actual.length === expected;
} else {
result.pass = Object.keys(actual).length === expected;
}
return result;
}
};
}
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; // eslint-disable-line compat/compat
function isLength(value) {
return (typeof value == 'number') && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
return toHaveSize;
};

View File

@@ -49,7 +49,6 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.Expector = jRequire.Expector(j$);
j$.Expectation = jRequire.Expectation(j$);
j$.buildExpectationResult = jRequire.buildExpectationResult(j$);
j$.noopTimer = jRequire.noopTimer();
j$.JsApiReporter = jRequire.JsApiReporter(j$);
j$.asymmetricEqualityTesterArgCompatShim = jRequire.asymmetricEqualityTesterArgCompatShim(
j$

View File

@@ -168,6 +168,30 @@ getJasmineRequireObj().interface = function(jasmine, env) {
return env.afterAll.apply(env, arguments);
},
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}
* @name setSpecProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
setSpecProperty: function(key, value) {
return env.setSpecProperty(key, value);
},
/**
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}
* @name setSuiteProperty
* @since 3.6.0
* @function
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
setSuiteProperty: function(key, value) {
return env.setSuiteProperty(key, value);
},
/**
* Create an expectation for a spec.
* @name expect
@@ -327,7 +351,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 3.6.0
* @function
* @param {Function} formatter - A function which takes a value to format and returns a string if it knows how to format it, and `undefined` otherwise.
* @see custom_object_formatter
* @see custom_object_formatters
*/
jasmine.addCustomObjectFormatter = function(formatter) {
return env.addCustomObjectFormatter(formatter);

View File

@@ -101,7 +101,7 @@ jasmineRequire.HtmlReporter = function(j$) {
if (result.status === 'failed') {
failures.push(failureDom(result));
}
addDeprecationWarnings(result);
addDeprecationWarnings(result, 'suite');
};
this.specStarted = function(result) {
@@ -137,7 +137,7 @@ jasmineRequire.HtmlReporter = function(j$) {
failures.push(failureDom(result));
}
addDeprecationWarnings(result);
addDeprecationWarnings(result, 'spec');
};
this.displaySpecInCorrectFormat = function(result) {
@@ -276,14 +276,27 @@ jasmineRequire.HtmlReporter = function(j$) {
addDeprecationWarnings(doneResult);
var warningBarClassName = 'jasmine-bar jasmine-warning';
for (i = 0; i < deprecationWarnings.length; i++) {
var warning = deprecationWarnings[i];
var context;
switch (deprecationWarnings[i].runnableType) {
case 'spec':
context = '(in spec: ' + deprecationWarnings[i].runnableName + ')';
break;
case 'suite':
context = '(in suite: ' + deprecationWarnings[i].runnableName + ')';
break;
default:
context = '';
}
alert.appendChild(
createDom(
'span',
{ className: warningBarClassName },
'DEPRECATION: ' + warning
{ className: 'jasmine-bar jasmine-warning' },
'DEPRECATION: ' + deprecationWarnings[i].message,
createDom('br'),
context
)
);
}
@@ -321,9 +334,11 @@ jasmineRequire.HtmlReporter = function(j$) {
find('.jasmine-failures-menu').onclick = function() {
setMenuModeTo('jasmine-failure-list');
return false;
};
find('.jasmine-spec-list-menu').onclick = function() {
setMenuModeTo('jasmine-spec-list');
return false;
};
setMenuModeTo('jasmine-failure-list');
@@ -592,12 +607,16 @@ jasmineRequire.HtmlReporter = function(j$) {
return addToExistingQueryString('spec', els.join(' '));
}
function addDeprecationWarnings(result) {
function addDeprecationWarnings(result, runnableType) {
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);
deprecationWarnings.push({
message: warning,
runnableName: result.fullName,
runnableType: runnableType
});
}
}
}

View File

@@ -1,3 +1,5 @@
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
jasmineRequire.html = function(j$) {
j$.ResultsNode = jasmineRequire.ResultsNode();
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);