Compare commits
123 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b1449228f | ||
|
|
65a6decd6d | ||
|
|
7cbd86357d | ||
|
|
4f278be2c2 | ||
|
|
f2bc9b5bd8 | ||
|
|
e9d79bc946 | ||
|
|
0b2097b616 | ||
|
|
f02824ae52 | ||
|
|
225c7bdda3 | ||
|
|
e855c898d1 | ||
|
|
426eebe1ce | ||
|
|
add841a1e9 | ||
|
|
023c998660 | ||
|
|
3dde7d0c29 | ||
|
|
4e3f9a4d09 | ||
|
|
b89fbc71a7 | ||
|
|
4c0e3b2aed | ||
|
|
19f812c4f6 | ||
|
|
5ea24a8448 | ||
|
|
4173a4089c | ||
|
|
f712b795d7 | ||
|
|
ff029b37b5 | ||
|
|
7cd8c41d31 | ||
|
|
d7dd85c64f | ||
|
|
2d5c071d28 | ||
|
|
76bc0a87db | ||
|
|
5cae401c98 | ||
|
|
1d366772b7 | ||
|
|
d137b83c1c | ||
|
|
692c8716f0 | ||
|
|
965229bd03 | ||
|
|
46044dd345 | ||
|
|
2af9a45fb2 | ||
|
|
abc0c4a97e | ||
|
|
eb1d98338a | ||
|
|
f0c480f456 | ||
|
|
7693a4c959 | ||
|
|
1a08d1e8c6 | ||
|
|
ce9600a3f6 | ||
|
|
c58d83bbe3 | ||
|
|
1c6f4ef0e6 | ||
|
|
c77ff30263 | ||
|
|
dc652cfb05 | ||
|
|
22f58c0049 | ||
|
|
715de7aa38 | ||
|
|
0c68cc4afc | ||
|
|
ce6ce4e2c7 | ||
|
|
10f87b3b90 | ||
|
|
0776146d3b | ||
|
|
bbac4bb23f | ||
|
|
8c59875afe | ||
|
|
cdee9c8853 | ||
|
|
69956bf8f6 | ||
|
|
e1249ac89a | ||
|
|
a84e0cd8ef | ||
|
|
6177a4aeff | ||
|
|
471a241493 | ||
|
|
d5dfbc98c3 | ||
|
|
2ab2a83a3b | ||
|
|
f22862fd80 | ||
|
|
53b0752ff0 | ||
|
|
7616e5a3fd | ||
|
|
e173cd1c9d | ||
|
|
234dc1a047 | ||
|
|
d22a030b87 | ||
|
|
4acb7448d8 | ||
|
|
a26e85ff3a | ||
|
|
39e175c05f | ||
|
|
d129a6c0ee | ||
|
|
837101c025 | ||
|
|
8e3066db42 | ||
|
|
a857f4c042 | ||
|
|
dca543accb | ||
|
|
5dbcf27f72 | ||
|
|
b54de4a180 | ||
|
|
46509f05a9 | ||
|
|
ebaa2e7f24 | ||
|
|
5eaf7152bf | ||
|
|
ebbaab4cf9 | ||
|
|
1936a36c79 | ||
|
|
1dd4af3835 | ||
|
|
6ae054c3e2 | ||
|
|
e5feba994f | ||
|
|
20faa883fb | ||
|
|
3bba1eabd4 | ||
|
|
9ad3eac469 | ||
|
|
3140d5fb95 | ||
|
|
69a61547e7 | ||
|
|
a999490de9 | ||
|
|
c1479acd17 | ||
|
|
3a93f845d6 | ||
|
|
6c58024321 | ||
|
|
aeae141fd4 | ||
|
|
a951bbbb47 | ||
|
|
895c17e5c1 | ||
|
|
a84eaf2cbe | ||
|
|
9f240c5b9e | ||
|
|
dfa8a77dc3 | ||
|
|
2472982fe9 | ||
|
|
c85500a924 | ||
|
|
482f4d62fc | ||
|
|
bfcd8b046d | ||
|
|
2ab22951a1 | ||
|
|
6c131beda7 | ||
|
|
ea88023553 | ||
|
|
6bd98cb2ab | ||
|
|
b4b3ac25a1 | ||
|
|
7570bc422b | ||
|
|
eca8d8f009 | ||
|
|
305252f5a8 | ||
|
|
0fdb28c6ff | ||
|
|
a84202a6f9 | ||
|
|
503f4b7f49 | ||
|
|
fbe38018c9 | ||
|
|
8bb2f67fb3 | ||
|
|
ba9c863de9 | ||
|
|
02161b7d48 | ||
|
|
4d5f27d359 | ||
|
|
a4faa80be4 | ||
|
|
b68ba90ad7 | ||
|
|
dc7be9c55e | ||
|
|
ac8ef2988d | ||
|
|
b5b77b318a |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,5 +20,5 @@ sauce_connect.log
|
||||
*.swp
|
||||
build/
|
||||
*.egg-info/
|
||||
dist/*.tar.gz
|
||||
dist
|
||||
nbproject/
|
||||
|
||||
13
.npmignore
13
.npmignore
@@ -1,6 +1,7 @@
|
||||
dist/
|
||||
grunt/
|
||||
node_modules
|
||||
pkg/
|
||||
release_notes/
|
||||
spec/
|
||||
src/
|
||||
@@ -8,14 +9,20 @@ Gemfile
|
||||
Gemfile.lock
|
||||
Rakefile
|
||||
jasmine-core.gemspec
|
||||
.rspec
|
||||
.travis.yml
|
||||
.jshintrc
|
||||
.bundle/
|
||||
.gitignore
|
||||
.gitmodules
|
||||
.idea
|
||||
.jshintrc
|
||||
.rspec
|
||||
.sass-cache/
|
||||
.travis.yml
|
||||
*.sh
|
||||
*.py
|
||||
Gruntfile.js
|
||||
lib/jasmine-core.rb
|
||||
lib/jasmine-core/boot/
|
||||
lib/jasmine-core/spec
|
||||
lib/jasmine-core/version.rb
|
||||
lib/jasmine-core/*.py
|
||||
sauce_connect.log
|
||||
|
||||
14
.travis.yml
14
.travis.yml
@@ -2,7 +2,7 @@ language: ruby
|
||||
|
||||
sudo: false
|
||||
|
||||
rvm: 1.9.3
|
||||
rvm: 2.2.0
|
||||
|
||||
script: $TEST_COMMAND
|
||||
|
||||
@@ -22,6 +22,14 @@ matrix:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.10"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.9"
|
||||
- SAUCE_BROWSER_VERSION=7
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.8"
|
||||
@@ -30,6 +38,10 @@ matrix:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.6"
|
||||
- SAUCE_BROWSER_VERSION=5
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8.1"
|
||||
- SAUCE_BROWSER_VERSION=11
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8"
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
# Developing for Jasmine Core
|
||||
|
||||
We welcome your contributions - Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists (the main group - [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) and the developer's list - [http://groups.google.com/group/jasmine-js-dev](http://groups.google.com/group/jasmine-js-dev)) before starting work - what you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
|
||||
We welcome your contributions! Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
|
||||
|
||||
## Links
|
||||
|
||||
- [Jasmine Google Group](http://groups.google.com/group/jasmine-js)
|
||||
- [Jasmine-dev Google Group](http://groups.google.com/group/jasmine-js-dev)
|
||||
- [Jasmine on PivotalTracker](https://www.pivotaltracker.com/n/projects/10606)
|
||||
|
||||
## General Workflow
|
||||
|
||||
Please submit pull requests via feature branches using the semi-standard workflow of:
|
||||
|
||||
1. Fork it
|
||||
1. Clone your fork: (`git clone git@github.com:yourUserName/jasmine.git`)
|
||||
1. Change directory: (`cd jasmine`)
|
||||
1. Asign original repository to a remote named 'upstream': (`git remote add
|
||||
upstream https://github.com/pivotal/jasmine.git`)
|
||||
1. Pull in changes not present in your local repository: (`git fetch upstream`)
|
||||
1. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
1. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
1. Push to the branch (`git push origin my-new-feature`)
|
||||
1. Create new Pull Request
|
||||
```bash
|
||||
git clone git@github.com:yourUserName/jasmine.git # Clone your fork
|
||||
cd jasmine # Change directory
|
||||
git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream'
|
||||
git fetch upstream # Pull in changes not present in your local repository
|
||||
git 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
|
||||
```
|
||||
|
||||
We favor pull requests with very small, single commits with a single purpose.
|
||||
Once you've pushed a feature branch to your forked repo, you're ready to open a pull request. We favor pull requests with very small, single commits with a single purpose.
|
||||
|
||||
## Background
|
||||
|
||||
@@ -67,7 +72,11 @@ To install the Ruby dependencies, you will need Ruby, Rubygems, and Bundler avai
|
||||
|
||||
$ bundle
|
||||
|
||||
...will install all of the Ruby dependencies.
|
||||
...will install all of the Ruby dependencies. If the ffi gem fails to build its native extensions, you may need to manually install some system dependencies. On Ubuntu:
|
||||
|
||||
$ apt-get install gcc ruby ruby-dev libxml2 libxml2-dev libxslt1-dev
|
||||
|
||||
...should get you to the point that `bundle` can install everything.
|
||||
|
||||
To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http://gruntjs.com/), the [grunt-cli](https://github.com/gruntjs/grunt-cli) and ensure that `grunt` is on your path.
|
||||
|
||||
@@ -94,13 +103,13 @@ Follow these tips and your pull request, patch, or suggestion is much more likel
|
||||
|
||||
### Running Specs
|
||||
|
||||
Jasmine uses the [Jasmine Ruby gem](http://github.com/pivotal/jasmine-gem) to test itself in browser.
|
||||
Jasmine uses the [Jasmine Ruby gem](http://github.com/jasmine/jasmine-gem) to test itself in browser.
|
||||
|
||||
$ rake jasmine
|
||||
|
||||
...and then visit `http://localhost:8888` to run specs.
|
||||
|
||||
Jasmine uses the [Jasmine NPM package](http://github.com/pivotal/jasmine-npm) to test itself in a Node.js/npm environment.
|
||||
Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/jasmine-npm) to test itself in a Node.js/npm environment.
|
||||
|
||||
$ grunt execSpecsInNode
|
||||
|
||||
@@ -114,8 +123,8 @@ Jasmine uses the [Jasmine NPM package](http://github.com/pivotal/jasmine-npm) to
|
||||
|
||||
## Submitting a Pull Request
|
||||
1. Revert your changes to `jasmine.js` and `jasmine-html.js`
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches.
|
||||
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master.
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
|
||||
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
|
||||
|
||||
Note that we use Travis for Continuous Integration. We only accept green pull requests.
|
||||
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -1,5 +1,5 @@
|
||||
source 'https://rubygems.org'
|
||||
gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git'
|
||||
gem "jasmine", :git => 'https://github.com/jasmine/jasmine-gem.git'
|
||||
# gem "jasmine", path: "../jasmine-gem"
|
||||
|
||||
gemspec
|
||||
|
||||
@@ -17,7 +17,6 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('default', ['jshint:all']);
|
||||
|
||||
var version = require('./grunt/tasks/version.js');
|
||||
var standaloneBuilder = require('./grunt/tasks/build_standalone.js');
|
||||
|
||||
grunt.registerTask('build:copyVersionToGem',
|
||||
"Propagates the version from package.json to version.rb",
|
||||
@@ -43,10 +42,8 @@ module.exports = function(grunt) {
|
||||
jasmine = new Jasmine({jasmineCore: jasmineCore});
|
||||
|
||||
jasmine.loadConfigFile('./spec/support/jasmine.json');
|
||||
jasmine.configureDefaultReporter({
|
||||
onComplete: function(passed) {
|
||||
done(passed);
|
||||
}
|
||||
jasmine.onComplete(function(passed) {
|
||||
done(passed);
|
||||
});
|
||||
|
||||
jasmine.execute();
|
||||
|
||||
36
README.md
36
README.md
@@ -1,4 +1,4 @@
|
||||
<a name="README">[<img src="https://rawgithub.com/pivotal/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
|
||||
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
|
||||
|
||||
[](https://travis-ci.org/jasmine/jasmine) [](https://codeclimate.com/github/pivotal/jasmine)
|
||||
|
||||
@@ -11,37 +11,43 @@ Jasmine is a Behavior Driven Development testing framework for JavaScript. It do
|
||||
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
|
||||
For a quick start guide of Jasmine 2.0, see the beginning of [http://jasmine.github.io/2.0/introduction.html](http://jasmine.github.io/2.0/introduction.html)
|
||||
|
||||
Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/pivotal/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes).
|
||||
Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/jasmine/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes). You can also read the [upgrade guide](http://jasmine.github.io/2.0/upgrading.html).
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md)
|
||||
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## Installation
|
||||
|
||||
To install Jasmine on your local box:
|
||||
For the Jasmine NPM module:<br>
|
||||
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm)
|
||||
|
||||
* Clone Jasmine - `git clone https://github.com/pivotal/jasmine.git`
|
||||
For the Jasmine Ruby Gem:<br>
|
||||
[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)
|
||||
|
||||
To install Jasmine standalone on your local box:
|
||||
|
||||
* 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 latest dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine`
|
||||
* Move the dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine`
|
||||
* Change directory - `cd my-project/jasmine`
|
||||
* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip`
|
||||
|
||||
Add the following to your HTML file:
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">
|
||||
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">
|
||||
|
||||
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>
|
||||
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>
|
||||
|
||||
For the Jasmine Ruby Gem:<br>
|
||||
[https://github.com/pivotal/jasmine-gem](https://github.com/pivotal/jasmine-gem)
|
||||
|
||||
For the Jasmine Python Egg:<br>
|
||||
[https://github.com/pivotal/jasmine-py](https://github.com/pivotal/jasmine-py)
|
||||
## Supported environments
|
||||
|
||||
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
|
||||
|
||||
|
||||
## Support
|
||||
@@ -55,11 +61,13 @@ For the Jasmine Python Egg:<br>
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs
|
||||
* [Gregg Van Hove](mailto:ghove@pivotal.io), Pivotal Labs
|
||||
* [Gregg Van Hove](mailto:gvanhove@pivotal.io), Pivotal Labs
|
||||
* [Greg Cobb](mailto:gcobb@pivotal.io), Pivotal Labs
|
||||
* [Chris Amavisca](mailto:camavisca@pivotal.io), Pivotal Labs
|
||||
|
||||
### Maintainers Emeritus
|
||||
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry
|
||||
* Sheel Choksi
|
||||
|
||||
Copyright (c) 2008-2014 Pivotal Labs. This software is licensed under the MIT License.
|
||||
Copyright (c) 2008-2015 Pivotal Labs. This software is licensed under the MIT License.
|
||||
|
||||
15
RELEASE.md
15
RELEASE.md
@@ -15,11 +15,16 @@ Please attempt to keep commits to `master` small, but cohesive. If a feature is
|
||||
|
||||
We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
|
||||
|
||||
The current version lives in the file `/package.json`. This file should be set to the version that is _currently_ under development. That is, if version 1.0.0 is the current release then version should be incremented say, to 1.1.0.
|
||||
The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` and `bower.json` with the new version and `grunt build:copyVersionToGem` to update the gem version number.
|
||||
|
||||
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
|
||||
|
||||
Note that Jasmine should *not* use the "patch" version number. Let downstream projects rev their patch versions as needed, keeping their major and minor version numbers in sync with Jasmine core.
|
||||
Note that Jasmine should only use the "patch" version number in the following cases:
|
||||
|
||||
* Changes related to packaging for a specific platform (npm, gem, or pip).
|
||||
* Fixes for regressions.
|
||||
|
||||
When jasmine-core revs its major or minor version, the binding libraries should also rev to that version.
|
||||
|
||||
## Release
|
||||
|
||||
@@ -32,8 +37,6 @@ When ready to release - specs are all green and the stories are done:
|
||||
### Build standalone distribution
|
||||
|
||||
1. Build the standalone distribution with `grunt buildStandaloneDist`
|
||||
1. Make sure you add the new ZIP file to git
|
||||
1. Should we still do this? Given we want to use github releases...
|
||||
|
||||
### Release the Python egg
|
||||
|
||||
@@ -56,12 +59,12 @@ When ready to release - specs are all green and the stories are done:
|
||||
|
||||
Probably only need to do this when releasing a minor version, and not a patch version.
|
||||
|
||||
1. `cp edge ${version}` to copy the current edge docs to the new 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`
|
||||
|
||||
### Finally
|
||||
|
||||
1. Visit the [Releases page for Jasmine](https://github.com/pivotal/jasmine/releases), find the tag just pushed.
|
||||
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
|
||||
|
||||
41
bower.json
Normal file
41
bower.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"version": "2.3.4",
|
||||
"homepage": "http://jasmine.github.io",
|
||||
"authors": [
|
||||
"slackersoft <gregg@slackersoft.net>"
|
||||
],
|
||||
"description": "Official packaging of Jasmine's core files",
|
||||
"keywords": [
|
||||
"test",
|
||||
"jasmine",
|
||||
"tdd",
|
||||
"bdd"
|
||||
],
|
||||
"license": "MIT",
|
||||
"moduleType": "globals",
|
||||
"main": "lib/jasmine-core/jasmine.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"dist",
|
||||
"grunt",
|
||||
"node_modules",
|
||||
"pkg",
|
||||
"release_notes",
|
||||
"spec",
|
||||
"src",
|
||||
"Gemfile",
|
||||
"Gemfile.lock",
|
||||
"Rakefile",
|
||||
"jasmine-core.gemspec",
|
||||
"*.sh",
|
||||
"*.py",
|
||||
"Gruntfile.js",
|
||||
"lib/jasmine-core.rb",
|
||||
"lib/jasmine-core/boot/",
|
||||
"lib/jasmine-core/spec",
|
||||
"lib/jasmine-core/version.rb",
|
||||
"lib/jasmine-core/*.py",
|
||||
"sauce_connect.log"
|
||||
]
|
||||
}
|
||||
BIN
dist/jasmine-standalone-1.0.0.zip
vendored
BIN
dist/jasmine-standalone-1.0.0.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-1.1.0.zip
vendored
BIN
dist/jasmine-standalone-1.1.0.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-1.2.0.zip
vendored
BIN
dist/jasmine-standalone-1.2.0.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-1.3.0.zip
vendored
BIN
dist/jasmine-standalone-1.3.0.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-1.3.1.zip
vendored
BIN
dist/jasmine-standalone-1.3.1.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.0.zip
vendored
BIN
dist/jasmine-standalone-2.0.0.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.1.zip
vendored
BIN
dist/jasmine-standalone-2.0.1.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.2.zip
vendored
BIN
dist/jasmine-standalone-2.0.2.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.3.zip
vendored
BIN
dist/jasmine-standalone-2.0.3.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.1.0.zip
vendored
BIN
dist/jasmine-standalone-2.1.0.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.1.1.zip
vendored
BIN
dist/jasmine-standalone-2.1.1.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.1.2.zip
vendored
BIN
dist/jasmine-standalone-2.1.2.zip
vendored
Binary file not shown.
BIN
dist/jasmine-standalone-2.1.3.zip
vendored
BIN
dist/jasmine-standalone-2.1.3.zip
vendored
Binary file not shown.
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
||||
s.summary = %q{JavaScript BDD framework}
|
||||
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
|
||||
s.email = %q{jasmine-js@googlegroups.com}
|
||||
s.homepage = "http://pivotal.github.com/jasmine"
|
||||
s.homepage = "http://jasmine.github.io"
|
||||
s.rubyforge_project = "jasmine-core"
|
||||
s.license = "MIT"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
Copyright (c) 2008-2015 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
Copyright (c) 2008-2015 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -57,13 +57,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
* 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`.
|
||||
*/
|
||||
if (typeof window == "undefined" && typeof exports == "object") {
|
||||
extend(exports, jasmineInterface);
|
||||
} else {
|
||||
extend(window, jasmineInterface);
|
||||
}
|
||||
extend(window, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
@@ -78,13 +74,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
|
||||
/**
|
||||
* ## Reporters
|
||||
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
|
||||
@@ -35,13 +35,9 @@
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
* 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`.
|
||||
*/
|
||||
if (typeof window == "undefined" && typeof exports == "object") {
|
||||
extend(exports, jasmineInterface);
|
||||
} else {
|
||||
extend(window, jasmineInterface);
|
||||
}
|
||||
extend(window, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
@@ -56,13 +52,18 @@
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
|
||||
/**
|
||||
* ## Reporters
|
||||
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe("Player", function() {
|
||||
var Player = require('../src/Player.js');
|
||||
var Song = require('../src/Song.js');
|
||||
var Player = require('../../lib/jasmine_examples/Player');
|
||||
var Song = require('../../lib/jasmine_examples/Song');
|
||||
var player;
|
||||
var song;
|
||||
|
||||
@@ -7,7 +7,7 @@ beforeEach(function () {
|
||||
|
||||
return {
|
||||
pass: player.currentlyPlayingSong === expected && player.isPlaying
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
Copyright (c) 2008-2015 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -40,6 +40,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
@@ -144,22 +146,51 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
this.jasmineDone = function() {
|
||||
var banner = find('.banner');
|
||||
banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
var alert = find('.alert');
|
||||
alert.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
alert.appendChild(createDom('span', { className: 'exceptions' },
|
||||
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
|
||||
createDom('input', {
|
||||
className: 'raise',
|
||||
id: 'raise-exceptions',
|
||||
type: 'checkbox'
|
||||
})
|
||||
));
|
||||
var checkbox = find('#raise-exceptions');
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'run-options' },
|
||||
createDom('span', { className: 'trigger' }, 'Options'),
|
||||
createDom('div', { className: 'payload' },
|
||||
createDom('div', { className: 'exceptions' },
|
||||
createDom('input', {
|
||||
className: 'raise',
|
||||
id: 'raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'throw',
|
||||
id: 'throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'label', 'for': 'throw-failures' }, 'stop spec on expectation failure'))
|
||||
)
|
||||
));
|
||||
|
||||
checkbox.checked = !env.catchingExceptions();
|
||||
checkbox.onclick = onRaiseExceptionsClick;
|
||||
var raiseCheckbox = find('#raise-exceptions');
|
||||
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var optionsMenu = find('.run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.payload'),
|
||||
isOpen = /\bopen\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' open';
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
@@ -220,6 +251,9 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: resultNode.result.status,
|
||||
@@ -267,7 +301,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
function clearPrior() {
|
||||
// return the reporter
|
||||
var oldReporter = find('');
|
||||
|
||||
|
||||
if(oldReporter) {
|
||||
getContainer().removeChild(oldReporter);
|
||||
}
|
||||
@@ -306,7 +340,11 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return '?spec=' + encodeURIComponent(result.fullName);
|
||||
return addToExistingQueryString('spec', result.fullName);
|
||||
}
|
||||
|
||||
function defaultQueryString(key, value) {
|
||||
return '?' + key + '=' + value;
|
||||
}
|
||||
|
||||
function setMenuModeTo(mode) {
|
||||
@@ -358,10 +396,14 @@ jasmineRequire.ResultsNode = function() {
|
||||
jasmineRequire.QueryString = function() {
|
||||
function QueryString(options) {
|
||||
|
||||
this.setParam = function(key, value) {
|
||||
this.navigateWithNewParam = function(key, value) {
|
||||
options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
|
||||
};
|
||||
|
||||
this.fullStringWithNewParam = function(key, value) {
|
||||
var paramMap = queryStringToParamMap();
|
||||
paramMap[key] = value;
|
||||
options.getWindowLocation().search = toQueryString(paramMap);
|
||||
return toQueryString(paramMap);
|
||||
};
|
||||
|
||||
this.getParam = function(key) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
Copyright (c) 2008-2015 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "2.1.3"
|
||||
VERSION = "2.3.4"
|
||||
end
|
||||
end
|
||||
|
||||
25
package.json
25
package.json
@@ -1,23 +1,34 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "2.1.3",
|
||||
"version": "2.3.4",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pivotal/jasmine.git"
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
},
|
||||
"keywords": [
|
||||
"test",
|
||||
"jasmine",
|
||||
"tdd",
|
||||
"bdd"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/grunt jshint execSpecsInNode"
|
||||
},
|
||||
"description": "Official packaging of Jasmine's core files for use by Node.js projects.",
|
||||
"homepage": "http://jasmine.github.io",
|
||||
"main": "./lib/jasmine-core.js",
|
||||
"devDependencies": {
|
||||
"glob": "~3.2.9",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-contrib-jshint": "~0.7.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-cli": "^0.1.13",
|
||||
"grunt-contrib-compass": "~0.6.0",
|
||||
"grunt-contrib-compress": "~0.5.2",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-jshint": "~0.7.0",
|
||||
"jasmine": "https://github.com/jasmine/jasmine-npm/archive/master.tar.gz",
|
||||
"load-grunt-tasks": "^0.4.0",
|
||||
"shelljs": "~0.1.4",
|
||||
"glob": "~3.2.9",
|
||||
"jasmine": "https://github.com/pivotal/jasmine-npm/archive/master.tar.gz",
|
||||
"load-grunt-tasks": "^0.4.0"
|
||||
"temp": "~0.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
98
release_notes/2.2.0.md
Normal file
98
release_notes/2.2.0.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Jasmine Core 2.2.0 Release Notes
|
||||
|
||||
## Changes
|
||||
|
||||
* `ObjectContaining` no longer tries to track exact mismatches
|
||||
* HTML reporter keeps extra query params when focusing on a spec or suite
|
||||
* Check custom properties on Arrays when computing equality
|
||||
* Better error message if `spyOn` is called without a method name
|
||||
* Rename `jasmineMatches` to `asymmetricMatch`
|
||||
* Don't double escape focus spec links
|
||||
* Jasmine equality checks if either side implements `asymmetricMatch`
|
||||
* Add asymmetric equality tester to match a string with a RegExp
|
||||
* Add jshint to node build on Travis for pull request builds
|
||||
* Restructure node examples directory to look more realistic
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Add a basic bower config
|
||||
- Fixes [#719](https://github.com/jasmine/jasmine/issues/719)
|
||||
|
||||
* Allow `pending` to take a reason and show it in the HtmlReporter
|
||||
- Fixes [#671](https://github.com/jasmine/jasmine/issues/671)
|
||||
|
||||
* Set jasmineGlobal correctly in GJS
|
||||
- Merges [#757](https://github.com/jasmine/jasmine/issues/757) from @ptomato
|
||||
- Fixes [#751](https://github.com/jasmine/jasmine/issues/751)
|
||||
|
||||
* Fix some SpiderMonkey lint warnings
|
||||
- Merges [#752](https://github.com/jasmine/jasmine/issues/752) from @ptomato
|
||||
- Fixes [#751](https://github.com/jasmine/jasmine/issues/751)
|
||||
|
||||
* Prevents *Alls from running when runnables are explicitly set
|
||||
- Fixes [#732](https://github.com/jasmine/jasmine/issues/732)
|
||||
|
||||
* Update contribution guide to mention possible ffi dependencies for Ubuntu
|
||||
- Fixes [#755](https://github.com/jasmine/jasmine/issues/755)
|
||||
|
||||
* Fix spelling mistake in contributors guide
|
||||
- Merges [#746](https://github.com/jasmine/jasmine/issues/746) from @swirlycheetah
|
||||
|
||||
* Use new jasmine github repo url
|
||||
- Merges [#745](https://github.com/jasmine/jasmine/issues/745) rohit
|
||||
|
||||
* Allow `createSpyObj` to be called with just an array of method names
|
||||
- Fixes [#321](https://github.com/jasmine/jasmine/issues/321)
|
||||
|
||||
* Add `arrayContaining` matcher
|
||||
- Merges [#440](https://github.com/jasmine/jasmine/issues/440) from @slackersoft
|
||||
|
||||
* Use the stack trace from the Error object if supplied
|
||||
- Fixes [#734](https://github.com/jasmine/jasmine/issues/734)
|
||||
|
||||
* Update readme with link to upgrading doc and mention browser support.
|
||||
- Fixes [#739](https://github.com/jasmine/jasmine/issues/739)
|
||||
|
||||
* Link to the Jasmine NPM module
|
||||
- Merges [#736](https://github.com/jasmine/jasmine/issues/736) from @moonmaster9000
|
||||
|
||||
* Allow null prototype objects to be compared for equality
|
||||
- Merges [#731](https://github.com/jasmine/jasmine/issues/731) from @rohit
|
||||
- Fixes [#729](https://github.com/jasmine/jasmine/issues/729)
|
||||
|
||||
* Fix URL's of Jasmine repositories on Github
|
||||
- Merges [#730](https://github.com/jasmine/jasmine/issues/730) from @rohit
|
||||
|
||||
* Add `anything` matcher to match any value that is neither null or undefined
|
||||
- Fixes [#186](https://github.com/jasmine/jasmine/issues/186)
|
||||
|
||||
* Allow asymmetric equality testers to preempt their symmetric brethren
|
||||
- Fixes [#540](https://github.com/jasmine/jasmine/issues/540)
|
||||
|
||||
* Check for `ObjectContaining` on either side of equality
|
||||
- Fixes [#682](https://github.com/jasmine/jasmine/issues/682)
|
||||
|
||||
* Display the name of the constructor when pretty printing objects
|
||||
- Fixes [#598](https://github.com/jasmine/jasmine/issues/598)
|
||||
|
||||
* `toMatch` requires the `expected` to be a String or RegExp
|
||||
- Fixes [#723](https://github.com/jasmine/jasmine/issues/723)
|
||||
|
||||
* Better equality comparison of Dom nodes
|
||||
- Merges [#657](https://github.com/jasmine/jasmine/issues/657) from @alexeibs
|
||||
|
||||
* Hide unnecessary files from the npm package
|
||||
- Fixes [#726](https://github.com/jasmine/jasmine/issues/726)
|
||||
|
||||
* Properly record finishing an `xdescribe` so further cleanup works
|
||||
- Fixes [#724](https://github.com/jasmine/jasmine/issues/724)
|
||||
|
||||
* Reschedule all functions for a tick before executing any. This allows any function run during a tick to cancel any other in the same tick.
|
||||
- Fixes [#708](https://github.com/jasmine/jasmine/issues/708)
|
||||
|
||||
* Pass through all args from external interface for befores, afters, its
|
||||
- Fixes [#483](https://github.com/jasmine/jasmine/issues/483)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
15
release_notes/2.2.1.md
Normal file
15
release_notes/2.2.1.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Jasmine Core 2.2.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release to fix the packaging for bower
|
||||
|
||||
## Changes
|
||||
|
||||
* Fix missing comma on bower.json
|
||||
- Merges [#763](https://github.com/jasmine/jasmine/issues/763) from @gabrielhpugliese
|
||||
- Merges [#764](https://github.com/jasmine/jasmine/issues/764) from @joshuacc
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
81
release_notes/2.3.0.md
Normal file
81
release_notes/2.3.0.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Jasmine Core 2.3.0 Release Notes
|
||||
|
||||
## Changes
|
||||
|
||||
* Style disabled specs in the results list
|
||||
* Use `onclick` directly to better support older webkit
|
||||
* Don't use deprecated `onComplete` syntax for jasmine-npm
|
||||
* Allow the clock to be installed for the duration of a single closure
|
||||
* Add safari 7 & 8 to browser matrix
|
||||
* Remove unused standaloneBuilder var from Gruntfile
|
||||
* Add test script to package.json
|
||||
* Update bower.json keywords to match package.json keywords
|
||||
* Add keywords to package.json
|
||||
* refuse to execute an order if it would cause a suite with a beforeAll or afterAll to be re-entered after leaving once
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Specify a main entry point for bower so it can be loaded easier
|
||||
- Merges [#827](https://github.com/jasmine/jasmine/issues/827) from @davetron5000
|
||||
|
||||
* Use `instanceof` when checking Error types in toThrowError
|
||||
- Fixes [#819](https://github.com/jasmine/jasmine/issues/819)
|
||||
|
||||
* Remove periods from bullet points for consistency with rest of document
|
||||
- Merge [#818](https://github.com/jasmine/jasmine/issues/818) from @lpww
|
||||
|
||||
* Subjective readability improvements to CONTRIBUTING.md
|
||||
- Merge [#815](https://github.com/jasmine/jasmine/issues/815) from @jhamon
|
||||
|
||||
* Don't install the clock if the current timing functions aren't the originals
|
||||
- Fixes [#782](https://github.com/jasmine/jasmine/issues/782)
|
||||
|
||||
* Properly pass `j$` to `Any` so it can use other jasmine stuff
|
||||
- Fixes [#806](https://github.com/jasmine/jasmine/issues/806)
|
||||
|
||||
* Correctly handle functions that are scheduled after the clock is uninstalled and reinstalled from within Clock#tick.
|
||||
- Merges [#804](https://github.com/jasmine/jasmine/issues/804) from @sgravrock
|
||||
- Fixes [#790](https://github.com/jasmine/jasmine/issues/790).
|
||||
|
||||
* Allow user to stop a specs execution when an expectation fails
|
||||
- Fixes [#577](https://github.com/jasmine/jasmine/issues/577)
|
||||
|
||||
* Remove unnecessary conditional
|
||||
- Merges [#788](https://github.com/jasmine/jasmine/issues/788) from @toddbranch
|
||||
|
||||
* Show the name of the constructor function when printing an `any` instead of a `toString` of the entire constructor
|
||||
- Fixes [#796](https://github.com/jasmine/jasmine/issues/796)
|
||||
|
||||
* Don't use hardcoded temporary directory paths
|
||||
- Merges [#789](https://github.com/jasmine/jasmine/issues/789) from sgravrock
|
||||
|
||||
* Execute beforeAll/afterAll once per suite instead of once per child when running focused specs/suites
|
||||
- Fixes [#773](https://github.com/jasmine/jasmine/issues/773)
|
||||
|
||||
* Report children of an xdescribe similarly to how they would be reported if they were themselves x'd out
|
||||
- Fixes [#774](https://github.com/jasmine/jasmine/issues/774)
|
||||
- Fixes [#776](https://github.com/jasmine/jasmine/issues/776)
|
||||
|
||||
* Fixes issue where mock clock was being used by QueueRunner
|
||||
- Fixes [#783](https://github.com/jasmine/jasmine/issues/783)
|
||||
- Fixes [#792](https://github.com/jasmine/jasmine/issues/792)
|
||||
|
||||
* add missing semicolon
|
||||
- Merges [#775](https://github.com/jasmine/jasmine/issues/775) from @joscha
|
||||
|
||||
* ObjectContaining matches prototype properties
|
||||
- Fixes [#769](https://github.com/jasmine/jasmine/issues/769)
|
||||
|
||||
* Updates pretty printer to include array properties
|
||||
- Fixes [#766](https://github.com/jasmine/jasmine/issues/766)
|
||||
|
||||
* Update year copyright
|
||||
- Merges [#768](https://github.com/jasmine/jasmine/issues/768) from @danilovaz
|
||||
|
||||
* Allow arrays from different frames or contexts to be equal
|
||||
- Merges [#767](https://github.com/jasmine/jasmine/issues/767) from @juliemr
|
||||
- Fixes [#765](https://github.com/jasmine/jasmine/issues/765)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
14
release_notes/2.3.1.md
Normal file
14
release_notes/2.3.1.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Jasmine 2.3.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is a packaging update for bower only.
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Point Bower's main field to jasmine.js, which is browser-friendly.
|
||||
- Merge [#843](https://github.com/jasmine/jasmine/issues/843) from @evoL
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
14
release_notes/2.3.2.md
Normal file
14
release_notes/2.3.2.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Jasmine 2.3.2 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release to fix a regression with specs declared without a function body
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* A spec without a function provided should be `pending` not `disabled`
|
||||
- Fixes [#840](https://github.com/jasmine/jasmine/issues/840)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
14
release_notes/2.3.3.md
Normal file
14
release_notes/2.3.3.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Jasmine 2.3.3 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release to fix a regression with the execution context for `beforeAll`
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Set the shared user context correctly when executing the top level suite
|
||||
- Fixes [#846](https://github.com/jasmine/jasmine/issues/846)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
22
release_notes/2.3.4.md
Normal file
22
release_notes/2.3.4.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Jasmine 2.3.4 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release to fix a regression with execution ordering
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Fix ordering for suites with more than 11 direct children.
|
||||
- Fixes [#850](https://github.com/jasmine/jasmine/issues/850)
|
||||
|
||||
* Update standalone installation instructions to reference the releases page
|
||||
- Fixes [#603](https://github.com/jasmine/jasmine/issues/603)
|
||||
|
||||
* Remove dead CSS class styles
|
||||
- Merges [#849](https://github.com/jasmine/jasmine/issues/849) from @prather-mcs
|
||||
- Merges [#848](https://github.com/jasmine/jasmine/issues/848) from @prather-mcs
|
||||
- Fixes [#847](https://github.com/jasmine/jasmine/issues/847)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
2
setup.py
2
setup.py
@@ -7,7 +7,7 @@ with open('package.json') as packageFile:
|
||||
setup(
|
||||
name="jasmine-core",
|
||||
version=version,
|
||||
url="http://pivotal.github.io/jasmine/",
|
||||
url="http://jasmine.github.io",
|
||||
author="Pivotal Labs",
|
||||
author_email="jasmine-js@googlegroups.com",
|
||||
description=('Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on '+
|
||||
|
||||
@@ -6,7 +6,7 @@ describe("Clock", function() {
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("Clock", function() {
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
|
||||
@@ -50,7 +50,7 @@ describe("Clock", function() {
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
fakeGlobal.setInterval(delayedFn, 0);
|
||||
|
||||
@@ -72,7 +72,7 @@ describe("Clock", function() {
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
fakeGlobal.clearInterval("foo");
|
||||
|
||||
@@ -88,6 +88,78 @@ describe("Clock", function() {
|
||||
expect(fakeClearInterval).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not install if the current setTimeout is not the original function on the global", function() {
|
||||
var originalFakeSetTimeout = function() {},
|
||||
replacedSetTimeout = function() {},
|
||||
fakeGlobal = { setTimeout: originalFakeSetTimeout },
|
||||
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
|
||||
mockDate = {},
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
|
||||
|
||||
fakeGlobal.setTimeout = replacedSetTimeout;
|
||||
|
||||
expect(function() {
|
||||
clock.install();
|
||||
}).toThrowError(/unable to install/);
|
||||
|
||||
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
|
||||
expect(fakeGlobal.setTimeout).toBe(replacedSetTimeout);
|
||||
});
|
||||
|
||||
it("does not install if the current clearTimeout is not the original function on the global", function() {
|
||||
var originalFakeClearTimeout = function() {},
|
||||
replacedClearTimeout = function() {},
|
||||
fakeGlobal = { clearTimeout: originalFakeClearTimeout },
|
||||
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
|
||||
mockDate = {},
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
|
||||
|
||||
fakeGlobal.clearTimeout = replacedClearTimeout;
|
||||
|
||||
expect(function() {
|
||||
clock.install();
|
||||
}).toThrowError(/unable to install/);
|
||||
|
||||
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
|
||||
expect(fakeGlobal.clearTimeout).toBe(replacedClearTimeout);
|
||||
});
|
||||
|
||||
it("does not install if the current setInterval is not the original function on the global", function() {
|
||||
var originalFakeSetInterval = function() {},
|
||||
replacedSetInterval = function() {},
|
||||
fakeGlobal = { setInterval: originalFakeSetInterval },
|
||||
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
|
||||
mockDate = {},
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
|
||||
|
||||
fakeGlobal.setInterval = replacedSetInterval;
|
||||
|
||||
expect(function() {
|
||||
clock.install();
|
||||
}).toThrowError(/unable to install/);
|
||||
|
||||
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
|
||||
expect(fakeGlobal.setInterval).toBe(replacedSetInterval);
|
||||
});
|
||||
|
||||
it("does not install if the current clearInterval is not the original function on the global", function() {
|
||||
var originalFakeClearInterval = function() {},
|
||||
replacedClearInterval = function() {},
|
||||
fakeGlobal = { clearInterval: originalFakeClearInterval },
|
||||
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
|
||||
mockDate = {},
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
|
||||
|
||||
fakeGlobal.clearInterval = replacedClearInterval;
|
||||
|
||||
expect(function() {
|
||||
clock.install();
|
||||
}).toThrowError(/unable to install/);
|
||||
|
||||
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
|
||||
expect(fakeGlobal.clearInterval).toBe(replacedClearInterval);
|
||||
});
|
||||
|
||||
it("replaces the global timer functions on uninstall", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
|
||||
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
|
||||
@@ -102,7 +174,7 @@ describe("Clock", function() {
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.uninstall();
|
||||
@@ -118,6 +190,103 @@ describe("Clock", function() {
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be installed for the duration of a passed in function and uninstalled when done", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
|
||||
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
|
||||
fakeSetInterval = jasmine.createSpy("global setInterval"),
|
||||
fakeClearInterval = jasmine.createSpy("global clearInterval"),
|
||||
fakeGlobal = {
|
||||
setTimeout: fakeSetTimeout,
|
||||
clearTimeout: fakeClearTimeout,
|
||||
setInterval: fakeSetInterval,
|
||||
clearInterval: fakeClearInterval
|
||||
},
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset", "removeFunctionWithId"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
passedFunctionCalled = false;
|
||||
|
||||
clock.withMock(function() {
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
fakeGlobal.setInterval(delayedFn, 10);
|
||||
fakeGlobal.clearInterval("bar");
|
||||
passedFunctionCalled = true;
|
||||
});
|
||||
|
||||
expect(passedFunctionCalled).toBe(true);
|
||||
|
||||
expect(fakeSetTimeout).not.toHaveBeenCalled();
|
||||
expect(fakeClearTimeout).not.toHaveBeenCalled();
|
||||
expect(fakeSetInterval).not.toHaveBeenCalled();
|
||||
expect(fakeClearInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction.calls.reset();
|
||||
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
fakeGlobal.setInterval(delayedFn, 10);
|
||||
fakeGlobal.clearInterval("bar");
|
||||
|
||||
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
|
||||
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
|
||||
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 10);
|
||||
expect(fakeClearInterval).toHaveBeenCalledWith("bar");
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be installed for the duration of a passed in function and uninstalled if an error is thrown", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
|
||||
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
|
||||
fakeSetInterval = jasmine.createSpy("global setInterval"),
|
||||
fakeClearInterval = jasmine.createSpy("global clearInterval"),
|
||||
fakeGlobal = {
|
||||
setTimeout: fakeSetTimeout,
|
||||
clearTimeout: fakeClearTimeout,
|
||||
setInterval: fakeSetInterval,
|
||||
clearInterval: fakeClearInterval
|
||||
},
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset", "removeFunctionWithId"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
passedFunctionCalled = false;
|
||||
|
||||
expect(function() {
|
||||
clock.withMock(function() {
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
fakeGlobal.setInterval(delayedFn, 10);
|
||||
fakeGlobal.clearInterval("bar");
|
||||
passedFunctionCalled = true;
|
||||
throw 'oops';
|
||||
});
|
||||
}).toThrow('oops');
|
||||
|
||||
expect(passedFunctionCalled).toBe(true);
|
||||
|
||||
expect(fakeSetTimeout).not.toHaveBeenCalled();
|
||||
expect(fakeClearTimeout).not.toHaveBeenCalled();
|
||||
expect(fakeSetInterval).not.toHaveBeenCalled();
|
||||
expect(fakeClearInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction.calls.reset();
|
||||
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
fakeGlobal.setInterval(delayedFn, 10);
|
||||
fakeGlobal.clearInterval("bar");
|
||||
|
||||
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
|
||||
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
|
||||
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 10);
|
||||
expect(fakeClearInterval).toHaveBeenCalledWith("bar");
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules the delayed function (via setTimeout) with the fake timer", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction'),
|
||||
@@ -125,7 +294,7 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn, 0, 'a', 'b');
|
||||
@@ -142,7 +311,7 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate),
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeoutId;
|
||||
|
||||
clock.install();
|
||||
@@ -157,7 +326,7 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setTimeout: fakeClearTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.clearTimeout(123);
|
||||
@@ -173,7 +342,7 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setInterval: fakeSetInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.setInterval(delayedFn, 0, 'a', 'b');
|
||||
@@ -190,7 +359,7 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setInterval: fakeSetInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate),
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
intervalId;
|
||||
|
||||
clock.install();
|
||||
@@ -205,7 +374,7 @@ describe("Clock", function() {
|
||||
fakeGlobal = { setInterval: clearInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.clearInterval(123);
|
||||
@@ -232,7 +401,7 @@ describe("Clock", function() {
|
||||
setInterval: fakeSetInterval
|
||||
},
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
fakeSetTimeout.apply = null;
|
||||
fakeSetInterval.apply = null;
|
||||
@@ -251,7 +420,6 @@ describe("Clock", function() {
|
||||
clock.setInterval(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Clock (acceptance)", function() {
|
||||
@@ -262,7 +430,7 @@ describe("Clock (acceptance)", function() {
|
||||
recurring1 = jasmine.createSpy('recurring1'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
@@ -309,7 +477,7 @@ describe("Clock (acceptance)", function() {
|
||||
var clearedFn = jasmine.createSpy('clearedFn'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate),
|
||||
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
timeoutId;
|
||||
|
||||
clock.install();
|
||||
@@ -327,7 +495,7 @@ describe("Clock (acceptance)", function() {
|
||||
var spy = jasmine.createSpy('spy'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setInterval: function() {}}, delayedFunctionScheduler, mockDate),
|
||||
clock = new j$.Clock({setInterval: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
intervalId;
|
||||
|
||||
clock.install();
|
||||
@@ -345,7 +513,7 @@ describe("Clock (acceptance)", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
@@ -362,7 +530,7 @@ describe("Clock (acceptance)", function() {
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 0); });
|
||||
clock.install();
|
||||
@@ -381,7 +549,7 @@ describe("Clock (acceptance)", function() {
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 1); });
|
||||
clock.install();
|
||||
@@ -392,11 +560,35 @@ describe("Clock (acceptance)", function() {
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("correctly schedules functions scheduled while the Clock is advancing but after the Clock is uninstalled", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
delayedFn1.and.callFake(function() {
|
||||
clock.uninstall();
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn2, 0);
|
||||
});
|
||||
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn1, 1);
|
||||
|
||||
clock.tick(1);
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(1);
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not mock the Date object by default", function() {
|
||||
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
global = {Date: Date},
|
||||
mockDate = new j$.MockDate(global),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
@@ -413,7 +605,7 @@ describe("Clock (acceptance)", function() {
|
||||
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
global = {Date: Date},
|
||||
mockDate = new j$.MockDate(global),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
|
||||
|
||||
clock.install().mockDate();
|
||||
|
||||
@@ -437,7 +629,7 @@ describe("Clock (acceptance)", function() {
|
||||
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
global = {Date: Date},
|
||||
mockDate = new j$.MockDate(global),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
baseTime = new Date(2013, 9, 23);
|
||||
|
||||
|
||||
|
||||
@@ -113,47 +113,6 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reset removes scheduled functions", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.reset();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reset resets the returned ids", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler();
|
||||
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
|
||||
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
|
||||
|
||||
scheduler.reset();
|
||||
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
|
||||
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
|
||||
});
|
||||
|
||||
it("reset resets the current tick time", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(15);
|
||||
scheduler.reset();
|
||||
|
||||
scheduler.scheduleFunction(fn, 20, [], false, 1, 20);
|
||||
|
||||
scheduler.tick(5);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions interleaved with regular functions in the correct order", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
@@ -255,5 +214,42 @@ describe("DelayedFunctionScheduler", function() {
|
||||
scheduler.tick(10);
|
||||
});
|
||||
|
||||
it("removes functions during a tick that runs the function", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, 2 * fnDelay);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(3 * fnDelay);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(fn.calls.count()).toBe(2);
|
||||
});
|
||||
|
||||
it("removes functions during the first tick that runs the function", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, fnDelay);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(3 * fnDelay);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(fn.calls.count()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,12 @@ describe("Env", function() {
|
||||
env.pending();
|
||||
}).toThrow(j$.Spec.pendingSpecExceptionMessage);
|
||||
});
|
||||
|
||||
it("throws the Pending Spec exception with a custom message", function() {
|
||||
expect(function() {
|
||||
env.pending('custom message');
|
||||
}).toThrow(j$.Spec.pendingSpecExceptionMessage + 'custom message');
|
||||
});
|
||||
});
|
||||
|
||||
describe("#topSuite", function() {
|
||||
@@ -19,4 +25,24 @@ describe("Env", function() {
|
||||
expect(suite.description).toEqual('Jasmine__TopLevel__Suite');
|
||||
});
|
||||
});
|
||||
|
||||
it('can configure specs to throw errors on expectation failures', function() {
|
||||
env.throwOnExpectationFailure(true);
|
||||
|
||||
spyOn(j$, 'Spec');
|
||||
env.it('foo', function() {});
|
||||
expect(j$.Spec).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
throwOnExpectationFailure: true
|
||||
}));
|
||||
});
|
||||
|
||||
it('can configure suites to throw errors on expectation failures', function() {
|
||||
env.throwOnExpectationFailure(true);
|
||||
|
||||
spyOn(j$, 'Suite');
|
||||
env.describe('foo', function() {});
|
||||
expect(j$.Suite).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
throwOnExpectationFailure: true
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
describe("ObjectContaining", function() {
|
||||
|
||||
it("matches any actual to an empty object", function() {
|
||||
var containing = new j$.ObjectContaining({});
|
||||
|
||||
expect(containing.jasmineMatches("foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match an empty object actual", function() {
|
||||
var containing = new j$.ObjectContaining("foo");
|
||||
|
||||
expect(function() {
|
||||
containing.jasmineMatches({})
|
||||
}).toThrowError(/not 'foo'/)
|
||||
});
|
||||
|
||||
it("matches when the key/value pair is present in the actual", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "fooVal"});
|
||||
|
||||
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"})).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match when the key/value pair is not present in the actual", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "fooVal"});
|
||||
|
||||
expect(containing.jasmineMatches({bar: "barVal", quux: "quuxVal"})).toBe(false);
|
||||
});
|
||||
|
||||
it("does not match when the key is present but the value is different in the actual", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "other"});
|
||||
|
||||
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"})).toBe(false);
|
||||
});
|
||||
|
||||
it("mismatchValues parameter must return array with mismatched reason", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "other"});
|
||||
|
||||
var mismatchKeys = [];
|
||||
var mismatchValues = [];
|
||||
|
||||
containing.jasmineMatches({foo: "fooVal", bar: "barVal"}, mismatchKeys, mismatchValues);
|
||||
|
||||
expect(mismatchValues.length).toBe(1);
|
||||
expect(mismatchValues[0]).toEqual("'foo' was 'fooVal' in actual, but was 'other' in expected.");
|
||||
});
|
||||
|
||||
it("adds keys in expected but not actual to the mismatchKeys parameter", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "fooVal"});
|
||||
|
||||
var mismatchKeys = [];
|
||||
var mismatchValues = [];
|
||||
|
||||
containing.jasmineMatches({bar: "barVal"}, mismatchKeys, mismatchValues);
|
||||
|
||||
expect(mismatchKeys.length).toBe(1);
|
||||
expect(mismatchKeys[0]).toEqual("expected has key 'foo', but missing from actual.");
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var containing = new j$.ObjectContaining({});
|
||||
|
||||
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
|
||||
});
|
||||
|
||||
it("matches recursively", function() {
|
||||
var containing = new j$.ObjectContaining({one: new j$.ObjectContaining({two: {}})});
|
||||
|
||||
expect(containing.jasmineMatches({one: {two: {}}})).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -14,36 +14,78 @@ describe("j$.pp", function () {
|
||||
expect(j$.pp(-0)).toEqual("-0");
|
||||
});
|
||||
|
||||
it("should stringify arrays properly", function() {
|
||||
expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
|
||||
expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', { }, undefined, null ]");
|
||||
});
|
||||
describe('stringify arrays', function() {
|
||||
it("should stringify arrays properly", function() {
|
||||
expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
|
||||
expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', Object({ }), undefined, null ]");
|
||||
});
|
||||
|
||||
it("should indicate circular array references", function() {
|
||||
var array1 = [1, 2];
|
||||
var array2 = [array1];
|
||||
array1.push(array2);
|
||||
expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
|
||||
});
|
||||
it("should truncate arrays that are longer than j$.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var array = [1, 2, 3];
|
||||
|
||||
it("should not indicate circular references incorrectly", function() {
|
||||
var array = [ [1] ];
|
||||
expect(j$.pp(array)).toEqual("[ [ 1 ] ]");
|
||||
try {
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(j$.pp(array)).toEqual("[ 1, 2, ... ]");
|
||||
} finally {
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify arrays with properties properly", function() {
|
||||
var arr = [1, 2];
|
||||
arr.foo = 'bar';
|
||||
arr.baz = {};
|
||||
expect(j$.pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
|
||||
});
|
||||
|
||||
it("should stringify empty arrays with properties properly", function() {
|
||||
var empty = [];
|
||||
empty.foo = 'bar';
|
||||
empty.baz = {};
|
||||
expect(j$.pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
|
||||
});
|
||||
|
||||
it("should stringify long arrays with properties properly", function() {
|
||||
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var long = [1,2,3];
|
||||
long.foo = 'bar';
|
||||
long.baz = {};
|
||||
|
||||
try {
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(j$.pp(long)).toEqual("[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]");
|
||||
} finally {
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
});
|
||||
|
||||
it("should indicate circular array references", function() {
|
||||
var array1 = [1, 2];
|
||||
var array2 = [array1];
|
||||
array1.push(array2);
|
||||
expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
|
||||
});
|
||||
|
||||
it("should not indicate circular references incorrectly", function() {
|
||||
var array = [ [1] ];
|
||||
expect(j$.pp(array)).toEqual("[ [ 1 ] ]");
|
||||
});
|
||||
});
|
||||
|
||||
it("should stringify objects properly", function() {
|
||||
expect(j$.pp({foo: 'bar'})).toEqual("{ foo: 'bar' }");
|
||||
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined }");
|
||||
expect(j$.pp({foo: 'bar'})).toEqual("Object({ foo: 'bar' })");
|
||||
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })");
|
||||
expect(j$.pp({foo: function () {
|
||||
}, bar: [1, 2, 3]})).toEqual("{ foo: Function, bar: [ 1, 2, 3 ] }");
|
||||
}, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
|
||||
});
|
||||
|
||||
it("should not include inherited properties when stringifying an object", function() {
|
||||
var SomeClass = function() {};
|
||||
var SomeClass = function SomeClass() {};
|
||||
SomeClass.prototype.foo = "inherited foo";
|
||||
var instance = new SomeClass();
|
||||
instance.bar = "my own bar";
|
||||
expect(j$.pp(instance)).toEqual("{ bar: 'my own bar' }");
|
||||
expect(j$.pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
|
||||
});
|
||||
|
||||
it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
|
||||
@@ -53,15 +95,15 @@ describe("j$.pp", function () {
|
||||
|
||||
try {
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 2;
|
||||
expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: Object } }");
|
||||
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object }) })");
|
||||
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
|
||||
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 3;
|
||||
expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: { level3: Object } } }");
|
||||
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object }) }) })");
|
||||
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
|
||||
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 4;
|
||||
expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: { level3: { level4: 'leaf' } } } }");
|
||||
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })");
|
||||
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
|
||||
} finally {
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
|
||||
@@ -73,19 +115,7 @@ describe("j$.pp", function () {
|
||||
var frozenObject = {foo: {bar: 'baz'}};
|
||||
frozenObject.circular = frozenObject;
|
||||
frozenObject = Object.freeze(frozenObject);
|
||||
expect(j$.pp(frozenObject)).toEqual("{ foo: { bar: 'baz' }, circular: <circular reference: Object> }");
|
||||
}
|
||||
});
|
||||
|
||||
it("should truncate arrays that are longer than j$.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var array = [1, 2, 3];
|
||||
|
||||
try {
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(j$.pp(array)).toEqual("[ 1, 2, ... ]");
|
||||
} finally {
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
expect(j$.pp(frozenObject)).toEqual("Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -96,7 +126,7 @@ describe("j$.pp", function () {
|
||||
it("should indicate circular object references", function() {
|
||||
var sampleValue = {foo: 'hello'};
|
||||
sampleValue.nested = sampleValue;
|
||||
expect(j$.pp(sampleValue)).toEqual("{ foo: 'hello', nested: <circular reference: Object> }");
|
||||
expect(j$.pp(sampleValue)).toEqual("Object({ foo: 'hello', nested: <circular reference: Object> })");
|
||||
});
|
||||
|
||||
it("should indicate getters on objects as such", function() {
|
||||
@@ -108,10 +138,10 @@ describe("j$.pp", function () {
|
||||
});
|
||||
}
|
||||
if (sampleValue.__defineGetter__) {
|
||||
expect(j$.pp(sampleValue)).toEqual("{ id: 1, calculatedValue: <getter> }");
|
||||
expect(j$.pp(sampleValue)).toEqual("Object({ id: 1, calculatedValue: <getter> })");
|
||||
}
|
||||
else {
|
||||
expect(j$.pp(sampleValue)).toEqual("{ id: 1 }");
|
||||
expect(j$.pp(sampleValue)).toEqual("Object({ id: 1 })");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -157,6 +187,6 @@ describe("j$.pp", function () {
|
||||
var obj = Object.create(null);
|
||||
obj.foo = 'bar';
|
||||
|
||||
expect(j$.pp(obj)).toEqual("{ foo: 'bar' }");
|
||||
expect(j$.pp(obj)).toEqual("null({ foo: 'bar' })");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,10 @@ describe("Spec", function() {
|
||||
expect(j$.Spec.isPendingSpecException(fakeError)).toBe(true);
|
||||
});
|
||||
|
||||
it("#isPendingSpecException returns true for a pending spec exception with a custom message", function() {
|
||||
expect(j$.Spec.isPendingSpecException(j$.Spec.pendingSpecExceptionMessage + 'foo')).toBe(true);
|
||||
});
|
||||
|
||||
it("#isPendingSpecException returns false for not a pending spec exception", function() {
|
||||
var e = new Error("foo");
|
||||
|
||||
@@ -115,7 +119,6 @@ describe("Spec", function() {
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
|
||||
expect(spec.status()).toBe('pending');
|
||||
});
|
||||
|
||||
@@ -144,6 +147,29 @@ describe("Spec", function() {
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be disabled at execution time by a parent", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
specBody = jasmine.createSpy('specBody'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart:startCallback,
|
||||
queueableFn: { fn: specBody },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute(undefined, false);
|
||||
|
||||
expect(spec.result.status).toBe('disabled');
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
expect(specBody).not.toHaveBeenCalled();
|
||||
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be marked pending, but still calls callbacks when executed", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
@@ -174,7 +200,8 @@ describe("Spec", function() {
|
||||
description: 'with a spec',
|
||||
fullName: 'a suite with a spec',
|
||||
failedExpectations: [],
|
||||
passedExpectations: []
|
||||
passedExpectations: [],
|
||||
pendingReason: ''
|
||||
});
|
||||
});
|
||||
|
||||
@@ -227,6 +254,40 @@ describe("Spec", function() {
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['expectation2']);
|
||||
});
|
||||
|
||||
it("throws an ExpectationFailed error upon receiving a failed expectation when 'throwOnExpectationFailure' is set", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
spec.addExpectationResult(true, 'passed');
|
||||
expect(function() {
|
||||
spec.addExpectationResult(false, 'failed')
|
||||
}).toThrowError(j$.errors.ExpectationFailed);
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['passed']);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['failed']);
|
||||
});
|
||||
|
||||
it("does not throw an ExpectationFailed error when handling an error", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
spec.onException('failing exception');
|
||||
});
|
||||
|
||||
it("can return its full name", function() {
|
||||
var specNameSpy = jasmine.createSpy('specNameSpy').and.returnValue('expected val');
|
||||
|
||||
@@ -239,7 +300,7 @@ describe("Spec", function() {
|
||||
expect(specNameSpy.calls.mostRecent().args[0].id).toEqual(spec.id);
|
||||
});
|
||||
|
||||
describe("when a spec is marked pending during execution", function() {
|
||||
describe("when a spec is marked pending during execution", function() {
|
||||
it("should mark the spec as pending", function() {
|
||||
var fakeQueueRunner = function(opts) {
|
||||
opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage));
|
||||
@@ -254,6 +315,106 @@ describe("Spec", function() {
|
||||
spec.execute();
|
||||
|
||||
expect(spec.status()).toEqual("pending");
|
||||
expect(spec.result.pendingReason).toEqual('');
|
||||
});
|
||||
|
||||
it("should set the pendingReason", function() {
|
||||
var fakeQueueRunner = function(opts) {
|
||||
opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage + 'custom message'));
|
||||
},
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
queueableFn: { fn: function() { } },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(spec.status()).toEqual("pending");
|
||||
expect(spec.result.pendingReason).toEqual('custom message');
|
||||
});
|
||||
});
|
||||
|
||||
it("should log a failure when handling an exception", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException('foo');
|
||||
spec.execute();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([{
|
||||
error: 'foo',
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: ''
|
||||
}]);
|
||||
});
|
||||
|
||||
it("should not log an additional failure when handling an ExpectationFailed error", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException(new j$.errors.ExpectationFailed());
|
||||
spec.execute();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it("retrieves a result with updated status", function() {
|
||||
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
|
||||
|
||||
expect(spec.getResult().status).toBe('passed');
|
||||
});
|
||||
|
||||
it("retrives a result with disabled status", function() {
|
||||
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
|
||||
spec.disable();
|
||||
|
||||
expect(spec.getResult().status).toBe('disabled');
|
||||
});
|
||||
|
||||
it("retrives a result with pending status", function() {
|
||||
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
|
||||
spec.pend();
|
||||
|
||||
expect(spec.getResult().status).toBe('pending');
|
||||
});
|
||||
|
||||
it("should not be executable when disabled", function() {
|
||||
var spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.disable();
|
||||
|
||||
expect(spec.isExecutable()).toBe(false);
|
||||
});
|
||||
|
||||
it("should be executable when pending", function() {
|
||||
var spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.pend();
|
||||
|
||||
expect(spec.isExecutable()).toBe(true);
|
||||
});
|
||||
|
||||
it("should be executable when not disabled or pending", function() {
|
||||
var spec = new j$.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
|
||||
expect(spec.isExecutable()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,6 +7,15 @@ describe("SpyRegistry", function() {
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it("checks that a method name was passed", function() {
|
||||
var spyRegistry = new j$.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject);
|
||||
}).toThrowError(/No method name supplied/);
|
||||
});
|
||||
|
||||
it("checks for the existence of the method", function() {
|
||||
var spyRegistry = new j$.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('Spies', function () {
|
||||
TestClass.prototype.someFunction = function() {};
|
||||
TestClass.prototype.someFunction.bob = "test";
|
||||
});
|
||||
|
||||
|
||||
it("preserves the properties of the spied function", function() {
|
||||
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
|
||||
@@ -68,6 +68,14 @@ describe('Spies', function () {
|
||||
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
|
||||
});
|
||||
|
||||
it("should allow you to omit the baseName", function() {
|
||||
var spyObj = j$.createSpyObj(['method1', 'method2']);
|
||||
|
||||
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
|
||||
expect(spyObj.method1.and.identity()).toEqual('unknown.method1');
|
||||
expect(spyObj.method2.and.identity()).toEqual('unknown.method2');
|
||||
});
|
||||
|
||||
it("should throw if you do not pass an array argument", function() {
|
||||
expect(function() {
|
||||
j$.createSpyObj('BaseName');
|
||||
|
||||
@@ -52,31 +52,6 @@ describe("Suite", function() {
|
||||
expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
|
||||
});
|
||||
|
||||
it("runs beforeAll functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
firstBefore = jasmine.createSpy('outerBeforeAll'),
|
||||
lastBefore = jasmine.createSpy('insideBeforeAll'),
|
||||
fakeIt = {execute: jasmine.createSpy('it'), isExecutable: function() { return true; } };
|
||||
|
||||
suite.beforeAll(firstBefore);
|
||||
suite.beforeAll(lastBefore);
|
||||
suite.addChild(fakeIt);
|
||||
|
||||
suite.execute();
|
||||
var suiteFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
suiteFns[0]();
|
||||
expect(firstBefore).toHaveBeenCalled();
|
||||
suiteFns[1]();
|
||||
expect(lastBefore).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("adds after functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
suite = new j$.Suite({
|
||||
@@ -92,218 +67,6 @@ describe("Suite", function() {
|
||||
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
|
||||
});
|
||||
|
||||
it("runs afterAll functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
firstAfter = jasmine.createSpy('outerAfterAll'),
|
||||
lastAfter = jasmine.createSpy('insideAfterAll'),
|
||||
fakeIt = {execute: jasmine.createSpy('it'), isExecutable: function() { return true; } };
|
||||
|
||||
suite.afterAll(firstAfter);
|
||||
suite.afterAll(lastAfter);
|
||||
suite.addChild(fakeIt);
|
||||
|
||||
suite.execute();
|
||||
var suiteFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
suiteFns[1]();
|
||||
expect(firstAfter).toHaveBeenCalled();
|
||||
suiteFns[2]();
|
||||
expect(lastAfter).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be disabled, but still calls callbacks", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
onStart = jasmine.createSpy('onStart'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
onStart: onStart,
|
||||
resultCallback: resultCallback,
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
|
||||
suite.disable();
|
||||
|
||||
expect(suite.disabled).toBe(true);
|
||||
|
||||
suite.execute(onComplete);
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
expect(onStart).toHaveBeenCalled();
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("delegates execution of its specs, suites, beforeAlls, and afterAlls", function() {
|
||||
var env = new j$.Env(),
|
||||
parentSuiteDone = jasmine.createSpy('parent suite done'),
|
||||
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
|
||||
parentSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a parent suite",
|
||||
queueRunner: fakeQueueRunnerForParent
|
||||
}),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1'),
|
||||
isExecutable: function() { return true; }
|
||||
},
|
||||
beforeAllFn = { fn: jasmine.createSpy('beforeAll') },
|
||||
afterAllFn = { fn: jasmine.createSpy('afterAll') };
|
||||
|
||||
spyOn(suite, "execute");
|
||||
|
||||
parentSuite.addChild(fakeSpec1);
|
||||
parentSuite.addChild(suite);
|
||||
parentSuite.beforeAll(beforeAllFn);
|
||||
parentSuite.afterAll(afterAllFn);
|
||||
|
||||
parentSuite.execute(parentSuiteDone);
|
||||
|
||||
var parentSuiteFns = fakeQueueRunnerForParent.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
parentSuiteFns[0].fn();
|
||||
expect(beforeAllFn.fn).toHaveBeenCalled();
|
||||
parentSuiteFns[1].fn();
|
||||
expect(fakeSpec1.execute).toHaveBeenCalled();
|
||||
parentSuiteFns[2].fn();
|
||||
expect(suite.execute).toHaveBeenCalled();
|
||||
parentSuiteFns[3].fn();
|
||||
expect(afterAllFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not run beforeAll or afterAll if there are no executable child specs", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
|
||||
fakeQueueRunnerForChild = jasmine.createSpy('fake child queue runner'),
|
||||
parentSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunnerForParent
|
||||
}),
|
||||
childSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunnerForChild,
|
||||
parentSuite: parentSuite
|
||||
}),
|
||||
beforeAllFn = jasmine.createSpy('beforeAll'),
|
||||
afterAllFn = jasmine.createSpy('afterAll');
|
||||
|
||||
parentSuite.addChild(childSuite);
|
||||
parentSuite.beforeAll(beforeAllFn);
|
||||
parentSuite.afterAll(afterAllFn);
|
||||
|
||||
parentSuite.execute();
|
||||
expect(fakeQueueRunnerForParent).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
queueableFns: [{ fn: jasmine.any(Function) }]
|
||||
}));
|
||||
});
|
||||
|
||||
it("calls a provided onStart callback when starting", function() {
|
||||
var env = new j$.Env(),
|
||||
suiteStarted = jasmine.createSpy('suiteStarted'),
|
||||
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
onStart: suiteStarted,
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1'),
|
||||
isExecutable: function() { return true; }
|
||||
};
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(suiteStarted).toHaveBeenCalledWith(suite);
|
||||
});
|
||||
|
||||
it("calls a provided onComplete callback when done", function() {
|
||||
var env = new j$.Env(),
|
||||
suiteCompleted = jasmine.createSpy('parent suite done'),
|
||||
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
};
|
||||
|
||||
suite.execute(suiteCompleted);
|
||||
|
||||
expect(suiteCompleted).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided result callback when done", function() {
|
||||
var env = new j$.Env(),
|
||||
suiteResultsCallback = jasmine.createSpy('suite result callback'),
|
||||
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner,
|
||||
resultCallback: suiteResultsCallback
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
};
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(suiteResultsCallback).toHaveBeenCalledWith({
|
||||
id: suite.id,
|
||||
status: 'finished',
|
||||
description: "with a child suite",
|
||||
fullName: "with a child suite",
|
||||
failedExpectations: []
|
||||
});
|
||||
});
|
||||
|
||||
it("calls a provided result callback with status being disabled when disabled and done", function() {
|
||||
var env = new j$.Env(),
|
||||
suiteResultsCallback = jasmine.createSpy('suite result callback'),
|
||||
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner,
|
||||
resultCallback: suiteResultsCallback
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
};
|
||||
|
||||
suite.disable();
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(suiteResultsCallback).toHaveBeenCalledWith({
|
||||
id: suite.id,
|
||||
status: 'disabled',
|
||||
description: "with a child suite",
|
||||
fullName: "with a child suite",
|
||||
failedExpectations: []
|
||||
});
|
||||
});
|
||||
|
||||
it('has a status of failed if any afterAll expectations have failed', function() {
|
||||
var suite = new j$.Suite({
|
||||
expectationResultFactory: function() { return 'hi'; }
|
||||
@@ -313,4 +76,70 @@ describe("Suite", function() {
|
||||
suite.addExpectationResult(false);
|
||||
expect(suite.status()).toBe('failed');
|
||||
});
|
||||
|
||||
it("retrieves a result with updated status", function() {
|
||||
var suite = new j$.Suite({});
|
||||
|
||||
expect(suite.getResult().status).toBe('finished');
|
||||
});
|
||||
|
||||
it("retrieves a result with disabled status", function() {
|
||||
var suite = new j$.Suite({});
|
||||
suite.disable();
|
||||
|
||||
expect(suite.getResult().status).toBe('disabled');
|
||||
});
|
||||
|
||||
it("is executable if not disabled", function() {
|
||||
var suite = new j$.Suite({});
|
||||
|
||||
expect(suite.isExecutable()).toBe(true);
|
||||
});
|
||||
|
||||
it("is not executable if disabled", function() {
|
||||
var suite = new j$.Suite({});
|
||||
suite.disable();
|
||||
|
||||
expect(suite.isExecutable()).toBe(false);
|
||||
});
|
||||
|
||||
it("tells all children about expectation failures, even if one throws", function() {
|
||||
var suite = new j$.Suite({}),
|
||||
child1 = { addExpectationResult: jasmine.createSpy('child1#expectationResult'), result: {} },
|
||||
child2 = { addExpectationResult: jasmine.createSpy('child2#expectationResult'), result: {} };
|
||||
|
||||
suite.addChild(child1);
|
||||
suite.addChild(child2);
|
||||
|
||||
child1.addExpectationResult.and.throwError('foo');
|
||||
|
||||
suite.addExpectationResult('stuff');
|
||||
|
||||
expect(child1.addExpectationResult).toHaveBeenCalledWith('stuff');
|
||||
expect(child2.addExpectationResult).toHaveBeenCalledWith('stuff');
|
||||
});
|
||||
|
||||
it("throws an ExpectationFailed when receiving a failed expectation in an afterAll when throwOnExpectationFailure is set", function() {
|
||||
var suite = new j$.Suite({
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
suite.addChild({ result: { status: 'done' } });
|
||||
|
||||
expect(function() {
|
||||
suite.addExpectationResult(false, 'failed');
|
||||
}).toThrowError(j$.errors.ExpectationFailed);
|
||||
|
||||
expect(suite.status()).toBe('failed');
|
||||
expect(suite.result.failedExpectations).toEqual(['failed']);
|
||||
});
|
||||
|
||||
it("does not add an additional failure when an expectation fails in an afterAll", function(){
|
||||
var suite = new j$.Suite({});
|
||||
suite.addChild({ result: { status: 'done' } });
|
||||
|
||||
suite.onException(new j$.errors.ExpectationFailed());
|
||||
|
||||
expect(suite.getResult().failedExpectations).toEqual([]);
|
||||
})
|
||||
});
|
||||
|
||||
693
spec/core/TreeProcessorSpec.js
Normal file
693
spec/core/TreeProcessorSpec.js
Normal file
@@ -0,0 +1,693 @@
|
||||
describe("TreeProcessor", function() {
|
||||
var nodeNumber = 0, leafNumber = 0;
|
||||
|
||||
function Node(attrs) {
|
||||
attrs = attrs || {};
|
||||
this.id = 'node' + nodeNumber++;
|
||||
this.children = attrs.children || [];
|
||||
this.canBeReentered = function() {
|
||||
return !attrs.noReenter;
|
||||
};
|
||||
this.isExecutable = function() {
|
||||
return attrs.executable !== false;
|
||||
};
|
||||
this.sharedUserContext = function() {
|
||||
return attrs.userContext || {};
|
||||
};
|
||||
this.getResult = jasmine.createSpy(this.id + '#execute');
|
||||
this.beforeAllFns = attrs.beforeAllFns || [];
|
||||
this.afterAllFns = attrs.afterAllFns || [];
|
||||
}
|
||||
|
||||
function Leaf(attrs) {
|
||||
attrs = attrs || {};
|
||||
this.id = 'leaf' + leafNumber++;
|
||||
this.isExecutable = function() {
|
||||
return attrs.executable !== false;
|
||||
};
|
||||
this.execute = jasmine.createSpy(this.id + '#execute');
|
||||
}
|
||||
|
||||
it("processes a single executable leaf", function() {
|
||||
var leaf = new Leaf(),
|
||||
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a single non-executable leaf", function() {
|
||||
var leaf = new Leaf({ executable: false }),
|
||||
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a single non-specified leaf", function() {
|
||||
var leaf = new Leaf(),
|
||||
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a tree with a single leaf with the root specified", function() {
|
||||
var leaf = new Leaf(),
|
||||
parent = new Node({ children: [leaf] }),
|
||||
processor = new j$.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[parent.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a tree with a single non-executable leaf, with the root specified", function() {
|
||||
var leaf = new Leaf({ executable: false }),
|
||||
parent = new Node({ children: [leaf] }),
|
||||
processor = new j$.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[parent.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[leaf.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("processes a complicated tree with the root specified", function() {
|
||||
var nonExecutable = new Leaf({ executable: false }),
|
||||
executable = new Leaf({ executable: true }),
|
||||
parent = new Node({ children: [nonExecutable, executable] }),
|
||||
childless = new Node(),
|
||||
childOfDisabled = new Leaf({ executable: true }),
|
||||
disabledNode = new Node({ executable: false, children: [childOfDisabled] }),
|
||||
root = new Node({ children: [parent, childless, disabledNode] }),
|
||||
processor = new j$.TreeProcessor({ tree: root, runnableIds: [root.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
expect(result[root.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[childless.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[nonExecutable.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[executable.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[parent.id]).toEqual({
|
||||
executable: true,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[disabledNode.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
|
||||
expect(result[childOfDisabled.id]).toEqual({
|
||||
executable: false,
|
||||
segments: jasmine.any(Array)
|
||||
});
|
||||
});
|
||||
|
||||
it("marks the run order invalid if it would re-enter a node that does not allow re-entry", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
reentered = new Node({ noReenter: true, children: [leaf1, leaf2] }),
|
||||
root = new Node({ children: [reentered, leaf3] }),
|
||||
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result).toEqual({ valid: false });
|
||||
});
|
||||
|
||||
it("marks the run order valid if a node being re-entered allows re-entry", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
reentered = new Node({ children: [leaf1, leaf2] }),
|
||||
root = new Node({ children: [reentered, leaf3] }),
|
||||
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
});
|
||||
|
||||
it("marks the run order valid if a node which can't be re-entered is only entered once", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
noReentry = new Node({ noReenter: true }),
|
||||
root = new Node({ children: [noReentry] }),
|
||||
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf2.id, leaf1.id, leaf3.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
});
|
||||
|
||||
it("marks the run order valid if a node which can't be re-entered is run directly", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
noReentry = new Node({ noReenter: true }),
|
||||
root = new Node({ children: [noReentry] }),
|
||||
processor = new j$.TreeProcessor({ tree: root, runnableIds: [root.id] }),
|
||||
result = processor.processTree();
|
||||
|
||||
expect(result.valid).toBe(true);
|
||||
});
|
||||
|
||||
it("runs a single leaf", function() {
|
||||
var leaf = new Leaf(),
|
||||
node = new Node({ children: [leaf], userContext: { root: 'context' } }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({ tree: node, runnableIds: [leaf.id], queueRunnerFactory: queueRunner }),
|
||||
treeComplete = jasmine.createSpy('treeComplete');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
|
||||
expect(queueRunner).toHaveBeenCalledWith({
|
||||
onComplete: treeComplete,
|
||||
onException: jasmine.any(Function),
|
||||
userContext: { root: 'context' },
|
||||
queueableFns: [{ fn: jasmine.any(Function) }]
|
||||
});
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
|
||||
|
||||
expect(leaf.execute).toHaveBeenCalledWith('foo', true);
|
||||
});
|
||||
|
||||
it("runs a node with no children", function() {
|
||||
var node = new Node({ userContext: { node: 'context' } }),
|
||||
root = new Node({ children: [node], userContext: { root: 'context' } }),
|
||||
nodeStart = jasmine.createSpy('nodeStart'),
|
||||
nodeComplete = jasmine.createSpy('nodeComplete'),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
nodeStart: nodeStart,
|
||||
nodeComplete: nodeComplete,
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
|
||||
expect(queueRunner).toHaveBeenCalledWith({
|
||||
onComplete: treeComplete,
|
||||
onException: jasmine.any(Function),
|
||||
userContext: { root: 'context' },
|
||||
queueableFns: [{ fn: jasmine.any(Function) }]
|
||||
});
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn(nodeDone);
|
||||
|
||||
expect(nodeStart).toHaveBeenCalledWith(node);
|
||||
expect(queueRunner).toHaveBeenCalledWith({
|
||||
onComplete: jasmine.any(Function),
|
||||
queueableFns: [],
|
||||
userContext: { node: 'context' },
|
||||
onException: jasmine.any(Function)
|
||||
});
|
||||
|
||||
node.getResult.and.returnValue({ my: 'result' });
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].onComplete();
|
||||
expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' });
|
||||
expect(nodeDone).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs a node with children", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
node = new Node({ children: [leaf1, leaf2] }),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(2);
|
||||
|
||||
queueableFns[0].fn('foo');
|
||||
expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
|
||||
|
||||
queueableFns[1].fn('bar');
|
||||
expect(leaf2.execute).toHaveBeenCalledWith('bar', true);
|
||||
});
|
||||
|
||||
it("runs a disabled node", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
node = new Node({ children: [leaf1], executable: false }),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
nodeStart = jasmine.createSpy('nodeStart'),
|
||||
nodeComplete = jasmine.createSpy('nodeComplete'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner,
|
||||
nodeStart: nodeStart,
|
||||
nodeComplete: nodeComplete
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
expect(nodeStart).toHaveBeenCalledWith(node);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(1);
|
||||
|
||||
queueableFns[0].fn('foo');
|
||||
expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
|
||||
|
||||
node.getResult.and.returnValue({ im: 'disabled' });
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].onComplete();
|
||||
expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' });
|
||||
});
|
||||
|
||||
it("runs beforeAlls for a node with children", function() {
|
||||
var leaf = new Leaf(),
|
||||
node = new Node({
|
||||
children: [leaf],
|
||||
beforeAllFns: ['beforeAll1', 'beforeAll2']
|
||||
}),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual(['beforeAll1', 'beforeAll2', { fn: jasmine.any(Function) }]);
|
||||
});
|
||||
|
||||
it("runs afterAlls for a node with children", function() {
|
||||
var leaf = new Leaf(),
|
||||
node = new Node({
|
||||
children: [leaf],
|
||||
afterAllFns: ['afterAll1', 'afterAll2']
|
||||
}),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, 'afterAll1', 'afterAll2']);
|
||||
});
|
||||
|
||||
it("does not run beforeAlls or afterAlls for a node with no children", function() {
|
||||
var node = new Node({
|
||||
beforeAllFns: ['before'],
|
||||
afterAllFns: ['after']
|
||||
}),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([]);
|
||||
});
|
||||
|
||||
it("does not run beforeAlls or afterAlls for a disabled node", function() {
|
||||
var leaf = new Leaf(),
|
||||
node = new Node({
|
||||
children: [leaf],
|
||||
beforeAllFns: ['before'],
|
||||
afterAllFns: ['after'],
|
||||
executable: false
|
||||
}),
|
||||
root = new Node({ children: [node] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [node.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete'),
|
||||
nodeDone = jasmine.createSpy('nodeDone');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn(nodeDone);
|
||||
|
||||
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }]);
|
||||
});
|
||||
|
||||
it("runs leaves in the order specified", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
root = new Node({ children: [leaf1, leaf2] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [leaf2.id, leaf1.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn();
|
||||
|
||||
expect(leaf1.execute).not.toHaveBeenCalled();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs specified leaves before non-specified leaves", function() {
|
||||
var specified = new Leaf(),
|
||||
nonSpecified = new Leaf(),
|
||||
root = new Node({ children: [nonSpecified, specified] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [specified.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
}),
|
||||
treeComplete = jasmine.createSpy('treeComplete');
|
||||
|
||||
processor.execute(treeComplete);
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn();
|
||||
|
||||
expect(nonSpecified.execute).not.toHaveBeenCalled();
|
||||
expect(specified.execute).toHaveBeenCalledWith(undefined, true);
|
||||
|
||||
queueableFns[1].fn();
|
||||
|
||||
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, false);
|
||||
});
|
||||
|
||||
it("runs nodes and leaves with a specified order", function() {
|
||||
var specifiedLeaf = new Leaf(),
|
||||
childLeaf = new Leaf(),
|
||||
specifiedNode = new Node({ children: [childLeaf] }),
|
||||
root = new Node({ children: [specifiedLeaf, specifiedNode] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [specifiedNode.id, specifiedLeaf.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
});
|
||||
|
||||
processor.execute();
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
queueableFns[0].fn();
|
||||
|
||||
expect(specifiedLeaf.execute).not.toHaveBeenCalled();
|
||||
var nodeQueueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
nodeQueueableFns[0].fn();
|
||||
|
||||
expect(childLeaf.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
|
||||
expect(specifiedLeaf.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs a node multiple times if the order specified leaves and re-enters it", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
leaf4 = new Leaf(),
|
||||
leaf5 = new Leaf(),
|
||||
reentered = new Node({ children: [leaf1, leaf2, leaf3] }),
|
||||
root = new Node({ children: [reentered, leaf4, leaf5] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [leaf1.id, leaf4.id, leaf2.id, leaf5.id, leaf3.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
});
|
||||
|
||||
processor.execute();
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(5);
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
expect(leaf4.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[2].fn();
|
||||
expect(queueRunner.calls.count()).toBe(3);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[3].fn();
|
||||
expect(leaf5.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[4].fn();
|
||||
expect(queueRunner.calls.count()).toBe(4);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs a parent of a node with segments correctly", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
leaf4 = new Leaf(),
|
||||
leaf5 = new Leaf(),
|
||||
parent = new Node({ children: [leaf1, leaf2, leaf3] }),
|
||||
grandparent = new Node({ children: [parent] }),
|
||||
root = new Node({ children: [grandparent, leaf4, leaf5] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [leaf1.id, leaf4.id, leaf2.id, leaf5.id, leaf3.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
});
|
||||
|
||||
processor.execute();
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(5);
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(2);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(3);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
expect(leaf4.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[2].fn();
|
||||
expect(queueRunner.calls.count()).toBe(4);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(5);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[3].fn();
|
||||
expect(leaf5.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[4].fn();
|
||||
expect(queueRunner.calls.count()).toBe(6);
|
||||
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(queueRunner.calls.count()).toBe(7);
|
||||
|
||||
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs nodes in the order they were declared", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
parent = new Node({ children: [leaf2, leaf3] }),
|
||||
root = new Node({ children: [leaf1, parent] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [root.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
});
|
||||
|
||||
processor.execute();
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(2);
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
|
||||
var childFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(childFns.length).toBe(2);
|
||||
childFns[0].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
childFns[1].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs large segments of nodes in the order they were declared", function() {
|
||||
var leaf1 = new Leaf(),
|
||||
leaf2 = new Leaf(),
|
||||
leaf3 = new Leaf(),
|
||||
leaf4 = new Leaf(),
|
||||
leaf5 = new Leaf(),
|
||||
leaf6 = new Leaf(),
|
||||
leaf7 = new Leaf(),
|
||||
leaf8 = new Leaf(),
|
||||
leaf9 = new Leaf(),
|
||||
leaf10 = new Leaf(),
|
||||
leaf11 = new Leaf(),
|
||||
root = new Node({ children: [leaf1, leaf2, leaf3, leaf4, leaf5, leaf6, leaf7, leaf8, leaf9, leaf10, leaf11] }),
|
||||
queueRunner = jasmine.createSpy('queueRunner'),
|
||||
processor = new j$.TreeProcessor({
|
||||
tree: root,
|
||||
runnableIds: [root.id],
|
||||
queueRunnerFactory: queueRunner
|
||||
});
|
||||
|
||||
processor.execute();
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(11);
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[2].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[3].fn();
|
||||
expect(leaf4.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[4].fn();
|
||||
expect(leaf5.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[5].fn();
|
||||
expect(leaf6.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[6].fn();
|
||||
expect(leaf7.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[7].fn();
|
||||
expect(leaf8.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[8].fn();
|
||||
expect(leaf9.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[9].fn();
|
||||
expect(leaf10.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[10].fn();
|
||||
expect(leaf11.execute).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -2,45 +2,44 @@ describe("Any", function() {
|
||||
it("matches a string", function() {
|
||||
var any = new j$.Any(String);
|
||||
|
||||
expect(any.jasmineMatches("foo")).toBe(true);
|
||||
expect(any.asymmetricMatch("foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a number", function() {
|
||||
var any = new j$.Any(Number);
|
||||
|
||||
expect(any.jasmineMatches(1)).toBe(true);
|
||||
expect(any.asymmetricMatch(1)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a function", function() {
|
||||
var any = new j$.Any(Function);
|
||||
|
||||
expect(any.jasmineMatches(function(){})).toBe(true);
|
||||
expect(any.asymmetricMatch(function(){})).toBe(true);
|
||||
});
|
||||
|
||||
it("matches an Object", function() {
|
||||
var any = new j$.Any(Object);
|
||||
|
||||
expect(any.jasmineMatches({})).toBe(true);
|
||||
expect(any.asymmetricMatch({})).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it("matches a Boolean", function() {
|
||||
var any = new j$.Any(Boolean);
|
||||
|
||||
expect(any.jasmineMatches(true)).toBe(true);
|
||||
expect(any.asymmetricMatch(true)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches another constructed object", function() {
|
||||
var Thing = function() {},
|
||||
any = new j$.Any(Thing);
|
||||
|
||||
expect(any.jasmineMatches(new Thing())).toBe(true);
|
||||
expect(any.asymmetricMatch(new Thing())).toBe(true);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var any = new j$.Any(Number);
|
||||
|
||||
expect(any.jasmineToString()).toMatch('<jasmine.any');
|
||||
expect(any.jasmineToString()).toMatch('Number');
|
||||
expect(any.jasmineToString()).toEqual('<jasmine.any(Number)>');
|
||||
});
|
||||
|
||||
});
|
||||
44
spec/core/asymmetric_equality/AnythingSpec.js
Normal file
44
spec/core/asymmetric_equality/AnythingSpec.js
Normal file
@@ -0,0 +1,44 @@
|
||||
describe("Anything", function() {
|
||||
it("matches a string", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch('foo')).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a number", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch(42)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches an object", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch({ foo: 'bar' })).toBe(true);
|
||||
});
|
||||
|
||||
it("matches an array", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch([1,2,3])).toBe(true);
|
||||
});
|
||||
|
||||
it("doesn't match undefined", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch()).toBe(false);
|
||||
expect(anything.asymmetricMatch(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it("doesn't match null", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.asymmetricMatch(null)).toBe(false);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var anything = new j$.Anything();
|
||||
|
||||
expect(anything.jasmineToString()).toEqual("<jasmine.anything>");
|
||||
});
|
||||
});
|
||||
39
spec/core/asymmetric_equality/ArrayContainingSpec.js
Normal file
39
spec/core/asymmetric_equality/ArrayContainingSpec.js
Normal file
@@ -0,0 +1,39 @@
|
||||
describe("ArrayContaining", function() {
|
||||
it("matches any actual to an empty array", function() {
|
||||
var containing = new j$.ArrayContaining([]);
|
||||
|
||||
expect(containing.asymmetricMatch("foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("does not work when not passed an array", function() {
|
||||
var containing = new j$.ArrayContaining("foo");
|
||||
|
||||
expect(function() {
|
||||
containing.asymmetricMatch([]);
|
||||
}).toThrowError(/not 'foo'/);
|
||||
});
|
||||
|
||||
it("matches when the item is in the actual", function() {
|
||||
var containing = new j$.ArrayContaining(["foo"]);
|
||||
|
||||
expect(containing.asymmetricMatch(["foo"])).toBe(true);
|
||||
});
|
||||
|
||||
it("matches when additional items are in the actual", function() {
|
||||
var containing = new j$.ArrayContaining(["foo"]);
|
||||
|
||||
expect(containing.asymmetricMatch(["foo", "bar"])).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match when the item is not in the actual", function() {
|
||||
var containing = new j$.ArrayContaining(["foo"]);
|
||||
|
||||
expect(containing.asymmetricMatch(["bar"])).toBe(false);
|
||||
});
|
||||
|
||||
it("jasmineToStrings itself", function() {
|
||||
var containing = new j$.ArrayContaining([]);
|
||||
|
||||
expect(containing.jasmineToString()).toMatch("<jasmine.arrayContaining");
|
||||
});
|
||||
});
|
||||
89
spec/core/asymmetric_equality/ObjectContainingSpec.js
Normal file
89
spec/core/asymmetric_equality/ObjectContainingSpec.js
Normal file
@@ -0,0 +1,89 @@
|
||||
describe("ObjectContaining", function() {
|
||||
|
||||
it("matches any actual to an empty object", function() {
|
||||
var containing = new j$.ObjectContaining({});
|
||||
|
||||
expect(containing.asymmetricMatch("foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match an empty object actual", function() {
|
||||
var containing = new j$.ObjectContaining("foo");
|
||||
|
||||
expect(function() {
|
||||
containing.asymmetricMatch({})
|
||||
}).toThrowError(/not 'foo'/)
|
||||
});
|
||||
|
||||
it("matches when the key/value pair is present in the actual", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "fooVal"});
|
||||
|
||||
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match when the key/value pair is not present in the actual", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "fooVal"});
|
||||
|
||||
expect(containing.asymmetricMatch({bar: "barVal", quux: "quuxVal"})).toBe(false);
|
||||
});
|
||||
|
||||
it("does not match when the key is present but the value is different in the actual", function() {
|
||||
var containing = new j$.ObjectContaining({foo: "other"});
|
||||
|
||||
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(false);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var containing = new j$.ObjectContaining({});
|
||||
|
||||
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
|
||||
});
|
||||
|
||||
it("matches recursively", function() {
|
||||
var containing = new j$.ObjectContaining({one: new j$.ObjectContaining({two: {}})});
|
||||
|
||||
expect(containing.asymmetricMatch({one: {two: {}}})).toBe(true);
|
||||
});
|
||||
|
||||
it("matches when key is present with undefined value", function() {
|
||||
var containing = new j$.ObjectContaining({ one: undefined });
|
||||
|
||||
expect(containing.asymmetricMatch({ one: undefined })).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match when key with undefined value is not present", function() {
|
||||
var containing = new j$.ObjectContaining({ one: undefined });
|
||||
|
||||
expect(containing.asymmetricMatch({})).toBe(false);
|
||||
});
|
||||
|
||||
it("matches defined properties", function(){
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var containing = new j$.ObjectContaining({ foo: "fooVal" });
|
||||
|
||||
var definedPropertyObject = {};
|
||||
Object.defineProperty(definedPropertyObject, "foo", {
|
||||
get: function() { return "fooVal" }
|
||||
});
|
||||
expect(containing.asymmetricMatch(definedPropertyObject)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches prototype properties", function(){
|
||||
var containing = new j$.ObjectContaining({ foo: "fooVal" });
|
||||
|
||||
var prototypeObject = {foo: "fooVal"};
|
||||
var obj;
|
||||
|
||||
if (Object.create) {
|
||||
obj = Object.create(prototypeObject);
|
||||
} else {
|
||||
function Foo() {}
|
||||
Foo.prototype = prototypeObject;
|
||||
Foo.prototype.constructor = Foo;
|
||||
obj = new Foo();
|
||||
}
|
||||
|
||||
expect(containing.asymmetricMatch(obj)).toBe(true);
|
||||
});
|
||||
});
|
||||
27
spec/core/asymmetric_equality/StringMatchingSpec.js
Normal file
27
spec/core/asymmetric_equality/StringMatchingSpec.js
Normal file
@@ -0,0 +1,27 @@
|
||||
describe("StringMatching", function() {
|
||||
it("matches a string against a provided regexp", function() {
|
||||
var matcher = new j$.StringMatching(/foo/);
|
||||
|
||||
expect(matcher.asymmetricMatch('barfoobaz')).toBe(true);
|
||||
expect(matcher.asymmetricMatch('barbaz')).toBe(false);
|
||||
});
|
||||
|
||||
it("matches a string against provided string", function() {
|
||||
var matcher = new j$.StringMatching('foo');
|
||||
|
||||
expect(matcher.asymmetricMatch('barfoobaz')).toBe(true);
|
||||
expect(matcher.asymmetricMatch('barbaz')).toBe(false);
|
||||
});
|
||||
|
||||
it("raises an Error when the expected is not a String or RegExp", function() {
|
||||
expect(function() {
|
||||
new j$.StringMatching({});
|
||||
}).toThrowError(/not a String or a RegExp/);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var matching = new j$.StringMatching(/^foo/);
|
||||
|
||||
expect(matching.jasmineToString()).toEqual("<jasmine.stringMatching(/^foo/)>");
|
||||
});
|
||||
});
|
||||
@@ -161,9 +161,24 @@ describe("Env integration", function() {
|
||||
})]
|
||||
}));
|
||||
expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
description: 'has a message from an Error',
|
||||
description: 'has a message and stack trace from an Error',
|
||||
failedExpectations: [jasmine.objectContaining({
|
||||
message: 'Failed: error message'
|
||||
message: 'Failed: error message',
|
||||
stack: {
|
||||
asymmetricMatch: function(other) {
|
||||
if (!other) {
|
||||
// IE doesn't give us a stacktrace so just ignore it.
|
||||
return true;
|
||||
}
|
||||
var split = other.split('\n'),
|
||||
firstLine = split[0];
|
||||
if (firstLine.indexOf('error message') >= 0) {
|
||||
// Chrome inserts the message and a newline before the first stacktrace line.
|
||||
firstLine = split[1];
|
||||
}
|
||||
return firstLine.indexOf('EnvSpec') >= 0;
|
||||
}
|
||||
}
|
||||
})]
|
||||
}));
|
||||
done();
|
||||
@@ -179,7 +194,7 @@ describe("Env integration", function() {
|
||||
env.fail('messy message');
|
||||
});
|
||||
|
||||
env.it('has a message from an Error', function() {
|
||||
env.it('has a message and stack trace from an Error', function() {
|
||||
env.fail(new Error('error message'));
|
||||
});
|
||||
});
|
||||
@@ -597,8 +612,6 @@ describe("Env integration", function() {
|
||||
expect(calls).toEqual([
|
||||
"before",
|
||||
"first spec",
|
||||
"after",
|
||||
"before",
|
||||
"second spec",
|
||||
"after"
|
||||
]);
|
||||
@@ -846,6 +859,36 @@ describe("Env integration", function() {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should not use the mock clock for asynchronous timeouts", function(){
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [ "specDone", "jasmineDone" ]),
|
||||
clock = env.clock;
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.specDone.calls.count()).toEqual(1);
|
||||
expect(reporter.specDone.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({status: 'passed'}));
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
j$.DEFAULT_TIMEOUT_INTERVAL = 5;
|
||||
|
||||
env.beforeAll(function() {
|
||||
clock.install();
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
clock.uninstall();
|
||||
});
|
||||
|
||||
env.it("spec that should not time out", function(done) {
|
||||
clock.tick(6);
|
||||
expect(true).toEqual(true);
|
||||
done();
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should wait the specified interval before reporting an afterAll that fails to call done", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
@@ -956,9 +999,6 @@ describe("Env integration", function() {
|
||||
|
||||
env.addReporter({
|
||||
specDone: specDone,
|
||||
specStarted: function() {
|
||||
jasmine.clock().tick(1);
|
||||
},
|
||||
jasmineDone: function() {
|
||||
expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
description: 'has a default message',
|
||||
@@ -1018,6 +1058,10 @@ describe("Env integration", function() {
|
||||
});
|
||||
|
||||
env.execute();
|
||||
jasmine.clock().tick(1);
|
||||
jasmine.clock().tick(1);
|
||||
jasmine.clock().tick(1);
|
||||
jasmine.clock().tick(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1090,6 +1134,27 @@ describe("Env integration", function() {
|
||||
});
|
||||
|
||||
expect(reporter.specDone.calls.count()).toBe(5);
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
description: 'with a top level spec',
|
||||
status: 'passed'
|
||||
}));
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
description: "with an x'ed spec",
|
||||
status: 'pending'
|
||||
}));
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
description: 'with a spec',
|
||||
status: 'failed'
|
||||
}));
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
description: 'is pending',
|
||||
status: 'pending'
|
||||
}));
|
||||
|
||||
var suiteResult = reporter.suiteStarted.calls.argsFor(0)[0];
|
||||
expect(suiteResult.description).toEqual("A Suite");
|
||||
|
||||
@@ -1103,7 +1168,7 @@ describe("Env integration", function() {
|
||||
env.expect(true).toBe(true);
|
||||
});
|
||||
env.describe("with a nested suite", function() {
|
||||
env.xit("with a pending spec", function() {
|
||||
env.xit("with an x'ed spec", function() {
|
||||
env.expect(true).toBe(true);
|
||||
});
|
||||
env.it("with a spec", function() {
|
||||
@@ -1111,9 +1176,9 @@ describe("Env integration", function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('with only pending specs', function() {
|
||||
env.describe('with only non-executable specs', function() {
|
||||
env.it('is pending');
|
||||
env.xit('is pending', function() {
|
||||
env.xit('is xed', function() {
|
||||
env.expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1122,6 +1187,67 @@ describe("Env integration", function() {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should report pending spec messages', function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'specDone',
|
||||
'jasmineDone'
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var specStatus = reporter.specDone.calls.argsFor(0)[0];
|
||||
|
||||
expect(specStatus.pendingReason).toBe('with a message');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.it('will be pending', function() {
|
||||
env.pending('with a message');
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should report xdescribes as expected', function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
|
||||
totalSpecsDefined: 1
|
||||
});
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ status: 'disabled' }));
|
||||
expect(reporter.suiteDone.calls.count()).toBe(3);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("A Suite", function() {
|
||||
env.describe("nested", function() {
|
||||
env.xdescribe("xd out", function() {
|
||||
env.it("with a spec", function() {
|
||||
env.expect(true).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should be possible to get full name from a spec", function() {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
topLevelSpec, nestedSpec, doublyNestedSpec;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
describe("jasmine spec running", function () {
|
||||
var env;
|
||||
var fakeTimer;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new j$.Env();
|
||||
@@ -61,13 +60,17 @@ describe("jasmine spec running", function () {
|
||||
expect(bar).toEqual(0);
|
||||
expect(baz).toEqual(0);
|
||||
expect(quux).toEqual(0);
|
||||
nested.execute(function() {
|
||||
var assertions = 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) {
|
||||
@@ -228,7 +231,7 @@ describe("jasmine spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should run beforeAlls before beforeEachs and afterAlls after afterEachs', function() {
|
||||
it('should run beforeAlls before beforeEachs and afterAlls after afterEachs', function(done) {
|
||||
var actions = [];
|
||||
|
||||
env.beforeAll(function() {
|
||||
@@ -289,7 +292,7 @@ describe("jasmine spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should run beforeAlls and afterAlls as beforeEachs and afterEachs in the order declared when runnablesToRun is provided', function() {
|
||||
it('should run beforeAlls and afterAlls in the order declared when runnablesToRun is provided', function(done) {
|
||||
var actions = [],
|
||||
spec,
|
||||
spec2;
|
||||
@@ -342,17 +345,13 @@ describe("jasmine spec running", function () {
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it",
|
||||
"it2",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
"runner afterAll",
|
||||
|
||||
"runner beforeAll",
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it2",
|
||||
"it",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
@@ -363,7 +362,31 @@ describe("jasmine spec running", function () {
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute([spec.id, spec2.id]);
|
||||
env.execute([spec2.id, spec.id]);
|
||||
});
|
||||
|
||||
it('only runs *Alls once in a focused suite', function(done){
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('Suite', function() {
|
||||
env.beforeAll(function(){
|
||||
actions.push('beforeAll');
|
||||
});
|
||||
env.it('should run beforeAll once', function() {
|
||||
actions.push('spec');
|
||||
});
|
||||
env.afterAll(function(){
|
||||
actions.push('afterAll');
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(actions).toEqual(['beforeAll', 'spec', 'afterAll']);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
describe('focused runnables', function() {
|
||||
@@ -392,9 +415,7 @@ describe("jasmine spec running", function () {
|
||||
'beforeEach',
|
||||
'spec in fdescribe',
|
||||
'afterEach',
|
||||
'afterAll',
|
||||
|
||||
'beforeAll',
|
||||
'beforeEach',
|
||||
'focused spec',
|
||||
'afterEach',
|
||||
@@ -525,10 +546,14 @@ describe("jasmine spec running", function () {
|
||||
pendingSpec = env.it("I am a pending spec");
|
||||
});
|
||||
|
||||
suite.execute(function() {
|
||||
var assertions = function() {
|
||||
expect(pendingSpec.status()).toBe("pending");
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
// TODO: is this useful? It doesn't catch syntax errors
|
||||
@@ -579,4 +604,96 @@ describe("jasmine spec running", function () {
|
||||
));
|
||||
|
||||
});
|
||||
|
||||
it("re-enters suites that have no *Alls", function(done) {
|
||||
var actions = [],
|
||||
spec1, spec2, spec3;
|
||||
|
||||
env.describe("top", function() {
|
||||
spec1 = env.it("spec1", function() {
|
||||
actions.push("spec1");
|
||||
});
|
||||
|
||||
spec2 = env.it("spec2", function() {
|
||||
actions.push("spec2");
|
||||
});
|
||||
});
|
||||
|
||||
spec3 = env.it("spec3", function() {
|
||||
actions.push("spec3");
|
||||
});
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: 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() {
|
||||
var actions = [],
|
||||
spec1, spec2, spec3;
|
||||
|
||||
env.describe("top", function() {
|
||||
env.beforeAll(function() {});
|
||||
|
||||
spec1 = env.it("spec1", function() {
|
||||
actions.push("spec1");
|
||||
});
|
||||
|
||||
spec2 = env.it("spec2", function() {
|
||||
actions.push("spec2");
|
||||
});
|
||||
});
|
||||
|
||||
spec3 = env.it("spec3", function() {
|
||||
actions.push("spec3");
|
||||
});
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: function() {
|
||||
expect(actions).toEqual([]);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
env.execute([spec2.id, spec3.id, spec1.id]);
|
||||
}).toThrowError(/beforeAll/);
|
||||
});
|
||||
|
||||
it("refuses to re-enter suites with a afterAll", function() {
|
||||
var actions = [],
|
||||
spec1, spec2, spec3;
|
||||
|
||||
env.describe("top", function() {
|
||||
env.afterAll(function() {});
|
||||
|
||||
spec1 = env.it("spec1", function() {
|
||||
actions.push("spec1");
|
||||
});
|
||||
|
||||
spec2 = env.it("spec2", function() {
|
||||
actions.push("spec2");
|
||||
});
|
||||
});
|
||||
|
||||
spec3 = env.it("spec3", function() {
|
||||
actions.push("spec3");
|
||||
});
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: function() {
|
||||
expect(actions).toEqual([]);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
env.execute([spec2.id, spec3.id, spec1.id]);
|
||||
}).toThrowError(/afterAll/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,6 +58,16 @@ describe("matchersUtil", function() {
|
||||
expect(j$.matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
|
||||
});
|
||||
|
||||
it("fails for Arrays whose contents are equivalent, but have differing properties", function() {
|
||||
var one = [1,2,3],
|
||||
two = [1,2,3];
|
||||
|
||||
one.foo = 'bar';
|
||||
two.foo = 'baz';
|
||||
|
||||
expect(j$.matchersUtil.equals(one, two)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Errors that are the same type and have the same message", function() {
|
||||
expect(j$.matchersUtil.equals(new Error("foo"), new Error("foo"))).toBe(true);
|
||||
});
|
||||
@@ -122,6 +132,72 @@ describe("matchersUtil", function() {
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes for equivalent DOM nodes", function() {
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
}
|
||||
var a = document.createElement("div");
|
||||
a.setAttribute("test-attr", "attr-value")
|
||||
a.appendChild(document.createTextNode('test'));
|
||||
|
||||
var b = document.createElement("div");
|
||||
b.setAttribute("test-attr", "attr-value")
|
||||
b.appendChild(document.createTextNode('test'));
|
||||
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for DOM nodes with different attributes or child nodes", function() {
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
}
|
||||
var a = document.createElement("div");
|
||||
a.setAttribute("test-attr", "attr-value")
|
||||
a.appendChild(document.createTextNode('test'));
|
||||
|
||||
var b = document.createElement("div");
|
||||
b.setAttribute("test-attr", "attr-value2")
|
||||
b.appendChild(document.createTextNode('test'));
|
||||
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(false);
|
||||
|
||||
b.setAttribute("test-attr", "attr-value");
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(true);
|
||||
|
||||
b.appendChild(document.createTextNode('2'));
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(false);
|
||||
|
||||
a.appendChild(document.createTextNode('2'));
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes for equivalent objects from different vm contexts", function() {
|
||||
if (typeof require !== 'function') {
|
||||
return;
|
||||
}
|
||||
var vm = require('vm');
|
||||
var sandbox = {
|
||||
obj: null
|
||||
};
|
||||
vm.runInNewContext('obj = {a: 1, b: 2}', sandbox);
|
||||
|
||||
expect(j$.matchersUtil.equals(sandbox.obj, {a: 1, b: 2})).toBe(true);
|
||||
});
|
||||
|
||||
it("passes for equivalent arrays from different vm contexts", function() {
|
||||
if (typeof require !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
var vm = require('vm');
|
||||
var sandbox = {
|
||||
arr: null
|
||||
};
|
||||
vm.runInNewContext('arr = [1, 2]', sandbox);
|
||||
|
||||
expect(j$.matchersUtil.equals(sandbox.arr, [1, 2])).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when Any is used", function() {
|
||||
var number = 3,
|
||||
anyNumber = new j$.Any(Number);
|
||||
@@ -142,9 +218,31 @@ describe("matchersUtil", function() {
|
||||
var obj = {
|
||||
foo: 3,
|
||||
bar: 7
|
||||
};
|
||||
},
|
||||
containing = new j$.ObjectContaining({foo: 3});
|
||||
|
||||
expect(j$.matchersUtil.equals(obj, new j$.ObjectContaining({foo: 3}))).toBe(true);
|
||||
expect(j$.matchersUtil.equals(obj, containing)).toBe(true);
|
||||
expect(j$.matchersUtil.equals(containing, obj)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when an asymmetric equality tester returns true", function() {
|
||||
var tester = { asymmetricMatch: function(other) { return true; } };
|
||||
|
||||
expect(j$.matchersUtil.equals(false, tester)).toBe(true);
|
||||
expect(j$.matchersUtil.equals(tester, false)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when an asymmetric equality tester returns false", function() {
|
||||
var tester = { asymmetricMatch: function(other) { return false; } };
|
||||
|
||||
expect(j$.matchersUtil.equals(true, tester)).toBe(false);
|
||||
expect(j$.matchersUtil.equals(tester, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes when ArrayContaining is used", function() {
|
||||
var arr = ["foo", "bar"];
|
||||
|
||||
expect(j$.matchersUtil.equals(arr, new j$.ArrayContaining(["bar"]))).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when a custom equality matcher returns true", function() {
|
||||
@@ -170,6 +268,45 @@ describe("matchersUtil", function() {
|
||||
|
||||
expect(j$.matchersUtil.equals(1, 1, [tester])).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for an asymmetric equality tester that returns true when a custom equality tester return false", function() {
|
||||
var asymmetricTester = { asymmetricMatch: function(other) { return true; } },
|
||||
symmetricTester = function(a, b) { return false; };
|
||||
|
||||
expect(j$.matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true);
|
||||
expect(j$.matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when an Any is compared to an Any that checks for the same type", function() {
|
||||
var any1 = new j$.Any(Function),
|
||||
any2 = new j$.Any(Function);
|
||||
|
||||
expect(j$.matchersUtil.equals(any1, any2)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes for null prototype objects with same properties", function () {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var objA = Object.create(null),
|
||||
objB = Object.create(null);
|
||||
|
||||
objA.name = 'test';
|
||||
objB.name = 'test';
|
||||
|
||||
expect(j$.matchersUtil.equals(objA, objB)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for null prototype objects with different properties", function () {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var objA = Object.create(null),
|
||||
objB = Object.create(null);
|
||||
|
||||
objA.name = 'test';
|
||||
objB.test = 'name';
|
||||
|
||||
expect(j$.matchersUtil.equals(objA, objB)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("contains", function() {
|
||||
|
||||
@@ -30,5 +30,13 @@ describe("toMatch", function() {
|
||||
result = matcher.compare('bar', 'foo');
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("throws an Error when the expected is not a String or RegExp", function() {
|
||||
var matcher = j$.matchers.toMatch();
|
||||
|
||||
expect(function() {
|
||||
matcher.compare('foo', { bar: 'baz' });
|
||||
}).toThrowError('Expected is not a String or a RegExp');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -170,7 +170,6 @@ describe("toThrowError", function() {
|
||||
result;
|
||||
|
||||
CustomError.prototype = new Error();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
|
||||
result = matcher.compare(fn, CustomError);
|
||||
|
||||
@@ -222,7 +221,6 @@ describe("toThrowError", function() {
|
||||
result;
|
||||
|
||||
CustomError.prototype = new Error();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
|
||||
result = matcher.compare(fn, CustomError, "foo");
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ describe("New HtmlReporter", function() {
|
||||
timer.elapsed.and.returnValue(100);
|
||||
reporter.jasmineDone();
|
||||
|
||||
var duration = container.querySelector(".banner .duration");
|
||||
var duration = container.querySelector(".alert .duration");
|
||||
expect(duration.innerHTML).toMatch(/finished in 0.1s/);
|
||||
});
|
||||
|
||||
@@ -278,7 +278,8 @@ describe("New HtmlReporter", function() {
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
addToExistingQueryString: function(key, value) { return "?foo=bar&" + key + "=" + value; }
|
||||
});
|
||||
reporter.initialize();
|
||||
|
||||
@@ -350,7 +351,7 @@ describe("New HtmlReporter", function() {
|
||||
var suiteDetail = outerSuite.childNodes[0];
|
||||
var suiteLink = suiteDetail.childNodes[0];
|
||||
expect(suiteLink.innerHTML).toEqual("A Suite");
|
||||
expect(suiteLink.getAttribute('href')).toEqual("?spec=A%20Suite");
|
||||
expect(suiteLink.getAttribute('href')).toEqual("?foo=bar&spec=A Suite");
|
||||
|
||||
var specs = outerSuite.childNodes[1];
|
||||
var spec = specs.childNodes[0];
|
||||
@@ -359,10 +360,44 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
var specLink = spec.childNodes[0];
|
||||
expect(specLink.innerHTML).toEqual("with a spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?spec=A%20Suite%20with%20a%20spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?foo=bar&spec=A Suite with a spec");
|
||||
// expect(specLink.getAttribute("title")).toEqual("A Suite with a spec");
|
||||
});
|
||||
|
||||
it("has an options menu", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var trigger = container.querySelector('.run-options .trigger'),
|
||||
payload = container.querySelector('.run-options .payload');
|
||||
|
||||
expect(payload.className).not.toContain('open');
|
||||
|
||||
trigger.onclick();
|
||||
|
||||
expect(payload.className).toContain('open');
|
||||
|
||||
trigger.onclick();
|
||||
|
||||
expect(payload.className).not.toContain('open');
|
||||
});
|
||||
|
||||
describe("UI for raising/catching exceptions", function() {
|
||||
it("should be unchecked if the env is catching", function() {
|
||||
var env = new j$.Env(),
|
||||
@@ -441,6 +476,86 @@ describe("New HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("UI for throwing errors on expectation failures", function() {
|
||||
it("should be unchecked if not throwing", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var throwingExpectationsUI = container.querySelector(".throw");
|
||||
expect(throwingExpectationsUI.checked).toBe(false);
|
||||
});
|
||||
|
||||
it("should be checked if throwing", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
env.throwOnExpectationFailure(true);
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var throwingExpectationsUI = container.querySelector(".throw");
|
||||
expect(throwingExpectationsUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("should affect the query param for throw expectation failures", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
throwingExceptionHandler = jasmine.createSpy('throwingExceptions'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
onThrowExpectationsClick: throwingExceptionHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var throwingExpectationsUI = container.querySelector(".throw");
|
||||
throwingExpectationsUI.click();
|
||||
|
||||
expect(throwingExceptionHandler).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("shows a message if no specs are run", function(){
|
||||
var env, container, reporter;
|
||||
env = new j$.Env();
|
||||
@@ -532,14 +647,17 @@ describe("New HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({ totalSpecsDefined: 1 });
|
||||
reporter.specDone({
|
||||
var specStatus = {
|
||||
id: 123,
|
||||
description: "with a spec",
|
||||
fullName: "A Suite with a spec",
|
||||
status: "pending",
|
||||
passedExpectations: [],
|
||||
failedExpectations: []
|
||||
});
|
||||
failedExpectations: [],
|
||||
pendingReason: "my custom pending reason"
|
||||
};
|
||||
reporter.specStarted(specStatus);
|
||||
reporter.specDone(specStatus);
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
@@ -554,6 +672,12 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
expect(specFailure.childNodes.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("displays the custom pending reason", function() {
|
||||
var pendingDetails = container.querySelector(".summary .pending");
|
||||
|
||||
expect(pendingDetails.innerHTML).toContain("my custom pending reason");
|
||||
});
|
||||
});
|
||||
|
||||
describe("and some tests fail", function() {
|
||||
@@ -567,7 +691,8 @@ describe("New HtmlReporter", function() {
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
addToExistingQueryString: function(key, value) { return "?foo=bar&" + key + "=" + value; }
|
||||
});
|
||||
reporter.initialize();
|
||||
|
||||
@@ -614,7 +739,7 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
var specLink = specDiv.childNodes[0];
|
||||
expect(specLink.getAttribute("title")).toEqual("a suite with a failing spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?spec=a%20suite%20with%20a%20failing%20spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?foo=bar&spec=a suite with a failing spec");
|
||||
|
||||
var message = failure.childNodes[1].childNodes[0];
|
||||
expect(message.getAttribute("class")).toEqual("result-message");
|
||||
|
||||
@@ -3,7 +3,7 @@ describe("j$.pp (HTML Dependent)", function () {
|
||||
var sampleNode = document.createElement('div');
|
||||
sampleNode.innerHTML = 'foo<b>bar</b>';
|
||||
expect(j$.pp(sampleNode)).toEqual("HTMLNode");
|
||||
expect(j$.pp({foo: sampleNode})).toEqual("{ foo: HTMLNode }");
|
||||
expect(j$.pp({foo: sampleNode})).toEqual("Object({ foo: HTMLNode })");
|
||||
});
|
||||
|
||||
it("should print Firefox's wrapped native objects correctly", function() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
describe("QueryString", function() {
|
||||
|
||||
describe("#setParam", function() {
|
||||
|
||||
describe("#navigateWithNewParam", function() {
|
||||
it("sets the query string to include the given key/value pair", function() {
|
||||
var windowLocation = {
|
||||
search: ""
|
||||
@@ -10,10 +9,40 @@ describe("QueryString", function() {
|
||||
getWindowLocation: function() { return windowLocation }
|
||||
});
|
||||
|
||||
queryString.setParam("foo", "bar baz");
|
||||
queryString.navigateWithNewParam("foo", "bar baz");
|
||||
|
||||
expect(windowLocation.search).toMatch(/foo=bar%20baz/);
|
||||
});
|
||||
|
||||
it("leaves existing params alone", function() {
|
||||
var windowLocation = {
|
||||
search: "?foo=bar"
|
||||
},
|
||||
queryString = new j$.QueryString({
|
||||
getWindowLocation: function() { return windowLocation }
|
||||
});
|
||||
|
||||
queryString.navigateWithNewParam("baz", "quux");
|
||||
|
||||
expect(windowLocation.search).toMatch(/foo=bar/);
|
||||
expect(windowLocation.search).toMatch(/baz=quux/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#fullStringWithNewParam', function() {
|
||||
it("gets the query string including the given key/value pair", function() {
|
||||
var windowLocation = {
|
||||
search: "?foo=bar"
|
||||
},
|
||||
queryString = new j$.QueryString({
|
||||
getWindowLocation: function() { return windowLocation }
|
||||
});
|
||||
|
||||
var result = queryString.fullStringWithNewParam("baz", "quux");
|
||||
|
||||
expect(result).toMatch(/foo=bar/);
|
||||
expect(result).toMatch(/baz=quux/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#getParam", function() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
describe('npm package', function() {
|
||||
var path = require('path'),
|
||||
temp = require('temp').track(),
|
||||
fs = require('fs');
|
||||
|
||||
beforeAll(function() {
|
||||
@@ -7,9 +8,7 @@ describe('npm package', function() {
|
||||
pack = shell.exec('npm pack', { silent: true });
|
||||
|
||||
this.tarball = pack.output.split('\n')[0];
|
||||
this.tmpDir = '/tmp/jasmine-core';
|
||||
|
||||
fs.mkdirSync(this.tmpDir);
|
||||
this.tmpDir = temp.mkdirSync(); // automatically deleted on exit
|
||||
|
||||
var untar = shell.exec('tar -xzf ' + this.tarball + ' -C ' + this.tmpDir, { silent: true });
|
||||
expect(untar.code).toBe(0);
|
||||
@@ -44,8 +43,6 @@ describe('npm package', function() {
|
||||
};
|
||||
|
||||
fs.unlink(this.tarball);
|
||||
fs.readdirSync(this.tmpDir).forEach(cleanup.bind(null, this.tmpDir));
|
||||
fs.rmdirSync(this.tmpDir);
|
||||
});
|
||||
|
||||
it('has a root path', function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
getJasmineRequireObj().Clock = function() {
|
||||
function Clock(global, delayedFunctionScheduler, mockDate) {
|
||||
function Clock(global, delayedFunctionSchedulerFactory, mockDate) {
|
||||
var self = this,
|
||||
realTimingFunctions = {
|
||||
setTimeout: global.setTimeout,
|
||||
@@ -14,19 +14,24 @@ getJasmineRequireObj().Clock = function() {
|
||||
clearInterval: clearInterval
|
||||
},
|
||||
installed = false,
|
||||
delayedFunctionScheduler,
|
||||
timer;
|
||||
|
||||
|
||||
self.install = function() {
|
||||
if(!originalTimingFunctionsIntact()) {
|
||||
throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?');
|
||||
}
|
||||
replace(global, fakeTimingFunctions);
|
||||
timer = fakeTimingFunctions;
|
||||
delayedFunctionScheduler = delayedFunctionSchedulerFactory();
|
||||
installed = true;
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
self.uninstall = function() {
|
||||
delayedFunctionScheduler.reset();
|
||||
delayedFunctionScheduler = null;
|
||||
mockDate.uninstall();
|
||||
replace(global, realTimingFunctions);
|
||||
|
||||
@@ -34,6 +39,15 @@ getJasmineRequireObj().Clock = function() {
|
||||
installed = false;
|
||||
};
|
||||
|
||||
self.withMock = function(closure) {
|
||||
this.install();
|
||||
try {
|
||||
closure();
|
||||
} finally {
|
||||
this.uninstall();
|
||||
}
|
||||
};
|
||||
|
||||
self.mockDate = function(initialDate) {
|
||||
mockDate.install(initialDate);
|
||||
};
|
||||
@@ -77,6 +91,13 @@ getJasmineRequireObj().Clock = function() {
|
||||
|
||||
return self;
|
||||
|
||||
function originalTimingFunctionsIntact() {
|
||||
return global.setTimeout === realTimingFunctions.setTimeout &&
|
||||
global.clearTimeout === realTimingFunctions.clearTimeout &&
|
||||
global.setInterval === realTimingFunctions.setInterval &&
|
||||
global.clearInterval === realTimingFunctions.clearInterval;
|
||||
}
|
||||
|
||||
function legacyIE() {
|
||||
//if these methods are polyfilled, apply will be present
|
||||
return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
|
||||
|
||||
@@ -72,13 +72,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
}
|
||||
};
|
||||
|
||||
self.reset = function() {
|
||||
currentTime = 0;
|
||||
scheduledLookup = [];
|
||||
scheduledFunctions = {};
|
||||
delayedFnCount = 0;
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function indexOfFirstToPass(array, testFn) {
|
||||
@@ -114,6 +107,12 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
scheduledFn.runAtMillis + scheduledFn.millis);
|
||||
}
|
||||
|
||||
function forEachFunction(funcsToRun, callback) {
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
callback(funcsToRun[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function runScheduledFunctions(endTime) {
|
||||
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
||||
return;
|
||||
@@ -125,15 +124,15 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
var funcsToRun = scheduledFunctions[currentTime];
|
||||
delete scheduledFunctions[currentTime];
|
||||
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
var funcToRun = funcsToRun[i];
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
if (funcToRun.recurring) {
|
||||
reschedule(funcToRun);
|
||||
}
|
||||
});
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
}
|
||||
});
|
||||
} while (scheduledLookup.length > 0 &&
|
||||
// checking first if we're out of time prevents setTimeout(0)
|
||||
// scheduled in a funcToRun from forcing an extra iteration
|
||||
|
||||
105
src/core/Env.js
105
src/core/Env.js
@@ -11,7 +11,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
var realSetTimeout = j$.getGlobal().setTimeout;
|
||||
var realClearTimeout = j$.getGlobal().clearTimeout;
|
||||
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global));
|
||||
this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global));
|
||||
|
||||
var runnableLookupTable = {};
|
||||
var runnableResources = {};
|
||||
@@ -19,6 +19,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var currentSpec = null;
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
var throwOnExpectationFailure = false;
|
||||
|
||||
var currentSuite = function() {
|
||||
return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
|
||||
@@ -100,27 +101,21 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
delete runnableResources[id];
|
||||
};
|
||||
|
||||
var beforeAndAfterFns = function(suite, runnablesExplictlySet) {
|
||||
var beforeAndAfterFns = function(suite) {
|
||||
return function() {
|
||||
var befores = [],
|
||||
afters = [],
|
||||
beforeAlls = [],
|
||||
afterAlls = [];
|
||||
afters = [];
|
||||
|
||||
while(suite) {
|
||||
befores = befores.concat(suite.beforeFns);
|
||||
afters = afters.concat(suite.afterFns);
|
||||
|
||||
if (runnablesExplictlySet()) {
|
||||
beforeAlls = beforeAlls.concat(suite.beforeAllFns);
|
||||
afterAlls = afterAlls.concat(suite.afterAllFns);
|
||||
}
|
||||
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
|
||||
return {
|
||||
befores: beforeAlls.reverse().concat(befores.reverse()),
|
||||
afters: afters.concat(afterAlls)
|
||||
befores: befores.reverse(),
|
||||
afters: afters
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -166,10 +161,18 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return j$.Spec.isPendingSpecException(e) || catchExceptions;
|
||||
};
|
||||
|
||||
this.throwOnExpectationFailure = function(value) {
|
||||
throwOnExpectationFailure = !!value;
|
||||
};
|
||||
|
||||
this.throwingExpectationFailures = function() {
|
||||
return throwOnExpectationFailure;
|
||||
};
|
||||
|
||||
var queueRunnerFactory = function(options) {
|
||||
options.catchException = catchException;
|
||||
options.clearStack = options.clearStack || clearStack;
|
||||
options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
|
||||
options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
|
||||
options.fail = self.fail;
|
||||
|
||||
new j$.QueueRunner(options).execute();
|
||||
@@ -190,26 +193,40 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
if(runnablesToRun) {
|
||||
runnablesExplictlySet = true;
|
||||
} else if (focusedRunnables.length) {
|
||||
runnablesExplictlySet = true;
|
||||
runnablesToRun = focusedRunnables;
|
||||
} else {
|
||||
runnablesToRun = [topSuite.id];
|
||||
if(!runnablesToRun) {
|
||||
if (focusedRunnables.length) {
|
||||
runnablesToRun = focusedRunnables;
|
||||
} else {
|
||||
runnablesToRun = [topSuite.id];
|
||||
}
|
||||
}
|
||||
var processor = new j$.TreeProcessor({
|
||||
tree: topSuite,
|
||||
runnableIds: runnablesToRun,
|
||||
queueRunnerFactory: queueRunnerFactory,
|
||||
nodeStart: function(suite) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result);
|
||||
},
|
||||
nodeComplete: function(suite, result) {
|
||||
if (!suite.disabled) {
|
||||
clearResourcesForRunnable(suite.id);
|
||||
}
|
||||
currentlyExecutingSuites.pop();
|
||||
reporter.suiteDone(result);
|
||||
}
|
||||
});
|
||||
|
||||
var allFns = [];
|
||||
for(var i = 0; i < runnablesToRun.length; i++) {
|
||||
var runnable = runnableLookupTable[runnablesToRun[i]];
|
||||
allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable));
|
||||
if(!processor.processTree().valid) {
|
||||
throw new Error('Invalid order: would cause a beforeAll or afterAll to be run multiple times');
|
||||
}
|
||||
|
||||
reporter.jasmineStarted({
|
||||
totalSpecsDefined: totalSpecsDefined
|
||||
});
|
||||
|
||||
queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone});
|
||||
processor.execute(reporter.jasmineDone);
|
||||
};
|
||||
|
||||
this.addReporter = function(reporterToAdd) {
|
||||
@@ -233,27 +250,13 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
id: getNextSuiteId(),
|
||||
description: description,
|
||||
parentSuite: currentDeclarationSuite,
|
||||
queueRunner: queueRunnerFactory,
|
||||
onStart: suiteStarted,
|
||||
expectationFactory: expectationFactory,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
resultCallback: function(attrs) {
|
||||
if (!suite.disabled) {
|
||||
clearResourcesForRunnable(suite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
}
|
||||
reporter.suiteDone(attrs);
|
||||
}
|
||||
throwOnExpectationFailure: throwOnExpectationFailure
|
||||
});
|
||||
|
||||
runnableLookupTable[suite.id] = suite;
|
||||
return suite;
|
||||
|
||||
function suiteStarted(suite) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result);
|
||||
}
|
||||
};
|
||||
|
||||
this.describe = function(description, specDefinitions) {
|
||||
@@ -325,17 +328,11 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
var runnablesExplictlySet = false;
|
||||
|
||||
var runnablesExplictlySetGetter = function(){
|
||||
return runnablesExplictlySet;
|
||||
};
|
||||
|
||||
var specFactory = function(description, fn, suite, timeout) {
|
||||
totalSpecsDefined++;
|
||||
var spec = new j$.Spec({
|
||||
id: getNextSpecId(),
|
||||
beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter),
|
||||
beforeAndAfterFns: beforeAndAfterFns(suite),
|
||||
expectationFactory: expectationFactory,
|
||||
resultCallback: specResultCallback,
|
||||
getSpecName: function(spec) {
|
||||
@@ -349,7 +346,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
queueableFn: {
|
||||
fn: fn,
|
||||
timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
|
||||
}
|
||||
},
|
||||
throwOnExpectationFailure: throwOnExpectationFailure
|
||||
});
|
||||
|
||||
runnableLookupTable[spec.id] = spec;
|
||||
@@ -429,8 +427,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
});
|
||||
};
|
||||
|
||||
this.pending = function() {
|
||||
throw j$.Spec.pendingSpecExceptionMessage;
|
||||
this.pending = function(message) {
|
||||
var fullMessage = j$.Spec.pendingSpecExceptionMessage;
|
||||
if(message) {
|
||||
fullMessage += message;
|
||||
}
|
||||
throw fullMessage;
|
||||
};
|
||||
|
||||
this.fail = function(error) {
|
||||
@@ -445,7 +447,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
message: message
|
||||
message: message,
|
||||
error: error && error.message ? error : null
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ getJasmineRequireObj().MockDate = function() {
|
||||
case 6:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4], arguments[5]);
|
||||
case 7:
|
||||
default:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4], arguments[5], arguments[6]);
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
getJasmineRequireObj().ObjectContaining = function(j$) {
|
||||
|
||||
function ObjectContaining(sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
|
||||
if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
|
||||
|
||||
mismatchKeys = mismatchKeys || [];
|
||||
mismatchValues = mismatchValues || [];
|
||||
|
||||
var hasKey = function(obj, keyName) {
|
||||
return obj !== null && !j$.util.isUndefined(obj[keyName]);
|
||||
};
|
||||
|
||||
for (var property in this.sample) {
|
||||
if (!hasKey(other, property) && hasKey(this.sample, property)) {
|
||||
mismatchKeys.push('expected has key \'' + property + '\', but missing from actual.');
|
||||
}
|
||||
else if (!j$.matchersUtil.equals(other[property], this.sample[property])) {
|
||||
mismatchValues.push('\'' + property + '\' was \'' + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + '\' in actual, but was \'' + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + '\' in expected.');
|
||||
}
|
||||
}
|
||||
|
||||
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
ObjectContaining.prototype.jasmineToString = function() {
|
||||
return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return ObjectContaining;
|
||||
};
|
||||
@@ -93,17 +93,36 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
if(array.length > length){
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var first = array.length === 0;
|
||||
this.iterateObject(array, function(property, isGetter) {
|
||||
if (property.match(/^\d+$/)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
self.append(', ');
|
||||
}
|
||||
|
||||
self.formatProperty(array, property, isGetter);
|
||||
});
|
||||
|
||||
this.append(' ]');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.emitObject = function(obj) {
|
||||
var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null';
|
||||
this.append(constructorName);
|
||||
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Object');
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.append('{ ');
|
||||
this.append('({ ');
|
||||
var first = true;
|
||||
|
||||
this.iterateObject(obj, function(property, isGetter) {
|
||||
@@ -113,16 +132,20 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
self.append(', ');
|
||||
}
|
||||
|
||||
self.append(property);
|
||||
self.append(': ');
|
||||
if (isGetter) {
|
||||
self.append('<getter>');
|
||||
} else {
|
||||
self.format(obj[property]);
|
||||
}
|
||||
self.formatProperty(obj, property, isGetter);
|
||||
});
|
||||
|
||||
this.append(' }');
|
||||
this.append(' })');
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
this.append(property);
|
||||
this.append(': ');
|
||||
if (isGetter) {
|
||||
this.append('<getter>');
|
||||
} else {
|
||||
this.format(obj[property]);
|
||||
}
|
||||
};
|
||||
|
||||
StringPrettyPrinter.prototype.append = function(value) {
|
||||
|
||||
@@ -17,7 +17,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.onException = attrs.onException || function() {};
|
||||
this.catchException = attrs.catchException || function() { return true; };
|
||||
this.userContext = attrs.userContext || {};
|
||||
this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
|
||||
this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
|
||||
this.fail = attrs.fail || function() {};
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
|
||||
var queueableFn = queueableFns[iterativeIndex];
|
||||
if (queueableFn.fn.length > 0) {
|
||||
return attemptAsync(queueableFn);
|
||||
attemptAsync(queueableFn);
|
||||
return;
|
||||
} else {
|
||||
attemptSync(queueableFn);
|
||||
}
|
||||
@@ -56,7 +57,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
|
||||
function attemptAsync(queueableFn) {
|
||||
var clearTimeout = function () {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
},
|
||||
next = once(function () {
|
||||
clearTimeout(timeoutId);
|
||||
@@ -70,7 +71,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
|
||||
if (queueableFn.timeout) {
|
||||
timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() {
|
||||
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
|
||||
onException(error, queueableFn);
|
||||
next();
|
||||
|
||||
@@ -12,6 +12,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
this.expectationResultFactory = attrs.expectationResultFactory || function() { };
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
|
||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||
|
||||
if (!this.queueableFn.fn) {
|
||||
this.pend();
|
||||
@@ -22,16 +23,21 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
description: this.description,
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: [],
|
||||
passedExpectations: []
|
||||
passedExpectations: [],
|
||||
pendingReason: ''
|
||||
};
|
||||
}
|
||||
|
||||
Spec.prototype.addExpectationResult = function(passed, data) {
|
||||
Spec.prototype.addExpectationResult = function(passed, data, isError) {
|
||||
var expectationResult = this.expectationResultFactory(data);
|
||||
if (passed) {
|
||||
this.result.passedExpectations.push(expectationResult);
|
||||
} else {
|
||||
this.result.failedExpectations.push(expectationResult);
|
||||
|
||||
if (this.throwOnExpectationFailure && !isError) {
|
||||
throw new j$.errors.ExpectationFailed();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,13 +45,13 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.expectationFactory(actual, this);
|
||||
};
|
||||
|
||||
Spec.prototype.execute = function(onComplete) {
|
||||
Spec.prototype.execute = function(onComplete, enabled) {
|
||||
var self = this;
|
||||
|
||||
this.onStart(this);
|
||||
|
||||
if (this.markedPending || this.disabled) {
|
||||
complete();
|
||||
if (!this.isExecutable() || this.markedPending || enabled === false) {
|
||||
complete(enabled);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,8 +65,8 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
userContext: this.userContext()
|
||||
});
|
||||
|
||||
function complete() {
|
||||
self.result.status = self.status();
|
||||
function complete(enabledAgain) {
|
||||
self.result.status = self.status(enabledAgain);
|
||||
self.resultCallback(self.result);
|
||||
|
||||
if (onComplete) {
|
||||
@@ -71,7 +77,11 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
|
||||
Spec.prototype.onException = function onException(e) {
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
this.pend();
|
||||
this.pend(extractCustomPendingMessage(e));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e instanceof j$.errors.ExpectationFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -81,19 +91,27 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
});
|
||||
}, true);
|
||||
};
|
||||
|
||||
Spec.prototype.disable = function() {
|
||||
this.disabled = true;
|
||||
};
|
||||
|
||||
Spec.prototype.pend = function() {
|
||||
Spec.prototype.pend = function(message) {
|
||||
this.markedPending = true;
|
||||
if (message) {
|
||||
this.result.pendingReason = message;
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.status = function() {
|
||||
if (this.disabled) {
|
||||
Spec.prototype.getResult = function() {
|
||||
this.result.status = this.status();
|
||||
return this.result;
|
||||
};
|
||||
|
||||
Spec.prototype.status = function(enabled) {
|
||||
if (this.disabled || enabled === false) {
|
||||
return 'disabled';
|
||||
}
|
||||
|
||||
@@ -109,13 +127,21 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
};
|
||||
|
||||
Spec.prototype.isExecutable = function() {
|
||||
return !this.disabled && !this.markedPending;
|
||||
return !this.disabled;
|
||||
};
|
||||
|
||||
Spec.prototype.getFullName = function() {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
|
||||
var extractCustomPendingMessage = function(e) {
|
||||
var fullMessage = e.toString(),
|
||||
boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
|
||||
boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length;
|
||||
|
||||
return fullMessage.substr(boilerplateEnd);
|
||||
};
|
||||
|
||||
Spec.pendingSpecExceptionMessage = '=> marked Pending';
|
||||
|
||||
Spec.isPendingSpecException = function(e) {
|
||||
|
||||
@@ -9,6 +9,10 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
|
||||
}
|
||||
|
||||
if (j$.util.isUndefined(methodName)) {
|
||||
throw new Error('No method name supplied');
|
||||
}
|
||||
|
||||
if (j$.util.isUndefined(obj[methodName])) {
|
||||
throw new Error(methodName + '() method does not exist');
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
getJasmineRequireObj().Suite = function() {
|
||||
getJasmineRequireObj().Suite = function(j$) {
|
||||
function Suite(attrs) {
|
||||
this.env = attrs.env;
|
||||
this.id = attrs.id;
|
||||
this.parentSuite = attrs.parentSuite;
|
||||
this.description = attrs.description;
|
||||
this.onStart = attrs.onStart || function() {};
|
||||
this.resultCallback = attrs.resultCallback || function() {};
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.expectationFactory = attrs.expectationFactory;
|
||||
this.expectationResultFactory = attrs.expectationResultFactory;
|
||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||
|
||||
this.beforeFns = [];
|
||||
this.afterFns = [];
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
this.queueRunner = attrs.queueRunner || function() {};
|
||||
this.disabled = false;
|
||||
|
||||
this.children = [];
|
||||
@@ -77,57 +74,17 @@ getJasmineRequireObj().Suite = function() {
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.execute = function(onComplete) {
|
||||
var self = this;
|
||||
|
||||
this.onStart(this);
|
||||
|
||||
if (this.disabled) {
|
||||
complete();
|
||||
return;
|
||||
}
|
||||
|
||||
var allFns = [];
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
allFns.push(wrapChildAsAsync(this.children[i]));
|
||||
}
|
||||
|
||||
if (this.isExecutable()) {
|
||||
allFns = this.beforeAllFns.concat(allFns);
|
||||
allFns = allFns.concat(this.afterAllFns);
|
||||
}
|
||||
|
||||
this.queueRunner({
|
||||
queueableFns: allFns,
|
||||
onComplete: complete,
|
||||
userContext: this.sharedUserContext(),
|
||||
onException: function() { self.onException.apply(self, arguments); }
|
||||
});
|
||||
|
||||
function complete() {
|
||||
self.result.status = self.status();
|
||||
self.resultCallback(self.result);
|
||||
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
}
|
||||
|
||||
function wrapChildAsAsync(child) {
|
||||
return { fn: function(done) { child.execute(done); } };
|
||||
}
|
||||
Suite.prototype.isExecutable = function() {
|
||||
return !this.disabled;
|
||||
};
|
||||
|
||||
Suite.prototype.isExecutable = function() {
|
||||
var foundActive = false;
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
if(this.children[i].isExecutable()) {
|
||||
foundActive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return foundActive;
|
||||
Suite.prototype.canBeReentered = function() {
|
||||
return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
|
||||
};
|
||||
|
||||
Suite.prototype.getResult = function() {
|
||||
this.result.status = this.status();
|
||||
return this.result;
|
||||
};
|
||||
|
||||
Suite.prototype.sharedUserContext = function() {
|
||||
@@ -143,6 +100,10 @@ getJasmineRequireObj().Suite = function() {
|
||||
};
|
||||
|
||||
Suite.prototype.onException = function() {
|
||||
if (arguments[0] instanceof j$.errors.ExpectationFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(isAfterAll(this.children)) {
|
||||
var data = {
|
||||
matcherName: '',
|
||||
@@ -164,10 +125,17 @@ getJasmineRequireObj().Suite = function() {
|
||||
if(isAfterAll(this.children) && isFailure(arguments)){
|
||||
var data = arguments[1];
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
if(this.throwOnExpectationFailure) {
|
||||
throw new j$.errors.ExpectationFailed();
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.addExpectationResult.apply(child, arguments);
|
||||
try {
|
||||
child.addExpectationResult.apply(child, arguments);
|
||||
} catch(e) {
|
||||
// keep going
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
203
src/core/TreeProcessor.js
Normal file
203
src/core/TreeProcessor.js
Normal file
@@ -0,0 +1,203 @@
|
||||
getJasmineRequireObj().TreeProcessor = function() {
|
||||
function TreeProcessor(attrs) {
|
||||
var tree = attrs.tree,
|
||||
runnableIds = attrs.runnableIds,
|
||||
queueRunnerFactory = attrs.queueRunnerFactory,
|
||||
nodeStart = attrs.nodeStart || function() {},
|
||||
nodeComplete = attrs.nodeComplete || function() {},
|
||||
stats = { valid: true },
|
||||
processed = false,
|
||||
defaultMin = Infinity,
|
||||
defaultMax = 1 - Infinity;
|
||||
|
||||
this.processTree = function() {
|
||||
processNode(tree, false);
|
||||
processed = true;
|
||||
return stats;
|
||||
};
|
||||
|
||||
this.execute = function(done) {
|
||||
if (!processed) {
|
||||
this.processTree();
|
||||
}
|
||||
|
||||
if (!stats.valid) {
|
||||
throw 'invalid order';
|
||||
}
|
||||
|
||||
var childFns = wrapChildren(tree, 0);
|
||||
|
||||
queueRunnerFactory({
|
||||
queueableFns: childFns,
|
||||
userContext: tree.sharedUserContext(),
|
||||
onException: function() {
|
||||
tree.onException.apply(tree, arguments);
|
||||
},
|
||||
onComplete: done
|
||||
});
|
||||
};
|
||||
|
||||
function runnableIndex(id) {
|
||||
for (var i = 0; i < runnableIds.length; i++) {
|
||||
if (runnableIds[i] === id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function processNode(node, parentEnabled) {
|
||||
var executableIndex = runnableIndex(node.id);
|
||||
|
||||
if (executableIndex !== undefined) {
|
||||
parentEnabled = true;
|
||||
}
|
||||
|
||||
parentEnabled = parentEnabled && node.isExecutable();
|
||||
|
||||
if (!node.children) {
|
||||
stats[node.id] = {
|
||||
executable: parentEnabled && node.isExecutable(),
|
||||
segments: [{
|
||||
index: 0,
|
||||
owner: node,
|
||||
nodes: [node],
|
||||
min: startingMin(executableIndex),
|
||||
max: startingMax(executableIndex)
|
||||
}]
|
||||
};
|
||||
} else {
|
||||
var hasExecutableChild = false;
|
||||
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
var child = node.children[i];
|
||||
|
||||
processNode(child, parentEnabled);
|
||||
|
||||
if (!stats.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
var childStats = stats[child.id];
|
||||
|
||||
hasExecutableChild = hasExecutableChild || childStats.executable;
|
||||
}
|
||||
|
||||
stats[node.id] = {
|
||||
executable: hasExecutableChild
|
||||
};
|
||||
|
||||
segmentChildren(node, stats[node.id], executableIndex);
|
||||
|
||||
if (!node.canBeReentered() && stats[node.id].segments.length > 1) {
|
||||
stats = { valid: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startingMin(executableIndex) {
|
||||
return executableIndex === undefined ? defaultMin : executableIndex;
|
||||
}
|
||||
|
||||
function startingMax(executableIndex) {
|
||||
return executableIndex === undefined ? defaultMax : executableIndex;
|
||||
}
|
||||
|
||||
function segmentChildren(node, nodeStats, executableIndex) {
|
||||
var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) },
|
||||
result = [currentSegment],
|
||||
lastMax = defaultMax,
|
||||
orderedChildSegments = orderChildSegments(node.children);
|
||||
|
||||
function isSegmentBoundary(minIndex) {
|
||||
return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < orderedChildSegments.length; i++) {
|
||||
var childSegment = orderedChildSegments[i],
|
||||
maxIndex = childSegment.max,
|
||||
minIndex = childSegment.min;
|
||||
|
||||
if (isSegmentBoundary(minIndex)) {
|
||||
currentSegment = {index: result.length, owner: node, nodes: [], min: defaultMin, max: defaultMax};
|
||||
result.push(currentSegment);
|
||||
}
|
||||
|
||||
currentSegment.nodes.push(childSegment);
|
||||
currentSegment.min = Math.min(currentSegment.min, minIndex);
|
||||
currentSegment.max = Math.max(currentSegment.max, maxIndex);
|
||||
lastMax = maxIndex;
|
||||
}
|
||||
|
||||
nodeStats.segments = result;
|
||||
}
|
||||
|
||||
function orderChildSegments(children) {
|
||||
var specifiedOrder = [],
|
||||
unspecifiedOrder = [];
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i],
|
||||
segments = stats[child.id].segments;
|
||||
|
||||
for (var j = 0; j < segments.length; j++) {
|
||||
var seg = segments[j];
|
||||
|
||||
if (seg.min === defaultMin) {
|
||||
unspecifiedOrder.push(seg);
|
||||
} else {
|
||||
specifiedOrder.push(seg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
specifiedOrder.sort(function(a, b) {
|
||||
return a.min - b.min;
|
||||
});
|
||||
|
||||
return specifiedOrder.concat(unspecifiedOrder);
|
||||
}
|
||||
|
||||
function executeNode(node, segmentNumber) {
|
||||
if (node.children) {
|
||||
return {
|
||||
fn: function(done) {
|
||||
nodeStart(node);
|
||||
|
||||
queueRunnerFactory({
|
||||
onComplete: function() {
|
||||
nodeComplete(node, node.getResult());
|
||||
done();
|
||||
},
|
||||
queueableFns: wrapChildren(node, segmentNumber),
|
||||
userContext: node.sharedUserContext(),
|
||||
onException: function() {
|
||||
node.onException.apply(node, arguments);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fn: function(done) { node.execute(done, stats[node.id].executable); }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function wrapChildren(node, segmentNumber) {
|
||||
var result = [],
|
||||
segmentChildren = stats[node.id].segments[segmentNumber].nodes;
|
||||
|
||||
for (var i = 0; i < segmentChildren.length; i++) {
|
||||
result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
|
||||
}
|
||||
|
||||
if (!stats[node.id].executable) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return node.beforeAllFns.concat(result).concat(node.afterAllFns);
|
||||
}
|
||||
}
|
||||
|
||||
return TreeProcessor;
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
getJasmineRequireObj().Any = function() {
|
||||
getJasmineRequireObj().Any = function(j$) {
|
||||
|
||||
function Any(expectedObject) {
|
||||
this.expectedObject = expectedObject;
|
||||
}
|
||||
|
||||
Any.prototype.jasmineMatches = function(other) {
|
||||
Any.prototype.asymmetricMatch = function(other) {
|
||||
if (this.expectedObject == String) {
|
||||
return typeof other == 'string' || other instanceof String;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ getJasmineRequireObj().Any = function() {
|
||||
if (this.expectedObject == Object) {
|
||||
return typeof other == 'object';
|
||||
}
|
||||
|
||||
|
||||
if (this.expectedObject == Boolean) {
|
||||
return typeof other == 'boolean';
|
||||
}
|
||||
@@ -29,7 +29,7 @@ getJasmineRequireObj().Any = function() {
|
||||
};
|
||||
|
||||
Any.prototype.jasmineToString = function() {
|
||||
return '<jasmine.any(' + this.expectedObject + ')>';
|
||||
return '<jasmine.any(' + j$.fnNameFor(this.expectedObject) + ')>';
|
||||
};
|
||||
|
||||
return Any;
|
||||
14
src/core/asymmetric_equality/Anything.js
Normal file
14
src/core/asymmetric_equality/Anything.js
Normal file
@@ -0,0 +1,14 @@
|
||||
getJasmineRequireObj().Anything = function(j$) {
|
||||
|
||||
function Anything() {}
|
||||
|
||||
Anything.prototype.asymmetricMatch = function(other) {
|
||||
return !j$.util.isUndefined(other) && other !== null;
|
||||
};
|
||||
|
||||
Anything.prototype.jasmineToString = function() {
|
||||
return '<jasmine.anything>';
|
||||
};
|
||||
|
||||
return Anything;
|
||||
};
|
||||
25
src/core/asymmetric_equality/ArrayContaining.js
Normal file
25
src/core/asymmetric_equality/ArrayContaining.js
Normal file
@@ -0,0 +1,25 @@
|
||||
getJasmineRequireObj().ArrayContaining = function(j$) {
|
||||
function ArrayContaining(sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
ArrayContaining.prototype.asymmetricMatch = function(other) {
|
||||
var className = Object.prototype.toString.call(this.sample);
|
||||
if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); }
|
||||
|
||||
for (var i = 0; i < this.sample.length; i++) {
|
||||
var item = this.sample[i];
|
||||
if (!j$.matchersUtil.contains(other, item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
ArrayContaining.prototype.jasmineToString = function () {
|
||||
return '<jasmine.arrayContaining(' + jasmine.pp(this.sample) +')>';
|
||||
};
|
||||
|
||||
return ArrayContaining;
|
||||
};
|
||||
49
src/core/asymmetric_equality/ObjectContaining.js
Normal file
49
src/core/asymmetric_equality/ObjectContaining.js
Normal file
@@ -0,0 +1,49 @@
|
||||
getJasmineRequireObj().ObjectContaining = function(j$) {
|
||||
|
||||
function ObjectContaining(sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
function getPrototype(obj) {
|
||||
if (Object.getPrototypeOf) {
|
||||
return Object.getPrototypeOf(obj);
|
||||
}
|
||||
|
||||
if (obj.constructor.prototype == obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return obj.constructor.prototype;
|
||||
}
|
||||
|
||||
function hasProperty(obj, property) {
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(obj, property)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return hasProperty(getPrototype(obj), property);
|
||||
}
|
||||
|
||||
ObjectContaining.prototype.asymmetricMatch = function(other) {
|
||||
if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
|
||||
|
||||
for (var property in this.sample) {
|
||||
if (!hasProperty(other, property) ||
|
||||
!j$.matchersUtil.equals(this.sample[property], other[property])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
ObjectContaining.prototype.jasmineToString = function() {
|
||||
return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return ObjectContaining;
|
||||
};
|
||||
20
src/core/asymmetric_equality/StringMatching.js
Normal file
20
src/core/asymmetric_equality/StringMatching.js
Normal file
@@ -0,0 +1,20 @@
|
||||
getJasmineRequireObj().StringMatching = function(j$) {
|
||||
|
||||
function StringMatching(expected) {
|
||||
if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
|
||||
throw new Error('Expected is not a String or a RegExp');
|
||||
}
|
||||
|
||||
this.regexp = new RegExp(expected);
|
||||
}
|
||||
|
||||
StringMatching.prototype.asymmetricMatch = function(other) {
|
||||
return this.regexp.test(other);
|
||||
};
|
||||
|
||||
StringMatching.prototype.jasmineToString = function() {
|
||||
return '<jasmine.stringMatching(' + this.regexp + ')>';
|
||||
};
|
||||
|
||||
return StringMatching;
|
||||
};
|
||||
@@ -37,14 +37,30 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return obj.nodeType > 0;
|
||||
};
|
||||
|
||||
j$.fnNameFor = function(func) {
|
||||
return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
|
||||
};
|
||||
|
||||
j$.any = function(clazz) {
|
||||
return new j$.Any(clazz);
|
||||
};
|
||||
|
||||
j$.anything = function() {
|
||||
return new j$.Anything();
|
||||
};
|
||||
|
||||
j$.objectContaining = function(sample) {
|
||||
return new j$.ObjectContaining(sample);
|
||||
};
|
||||
|
||||
j$.stringMatching = function(expected) {
|
||||
return new j$.StringMatching(expected);
|
||||
};
|
||||
|
||||
j$.arrayContaining = function(sample) {
|
||||
return new j$.ArrayContaining(sample);
|
||||
};
|
||||
|
||||
j$.createSpy = function(name, originalFn) {
|
||||
|
||||
var spyStrategy = new j$.SpyStrategy({
|
||||
@@ -89,6 +105,11 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
};
|
||||
|
||||
j$.createSpyObj = function(baseName, methodNames) {
|
||||
if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) {
|
||||
methodNames = baseName;
|
||||
baseName = 'unknown';
|
||||
}
|
||||
|
||||
if (!j$.isArray_(methodNames) || methodNames.length === 0) {
|
||||
throw 'createSpyObj requires a non-empty array of method names to create spies for';
|
||||
}
|
||||
|
||||
10
src/core/errors.js
Normal file
10
src/core/errors.js
Normal file
@@ -0,0 +1,10 @@
|
||||
getJasmineRequireObj().errors = function() {
|
||||
function ExpectationFailed() {}
|
||||
|
||||
ExpectationFailed.prototype = new Error();
|
||||
ExpectationFailed.prototype.constructor = ExpectationFailed;
|
||||
|
||||
return {
|
||||
ExpectationFailed: ExpectationFailed
|
||||
};
|
||||
};
|
||||
@@ -51,11 +51,37 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
function isAsymmetric(obj) {
|
||||
return obj && j$.isA_('Function', obj.asymmetricMatch);
|
||||
}
|
||||
|
||||
function asymmetricMatch(a, b) {
|
||||
var asymmetricA = isAsymmetric(a),
|
||||
asymmetricB = isAsymmetric(b);
|
||||
|
||||
if (asymmetricA && asymmetricB) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (asymmetricA) {
|
||||
return a.asymmetricMatch(b);
|
||||
}
|
||||
|
||||
if (asymmetricB) {
|
||||
return b.asymmetricMatch(a);
|
||||
}
|
||||
}
|
||||
|
||||
// Equality function lovingly adapted from isEqual in
|
||||
// [Underscore](http://underscorejs.org)
|
||||
function eq(a, b, aStack, bStack, customTesters) {
|
||||
var result = true;
|
||||
|
||||
var asymmetricResult = asymmetricMatch(a, b);
|
||||
if (!j$.util.isUndefined(asymmetricResult)) {
|
||||
return asymmetricResult;
|
||||
}
|
||||
|
||||
for (var i = 0; i < customTesters.length; i++) {
|
||||
var customTesterResult = customTesters[i](a, b);
|
||||
if (!j$.util.isUndefined(customTesterResult)) {
|
||||
@@ -63,27 +89,6 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
if (a instanceof j$.Any) {
|
||||
result = a.jasmineMatches(b);
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (b instanceof j$.Any) {
|
||||
result = b.jasmineMatches(a);
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (b instanceof j$.ObjectContaining) {
|
||||
result = b.jasmineMatches(a);
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (a instanceof Error && b instanceof Error) {
|
||||
return a.message == b.message;
|
||||
}
|
||||
@@ -119,6 +124,29 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
a.ignoreCase == b.ignoreCase;
|
||||
}
|
||||
if (typeof a != 'object' || typeof b != 'object') { return false; }
|
||||
|
||||
var aIsDomNode = j$.isDomNode(a);
|
||||
var bIsDomNode = j$.isDomNode(b);
|
||||
if (aIsDomNode && bIsDomNode) {
|
||||
// At first try to use DOM3 method isEqualNode
|
||||
if (a.isEqualNode) {
|
||||
return a.isEqualNode(b);
|
||||
}
|
||||
// IE8 doesn't support isEqualNode, try to use outerHTML && innerText
|
||||
var aIsElement = a instanceof Element;
|
||||
var bIsElement = b instanceof Element;
|
||||
if (aIsElement && bIsElement) {
|
||||
return a.outerHTML == b.outerHTML;
|
||||
}
|
||||
if (aIsElement || bIsElement) {
|
||||
return false;
|
||||
}
|
||||
return a.innerText == b.innerText && a.textContent == b.textContent;
|
||||
}
|
||||
if (aIsDomNode || bIsDomNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
var length = aStack.length;
|
||||
@@ -132,23 +160,20 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
bStack.push(b);
|
||||
var size = 0;
|
||||
// Recursively compare objects and arrays.
|
||||
if (className == '[object Array]') {
|
||||
// Compare array lengths to determine if a deep comparison is necessary.
|
||||
size = a.length;
|
||||
result = size == b.length;
|
||||
if (result) {
|
||||
// Deep compare the contents, ignoring non-numeric properties.
|
||||
while (size--) {
|
||||
if (!(result = eq(a[size], b[size], aStack, bStack, customTesters))) { break; }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Compare array lengths to determine if a deep comparison is necessary.
|
||||
if (className == '[object Array]' && a.length !== b.length) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
// Objects with different constructors are not equivalent, but `Object`s
|
||||
// from different frames are.
|
||||
var aCtor = a.constructor, bCtor = b.constructor;
|
||||
if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) &&
|
||||
isFunction(bCtor) && (bCtor instanceof bCtor))) {
|
||||
return false;
|
||||
// or `Array`s from different frames are.
|
||||
if (className !== '[object Array]') {
|
||||
var aCtor = a.constructor, bCtor = b.constructor;
|
||||
if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor &&
|
||||
isFunction(bCtor) && bCtor instanceof bCtor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Deep compare objects.
|
||||
for (var key in a) {
|
||||
@@ -174,7 +199,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
return result;
|
||||
|
||||
function has(obj, key) {
|
||||
return obj.hasOwnProperty(key);
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
getJasmineRequireObj().toMatch = function() {
|
||||
getJasmineRequireObj().toMatch = function(j$) {
|
||||
|
||||
function toMatch() {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
|
||||
throw new Error('Expected is not a String or a RegExp');
|
||||
}
|
||||
|
||||
var regexp = new RegExp(expected);
|
||||
|
||||
return {
|
||||
|
||||
@@ -31,7 +31,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
}
|
||||
|
||||
if (errorMatcher.hasNoSpecifics()) {
|
||||
pass.message = 'Expected function not to throw an Error, but it threw ' + fnNameFor(thrown) + '.';
|
||||
pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.';
|
||||
return pass;
|
||||
}
|
||||
|
||||
@@ -85,9 +85,9 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
}
|
||||
|
||||
return {
|
||||
errorTypeDescription: errorType ? fnNameFor(errorType) : 'an exception',
|
||||
errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception',
|
||||
thrownDescription: function(thrown) {
|
||||
var thrownName = errorType ? fnNameFor(thrown.constructor) : 'an exception',
|
||||
var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
|
||||
thrownMessage = '';
|
||||
|
||||
if (expected) {
|
||||
@@ -109,16 +109,12 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
return expected === null && errorType === null;
|
||||
},
|
||||
matches: function(error) {
|
||||
return (errorType === null || error.constructor === errorType) &&
|
||||
return (errorType === null || error instanceof errorType) &&
|
||||
(expected === null || messageMatch(error.message));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function fnNameFor(func) {
|
||||
return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
|
||||
}
|
||||
|
||||
function isStringOrRegExp(potential) {
|
||||
return potential instanceof RegExp || (typeof potential == 'string');
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
var jasmineRequire;
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
jasmineGlobal = global;
|
||||
jasmineRequire = exports;
|
||||
} else {
|
||||
if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
|
||||
jasmineGlobal = window;
|
||||
}
|
||||
jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {};
|
||||
}
|
||||
|
||||
@@ -17,7 +20,9 @@ getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
|
||||
jRequire.base(j$, jasmineGlobal);
|
||||
j$.util = jRequire.util();
|
||||
j$.Any = jRequire.Any();
|
||||
j$.errors = jRequire.errors();
|
||||
j$.Any = jRequire.Any(j$);
|
||||
j$.Anything = jRequire.Anything(j$);
|
||||
j$.CallTracker = jRequire.CallTracker();
|
||||
j$.MockDate = jRequire.MockDate();
|
||||
j$.Clock = jRequire.Clock();
|
||||
@@ -29,14 +34,17 @@ getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.JsApiReporter = jRequire.JsApiReporter();
|
||||
j$.matchersUtil = jRequire.matchersUtil(j$);
|
||||
j$.ObjectContaining = jRequire.ObjectContaining(j$);
|
||||
j$.ArrayContaining = jRequire.ArrayContaining(j$);
|
||||
j$.pp = jRequire.pp(j$);
|
||||
j$.QueueRunner = jRequire.QueueRunner(j$);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher();
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.SpyRegistry = jRequire.SpyRegistry(j$);
|
||||
j$.SpyStrategy = jRequire.SpyStrategy();
|
||||
j$.Suite = jRequire.Suite();
|
||||
j$.StringMatching = jRequire.StringMatching(j$);
|
||||
j$.Suite = jRequire.Suite(j$);
|
||||
j$.Timer = jRequire.Timer();
|
||||
j$.TreeProcessor = jRequire.TreeProcessor();
|
||||
j$.version = jRequire.version();
|
||||
|
||||
j$.matchers = jRequire.requireMatchers(jRequire, j$);
|
||||
|
||||
@@ -12,32 +12,32 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.fdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
it: function() {
|
||||
return env.it.apply(env, arguments);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
xit: function() {
|
||||
return env.xit.apply(env, arguments);
|
||||
},
|
||||
|
||||
fit: function(desc, func) {
|
||||
return env.fit(desc, func);
|
||||
fit: function() {
|
||||
return env.fit.apply(env, arguments);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
beforeEach: function() {
|
||||
return env.beforeEach.apply(env, arguments);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
afterEach: function() {
|
||||
return env.afterEach.apply(env, arguments);
|
||||
},
|
||||
|
||||
beforeAll: function(beforeAllFunction) {
|
||||
return env.beforeAll(beforeAllFunction);
|
||||
beforeAll: function() {
|
||||
return env.beforeAll.apply(env, arguments);
|
||||
},
|
||||
|
||||
afterAll: function(afterAllFunction) {
|
||||
return env.afterAll(afterAllFunction);
|
||||
afterAll: function() {
|
||||
return env.afterAll.apply(env, arguments);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
@@ -45,7 +45,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
},
|
||||
|
||||
pending: function() {
|
||||
return env.pending();
|
||||
return env.pending.apply(env, arguments);
|
||||
},
|
||||
|
||||
fail: function() {
|
||||
|
||||
@@ -11,6 +11,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
@@ -115,22 +117,51 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
this.jasmineDone = function() {
|
||||
var banner = find('.banner');
|
||||
banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
var alert = find('.alert');
|
||||
alert.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
alert.appendChild(createDom('span', { className: 'exceptions' },
|
||||
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
|
||||
createDom('input', {
|
||||
className: 'raise',
|
||||
id: 'raise-exceptions',
|
||||
type: 'checkbox'
|
||||
})
|
||||
));
|
||||
var checkbox = find('#raise-exceptions');
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'run-options' },
|
||||
createDom('span', { className: 'trigger' }, 'Options'),
|
||||
createDom('div', { className: 'payload' },
|
||||
createDom('div', { className: 'exceptions' },
|
||||
createDom('input', {
|
||||
className: 'raise',
|
||||
id: 'raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'throw',
|
||||
id: 'throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'label', 'for': 'throw-failures' }, 'stop spec on expectation failure'))
|
||||
)
|
||||
));
|
||||
|
||||
checkbox.checked = !env.catchingExceptions();
|
||||
checkbox.onclick = onRaiseExceptionsClick;
|
||||
var raiseCheckbox = find('#raise-exceptions');
|
||||
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var optionsMenu = find('.run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.payload'),
|
||||
isOpen = /\bopen\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' open';
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
@@ -191,6 +222,9 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: resultNode.result.status,
|
||||
@@ -238,7 +272,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
function clearPrior() {
|
||||
// return the reporter
|
||||
var oldReporter = find('');
|
||||
|
||||
|
||||
if(oldReporter) {
|
||||
getContainer().removeChild(oldReporter);
|
||||
}
|
||||
@@ -277,7 +311,11 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return '?spec=' + encodeURIComponent(result.fullName);
|
||||
return addToExistingQueryString('spec', result.fullName);
|
||||
}
|
||||
|
||||
function defaultQueryString(key, value) {
|
||||
return '?' + key + '=' + value;
|
||||
}
|
||||
|
||||
function setMenuModeTo(mode) {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
jasmineRequire.QueryString = function() {
|
||||
function QueryString(options) {
|
||||
|
||||
this.setParam = function(key, value) {
|
||||
this.navigateWithNewParam = function(key, value) {
|
||||
options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
|
||||
};
|
||||
|
||||
this.fullStringWithNewParam = function(key, value) {
|
||||
var paramMap = queryStringToParamMap();
|
||||
paramMap[key] = value;
|
||||
options.getWindowLocation().search = toQueryString(paramMap);
|
||||
return toQueryString(paramMap);
|
||||
};
|
||||
|
||||
this.getParam = function(key) {
|
||||
|
||||
@@ -14,6 +14,7 @@ $failing-color: #ca3a11;
|
||||
$pending-color: #ba9d37;
|
||||
$empty-color: #eff543;
|
||||
$neutral-color: #bababa;
|
||||
$jasmine-color: #8a4182;
|
||||
|
||||
$font-size: 11px;
|
||||
$large-font-size: 14px;
|
||||
@@ -77,12 +78,6 @@ body {
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.banner .duration {
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
// This div is available for testing elements that must be added to the DOM.
|
||||
// We position it out of view, so it doesn't obstruct the runner.
|
||||
#jasmine_content {
|
||||
@@ -101,8 +96,10 @@ body {
|
||||
}
|
||||
|
||||
.duration {
|
||||
color: $faint-text-color;
|
||||
color: #fff;
|
||||
float: right;
|
||||
line-height: $line-height * 2;
|
||||
padding-right: 9px;
|
||||
}
|
||||
|
||||
//--- Symbol summary ---//
|
||||
@@ -166,11 +163,32 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.exceptions {
|
||||
color: #fff;
|
||||
.run-options {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
border: 1px solid $jasmine-color;
|
||||
color: $jasmine-color;
|
||||
position: relative;
|
||||
line-height: 20px;
|
||||
|
||||
.trigger {
|
||||
cursor: pointer;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.payload {
|
||||
position: absolute;
|
||||
display: none;
|
||||
right: -1px;
|
||||
border: 1px solid $jasmine-color;
|
||||
background-color: $page-background-color;
|
||||
white-space: nowrap;
|
||||
padding: 4px 8px;
|
||||
|
||||
&.open {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- Alerts: status bars ---//
|
||||
@@ -227,48 +245,12 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.running-alert {
|
||||
background-color: $light-text-color;
|
||||
}
|
||||
|
||||
//--- Results ---//
|
||||
|
||||
.results {
|
||||
margin-top: $line-height;
|
||||
}
|
||||
|
||||
//--- Results menu ---//
|
||||
|
||||
&.showDetails {
|
||||
|
||||
.summaryMenuItem {
|
||||
font-weight: normal;
|
||||
text-decoration: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.detailsMenuItem {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.summary {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#details {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.summaryMenuItem {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
//--- Results summary: Suites and Specs names/links ---//
|
||||
|
||||
.summary {
|
||||
@@ -302,6 +284,10 @@ body {
|
||||
&.pending a {
|
||||
color: $pending-color;
|
||||
}
|
||||
|
||||
&.disabled a {
|
||||
color: $neutral-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
npm install -g grunt-cli
|
||||
npm install
|
||||
|
||||
grunt execSpecsInNode
|
||||
npm test
|
||||
|
||||
Reference in New Issue
Block a user