Compare commits
329 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a95c2cfe3f | ||
|
|
e2e2d1b343 | ||
|
|
3b53e469fd | ||
|
|
b3f69852c1 | ||
|
|
1613a376b1 | ||
|
|
1e35e8ba95 | ||
|
|
a6b209bc2f | ||
|
|
2301914549 | ||
|
|
320c42b6cc | ||
|
|
df45b4fede | ||
|
|
c1ab3c9cbe | ||
|
|
d2f2e2b870 | ||
|
|
0f6a7f04b3 | ||
|
|
728af5e556 | ||
|
|
018fd53c10 | ||
|
|
25d73515f3 | ||
|
|
8e317d4026 | ||
|
|
ea4c44904d | ||
|
|
77514bbb80 | ||
|
|
a85c3a4da8 | ||
|
|
0b1e1a0401 | ||
|
|
3374415add | ||
|
|
c2ae3b6b12 | ||
|
|
110cacab19 | ||
|
|
db7879a478 | ||
|
|
a81466d9e7 | ||
|
|
48f42eaa7d | ||
|
|
e5c2572753 | ||
|
|
141fd910f2 | ||
|
|
a93bfd2120 | ||
|
|
4221b2d2c4 | ||
|
|
6ee7fd6ced | ||
|
|
878325e2cf | ||
|
|
80c4f87dd5 | ||
|
|
3f3fa484b2 | ||
|
|
d0ad9b98cd | ||
|
|
375a6f9fda | ||
|
|
c017f0000d | ||
|
|
4097718b66 | ||
|
|
825dab32ff | ||
|
|
f3a7396845 | ||
|
|
850bee5492 | ||
|
|
6028a5d92c | ||
|
|
93a13ab791 | ||
|
|
542f483228 | ||
|
|
459b4c29b6 | ||
|
|
750a9aac6d | ||
|
|
cd55f03912 | ||
|
|
79954311fb | ||
|
|
3f71bcdb2d | ||
|
|
06f05ac57b | ||
|
|
5ea5ec6004 | ||
|
|
f7033f6551 | ||
|
|
7e6e905814 | ||
|
|
a6a1962924 | ||
|
|
50944fea6f | ||
|
|
7bfc4c0a45 | ||
|
|
4be2079482 | ||
|
|
d6f47ea886 | ||
|
|
5061dd066c | ||
|
|
2a847a67e3 | ||
|
|
50223d97d6 | ||
|
|
302e78f1df | ||
|
|
42ad12ec52 | ||
|
|
c41fa7d156 | ||
|
|
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 | ||
|
|
b56c2a69ac | ||
|
|
4b6789ccd9 | ||
|
|
9f94e8e226 | ||
|
|
55f32e2dc6 | ||
|
|
b30a85c8f1 | ||
|
|
20ce62d5f5 | ||
|
|
c3de57aaac | ||
|
|
2517ddfe17 | ||
|
|
23a492cb65 | ||
|
|
25c546a904 | ||
|
|
97ab0cb403 | ||
|
|
42b1bda919 | ||
|
|
216b40439f | ||
|
|
590a9d9d41 | ||
|
|
66c8624022 | ||
|
|
75e5a5c308 | ||
|
|
9b5c20cc19 | ||
|
|
cc720e7f56 | ||
|
|
1426416666 | ||
|
|
197cb13817 | ||
|
|
816b7d701f | ||
|
|
da6813ef0d | ||
|
|
a4d134521a | ||
|
|
d4fc787ea7 | ||
|
|
663fbd0cdb | ||
|
|
cf83ae474c | ||
|
|
325c5a2288 | ||
|
|
3ca687a9ad | ||
|
|
3b557f85c7 | ||
|
|
b67a19507f | ||
|
|
ecae3d47a7 | ||
|
|
a76d6d1cd4 | ||
|
|
916dc03d9c | ||
|
|
2151a13705 | ||
|
|
6cc09e00d3 | ||
|
|
6d6c31328b | ||
|
|
c8cd2eabe5 | ||
|
|
f77071254a | ||
|
|
8880729250 | ||
|
|
9ad15eeaba | ||
|
|
10ca5f0246 | ||
|
|
a5cd2731b4 | ||
|
|
b12974db2e | ||
|
|
f4e5573ee3 | ||
|
|
0c77c6cfb5 | ||
|
|
cfc64a6f5c | ||
|
|
6ab70923b3 | ||
|
|
d9c0b10be4 | ||
|
|
a58fd20d82 | ||
|
|
eefa716530 | ||
|
|
66c364564e | ||
|
|
68ba5b6d48 | ||
|
|
15ae0379ec | ||
|
|
1fb0d2eefa | ||
|
|
ba0982d89f | ||
|
|
f703539942 | ||
|
|
62840f72a6 | ||
|
|
6d10f97151 | ||
|
|
15f3d0e9d7 | ||
|
|
b1344d5c73 | ||
|
|
59aaac026c | ||
|
|
21f62c697a | ||
|
|
dc93c33af6 | ||
|
|
4889583d5c | ||
|
|
41df058171 | ||
|
|
fa837ae90a | ||
|
|
c82c958e0d | ||
|
|
752e831b30 | ||
|
|
bd30065d66 | ||
|
|
84dff421ea | ||
|
|
709e032d1c | ||
|
|
1290d93b6a | ||
|
|
345903220c | ||
|
|
3332f93a24 | ||
|
|
3b19d66268 | ||
|
|
137c1a39f6 | ||
|
|
9402d59859 | ||
|
|
e8178d061b | ||
|
|
dd75394ea8 | ||
|
|
6b857d11ce | ||
|
|
eb48c83649 | ||
|
|
08a35d134d | ||
|
|
14824b5f9e | ||
|
|
9afae3d978 | ||
|
|
64a67ed320 | ||
|
|
dee1066652 | ||
|
|
d7ab9083be | ||
|
|
caee1508d1 | ||
|
|
3b8326f1e6 | ||
|
|
980509cd7b | ||
|
|
b984ff2fa6 | ||
|
|
61bf9ac7d7 | ||
|
|
5b397ff33e | ||
|
|
cd4d5c2445 | ||
|
|
5b6edff3fd | ||
|
|
cc3678f033 | ||
|
|
35f52bcb24 | ||
|
|
f8bccabf03 | ||
|
|
97867b2bf5 | ||
|
|
18eb6e2f36 | ||
|
|
51462f369b | ||
|
|
ea57ad97cf | ||
|
|
3132d98f23 | ||
|
|
b799f54bc9 | ||
|
|
ac8ef2988d | ||
|
|
3c051fc291 | ||
|
|
6b937da863 | ||
|
|
89232db2ee | ||
|
|
8b0d9c83bb | ||
|
|
60533ca868 | ||
|
|
048ab728ec | ||
|
|
488df899fb | ||
|
|
753f4b44b4 | ||
|
|
2c23d35b03 | ||
|
|
2b0be0c74b | ||
|
|
b4f49db6bd | ||
|
|
cee3cc56e6 | ||
|
|
f2346d357f | ||
|
|
ee09301d8d | ||
|
|
760b50d969 | ||
|
|
773b15e450 | ||
|
|
ae94dd1bfa | ||
|
|
1bad048c15 | ||
|
|
f0892a55aa | ||
|
|
6066c71966 | ||
|
|
0d4b04d37c | ||
|
|
7ad261837a | ||
|
|
668846147c | ||
|
|
76fafa0388 | ||
|
|
bed1c15ea4 | ||
|
|
6caf4c5de2 | ||
|
|
97ae9a2d88 | ||
|
|
a3c3505086 | ||
|
|
a9e0112a9b | ||
|
|
a2ac5ef3b6 | ||
|
|
b200952195 | ||
|
|
752a36d3ff | ||
|
|
52026fb0f7 | ||
|
|
e17a2cb1e0 | ||
|
|
ec5695acc1 | ||
|
|
b1d4ab09af | ||
|
|
3b52d015ea | ||
|
|
b5b77b318a |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,5 +20,5 @@ sauce_connect.log
|
||||
*.swp
|
||||
build/
|
||||
*.egg-info/
|
||||
dist/*.tar.gz
|
||||
dist
|
||||
nbproject/
|
||||
|
||||
19
.npmignore
19
.npmignore
@@ -1,7 +1,7 @@
|
||||
dist/
|
||||
grunt/
|
||||
images/
|
||||
node_modules
|
||||
pkg/
|
||||
release_notes/
|
||||
spec/
|
||||
src/
|
||||
@@ -9,15 +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/boot.js
|
||||
lib/jasmine-core/spec
|
||||
lib/jasmine-core/*.css
|
||||
lib/jasmine-core/jasmine-html.js
|
||||
lib/jasmine-core/version.rb
|
||||
lib/jasmine-core/*.py
|
||||
sauce_connect.log
|
||||
|
||||
111
.travis.yml
111
.travis.yml
@@ -1,51 +1,70 @@
|
||||
---
|
||||
script: $TEST_COMMAND
|
||||
language: ruby
|
||||
cache: bundler
|
||||
rvm: 1.9.3
|
||||
|
||||
sudo: false
|
||||
|
||||
rvm: 2.2.0
|
||||
|
||||
script: $TEST_COMMAND
|
||||
|
||||
env:
|
||||
global:
|
||||
- USE_SAUCE=true
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="firefox"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
|
||||
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.8"
|
||||
- SAUCE_BROWSER_VERSION=6
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.6"
|
||||
- SAUCE_BROWSER_VERSION=5
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="chrome"
|
||||
- USE_SAUCE=true
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="firefox"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- env:
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- USE_SAUCE=false
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- TEST_COMMAND="bash travis-docs-script.sh"
|
||||
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
|
||||
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
|
||||
|
||||
addons:
|
||||
sauce_connect: true
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.11"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- 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"
|
||||
- SAUCE_BROWSER_VERSION=6
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8.1"
|
||||
- SAUCE_BROWSER_VERSION=11
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="chrome"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- env:
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- USE_SAUCE=false
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- TEST_COMMAND="bash travis-docs-script.sh"
|
||||
|
||||
@@ -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. If you want to contribute but don't know what to work on, [issues tagged ready for work](https://github.com/jasmine/jasmine/labels/ready%20for%20work) should have enough detail to get started.
|
||||
|
||||
## 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,17 +72,21 @@ 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.
|
||||
|
||||
$ npm install --local
|
||||
|
||||
...will install all of the node modules locally. If when you run
|
||||
...will install all of the node modules locally. Now run
|
||||
|
||||
$ grunt
|
||||
|
||||
...you see that JSHint runs your system is ready.
|
||||
...if you see that JSHint runs, your system is ready.
|
||||
|
||||
### How to write new Jasmine code
|
||||
|
||||
@@ -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
|
||||
$ bundle exec rake jasmine
|
||||
|
||||
...and then visit `http://localhost:8888` to run specs.
|
||||
|
||||
Jasmine uses Node.js with a custom runner to test outside of a browser.
|
||||
Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/jasmine-npm) to test itself in a Node.js/npm environment.
|
||||
|
||||
$ grunt execSpecsInNode
|
||||
|
||||
@@ -109,13 +118,13 @@ Jasmine uses Node.js with a custom runner to test outside of a browser.
|
||||
## Before Committing or Submitting a Pull Request
|
||||
|
||||
1. Ensure all specs are green in browser *and* node
|
||||
1. Ensure JSHint is green with `grunt jsHint`
|
||||
1. Ensure JSHint is green with `grunt jshint`
|
||||
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
|
||||
|
||||
## Submitting a Pull Request
|
||||
1. Revert your changes to `jasmine.js` and `jasmine-html.js`
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches.
|
||||
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master.
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
|
||||
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.
|
||||
|
||||
|
||||
64
GOALS_2.0.md
64
GOALS_2.0.md
@@ -1,64 +0,0 @@
|
||||
# (Vague) Jasmine 2.0 Goals/(Guidelines)
|
||||
|
||||
1. No globals!
|
||||
* jasmine library is entirely inside `jasmine` namespace
|
||||
* globals required for backwards compatibility should be added in `boot.js` (EG, var describe = jasmine.getCurrentEnv().describe lives in boot.js)
|
||||
1. Don't use properties as getters. Use methods.
|
||||
* Properties aren't encapsulated -- can be mutated, unsafe.
|
||||
1. Reporters get data objects (no methods).
|
||||
* easier to refactor as needed
|
||||
1. More unit tests - fewer nasty integration tests
|
||||
|
||||
## Remaining non-story-able work:
|
||||
* Make a `TODO` list
|
||||
|
||||
### Hard
|
||||
* Finish killing Globals
|
||||
* Guidelines:
|
||||
* New objects can have constructors on `jasmine`
|
||||
* Top level functions can live on `jasmine`
|
||||
* Top level (i.e., any `jasmine` property) should only be referenced inside the `Env` constructor
|
||||
* should better allow any object to get jasmine code (Node-friendly)
|
||||
* review everything in base.js
|
||||
* Remove isA functions:
|
||||
* isArray_ - used in matchers and spies
|
||||
* isString_
|
||||
* isDOMNode_
|
||||
* isA_
|
||||
* unimplementedMethod_, used by PrettyPrinter
|
||||
* jasmine.util should be util closure inside of env or something
|
||||
* argsToArray is used for Spies and matching (and can be replaced)
|
||||
* inherit is only for PrettyPrinter now
|
||||
* formatException is used only inside Env/spec
|
||||
* htmlEscape is for messages in matchers - should this be HTML at all?
|
||||
* Pretty printing
|
||||
* move away from pretty printer and to a JSON.stringify implementation?
|
||||
* jasmineToString vs. custom toString ?
|
||||
|
||||
### Easy
|
||||
|
||||
* unify params to ctors: options vs. attrs.
|
||||
* This will be a lot of the TODOs, but clean up & simplify Env.js (is this a 2.1 task?)
|
||||
|
||||
### DONE
|
||||
* Matchers improvements
|
||||
* unit testable DONE
|
||||
* better equality (from Underscore) DONE
|
||||
* addCustomMatchers doesn't explode stack DONE
|
||||
* refactor equals function so that it just loops & recurses over a list of fns (custom and built-in) - 2.1? (Tracker story)
|
||||
* Spies
|
||||
* break these out into their own tests/file DONE
|
||||
|
||||
|
||||
## Other Topics
|
||||
|
||||
* Docs
|
||||
* Docco has gone over well. Should we annotate all the sources and then have Pages be more complex, having tutorials and annotated source like Backbone? Are we small enough?
|
||||
* Need examples for:
|
||||
* How to build a Custom Matcher
|
||||
* How to add a custom equality tester
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
11
Gemfile
11
Gemfile
@@ -1,12 +1,9 @@
|
||||
source 'https://rubygems.org'
|
||||
gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git'
|
||||
# gem "jasmine", path: "/Users/pivotal/workspace/jasmine-gem"
|
||||
unless ENV["TRAVIS"]
|
||||
group :debug do
|
||||
gem 'debugger'
|
||||
end
|
||||
end
|
||||
gem "jasmine", :git => 'https://github.com/jasmine/jasmine-gem.git'
|
||||
# gem "jasmine", path: "../jasmine-gem"
|
||||
|
||||
gemspec
|
||||
|
||||
gem "jasmine_selenium_runner", :github => 'jasmine/jasmine_selenium_runner'
|
||||
|
||||
gem "anchorman"
|
||||
|
||||
16
Gruntfile.js
16
Gruntfile.js
@@ -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",
|
||||
@@ -37,10 +36,17 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask("execSpecsInNode",
|
||||
"Run Jasmine core specs in Node.js",
|
||||
function() {
|
||||
var exitInfo = require("shelljs").exec("node_modules/.bin/jasmine");
|
||||
if (exitInfo.code !== 0) {
|
||||
grunt.fail.fatal("Specs Failed", exitInfo.code);
|
||||
}
|
||||
var done = this.async(),
|
||||
Jasmine = require('jasmine'),
|
||||
jasmineCore = require('./lib/jasmine-core.js'),
|
||||
jasmine = new Jasmine({jasmineCore: jasmineCore});
|
||||
|
||||
jasmine.loadConfigFile('./spec/support/jasmine.json');
|
||||
jasmine.onComplete(function(passed) {
|
||||
done(passed);
|
||||
});
|
||||
|
||||
jasmine.execute();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
56
README.md
56
README.md
@@ -1,6 +1,7 @@
|
||||
<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/pivotal/jasmine) [](https://codeclimate.com/github/pivotal/jasmine)
|
||||
[](https://travis-ci.org/jasmine/jasmine)
|
||||
[](https://codeclimate.com/github/pivotal/jasmine)
|
||||
|
||||
=======
|
||||
|
||||
@@ -11,37 +12,45 @@ 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">
|
||||
```html
|
||||
<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">
|
||||
|
||||
<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>
|
||||
<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
|
||||
@@ -53,12 +62,15 @@ For the Jasmine Python Egg:<br>
|
||||
|
||||
## Maintainers
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
|
||||
* [Sheel Choksi](mailto:schoksi@pivotallabs.com), Pivotal Labs
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@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), Square
|
||||
* [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.
|
||||
|
||||
29
RELEASE.md
29
RELEASE.md
@@ -15,19 +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` 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:
|
||||
|
||||
### Update the Github Pages (as needed)
|
||||
* Changes related to packaging for a specific platform (npm, gem, or pip).
|
||||
* Fixes for regressions.
|
||||
|
||||
___Note: This is going to change right after 2.0___
|
||||
|
||||
Github pages have to exist in a branch called `gh-pages` in order for their app to serve them. This repo adds that branch as a submodule under the `pages` directory. This is a bit of a hack, but it allows us to work with the pages and the source at the same time and with one set of rake tasks.
|
||||
|
||||
If you want to submit changes to this repo and aren't a Pivotal Labs employee, you can fork and work in the `gh-pages` branch. You won't be able to edit the pages in the submodule off of master.
|
||||
When jasmine-core revs its major or minor version, the binding libraries should also rev to that version.
|
||||
|
||||
## Release
|
||||
|
||||
@@ -40,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 guthub releases...
|
||||
|
||||
### Release the Python egg
|
||||
|
||||
@@ -55,9 +50,21 @@ When ready to release - specs are all green and the stories are done:
|
||||
1. Push these changes to GitHub and verify that this SHA is green
|
||||
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
|
||||
|
||||
### Release the NPM
|
||||
|
||||
1. `npm adduser` to save your credentials locally
|
||||
1. `npm publish .` to publish what's in `package.json`
|
||||
|
||||
### Release the docs
|
||||
|
||||
Probably only need to do this when releasing a minor version, and not a patch version.
|
||||
|
||||
1. `cp -R edge ${version}` to copy the current edge docs to the new version
|
||||
1. Add a link to the new version in `index.html`
|
||||
|
||||
### 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
|
||||
|
||||
40
bower.json
Normal file
40
bower.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"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.
@@ -26,6 +26,7 @@ module.exports = {
|
||||
'src/core/base.js',
|
||||
'src/core/util.js',
|
||||
'src/core/Spec.js',
|
||||
'src/core/Order.js',
|
||||
'src/core/Env.js',
|
||||
'src/core/JsApiReporter.js',
|
||||
'src/core/PrettyPrinter',
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Jasmine Spec Runner v<%= jasmineVersion %></title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-<%= jasmineVersion %>/jasmine_favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-<%= jasmineVersion %>/jasmine.css">
|
||||
<link rel="stylesheet" href="lib/jasmine-<%= jasmineVersion %>/jasmine.css">
|
||||
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmineVersion %>/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmineVersion %>/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmineVersion %>/boot.js"></script>
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine.js"></script>
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine-html.js"></script>
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/boot.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" src="src/Song.js"></script>
|
||||
<script src="src/Player.js"></script>
|
||||
<script src="src/Song.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
|
||||
<script src="spec/SpecHelper.js"></script>
|
||||
<script src="spec/PlayerSpec.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
|
||||
s.name = "jasmine-core"
|
||||
s.version = Jasmine::Core::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Christian Williams"]
|
||||
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Gregg Van Hove"]
|
||||
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
|
||||
@@ -54,7 +54,10 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
};
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
print('ConsoleReporter is deprecated and will be removed in a future version.');
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
@@ -89,9 +92,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
@@ -116,6 +122,13 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
@@ -154,11 +167,23 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var failedExpectation = result.failedExpectations[i];
|
||||
printNewline();
|
||||
print(indent(failedExpectation.message, 2));
|
||||
print(indent(failedExpectation.stack, 2));
|
||||
}
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
|
||||
@@ -1,2 +1,37 @@
|
||||
module.exports = require("./jasmine-core/jasmine.js");
|
||||
module.exports.boot = require('./jasmine-core/node_boot.js');
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var rootPath = path.join(__dirname, "jasmine-core"),
|
||||
bootFiles = ['boot.js'],
|
||||
nodeBootFiles = ['node_boot.js'],
|
||||
cssFiles = [],
|
||||
jsFiles = [],
|
||||
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles);
|
||||
|
||||
fs.readdirSync(rootPath).forEach(function(file) {
|
||||
if(fs.statSync(path.join(rootPath, file)).isFile()) {
|
||||
switch(path.extname(file)) {
|
||||
case '.css':
|
||||
cssFiles.push(file);
|
||||
break;
|
||||
case '.js':
|
||||
if (jsFilesToSkip.indexOf(file) < 0) {
|
||||
jsFiles.push(file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports.files = {
|
||||
path: rootPath,
|
||||
bootDir: rootPath,
|
||||
bootFiles: bootFiles,
|
||||
nodeBootFiles: nodeBootFiles,
|
||||
cssFiles: cssFiles,
|
||||
jsFiles: ['jasmine.js'].concat(jsFiles),
|
||||
imagesDir: path.join(__dirname, '../images')
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -21,7 +21,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
|
||||
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
|
||||
|
||||
@@ -54,77 +54,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
|
||||
*/
|
||||
var jasmineInterface = {
|
||||
describe: function(description, specDefinitions) {
|
||||
return env.describe(description, specDefinitions);
|
||||
},
|
||||
|
||||
xdescribe: function(description, specDefinitions) {
|
||||
return env.xdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
pending: function() {
|
||||
return env.pending();
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
})
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the interface for adding custom equality testers.
|
||||
*/
|
||||
jasmine.addCustomEqualityTester = function(tester) {
|
||||
env.addCustomEqualityTester(tester);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose the interface for adding custom expectation matchers
|
||||
*/
|
||||
jasmine.addMatchers = function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose the mock interface for the JavaScript timeout functions
|
||||
*/
|
||||
jasmine.clock = function() {
|
||||
return env.clock;
|
||||
};
|
||||
extend(window, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
@@ -139,13 +74,27 @@ 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);
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
env.randomizeTests(random);
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
env.seed(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* ## 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()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
|
||||
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
|
||||
|
||||
@@ -32,77 +32,12 @@
|
||||
*
|
||||
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
|
||||
*/
|
||||
var jasmineInterface = {
|
||||
describe: function(description, specDefinitions) {
|
||||
return env.describe(description, specDefinitions);
|
||||
},
|
||||
|
||||
xdescribe: function(description, specDefinitions) {
|
||||
return env.xdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
pending: function() {
|
||||
return env.pending();
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
})
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the interface for adding custom equality testers.
|
||||
*/
|
||||
jasmine.addCustomEqualityTester = function(tester) {
|
||||
env.addCustomEqualityTester(tester);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose the interface for adding custom expectation matchers
|
||||
*/
|
||||
jasmine.addMatchers = function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose the mock interface for the JavaScript timeout functions
|
||||
*/
|
||||
jasmine.clock = function() {
|
||||
return env.clock;
|
||||
};
|
||||
extend(window, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
@@ -117,13 +52,27 @@
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
env.randomizeTests(random);
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
env.seed(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* ## 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()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
|
||||
@@ -6,66 +6,14 @@ module.exports = function(jasmineRequire) {
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = {
|
||||
describe: function(description, specDefinitions) {
|
||||
return env.describe(description, specDefinitions);
|
||||
},
|
||||
|
||||
xdescribe: function(description, specDefinitions) {
|
||||
return env.xdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
}),
|
||||
|
||||
|
||||
jasmine: jasmine
|
||||
};
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
jasmine.addCustomEqualityTester = function(tester) {
|
||||
env.addCustomEqualityTester(tester);
|
||||
};
|
||||
|
||||
jasmine.addMatchers = function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
jasmine.clock = function() {
|
||||
return env.clock;
|
||||
};
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
|
||||
return jasmine;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe("Player", function() {
|
||||
var Player = require('../../jasmine_examples/Player.js');
|
||||
var Song = require('../../jasmine_examples/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,30 +40,32 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
onRandomClick = options.onRandomClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols;
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
|
||||
createDom('div', {className: 'banner'},
|
||||
createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
|
||||
createDom('span', {className: 'version'}, j$.version)
|
||||
createDom('div', {className: 'jasmine-banner'},
|
||||
createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
|
||||
createDom('span', {className: 'jasmine-version'}, j$.version)
|
||||
),
|
||||
createDom('ul', {className: 'symbol-summary'}),
|
||||
createDom('div', {className: 'alert'}),
|
||||
createDom('div', {className: 'results'},
|
||||
createDom('div', {className: 'failures'})
|
||||
createDom('ul', {className: 'jasmine-symbol-summary'}),
|
||||
createDom('div', {className: 'jasmine-alert'}),
|
||||
createDom('div', {className: 'jasmine-results'},
|
||||
createDom('div', {className: 'jasmine-failures'})
|
||||
)
|
||||
);
|
||||
getContainer().appendChild(htmlReporterMain);
|
||||
|
||||
symbols = find('.symbol-summary');
|
||||
};
|
||||
|
||||
var totalSpecsDefined;
|
||||
@@ -72,7 +74,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
timer.start();
|
||||
};
|
||||
|
||||
var summary = createDom('div', {className: 'summary'});
|
||||
var summary = createDom('div', {className: 'jasmine-summary'});
|
||||
|
||||
var topResults = new j$.ResultsNode({}, '', null),
|
||||
currentParent = topResults;
|
||||
@@ -83,6 +85,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.status == 'failed') {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
@@ -96,7 +102,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
if(noExpectations(result) && console && console.error) {
|
||||
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
|
||||
console.error('Spec \'' + result.fullName + '\' has no expectations.');
|
||||
}
|
||||
|
||||
@@ -104,8 +110,12 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
if (!symbols){
|
||||
symbols = find('.jasmine-symbol-summary');
|
||||
}
|
||||
|
||||
symbols.appendChild(createDom('li', {
|
||||
className: noExpectations(result) ? 'empty' : result.status,
|
||||
className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
|
||||
id: 'spec_' + result.id,
|
||||
title: result.fullName
|
||||
}
|
||||
@@ -115,18 +125,18 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom('div', {className: 'spec-detail failed'},
|
||||
createDom('div', {className: 'description'},
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
|
||||
),
|
||||
createDom('div', {className: 'messages'})
|
||||
createDom('div', {className: 'jasmine-messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
@@ -137,48 +147,106 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
var banner = find('.banner');
|
||||
banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
this.jasmineDone = function(doneResult) {
|
||||
var banner = find('.jasmine-banner');
|
||||
var alert = find('.jasmine-alert');
|
||||
var order = doneResult && doneResult.order;
|
||||
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
var alert = find('.alert');
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-exceptions' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-raise',
|
||||
id: 'jasmine-raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
));
|
||||
|
||||
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');
|
||||
var raiseCheckbox = find('#jasmine-raise-exceptions');
|
||||
|
||||
checkbox.checked = !env.catchingExceptions();
|
||||
checkbox.onclick = onRaiseExceptionsClick;
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var randomCheckbox = find('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = onRandomClick;
|
||||
|
||||
var optionsMenu = find('.jasmine-run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
|
||||
isOpen = /\bjasmine-open\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' jasmine-open';
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'bar skipped'},
|
||||
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
|
||||
createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
|
||||
)
|
||||
);
|
||||
}
|
||||
var statusBarMessage = '';
|
||||
var statusBarClassName = 'bar ';
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
|
||||
statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
|
||||
statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
} else {
|
||||
statusBarClassName += 'skipped';
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
}
|
||||
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
|
||||
var seedBar;
|
||||
if (order && order.random) {
|
||||
seedBar = createDom('span', {className: 'jasmine-seed-bar'},
|
||||
', randomized with seed ',
|
||||
createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed)
|
||||
);
|
||||
}
|
||||
|
||||
var results = find('.results');
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
|
||||
var errorBarClassName = 'jasmine-bar jasmine-errored';
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
|
||||
}
|
||||
}
|
||||
|
||||
var results = find('.jasmine-results');
|
||||
results.appendChild(summary);
|
||||
|
||||
summaryList(topResults, summary);
|
||||
@@ -188,8 +256,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (resultNode.type == 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'suite-detail'},
|
||||
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-suite-detail'},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
@@ -198,17 +266,20 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type == 'spec') {
|
||||
if (domParent.getAttribute('class') != 'specs') {
|
||||
specListNode = createDom('ul', {className: 'specs'});
|
||||
if (domParent.getAttribute('class') != 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: resultNode.result.status,
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
@@ -220,24 +291,24 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'menu bar spec-list'},
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
|
||||
createDom('span', {}, 'Spec List | '),
|
||||
createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
|
||||
createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures')));
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'menu bar failure-list'},
|
||||
createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'},
|
||||
createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'),
|
||||
createDom('span', {}, ' | Failures ')));
|
||||
|
||||
find('.failures-menu').onclick = function() {
|
||||
setMenuModeTo('failure-list');
|
||||
find('.jasmine-failures-menu').onclick = function() {
|
||||
setMenuModeTo('jasmine-failure-list');
|
||||
};
|
||||
find('.spec-list-menu').onclick = function() {
|
||||
setMenuModeTo('spec-list');
|
||||
find('.jasmine-spec-list-menu').onclick = function() {
|
||||
setMenuModeTo('jasmine-spec-list');
|
||||
};
|
||||
|
||||
setMenuModeTo('failure-list');
|
||||
setMenuModeTo('jasmine-failure-list');
|
||||
|
||||
var failureNode = find('.failures');
|
||||
var failureNode = find('.jasmine-failures');
|
||||
for (var i = 0; i < failures.length; i++) {
|
||||
failureNode.appendChild(failures[i]);
|
||||
}
|
||||
@@ -253,7 +324,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
function clearPrior() {
|
||||
// return the reporter
|
||||
var oldReporter = find('');
|
||||
|
||||
|
||||
if(oldReporter) {
|
||||
getContainer().removeChild(oldReporter);
|
||||
}
|
||||
@@ -292,7 +363,15 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return '?spec=' + encodeURIComponent(result.fullName);
|
||||
return addToExistingQueryString('spec', result.fullName);
|
||||
}
|
||||
|
||||
function seedHref(seed) {
|
||||
return addToExistingQueryString('seed', seed);
|
||||
}
|
||||
|
||||
function defaultQueryString(key, value) {
|
||||
return '?' + key + '=' + value;
|
||||
}
|
||||
|
||||
function setMenuModeTo(mode) {
|
||||
@@ -344,10 +423,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,6 +1,6 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2009-08-17
|
||||
json2.js
|
||||
2014-02-04
|
||||
|
||||
Public Domain.
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
@@ -136,15 +144,9 @@
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
*/
|
||||
|
||||
/*jslint evil: true */
|
||||
/*jslint evil: true, regexp: true */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
@@ -153,16 +155,16 @@
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
if (!this.JSON) {
|
||||
this.JSON = {};
|
||||
if (typeof JSON !== 'object') {
|
||||
JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
@@ -171,37 +173,30 @@ if (!this.JSON) {
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
Date.prototype.toJSON = function () {
|
||||
|
||||
return isFinite(this.valueOf()) ?
|
||||
this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z' : null;
|
||||
return isFinite(this.valueOf())
|
||||
? this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z'
|
||||
: null;
|
||||
};
|
||||
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function (key) {
|
||||
return this.valueOf();
|
||||
};
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function () {
|
||||
return this.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
var cx,
|
||||
escapable,
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
meta,
|
||||
rep;
|
||||
|
||||
|
||||
@@ -213,17 +208,17 @@ if (!this.JSON) {
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0;
|
||||
return escapable.test(string) ?
|
||||
'"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string' ? c :
|
||||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' :
|
||||
'"' + string + '"';
|
||||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string'
|
||||
? c
|
||||
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' : '"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
@@ -301,11 +296,11 @@ if (!this.JSON) {
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0 ? '[]' :
|
||||
gap ? '[\n' + gap +
|
||||
partial.join(',\n' + gap) + '\n' +
|
||||
mind + ']' :
|
||||
'[' + partial.join(',') + ']';
|
||||
v = partial.length === 0
|
||||
? '[]'
|
||||
: gap
|
||||
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||
: '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
@@ -315,8 +310,8 @@ if (!this.JSON) {
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
k = rep[i];
|
||||
if (typeof k === 'string') {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
@@ -328,7 +323,7 @@ if (!this.JSON) {
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
@@ -340,9 +335,11 @@ if (!this.JSON) {
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0 ? '{}' :
|
||||
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
|
||||
mind + '}' : '{' + partial.join(',') + '}';
|
||||
v = partial.length === 0
|
||||
? '{}'
|
||||
: gap
|
||||
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||
: '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
@@ -351,7 +348,18 @@ if (!this.JSON) {
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
};
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
@@ -382,7 +390,7 @@ if (!this.JSON) {
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
@@ -397,6 +405,7 @@ if (!this.JSON) {
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
@@ -412,7 +421,7 @@ if (!this.JSON) {
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
@@ -430,6 +439,7 @@ if (!this.JSON) {
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
cx.lastIndex = 0;
|
||||
if (cx.test(text)) {
|
||||
text = text.replace(cx, function (a) {
|
||||
@@ -451,10 +461,10 @@ if (!this.JSON) {
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/.
|
||||
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
|
||||
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
|
||||
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
if (/^[\],:{}\s]*$/
|
||||
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||||
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||||
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
@@ -466,8 +476,9 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function' ?
|
||||
walk({'': j}, '') : j;
|
||||
return typeof reviver === 'function'
|
||||
? walk({'': j}, '')
|
||||
: j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
@@ -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
|
||||
@@ -28,66 +28,14 @@ module.exports = function(jasmineRequire) {
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = {
|
||||
describe: function(description, specDefinitions) {
|
||||
return env.describe(description, specDefinitions);
|
||||
},
|
||||
|
||||
xdescribe: function(description, specDefinitions) {
|
||||
return env.xdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
}),
|
||||
|
||||
|
||||
jasmine: jasmine
|
||||
};
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
jasmine.addCustomEqualityTester = function(tester) {
|
||||
env.addCustomEqualityTester(tester);
|
||||
};
|
||||
|
||||
jasmine.addMatchers = function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
jasmine.clock = function() {
|
||||
return env.clock;
|
||||
};
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
|
||||
return jasmine;
|
||||
};
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "2.0.1"
|
||||
VERSION = "2.4.1"
|
||||
end
|
||||
end
|
||||
|
||||
25
package.json
25
package.json
@@ -1,23 +1,34 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "2.0.1",
|
||||
"version": "2.4.1",
|
||||
"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": "~5.0.13",
|
||||
"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": "git://github.com/jasmine/jasmine-npm.git",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
22
release_notes/1.3.0.md
Normal file
22
release_notes/1.3.0.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Jasmine Core 1.3.0 Release Notes
|
||||
|
||||
## Summary
|
||||
This version was a very incremental release that merged in some pull requests for bug fixes.
|
||||
|
||||
## Features
|
||||
|
||||
* HTML Runner exposes UI to not swallow Exceptions, instead raising as soon as thrown
|
||||
* Migrated homepage content to Wiki
|
||||
* Made a far more useful [tutorial page](http://pivotal.github.com/jasmine)
|
||||
* Added a `toBeNaN` matcher
|
||||
|
||||
## Fixes
|
||||
|
||||
* Better detection of in-browser vs. not
|
||||
* `afterEach` functions will run now even when there is a timeout
|
||||
* `toBeCloseTo` matcher is more accurate
|
||||
* More explicit matcher messages for spies
|
||||
* Better equality comparisons for regular expressions
|
||||
* Improvements to the Pretty Printer: controllable recursion depth, don't include inherited properties
|
||||
* Fix where `for` was being used as a property on an object (failed on IE)
|
||||
|
||||
12
release_notes/1.3.1.md
Normal file
12
release_notes/1.3.1.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Jasmine Core 1.3.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is for browser compatibility fixes
|
||||
|
||||
## Changes
|
||||
|
||||
### Features
|
||||
|
||||
Fixing test runner failures in IE 6/7/8
|
||||
|
||||
@@ -49,7 +49,7 @@ to determine that there a spec is 'empty'
|
||||
* [Add package.json to Python egg to get correct version number](http://www.pivotaltracker.com/story/67556148) - Fixes #551
|
||||
* Allow users to set the maximum length of array that the pretty-printer
|
||||
will print out - Fixes #323 @mikemoraned and #374 @futuraprime
|
||||
* `matchersUtil.equals()`` does not expect a matcher as its first argument,
|
||||
* `matchersUtil.equals()` does not expect a matcher as its first argument,
|
||||
so send the "actual" value first and the "expected" value second. - Merges #538 from @cbandy
|
||||
* Add single quote check to `jshint` and fix src files for that - Closes #522
|
||||
* Remove an `eval` in order to support running jasmine within CSP - Closes #503
|
||||
|
||||
25
release_notes/2.0.2.md
Normal file
25
release_notes/2.0.2.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
## Changes
|
||||
|
||||
* keep the files for running in a webpage around in the npm package
|
||||
* Expose files and paths necessary to embed jasmine in an html page for nodejs
|
||||
* Pull out the building of the jasmine interface so node and web both get the same one.
|
||||
* Show a dot with color of pending spec when no expectations
|
||||
* Console reporter prints out failed expectation's message
|
||||
|
||||
### Bugs
|
||||
|
||||
* Allow mocked Date constructor to be called with a subset of full params
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
* a disabled suite should call resultCallback with status being disabled
|
||||
* disabled suite should still call onStart callback
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
83
release_notes/2.1.0.md
Normal file
83
release_notes/2.1.0.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Jasmine Core 2.1.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is the release of Jasmine 2.1.
|
||||
|
||||
## Features
|
||||
|
||||
- Support for focused specs via `fit` and `fdescribe`
|
||||
- Support for `beforeAll` and `afterAll`
|
||||
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
|
||||
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
|
||||
- Spies now track return values
|
||||
- Specs can now specify their own timeouts
|
||||
- Testing in Node.js via the official Jasmine Node Module
|
||||
- Spec results now have `suiteResults` method that behaves similarly to to `specResults`
|
||||
- HtmlReporter shows error alerts for afterAllExceptions
|
||||
|
||||
## Bugs
|
||||
|
||||
- CI now works for IE8 (this was releated to `ConsoleReporter` below)
|
||||
- Detect global object properly when getting the jasmine require obj
|
||||
- Fixes Issue #[569][issue_569] - [Tracker Story #73684570](http://www.pivotaltracker.com/story/73684570)
|
||||
|
||||
## Deprecations
|
||||
|
||||
### `ConsoleReporter` as part of Jasmine core
|
||||
|
||||
The Console Reporter exists nearly entirely for the old manner of running Jasmine's own specs in node.js. As we are now supporting node.js officially, this reporter code no longer needs to be in this repo and instead will be in the Jasmine npm.
|
||||
|
||||
For now you will see a deprecation message. It will be removed entirely in Jasmine 3.0.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Release Notes from previous releases now live at [Jasmine's GitHub release page][releases]. See Tracker Story #[54582902][tracker_1]
|
||||
- Better instructions for releasing new documentation
|
||||
|
||||
[releases]: https://github.com/pivotal/jasmine/releases
|
||||
[tracker_1]: http://www.pivotaltracker.com/story/54582902
|
||||
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
- Simplification of HTMLtags in SpecRunner.html
|
||||
- Merges #[700][issue_700] from @tkrotoff
|
||||
- `toContain` works with array-like objects (Arguments, HTMLCollections, etc)
|
||||
- Merges #[699][issue_699] from @charleshansen
|
||||
- Fixed isPendingSpecException test title
|
||||
- Merges #[691][issue_691] from @ertrzyiks
|
||||
- Fixed an issue with example code in the npm
|
||||
- Merges #[686][issue_686] from @akoptsov
|
||||
- When the Jasmine clock is installed and date is mocked, `new Date() instanceof Date` should equal `true` Issue #[678][issue_678] & Issue #[679][issue_679] from @chernetsov
|
||||
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
|
||||
- Fixes Issue #[567][issue_567], Issue #[568][issue_568], and Issue #[563][issue_563]
|
||||
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
|
||||
- Fixes Issue #[483][issue_483] - specs can now specify their own timeouts
|
||||
- Spies can track return values
|
||||
- Fixes Issue #[660][issue_660], Merged Issue #[669][issue_669] from @mkhanal
|
||||
- Interval handlers can now clear their interval
|
||||
- Fixes Issue #[655][issue_655] Merged Issue #[658][issue_658] from @tgirardi
|
||||
- Updated to the latest `json2.js`
|
||||
- Merges #[616][issue_616] from @apaladox2015
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
|
||||
|
||||
[issue_569]: http://github.com/pivotal/jasmine/issues/569
|
||||
[issue_700]: http://github.com/pivotal/jasmine/issues/700
|
||||
[issue_699]: http://github.com/pivotal/jasmine/issues/699
|
||||
[issue_691]: http://github.com/pivotal/jasmine/issues/691
|
||||
[issue_678]: http://github.com/pivotal/jasmine/issues/678
|
||||
[issue_679]: http://github.com/pivotal/jasmine/issues/679
|
||||
[issue_567]: http://github.com/pivotal/jasmine/issues/567
|
||||
[issue_568]: http://github.com/pivotal/jasmine/issues/568
|
||||
[issue_563]: http://github.com/pivotal/jasmine/issues/563
|
||||
[issue_483]: http://github.com/pivotal/jasmine/issues/483
|
||||
[issue_660]: http://github.com/pivotal/jasmine/issues/660
|
||||
[issue_669]: http://github.com/pivotal/jasmine/issues/669
|
||||
[issue_655]: http://github.com/pivotal/jasmine/issues/655
|
||||
[issue_658]: http://github.com/pivotal/jasmine/issues/658
|
||||
[issue_616]: http://github.com/pivotal/jasmine/issues/616
|
||||
[issue_686]: http://github.com/pivotal/jasmine/issues/686
|
||||
14
release_notes/2.1.1.md
Normal file
14
release_notes/2.1.1.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Jasmine Core 2.1.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release of jasmine core to fix a breaking change with events emitted by the top-level suite
|
||||
|
||||
## Issues
|
||||
|
||||
- Top-level suite triggers suiteStarted and suiteEnd to be consistent
|
||||
- Fixes [#706](http://github.com/pivotal/jasmine/issues/706)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
14
release_notes/2.1.2.md
Normal file
14
release_notes/2.1.2.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Jasmine Core 2.1.2 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release of jasmine core to fix a breaking change with reporting when all of the specs in a suite are pending.
|
||||
|
||||
## Changes
|
||||
|
||||
- Suites still run their children even if none are executable
|
||||
- Fixes [#707](http://github.com/pivotal/jasmine/issues/707)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
21
release_notes/2.1.3.md
Normal file
21
release_notes/2.1.3.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Jasmine Core 2.1.3 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is primarily a bug-fix release to clean up some recent regressions.
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Top level suite no longer reports suiteStart and suiteDone
|
||||
- Fixes [#716](https://github.com/jasmine/jasmine/issues/716)
|
||||
|
||||
* Don't keep the expected and actual for a passed expectation
|
||||
- Fixes [#640](https://github.com/jasmine/jasmine/issues/640)
|
||||
- Fixes [#690](https://github.com/jasmine/jasmine/issues/690)
|
||||
|
||||
* Use the new build env on Travis
|
||||
- Merges [#712](https://github.com/jasmine/jasmine/issues/712) from @joshk
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
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)_
|
||||
91
release_notes/2.4.0.md
Normal file
91
release_notes/2.4.0.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Jasmine Core 2.4.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests.
|
||||
The most notable is probably that Jasmine now supports randomization of spec order
|
||||
|
||||
## Changes
|
||||
|
||||
* Run jasmine's specs in random order
|
||||
* Add support for returning run details for reporting randomness
|
||||
* Use className instead of class when creating DOM elements
|
||||
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Syntax highlighting in README.md
|
||||
- Merges [#973](https://github.com/jasmine/jasmine/issues/973) from @brunoqc
|
||||
|
||||
* Added a throw error block in describe incase a function with arguments is passed in describe
|
||||
- Fixes [#896](https://github.com/jasmine/jasmine/issues/896)
|
||||
- Merges [#955](https://github.com/jasmine/jasmine/issues/955) from @himajasuman
|
||||
|
||||
* Remove unused `queueableFn` arg from `onException`
|
||||
- Fixes [#958](https://github.com/jasmine/jasmine/issues/958)
|
||||
|
||||
* Remove unused parameter from toThrowError
|
||||
- Merges [#957](https://github.com/jasmine/jasmine/issues/957) from @FuzzySockets
|
||||
|
||||
* Abort spying when the target cannot be spied upon
|
||||
- Fixes [#948](https://github.com/jasmine/jasmine/issues/948)
|
||||
- Merges [#949](https://github.com/jasmine/jasmine/issues/949) from @StephanBijzitter
|
||||
|
||||
* Removed GOALS_2.0.md, doesn't seem to be needed anymore
|
||||
- Merges [#954](https://github.com/jasmine/jasmine/issues/954) from @matthewhuff89
|
||||
|
||||
* Change #xit so that it will output a more BDD-style pending message
|
||||
- Merges [#942](https://github.com/jasmine/jasmine/issues/942) from @lalunamel
|
||||
- Fixes [#930](https://github.com/jasmine/jasmine/issues/930)
|
||||
- Fixes [#912](https://github.com/jasmine/jasmine/issues/912)
|
||||
|
||||
* Allow tests to run in random order
|
||||
- Merges [#927](https://github.com/jasmine/jasmine/issues/927) from @marcioj
|
||||
|
||||
* Use toString for objects if it has been overriden
|
||||
- Merges [#929](https://github.com/jasmine/jasmine/issues/929) from @myitcv
|
||||
- Fixes [#928](https://github.com/jasmine/jasmine/issues/928)
|
||||
|
||||
* Fix circles/x from getting cut off on Mac/chrome
|
||||
- Merges [#932](https://github.com/jasmine/jasmine/issues/932) from @James-Dunn
|
||||
|
||||
* Postpone find() until it is needed
|
||||
- Merges [#924](https://github.com/jasmine/jasmine/issues/924) from @danielalexiuc
|
||||
- Fixes [#917](https://github.com/jasmine/jasmine/issues/917)
|
||||
|
||||
* check for global before assigning
|
||||
* Reverse suite afterEach behavior to match semantics?
|
||||
- Merges [#908](https://github.com/jasmine/jasmine/issues/908) from @mcamac
|
||||
|
||||
* Use badges from shields.io
|
||||
- Merges [#902](https://github.com/jasmine/jasmine/issues/902) from @SimenB
|
||||
|
||||
* xdescribe marks pending, plus associated tests.
|
||||
- Merges [#869](https://github.com/jasmine/jasmine/issues/869) from @ljwall
|
||||
- Fixes [#855](https://github.com/jasmine/jasmine/issues/855)
|
||||
|
||||
* Update glob to latest
|
||||
- Merge [#892](https://github.com/jasmine/jasmine/issues/892) from @obastemur
|
||||
- Fixes [#891](https://github.com/jasmine/jasmine/issues/891)
|
||||
|
||||
* Remove moot `version` property from bower.json
|
||||
- Merges [#874](https://github.com/jasmine/jasmine/issues/874) from @kkirsche
|
||||
|
||||
* add toHaveBeenCalledTimes matcher
|
||||
- Merges [#871](https://github.com/jasmine/jasmine/issues/871) from @logankd
|
||||
- Fixes [#853](https://github.com/jasmine/jasmine/issues/853)
|
||||
|
||||
* Update CONTRIBUTING.md
|
||||
- Merges [#856](https://github.com/jasmine/jasmine/issues/856) from @lpww
|
||||
|
||||
* Make the HtmlReport CSS classes "unique enough"
|
||||
- Merges [#851](https://github.com/jasmine/jasmine/issues/851) from @prather-mcs
|
||||
- Fixes [#844](https://github.com/jasmine/jasmine/issues/844)
|
||||
|
||||
* Raise an error when jasmine.any() isn't passed a constructor
|
||||
- Merges [#854](https://github.com/jasmine/jasmine/issues/854) from @danfinnie
|
||||
- Fixes [#852](https://github.com/jasmine/jasmine/issues/852)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
11
release_notes/2.4.1.md
Normal file
11
release_notes/2.4.1.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Jasmine Core 2.4.1 Release Notes
|
||||
|
||||
## Changes
|
||||
|
||||
* Run `afterEach` in reverse order declared as before
|
||||
- Reverts [#908](https://github.com/jasmine/jasmine/issues/908)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
110
release_notes/older_versions.md
Normal file
110
release_notes/older_versions.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Release 1.0.1.1 — November 9, 2010
|
||||
|
||||
## Jasmine Gem
|
||||
|
||||
## Bugs fixed
|
||||
* Rails 3.0 and RSpec 2.0 are now supported.
|
||||
|
||||
|
||||
## Known issues
|
||||
* Rails 3 generators are not yet implemented -- coming soon!
|
||||
|
||||
|
||||
-----
|
||||
# Release 1.0.1 — October 5, 2010
|
||||
-----
|
||||
|
||||
## Jasmine Core
|
||||
|
||||
## Bugs fixed
|
||||
* Bug fixes for Internet Explorer (thanks fschwiet, fabiomcosta, and jfirebaugh).
|
||||
|
||||
|
||||
## Jasmine Gem
|
||||
|
||||
## Bugs fixed
|
||||
* Bug fix for Windows (thanks jfirebaugh).
|
||||
|
||||
|
||||
-----
|
||||
# Release 1.0 — September 14, 2010
|
||||
-----
|
||||
|
||||
## Jasmine Core
|
||||
|
||||
## Features
|
||||
* `waitsFor()` arguments can now be specified in any order. Timeout and message are optional.
|
||||
* The default `waitsFor()` timeout period is now specified in `env.defaultTimeoutInterval`; the default value is 5 seconds.
|
||||
* Added link to jasmine site from html runner.
|
||||
* Added license file to standalone distribution.
|
||||
* New friendly version number.
|
||||
|
||||
|
||||
## Bugs fixed
|
||||
* `waitsFor()` hanged forever if latch function never returned true.
|
||||
* The `not.toThrow()` matcher threw an exception when used with no args.
|
||||
* The `toThrow()` matcher, when inverted, gave misleading failure messages.
|
||||
* Spy matchers, when inverted, gave misleading failure messages.
|
||||
|
||||
|
||||
## Deprecations
|
||||
* Deprecated `waits()` block in favor of `waitsFor()`; `waits()` will be removed in a future release.
|
||||
* Deprecated `toNotBe()`, `toNotEqual()`, `toNotMatch()`, and `toNotContain()` matchers; they will be removed in a future release.
|
||||
* Console X was removed from the distribution as it was no longer used.
|
||||
* To give us some flexibility for future features, wrapped matcher functions now return `undefined` (they previously returned `true` or `false`, but this was undocumented).
|
||||
|
||||
|
||||
## Jasmine Gem
|
||||
|
||||
## Features
|
||||
* Jasmine now supports JRuby.
|
||||
* Jasmine now supports Ruby 1.9.
|
||||
|
||||
|
||||
## Bugs fixed
|
||||
* Various generator issues fixed.
|
||||
|
||||
|
||||
## Known issues
|
||||
* Rails 3 and RSpec 2 are not yet fully supported.
|
||||
|
||||
|
||||
-----
|
||||
# Release 0.11.1 — June 25, 2010
|
||||
-----
|
||||
|
||||
## Jasmine Core
|
||||
|
||||
### Features
|
||||
* Jasmine no longer logs "Jasmine Running…" messages to the log by default. This can be enabled in runner.html by adding 'trivialReporter.logRunningSpecs = true;'.
|
||||
* The `wasCalled()`, `wasCalledWith()`, `wasNotCalled()` and `wasNotCalledWith()` matchers have been deprecated. The new matchers `toHaveBeenCalled()` and `toHaveBeenCalledWith()` have been added. You can use the `not` prefix to achieve equivalent of the `wasNot…()` expectation (e.g. `not.toHaveBeenCalled()`).
|
||||
|
||||
|
||||
## Notables
|
||||
* A barebones version of Jasmine is now available on <a href="http://pivotal.github.com/jasmine/">http://pivotal.github.com/jasmine/</a>.
|
||||
|
||||
|
||||
-----
|
||||
# Release 0.11.0 — June 23, 2010
|
||||
-----
|
||||
## Jasmine Core
|
||||
|
||||
## Features
|
||||
* The version number has been removed from the generated single-file /lib/jasmine.js. We're also now uploading this file, with the version number in the filename, to github's Downloads page.
|
||||
* Old-style matchers (those using this.report(), from before 0.10.x) are no longer supported. See the <span class="caps">README</span> for instructions on writing new-style matchers.
|
||||
* <strong>jasmine.log</strong> pretty-prints its parameters to the spec's output.
|
||||
* Jasmine no longer depends on 'window'.
|
||||
* <span class="caps">HTML</span> runner should show number of passes/fails by spec, not expectation.
|
||||
* Small modification to JsApiReporter data format.
|
||||
|
||||
|
||||
## Bugs fixed:
|
||||
* If multiple beforeEach blocks were declared, they were executed in reverse order.
|
||||
* Specs with duplicate names confused TrivialReporter output.
|
||||
* Errors in describe functions caused later tests to be weirdly nested.
|
||||
* Nested specs weren't reported properly by the JsApiReporter.
|
||||
|
||||
|
||||
## Known issues:
|
||||
* If you turn on the mock clock, you'll get a spurious log message at the end of your spec.
|
||||
|
||||
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 '+
|
||||
|
||||
@@ -9,7 +9,7 @@ describe("ConsoleReporter", function() {
|
||||
output += str;
|
||||
},
|
||||
getOutput: function() {
|
||||
return output;
|
||||
return output.replace('ConsoleReporter is deprecated and will be removed in a future version.', '');
|
||||
},
|
||||
clear: function() {
|
||||
output = "";
|
||||
@@ -171,26 +171,44 @@ describe("ConsoleReporter", function() {
|
||||
|
||||
out.clear();
|
||||
|
||||
reporter.jasmineDone({});
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/true to be false/);
|
||||
expect(out.getOutput()).toMatch(/foo bar baz/);
|
||||
});
|
||||
|
||||
it("calls the onComplete callback when the suite is done", function() {
|
||||
var onComplete = jasmine.createSpy('onComplete'),
|
||||
describe('onComplete callback', function(){
|
||||
var onComplete, reporter;
|
||||
|
||||
beforeEach(function() {
|
||||
onComplete = jasmine.createSpy('onComplete');
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
onComplete: onComplete
|
||||
});
|
||||
reporter.jasmineStarted();
|
||||
});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
it("is called when the suite is done", function() {
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
it('calls it with false if there are spec failures', function() {
|
||||
reporter.specDone({status: "failed", failedExpectations: []});
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('calls it with false if there are suite failures', function() {
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.suiteDone({failedExpectations: [{ message: 'bananas' }] });
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("with color", function() {
|
||||
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
@@ -234,5 +252,19 @@ describe("ConsoleReporter", function() {
|
||||
|
||||
expect(out.getOutput()).toEqual("\x1B[31mF\x1B[0m");
|
||||
});
|
||||
|
||||
it("displays all afterAll exceptions", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'After All Exception' }] });
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'Some Other Exception' }] });
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/After All Exception/);
|
||||
expect(out.getOutput()).toMatch(/Some Other Exception/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
@@ -323,11 +491,29 @@ describe("Clock (acceptance)", function() {
|
||||
expect(clearedFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can clear a previously set interval using that interval's handler", function() {
|
||||
var spy = jasmine.createSpy('spy'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setInterval: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
|
||||
intervalId;
|
||||
|
||||
clock.install();
|
||||
|
||||
intervalId = clock.setInterval(function() {
|
||||
spy();
|
||||
clock.clearInterval(intervalId);
|
||||
}, 100);
|
||||
clock.tick(200);
|
||||
|
||||
expect(spy.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("correctly schedules functions after the Clock has advanced", 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();
|
||||
|
||||
@@ -344,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();
|
||||
@@ -363,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();
|
||||
@@ -371,14 +557,38 @@ describe("Clock (acceptance)", function() {
|
||||
|
||||
clock.tick(6);
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
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();
|
||||
|
||||
@@ -395,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();
|
||||
|
||||
@@ -419,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'),
|
||||
@@ -242,5 +201,55 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(innerFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions after rescheduling them", function () {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
recurring = function() {
|
||||
expect(scheduler.scheduleFunction).toHaveBeenCalled();
|
||||
};
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
|
||||
spyOn(scheduler, "scheduleFunction");
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,74 +5,18 @@ describe("Env", function() {
|
||||
env = new j$.Env();
|
||||
});
|
||||
|
||||
it('removes all spies when env is executed', function(done) {
|
||||
var originalFoo = function() {},
|
||||
testObj = {
|
||||
foo: originalFoo
|
||||
},
|
||||
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
|
||||
env.spyOn(testObj, 'foo');
|
||||
}),
|
||||
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
|
||||
expect(testObj.foo).toBe(originalFoo);
|
||||
});
|
||||
env.describe('test suite', function() {
|
||||
env.it('spec 0', firstSpec);
|
||||
env.it('spec 1', secondSpec);
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(firstSpec).toHaveBeenCalled();
|
||||
expect(secondSpec).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
describe("#spyOn", function() {
|
||||
it("checks for the existence of the object", function() {
|
||||
expect(function() {
|
||||
env.spyOn(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it("checks for the existence of the method", function() {
|
||||
var subject = {};
|
||||
|
||||
expect(function() {
|
||||
env.spyOn(subject, 'pants');
|
||||
}).toThrowError(/method does not exist/);
|
||||
});
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
var subject = { spiedFunc: function() {} };
|
||||
|
||||
env.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(function() {
|
||||
env.spyOn(subject, 'spiedFunc');
|
||||
}).toThrowError(/has already been spied upon/);
|
||||
});
|
||||
|
||||
it("overrides the method on the object and returns the spy", function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
|
||||
|
||||
var spy = env.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#pending", function() {
|
||||
it("throws the Pending Spec exception", function() {
|
||||
expect(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() {
|
||||
@@ -81,5 +25,44 @@ describe("Env", function() {
|
||||
expect(suite.description).toEqual('Jasmine__TopLevel__Suite');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#describe', function () {
|
||||
var spec = function(done){};
|
||||
it("throws the error", function() {
|
||||
expect(function() {
|
||||
env.describe('done method', spec);
|
||||
}).toThrow(new Error('describe does not expect a done parameter'));
|
||||
});
|
||||
});
|
||||
|
||||
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
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#xit', function() {
|
||||
it('calls spec.pend with "Temporarily disabled with xit"', function() {
|
||||
var pendSpy = jasmine.createSpy();
|
||||
spyOn(env, 'it').and.returnValue({
|
||||
pend: pendSpy
|
||||
});
|
||||
env.xit();
|
||||
expect(pendSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
describe("Expectation", function() {
|
||||
it(".addMatchers makes matchers available to any expectation", function() {
|
||||
it("makes custom matchers available to this expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {},
|
||||
toBar: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers
|
||||
});
|
||||
|
||||
expect(expectation.toFoo).toBeDefined();
|
||||
expect(expectation.toBar).toBeDefined();
|
||||
@@ -27,25 +27,6 @@ describe("Expectation", function() {
|
||||
expect(expectation.toQuux).toBeDefined();
|
||||
});
|
||||
|
||||
it(".resetMatchers should keep only core matchers", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {}
|
||||
},
|
||||
coreMatchers = {
|
||||
toQuux: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addCoreMatchers(coreMatchers);
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
j$.Expectation.resetMatchers();
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
|
||||
expect(expectation.toQuux).toBeDefined();
|
||||
expect(expectation.toFoo).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Factory builds an expectation/negative expectation", function() {
|
||||
var builtExpectation = j$.Expectation.Factory();
|
||||
|
||||
@@ -65,10 +46,9 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customMatchers: matchers,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
@@ -94,10 +74,9 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -121,10 +100,8 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
@@ -155,10 +132,8 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
@@ -191,10 +166,9 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
actual: "an actual",
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
@@ -225,10 +199,8 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -259,10 +231,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
@@ -294,10 +264,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
util: util,
|
||||
addExpectationResult: addExpectationResult,
|
||||
@@ -332,10 +300,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
@@ -365,10 +331,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
@@ -403,10 +367,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
|
||||
@@ -178,6 +178,43 @@ describe("JsApiReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#suiteResults", function(){
|
||||
var reporter, suiteResult1, suiteResult2;
|
||||
beforeEach(function() {
|
||||
reporter = new j$.JsApiReporter({});
|
||||
suiteStarted1 = {
|
||||
id: 1
|
||||
};
|
||||
suiteResult1 = {
|
||||
id: 1,
|
||||
status: 'failed',
|
||||
failedExpectations: [{ message: 'My After All Exception' }]
|
||||
};
|
||||
suiteResult2 = {
|
||||
id: 2,
|
||||
status: 'finished'
|
||||
};
|
||||
|
||||
reporter.suiteStarted(suiteStarted1);
|
||||
reporter.suiteDone(suiteResult1);
|
||||
reporter.suiteDone(suiteResult2);
|
||||
});
|
||||
|
||||
it('should not include suite starts', function(){
|
||||
expect(reporter.suiteResults(0,3).length).toEqual(2);
|
||||
});
|
||||
|
||||
it("should return a slice of results", function() {
|
||||
expect(reporter.suiteResults(0, 1)).toEqual([suiteResult1]);
|
||||
expect(reporter.suiteResults(1, 1)).toEqual([suiteResult2]);
|
||||
});
|
||||
|
||||
it("returns nothing for out of bounds indicies", function() {
|
||||
expect(reporter.suiteResults(0, 3)).toEqual([suiteResult1, suiteResult2]);
|
||||
expect(reporter.suiteResults(2, 3)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#executionTime", function() {
|
||||
it("should start the timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
@@ -211,4 +248,12 @@ describe("JsApiReporter", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#runDetails', function() {
|
||||
it('should have details about the run', function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
reporter.jasmineDone({some: {run: 'details'}});
|
||||
expect(reporter.runDetails).toEqual({some: {run: 'details'}});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -75,6 +75,7 @@ describe("FakeDate", function() {
|
||||
|
||||
mockDate.install();
|
||||
expect(new fakeGlobal.Date()).toEqual(jasmine.any(Date));
|
||||
expect(new fakeGlobal.Date() instanceof fakeGlobal.Date).toBe(true);
|
||||
});
|
||||
|
||||
it("fakes current time when using Date.now()", function() {
|
||||
@@ -157,15 +158,35 @@ describe("FakeDate", function() {
|
||||
expect(fakeGlobal.Date.now()).toEqual(1000);
|
||||
});
|
||||
|
||||
it("allows to create a Date in a different time than the mocked time", function() {
|
||||
it("allows creation of a Date in a different time than the mocked time", function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new j$.MockDate(fakeGlobal),
|
||||
baseDate = new Date(2013, 9, 23, 0, 0, 0, 0);
|
||||
mockDate = new j$.MockDate(fakeGlobal);
|
||||
|
||||
mockDate.install(baseDate);
|
||||
mockDate.install();
|
||||
|
||||
var otherDate = new fakeGlobal.Date(2013, 9, 23, 0, 0, 1, 0);
|
||||
expect(otherDate.getTime()).not.toEqual(baseDate.getTime());
|
||||
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23, 0, 0, 1, 0).getTime());
|
||||
});
|
||||
|
||||
it("allows creation of a Date that isn't fully specified", function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new j$.MockDate(fakeGlobal);
|
||||
|
||||
mockDate.install();
|
||||
|
||||
var otherDate = new fakeGlobal.Date(2013, 9, 23);
|
||||
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23).getTime());
|
||||
});
|
||||
|
||||
it('allows creation of a Date with millis', function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new j$.MockDate(fakeGlobal),
|
||||
now = new Date(2014, 3, 15).getTime();
|
||||
|
||||
mockDate.install();
|
||||
|
||||
var otherDate = new fakeGlobal.Date(now);
|
||||
expect(otherDate.getTime()).toEqual(now);
|
||||
});
|
||||
|
||||
it("copies all Date properties to the mocked date", function() {
|
||||
|
||||
@@ -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,31 +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];
|
||||
|
||||
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() {
|
||||
@@ -48,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;
|
||||
@@ -68,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> })");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -91,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() {
|
||||
@@ -103,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 })");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -130,7 +165,9 @@ describe("j$.pp", function () {
|
||||
},
|
||||
env = new j$.Env();
|
||||
|
||||
env.spyOn(TestObject, 'someFunction');
|
||||
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {return [];}});
|
||||
|
||||
spyRegistry.spyOn(TestObject, 'someFunction');
|
||||
expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
|
||||
|
||||
expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
|
||||
@@ -144,13 +181,20 @@ describe("j$.pp", function () {
|
||||
expect(j$.pp(obj)).toEqual("strung");
|
||||
});
|
||||
|
||||
it("should stringify objects that implement custom toString", function () {
|
||||
var obj = {
|
||||
toString: function () { return "my toString"; }
|
||||
};
|
||||
|
||||
expect(j$.pp(obj)).toEqual("my toString");
|
||||
});
|
||||
|
||||
it("should handle objects with null prototype", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var obj = Object.create(null);
|
||||
obj.foo = 'bar';
|
||||
|
||||
expect(j$.pp(obj)).toEqual("{ foo: 'bar' }");
|
||||
expect(j$.pp(obj)).toEqual("null({ foo: 'bar' })");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@ describe("QueueRunner", function() {
|
||||
|
||||
it("runs all the functions it's passed", function() {
|
||||
var calls = [],
|
||||
fn1 = jasmine.createSpy('fn1'),
|
||||
fn2 = jasmine.createSpy('fn2'),
|
||||
queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2]
|
||||
queueableFns: [queueableFn1, queueableFn2]
|
||||
});
|
||||
fn1.and.callFake(function() {
|
||||
queueableFn1.fn.and.callFake(function() {
|
||||
calls.push('fn1');
|
||||
});
|
||||
fn2.and.callFake(function() {
|
||||
queueableFn2.fn.and.callFake(function() {
|
||||
calls.push('fn2');
|
||||
});
|
||||
|
||||
@@ -20,19 +20,19 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("calls each function with a consistent 'this'-- an empty object", function() {
|
||||
var fn1 = jasmine.createSpy('fn1'),
|
||||
fn2 = jasmine.createSpy('fn2'),
|
||||
fn3 = function(done) { asyncContext = this; done(); },
|
||||
var queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2, fn3]
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3]
|
||||
}),
|
||||
asyncContext;
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
var context = fn1.calls.first().object;
|
||||
var context = queueableFn1.fn.calls.first().object;
|
||||
expect(context).toEqual({});
|
||||
expect(fn2.calls.first().object).toBe(context);
|
||||
expect(queueableFn2.fn.calls.first().object).toBe(context);
|
||||
expect(asyncContext).toBe(context);
|
||||
});
|
||||
|
||||
@@ -53,20 +53,20 @@ describe("QueueRunner", function() {
|
||||
beforeCallback = jasmine.createSpy('beforeCallback'),
|
||||
fnCallback = jasmine.createSpy('fnCallback'),
|
||||
afterCallback = jasmine.createSpy('afterCallback'),
|
||||
fn1 = function(done) {
|
||||
queueableFn1 = { fn: function(done) {
|
||||
beforeCallback();
|
||||
setTimeout(done, 100);
|
||||
},
|
||||
fn2 = function(done) {
|
||||
} },
|
||||
queueableFn2 = { fn: function(done) {
|
||||
fnCallback();
|
||||
setTimeout(done, 100);
|
||||
},
|
||||
fn3 = function(done) {
|
||||
} },
|
||||
queueableFn3 = { fn: function(done) {
|
||||
afterCallback();
|
||||
setTimeout(done, 100);
|
||||
},
|
||||
} },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2, fn3],
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3],
|
||||
onComplete: onComplete
|
||||
});
|
||||
|
||||
@@ -93,55 +93,77 @@ describe("QueueRunner", function() {
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
|
||||
var beforeFn = function(done) { },
|
||||
fn = jasmine.createSpy('fn'),
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
it("explicitly fails an async function with a provided fail function and moves to the next function", function() {
|
||||
var queueableFn1 = { fn: function(done) {
|
||||
setTimeout(function() { done.fail('foo'); }, 100);
|
||||
} },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [beforeFn, fn],
|
||||
onComplete: onComplete,
|
||||
onException: onException,
|
||||
enforceTimeout: function() { return true; }
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
fail: failFn
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(failFn).toHaveBeenCalledWith('foo');
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
|
||||
var timeout = 3,
|
||||
beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
|
||||
queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
queueableFns: [beforeFn, queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(queueableFn.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(timeout);
|
||||
|
||||
expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(queueableFn.fn).toHaveBeenCalled();
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("by default does not set a timeout for asynchronous functions", function() {
|
||||
var beforeFn = function(done) { },
|
||||
fn = jasmine.createSpy('fn'),
|
||||
var beforeFn = { fn: function(done) { } },
|
||||
queueableFn = { fn: jasmine.createSpy('fn') },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [beforeFn, fn],
|
||||
queueableFns: [beforeFn, queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException,
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
expect(queueableFn.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
|
||||
|
||||
expect(onException).not.toHaveBeenCalled();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
expect(queueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("clears the timeout when an async function throws an exception, to prevent additional onException calls", function() {
|
||||
var fn = function(done) { throw new Error("error!"); },
|
||||
it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
|
||||
var queueableFn = { fn: function(done) { throw new Error("error!"); } },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException
|
||||
});
|
||||
@@ -156,11 +178,11 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("clears the timeout when the done callback is called", function() {
|
||||
var fn = function(done) { done(); },
|
||||
var queueableFn = { fn: function(done) { done(); } },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException
|
||||
});
|
||||
@@ -174,75 +196,78 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("only moves to the next spec the first time you call done", function() {
|
||||
var fn = function(done) {done(); done();},
|
||||
nextFn = jasmine.createSpy('nextFn');
|
||||
var queueableFn = { fn: function(done) {done(); done();} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextFn.calls.count()).toEqual(1);
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("does not move to the next spec if done is called after an exception has ended the spec", function() {
|
||||
var fn = function(done) {
|
||||
var queueableFn = { fn: function(done) {
|
||||
setTimeout(done, 1);
|
||||
throw new Error('error!');
|
||||
},
|
||||
nextFn = jasmine.createSpy('nextFn');
|
||||
} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick(1);
|
||||
expect(nextFn.calls.count()).toEqual(1);
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("calls an exception handler when an exception is thrown in a fn", function() {
|
||||
var fn = function() {
|
||||
it("calls exception handlers when an exception is thrown in a fn", function() {
|
||||
var queueableFn = { type: 'queueable',
|
||||
fn: function() {
|
||||
throw new Error('fake error');
|
||||
},
|
||||
exceptionCallback = jasmine.createSpy('exception callback'),
|
||||
} },
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
onException: exceptionCallback
|
||||
queueableFns: [queueableFn],
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
});
|
||||
|
||||
it("rethrows an exception if told to", function() {
|
||||
var fn = function() {
|
||||
var queueableFn = { fn: function() {
|
||||
throw new Error('fake error');
|
||||
},
|
||||
} },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
catchException: function(e) { return false; }
|
||||
});
|
||||
|
||||
expect(queueRunner.execute).toThrow();
|
||||
expect(function() {
|
||||
queueRunner.execute();
|
||||
}).toThrowError('fake error');
|
||||
});
|
||||
|
||||
it("continues running the functions even after an exception is thrown in an async spec", function() {
|
||||
var fn = function(done) { throw new Error("error"); },
|
||||
nextFn = jasmine.createSpy("nextFunction"),
|
||||
var queueableFn = { fn: function(done) { throw new Error("error"); } },
|
||||
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextFn).toHaveBeenCalled();
|
||||
expect(nextQueueableFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided complete callback when done", function() {
|
||||
var fn = jasmine.createSpy('fn'),
|
||||
var queueableFn = { fn: jasmine.createSpy('fn') },
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
onComplete: completeCallback
|
||||
});
|
||||
|
||||
@@ -252,12 +277,12 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("calls a provided stack clearing function when done", function() {
|
||||
var asyncFn = function(done) { done() },
|
||||
afterFn = jasmine.createSpy('afterFn'),
|
||||
var asyncFn = { fn: function(done) { done() } },
|
||||
afterFn = { fn: jasmine.createSpy('afterFn') },
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
clearStack = jasmine.createSpy('clearStack'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [asyncFn, afterFn],
|
||||
queueableFns: [asyncFn, afterFn],
|
||||
clearStack: clearStack,
|
||||
onComplete: completeCallback
|
||||
});
|
||||
@@ -265,7 +290,7 @@ describe("QueueRunner", function() {
|
||||
clearStack.and.callFake(function(fn) { fn(); });
|
||||
|
||||
queueRunner.execute();
|
||||
expect(afterFn).toHaveBeenCalled();
|
||||
expect(afterFn.fn).toHaveBeenCalled();
|
||||
expect(clearStack).toHaveBeenCalledWith(completeCallback);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,11 @@ describe("Spec", function() {
|
||||
expect(j$.Spec.isPendingSpecException(fakeError)).toBe(true);
|
||||
});
|
||||
|
||||
it("#isPendingSpecException returns true for a pending spec exception", function() {
|
||||
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");
|
||||
|
||||
expect(j$.Spec.isPendingSpecException(e)).toBe(false);
|
||||
@@ -29,7 +33,7 @@ describe("Spec", function() {
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
@@ -44,7 +48,7 @@ describe("Spec", function() {
|
||||
spec = new j$.Spec({
|
||||
id: 123,
|
||||
description: 'foo bar',
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
onStart: startCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
@@ -66,7 +70,7 @@ describe("Spec", function() {
|
||||
expect(beforesWereCalled).toBe(false);
|
||||
}),
|
||||
spec = new j$.Spec({
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
beforeFns: function() {
|
||||
return [function() {
|
||||
beforesWereCalled = true
|
||||
@@ -85,25 +89,22 @@ describe("Spec", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
before = jasmine.createSpy('before'),
|
||||
after = jasmine.createSpy('after'),
|
||||
fn = jasmine.createSpy('test body').and.callFake(function() {
|
||||
queueableFn = { fn: jasmine.createSpy('test body').and.callFake(function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
}),
|
||||
}) },
|
||||
spec = new j$.Spec({
|
||||
fn: fn,
|
||||
beforeFns: function() {
|
||||
return [before]
|
||||
},
|
||||
afterFns: function() {
|
||||
return [after]
|
||||
queueableFn: queueableFn,
|
||||
beforeAndAfterFns: function() {
|
||||
return {befores: [before], afters: [after]}
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].fns;
|
||||
expect(allSpecFns).toEqual([before, fn, after]);
|
||||
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(allSpecFns).toEqual([before, queueableFn, after]);
|
||||
});
|
||||
|
||||
it("is marked pending if created without a function body", function() {
|
||||
@@ -113,12 +114,11 @@ describe("Spec", function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart: startCallback,
|
||||
fn: null,
|
||||
queueableFn: { fn: null },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
|
||||
expect(spec.status()).toBe('pending');
|
||||
});
|
||||
|
||||
@@ -129,7 +129,7 @@ describe("Spec", function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart:startCallback,
|
||||
fn: specBody,
|
||||
queueableFn: { fn: specBody },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
@@ -147,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'),
|
||||
@@ -158,7 +181,8 @@ describe("Spec", function() {
|
||||
getSpecName: function() {
|
||||
return "a suite with a spec"
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
queueableFn: { fn: null }
|
||||
});
|
||||
|
||||
spec.pend();
|
||||
@@ -176,14 +200,15 @@ describe("Spec", function() {
|
||||
description: 'with a spec',
|
||||
fullName: 'a suite with a spec',
|
||||
failedExpectations: [],
|
||||
passedExpectations: []
|
||||
passedExpectations: [],
|
||||
pendingReason: ''
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the done callback on execution complete", function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new j$.Spec({
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
catchExceptions: function() { return false; },
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); }
|
||||
@@ -194,19 +219,19 @@ describe("Spec", function() {
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("#status returns passing by default", function(){
|
||||
var spec = new j$.Spec({ fn: function () {} });
|
||||
expect(spec.status()).toBe("passed");
|
||||
it("#status returns passing by default", function() {
|
||||
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
it("#status returns passed if all expectations in the spec have passed", function() {
|
||||
var spec = new j$.Spec({fn: jasmine.createSpy("spec body")});
|
||||
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
spec.addExpectationResult(true);
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
it("#status returns failed if any expectations in the spec have failed", function() {
|
||||
var spec = new j$.Spec({ fn: jasmine.createSpy("spec body") });
|
||||
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body") } });
|
||||
spec.addExpectationResult(true);
|
||||
spec.addExpectationResult(false);
|
||||
expect(spec.status()).toBe('failed');
|
||||
@@ -215,7 +240,7 @@ describe("Spec", function() {
|
||||
it("keeps track of passed and failed expectations", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
fn: jasmine.createSpy("spec body"),
|
||||
queueableFn: { fn: jasmine.createSpy("spec body") },
|
||||
expectationResultFactory: function (data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
@@ -229,18 +254,53 @@ 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');
|
||||
|
||||
var spec = new j$.Spec({
|
||||
getSpecName: specNameSpy
|
||||
getSpecName: specNameSpy,
|
||||
queueableFn: { fn: null }
|
||||
});
|
||||
|
||||
expect(spec.getFullName()).toBe('expected val');
|
||||
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));
|
||||
@@ -248,13 +308,113 @@ describe("Spec", function() {
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
fn: function() { },
|
||||
queueableFn: { fn: function() { } },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
93
spec/core/SpyRegistrySpec.js
Normal file
93
spec/core/SpyRegistrySpec.js
Normal file
@@ -0,0 +1,93 @@
|
||||
describe("SpyRegistry", function() {
|
||||
describe("#spyOn", function() {
|
||||
it("checks for the existence of the object", function() {
|
||||
var spyRegistry = new j$.SpyRegistry();
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(void 0, 'pants');
|
||||
}).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 = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject, 'pants');
|
||||
}).toThrowError(/method does not exist/);
|
||||
});
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
subject = { spiedFunc: function() {} };
|
||||
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
}).toThrowError(/has already been spied upon/);
|
||||
});
|
||||
|
||||
it("checks if it can be spied upon", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var scope = {};
|
||||
|
||||
function myFunc() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Object.defineProperty(scope, 'myFunc', {
|
||||
get: function() {
|
||||
return myFunc;
|
||||
}
|
||||
});
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
subject = { spiedFunc: scope.myFunc };
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(scope, 'myFunc');
|
||||
}).toThrowError(/is not declared writable or has no setter/);
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
}).not.toThrowError(/is not declared writable or has no setter/);
|
||||
});
|
||||
|
||||
it("overrides the method on the object and returns the spy", function() {
|
||||
var originalFunctionWasCalled = false,
|
||||
spyRegistry = new j$.SpyRegistry(),
|
||||
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
|
||||
|
||||
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#clearSpies", function() {
|
||||
it("restores the original functions on the spied-upon objects", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalFunction = function() {},
|
||||
subject = { spiedFunc: originalFunction };
|
||||
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
spyRegistry.clearSpies();
|
||||
|
||||
expect(subject.spiedFunc).toBe(originalFunction);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
|
||||
@@ -47,6 +47,16 @@ describe('Spies', function () {
|
||||
|
||||
expect(trackSpy.calls.mostRecent().args[0].object).toEqual(contextObject);
|
||||
});
|
||||
|
||||
it("tracks the return value of calls", function () {
|
||||
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
|
||||
spy.and.returnValue("return value");
|
||||
spy();
|
||||
|
||||
expect(trackSpy.calls.mostRecent().args[0].returnValue).toEqual("return value");
|
||||
});
|
||||
});
|
||||
|
||||
describe("createSpyObj", function() {
|
||||
@@ -58,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');
|
||||
|
||||
@@ -46,6 +46,19 @@ describe("SpyStrategy", function() {
|
||||
expect(returnValue).toEqual(17);
|
||||
});
|
||||
|
||||
it("can return specified values in order specified when executed", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn});
|
||||
|
||||
spyStrategy.returnValues('value1', 'value2', 'value3');
|
||||
|
||||
expect(spyStrategy.exec()).toEqual('value1');
|
||||
expect(spyStrategy.exec()).toEqual('value2');
|
||||
expect(spyStrategy.exec()).toBe('value3');
|
||||
expect(spyStrategy.exec()).toBeUndefined();
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows an exception to be thrown when executed", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn});
|
||||
|
||||
@@ -67,116 +67,94 @@ describe("Suite", function() {
|
||||
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
|
||||
});
|
||||
|
||||
it("can be disabled", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
it('has a status of failed if any afterAll expectations have failed', function() {
|
||||
var suite = new j$.Suite({
|
||||
expectationResultFactory: function() { return 'hi'; }
|
||||
});
|
||||
suite.addChild({ result: { status: 'done' } });
|
||||
|
||||
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.disabled).toBe(true);
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
expect(suite.getResult().status).toBe('disabled');
|
||||
});
|
||||
|
||||
it("delegates execution of its specs and suites", 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')
|
||||
};
|
||||
it("retrieves a result with pending status", function() {
|
||||
var suite = new j$.Suite({});
|
||||
suite.pend();
|
||||
|
||||
spyOn(suite, "execute");
|
||||
|
||||
parentSuite.addChild(fakeSpec1);
|
||||
parentSuite.addChild(suite);
|
||||
|
||||
parentSuite.execute(parentSuiteDone);
|
||||
|
||||
var parentSuiteFns = fakeQueueRunnerForParent.calls.mostRecent().args[0].fns;
|
||||
|
||||
parentSuiteFns[0]();
|
||||
expect(fakeSpec1.execute).toHaveBeenCalled();
|
||||
parentSuiteFns[1]();
|
||||
expect(suite.execute).toHaveBeenCalled();
|
||||
expect(suite.getResult().status).toBe('pending');
|
||||
});
|
||||
|
||||
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')
|
||||
};
|
||||
it("priviledges a disabled status over pending status", function() {
|
||||
var suite = new j$.Suite({});
|
||||
suite.disable();
|
||||
suite.pend();
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(suiteStarted).toHaveBeenCalledWith(suite);
|
||||
expect(suite.getResult().status).toBe('disabled');
|
||||
});
|
||||
|
||||
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')
|
||||
};
|
||||
it("is executable if not disabled", function() {
|
||||
var suite = new j$.Suite({});
|
||||
|
||||
suite.execute(suiteCompleted);
|
||||
|
||||
expect(suiteCompleted).toHaveBeenCalled();
|
||||
expect(suite.isExecutable()).toBe(true);
|
||||
});
|
||||
|
||||
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')
|
||||
};
|
||||
it("is not executable if disabled", function() {
|
||||
var suite = new j$.Suite({});
|
||||
suite.disable();
|
||||
|
||||
suite.execute();
|
||||
expect(suite.isExecutable()).toBe(false);
|
||||
});
|
||||
|
||||
expect(suiteResultsCallback).toHaveBeenCalledWith({
|
||||
id: suite.id,
|
||||
status: '',
|
||||
description: "with a child suite",
|
||||
fullName: "with a child suite"
|
||||
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([]);
|
||||
})
|
||||
});
|
||||
|
||||
756
spec/core/TreeProcessorSpec.js
Normal file
756
spec/core/TreeProcessorSpec.js
Normal file
@@ -0,0 +1,756 @@
|
||||
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();
|
||||
});
|
||||
|
||||
it("runs nodes in a custom order when orderChildren is overrided", 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,
|
||||
orderChildren: function(node) {
|
||||
var children = node.children.slice();
|
||||
return children.reverse();
|
||||
}
|
||||
});
|
||||
|
||||
processor.execute();
|
||||
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(queueableFns.length).toBe(11);
|
||||
|
||||
queueableFns[0].fn();
|
||||
expect(leaf11.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[1].fn();
|
||||
expect(leaf10.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[2].fn();
|
||||
expect(leaf9.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[3].fn();
|
||||
expect(leaf8.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[4].fn();
|
||||
expect(leaf7.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[5].fn();
|
||||
expect(leaf6.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[6].fn();
|
||||
expect(leaf5.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[7].fn();
|
||||
expect(leaf4.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[8].fn();
|
||||
expect(leaf3.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[9].fn();
|
||||
expect(leaf2.execute).toHaveBeenCalled();
|
||||
|
||||
queueableFns[10].fn();
|
||||
expect(leaf1.execute).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
});
|
||||
@@ -2,45 +2,51 @@ 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)>');
|
||||
});
|
||||
|
||||
describe("when called without an argument", function() {
|
||||
it("tells the user to pass a constructor or use jasmine.anything()", function() {
|
||||
expect(function() {
|
||||
new j$.Any();
|
||||
}).toThrowError(TypeError, /constructor.*anything/);
|
||||
});
|
||||
});
|
||||
});
|
||||
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/)>");
|
||||
});
|
||||
});
|
||||
@@ -38,13 +38,13 @@ describe("Custom Matchers (Integration)", function() {
|
||||
});
|
||||
|
||||
it("passes the spec if the custom matcher passes", function(done) {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: function() { return { pass: true }; } };
|
||||
}
|
||||
});
|
||||
|
||||
env.it("spec using custom matcher", function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: function() { return { pass: true }; } };
|
||||
}
|
||||
});
|
||||
|
||||
env.expect(true).toBeReal();
|
||||
});
|
||||
|
||||
@@ -57,16 +57,16 @@ describe("Custom Matchers (Integration)", function() {
|
||||
});
|
||||
|
||||
it("uses the negative compare function for a negative comparison, if provided", function(done) {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
env.it("spec with custom negative comparison matcher", function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
env.expect(true).not.toBeReal();
|
||||
});
|
||||
|
||||
@@ -79,17 +79,17 @@ describe("Custom Matchers (Integration)", function() {
|
||||
});
|
||||
|
||||
it("generates messages with the same rules as built in matchers absent a custom message", function(done) {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
env.it('spec with an expectation', function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
env.it('spec with an expectation', function() {
|
||||
env.expect("a").toBeReal();
|
||||
});
|
||||
|
||||
@@ -103,13 +103,14 @@ describe("Custom Matchers (Integration)", function() {
|
||||
|
||||
it("passes the expected and actual arguments to the comparison function", function(done) {
|
||||
var argumentSpy = jasmine.createSpy("argument spy").and.returnValue({ pass: true });
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: argumentSpy };
|
||||
}
|
||||
});
|
||||
|
||||
env.it('spec with an expectation', function () {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: argumentSpy };
|
||||
}
|
||||
});
|
||||
|
||||
env.expect(true).toBeReal();
|
||||
env.expect(true).toBeReal("arg");
|
||||
env.expect(true).toBeReal("arg1", "arg2");
|
||||
@@ -130,12 +131,13 @@ describe("Custom Matchers (Integration)", function() {
|
||||
argumentSpy = jasmine.createSpy("argument spy").and.returnValue(matcherFactory),
|
||||
customEqualityFn = function() { return true; };
|
||||
|
||||
env.addCustomEqualityTester(customEqualityFn);
|
||||
env.addMatchers({
|
||||
toBeReal: argumentSpy
|
||||
});
|
||||
|
||||
env.it("spec with expectation", function() {
|
||||
env.addCustomEqualityTester(customEqualityFn);
|
||||
env.addMatchers({
|
||||
toBeReal: argumentSpy
|
||||
});
|
||||
|
||||
env.expect(true).toBeReal();
|
||||
});
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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) {
|
||||
@@ -159,14 +162,14 @@ describe("jasmine spec running", function () {
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should run multiple befores and afters in the order they are declared", function(done) {
|
||||
it("should run multiple befores and afters ordered so functions declared later are treated as more specific", function(done) {
|
||||
var actions = [];
|
||||
|
||||
env.beforeEach(function () {
|
||||
@@ -228,6 +231,275 @@ describe("jasmine spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should run beforeAlls before beforeEachs and afterAlls after afterEachs', function(done) {
|
||||
var actions = [];
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('runner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('runner afterAll');
|
||||
});
|
||||
|
||||
env.beforeEach(function () {
|
||||
actions.push('runner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function () {
|
||||
actions.push('runner afterEach');
|
||||
});
|
||||
|
||||
env.describe('Something', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('inner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('inner afterEach');
|
||||
});
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('inner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('inner afterAll');
|
||||
});
|
||||
|
||||
env.it('does something or other', function() {
|
||||
actions.push('it');
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
"runner beforeAll",
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
"runner afterAll"
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should run beforeAlls and afterAlls in the order declared when runnablesToRun is provided', function(done) {
|
||||
var actions = [],
|
||||
spec,
|
||||
spec2;
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('runner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('runner afterAll');
|
||||
});
|
||||
|
||||
env.beforeEach(function () {
|
||||
actions.push('runner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function () {
|
||||
actions.push('runner afterEach');
|
||||
});
|
||||
|
||||
env.describe('Something', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('inner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('inner afterEach');
|
||||
});
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('inner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('inner afterAll');
|
||||
});
|
||||
|
||||
spec = env.it('does something', function() {
|
||||
actions.push('it');
|
||||
});
|
||||
|
||||
spec2 = env.it('does something or other', function() {
|
||||
actions.push('it2');
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
"runner beforeAll",
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it2",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
"runner afterAll"
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute([spec2.id, spec.id]);
|
||||
});
|
||||
|
||||
it('only runs *Alls once in a focused suite', function(done){
|
||||
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() {
|
||||
it('runs the relevant alls and eachs for each runnable', function(done) {
|
||||
var actions = [];
|
||||
env.beforeAll(function() {actions.push('beforeAll')});
|
||||
env.afterAll(function() {actions.push('afterAll')});
|
||||
env.beforeEach(function() {actions.push('beforeEach')});
|
||||
env.afterEach(function() {actions.push('afterEach')});
|
||||
|
||||
env.fdescribe('a focused suite', function() {
|
||||
env.it('is run', function() {
|
||||
actions.push('spec in fdescribe')
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('an unfocused suite', function() {
|
||||
env.fit('has a focused spec', function() {
|
||||
actions.push('focused spec')
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
'beforeAll',
|
||||
'beforeEach',
|
||||
'spec in fdescribe',
|
||||
'afterEach',
|
||||
|
||||
'beforeEach',
|
||||
'focused spec',
|
||||
'afterEach',
|
||||
'afterAll'
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused specs in focused suites cause non-focused siblings to not run', function(done){
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
env.it('unfocused spec', function() {
|
||||
actions.push('unfocused spec')
|
||||
});
|
||||
env.fit('focused spec', function() {
|
||||
actions.push('focused spec')
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = ['focused spec'];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused suites in focused suites cause non-focused siblings to not run', function(done){
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
env.it('unfocused spec', function() {
|
||||
actions.push('unfocused spec')
|
||||
});
|
||||
env.fdescribe('inner focused suite', function() {
|
||||
env.it('inner spec', function() {
|
||||
actions.push('inner spec');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = ['inner spec'];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused runnables unfocus ancestor focused suites', function() {
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
env.it('unfocused spec', function() {
|
||||
actions.push('unfocused spec')
|
||||
});
|
||||
env.describe('inner focused suite', function() {
|
||||
env.fit('focused spec', function() {
|
||||
actions.push('focused spec');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = ['focused spec'];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
it("shouldn't run disabled suites", function(done) {
|
||||
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
|
||||
suite = env.describe('A Suite', function() {
|
||||
@@ -236,10 +508,36 @@ describe("jasmine spec running", function () {
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute(function() {
|
||||
var assertions = function() {
|
||||
expect(specInADisabledSuite).not.toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should allow top level suites to be disabled", function() {
|
||||
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
|
||||
otherSpec = jasmine.createSpy("otherSpec");
|
||||
|
||||
env.xdescribe('A disabled suite', function() {
|
||||
env.it('spec inside a disabled suite', specInADisabledSuite);
|
||||
});
|
||||
env.describe('Another suite', function() {
|
||||
env.it('another spec', otherSpec);
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(specInADisabledSuite).not.toHaveBeenCalled();
|
||||
expect(otherSpec).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should set all pending specs to pending when a suite is run", function(done) {
|
||||
@@ -248,12 +546,15 @@ 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
|
||||
xit("should recover gracefully when there are errors in describe functions", function() {
|
||||
@@ -303,4 +604,195 @@ 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/);
|
||||
});
|
||||
|
||||
it("should run the tests in a consistent order when a seed is supplied", function(done) {
|
||||
var actions = [];
|
||||
env.randomizeTests(true);
|
||||
env.seed('123456');
|
||||
|
||||
env.beforeEach(function () {
|
||||
actions.push('topSuite beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function () {
|
||||
actions.push('topSuite afterEach');
|
||||
});
|
||||
|
||||
env.describe('Something', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('outer beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('outer afterEach');
|
||||
});
|
||||
|
||||
env.it('does it 1', function() {
|
||||
actions.push('outer it 1');
|
||||
});
|
||||
|
||||
env.describe('Inner 1', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('inner 1 beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('inner 1 afterEach');
|
||||
});
|
||||
|
||||
env.it('does it 2', function() {
|
||||
actions.push('inner 1 it');
|
||||
});
|
||||
});
|
||||
|
||||
env.it('does it 3', function() {
|
||||
actions.push('outer it 2');
|
||||
});
|
||||
|
||||
env.describe('Inner 2', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('inner 2 beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('inner 2 afterEach');
|
||||
});
|
||||
|
||||
env.it('does it 2', function() {
|
||||
actions.push('inner 2 it');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
'topSuite beforeEach',
|
||||
'outer beforeEach',
|
||||
'outer it 2',
|
||||
'outer afterEach',
|
||||
'topSuite afterEach',
|
||||
|
||||
'topSuite beforeEach',
|
||||
'outer beforeEach',
|
||||
'inner 2 beforeEach',
|
||||
'inner 2 it',
|
||||
'inner 2 afterEach',
|
||||
'outer afterEach',
|
||||
'topSuite afterEach',
|
||||
|
||||
'topSuite beforeEach',
|
||||
'outer beforeEach',
|
||||
'inner 1 beforeEach',
|
||||
'inner 1 it',
|
||||
'inner 1 afterEach',
|
||||
'outer afterEach',
|
||||
'topSuite afterEach',
|
||||
|
||||
'topSuite beforeEach',
|
||||
'outer beforeEach',
|
||||
'outer it 1',
|
||||
'outer afterEach',
|
||||
'topSuite afterEach'
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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,11 +268,50 @@ 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() {
|
||||
it("passes when expected is a substring of actual", function() {
|
||||
expect(j$.matchersUtil.contains("ABC", "B")).toBe(true);
|
||||
expect(j$.matchersUtil.contains("ABC", "BC")).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when expected is a not substring of actual", function() {
|
||||
@@ -207,6 +344,15 @@ describe("matchersUtil", function() {
|
||||
it("fails when actual is null", function() {
|
||||
expect(j$.matchersUtil.contains(null, 'A')).toBe(false);
|
||||
});
|
||||
|
||||
it("passes with array-like objects", function() {
|
||||
var capturedArgs = null;
|
||||
function testFunction(){
|
||||
capturedArgs = arguments;
|
||||
}
|
||||
testFunction('foo', 'bar');
|
||||
expect(j$.matchersUtil.contains(capturedArgs, 'bar')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildMessage", function() {
|
||||
|
||||
81
spec/core/matchers/toHaveBeenCalledTimesSpec.js
Normal file
81
spec/core/matchers/toHaveBeenCalledTimesSpec.js
Normal file
@@ -0,0 +1,81 @@
|
||||
describe("toHaveBeenCalledTimes", function() {
|
||||
it("passes when the actual matches the expected", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
calledSpy = j$.createSpy('called-spy'),
|
||||
result;
|
||||
calledSpy();
|
||||
|
||||
result = matcher.compare(calledSpy, 1);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when expected numbers is not supplied", function(){
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
spy = j$.createSpy('spy'),
|
||||
result;
|
||||
|
||||
spy();
|
||||
expect(function() {
|
||||
matcher.compare(spy);
|
||||
}).toThrowError('Expected times failed is required as an argument.');
|
||||
});
|
||||
|
||||
it("fails when the actual was called less than the expected", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
uncalledSpy = j$.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(uncalledSpy, 2);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("fails when the actual was called more than expected", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
uncalledSpy = j$.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
uncalledSpy();
|
||||
uncalledSpy();
|
||||
|
||||
result = matcher.compare(uncalledSpy, 1);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("throws an exception when the actual is not a spy", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
fn = function() {};
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(fn);
|
||||
}).toThrowError("Expected a spy, but got Function.");
|
||||
});
|
||||
|
||||
it("has a custom message on failure that tells it was called only once", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
spy = j$.createSpy('sample-spy'),
|
||||
result;
|
||||
spy();
|
||||
spy();
|
||||
spy();
|
||||
spy();
|
||||
|
||||
result = matcher.compare(spy, 1);
|
||||
|
||||
expect(result.message).toEqual('Expected spy sample-spy to have been called once. It was called ' + 4 + ' times.');
|
||||
});
|
||||
|
||||
it("has a custom message on failure that tells how many times it was called", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledTimes(),
|
||||
spy = j$.createSpy('sample-spy'),
|
||||
result;
|
||||
spy();
|
||||
spy();
|
||||
spy();
|
||||
spy();
|
||||
|
||||
result = matcher.compare(spy, 2);
|
||||
|
||||
expect(result.message).toEqual('Expected spy sample-spy to have been called 2 times. It was called ' + 4 + ' times.');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ describe("toThrowError", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error();
|
||||
},
|
||||
@@ -155,14 +155,14 @@ describe("toThrowError", function() {
|
||||
result = matcher.compare(fn, Error);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw Error.");
|
||||
expect(result.message()).toEqual("Expected function not to throw Error.");
|
||||
});
|
||||
|
||||
it("passes if thrown is a custom error that takes arguments and the expected is the same error", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
CustomError = function CustomError(arg) { arg.x },
|
||||
fn = function() {
|
||||
throw new CustomError({ x: 1 });
|
||||
@@ -170,19 +170,18 @@ describe("toThrowError", function() {
|
||||
result;
|
||||
|
||||
CustomError.prototype = new Error();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
|
||||
result = matcher.compare(fn, CustomError);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw CustomError.");
|
||||
expect(result.message()).toEqual("Expected function not to throw CustomError.");
|
||||
});
|
||||
|
||||
it("fails if thrown is an Error and the expected is a different Error", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error();
|
||||
},
|
||||
@@ -191,14 +190,14 @@ describe("toThrowError", function() {
|
||||
result = matcher.compare(fn, TypeError);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw TypeError, but it threw Error.");
|
||||
expect(result.message()).toEqual("Expected function to throw TypeError, but it threw Error.");
|
||||
});
|
||||
|
||||
it("passes if thrown is a type of Error and it is equal to the expected Error and message", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
@@ -214,7 +213,7 @@ describe("toThrowError", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
CustomError = function CustomError(arg) { this.message = arg.message },
|
||||
fn = function() {
|
||||
throw new CustomError({message: "foo"});
|
||||
@@ -222,7 +221,6 @@ describe("toThrowError", function() {
|
||||
result;
|
||||
|
||||
CustomError.prototype = new Error();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
|
||||
result = matcher.compare(fn, CustomError, "foo");
|
||||
|
||||
@@ -234,7 +232,7 @@ describe("toThrowError", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
@@ -250,7 +248,7 @@ describe("toThrowError", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
@@ -259,14 +257,14 @@ describe("toThrowError", function() {
|
||||
result = matcher.compare(fn, TypeError, /foo/);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message()).toEqual("Expected function not to throw TypeError with message matching /foo/.");
|
||||
expect(result.message()).toEqual("Expected function not to throw TypeError with a message matching /foo/.");
|
||||
});
|
||||
|
||||
it("fails if thrown is a type of Error and the expected is a different Error", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
@@ -275,6 +273,6 @@ describe("toThrowError", function() {
|
||||
result = matcher.compare(fn, TypeError, /bar/);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message()).toEqual("Expected function to throw TypeError with message matching /bar/, but it threw TypeError with message 'foo'.");
|
||||
expect(result.message()).toEqual("Expected function to throw TypeError with a message matching /bar/, but it threw TypeError with message 'foo'.");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,20 +14,20 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
// Main top-level elements
|
||||
expect(container.querySelector("div.jasmine_html-reporter")).toBeTruthy();
|
||||
expect(container.querySelector("div.banner")).toBeTruthy();
|
||||
expect(container.querySelector("div.alert")).toBeTruthy();
|
||||
expect(container.querySelector("div.results")).toBeTruthy();
|
||||
expect(container.querySelector("div.jasmine-banner")).toBeTruthy();
|
||||
expect(container.querySelector("div.jasmine-alert")).toBeTruthy();
|
||||
expect(container.querySelector("div.jasmine-results")).toBeTruthy();
|
||||
|
||||
expect(container.querySelector("ul.symbol-summary")).toBeTruthy();
|
||||
expect(container.querySelector("ul.jasmine-symbol-summary")).toBeTruthy();
|
||||
|
||||
// title banner
|
||||
var banner = container.querySelector(".banner");
|
||||
var banner = container.querySelector(".jasmine-banner");
|
||||
|
||||
var title = banner.querySelector("a.title");
|
||||
var title = banner.querySelector("a.jasmine-title");
|
||||
expect(title.getAttribute('href')).toEqual('http://jasmine.github.io/');
|
||||
expect(title.getAttribute('target')).toEqual('_blank');
|
||||
|
||||
var version = banner.querySelector(".version"),
|
||||
var version = banner.querySelector(".jasmine-version"),
|
||||
versionText = 'textContent' in version ? version.textContent : version.innerText;
|
||||
expect(versionText).toEqual(j$.version);
|
||||
});
|
||||
@@ -65,8 +65,8 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
describe("when a spec is done", function() {
|
||||
it("logs errors to the console and prints a special symbol if it is an empty spec", function() {
|
||||
if (!window.console) {
|
||||
window.console = { error: function(){} };
|
||||
if (typeof console === "undefined") {
|
||||
console = { error: function(){} };
|
||||
}
|
||||
|
||||
var env = new j$.Env(),
|
||||
@@ -90,8 +90,8 @@ describe("New HtmlReporter", function() {
|
||||
failedExpectations: []
|
||||
});
|
||||
expect(console.error).toHaveBeenCalledWith("Spec \'Some Name\' has no expectations.");
|
||||
var specEl = container.querySelector('.symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("empty");
|
||||
var specEl = container.querySelector('.jasmine-symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-empty");
|
||||
});
|
||||
|
||||
it("reports the status symbol of a disabled spec", function() {
|
||||
@@ -108,8 +108,8 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
reporter.specDone({id: 789, status: "disabled", fullName: "symbols should have titles", passedExpectations: [], failedExpectations: []});
|
||||
|
||||
var specEl = container.querySelector('.symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("disabled");
|
||||
var specEl = container.querySelector('.jasmine-symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-disabled");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_789");
|
||||
expect(specEl.getAttribute("title")).toEqual("symbols should have titles");
|
||||
});
|
||||
@@ -128,8 +128,8 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
reporter.specDone({id: 789, status: "pending", passedExpectations: [], failedExpectations: []});
|
||||
|
||||
var specEl = container.querySelector('.symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("pending");
|
||||
var specEl = container.querySelector('.jasmine-symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-pending");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_789");
|
||||
});
|
||||
|
||||
@@ -147,9 +147,9 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
reporter.specDone({id: 123, status: "passed", passedExpectations: [{passed: true}], failedExpectations: []});
|
||||
|
||||
var statuses = container.querySelector(".symbol-summary");
|
||||
var statuses = container.querySelector(".jasmine-symbol-summary");
|
||||
var specEl = statuses.querySelector("li");
|
||||
expect(specEl.getAttribute("class")).toEqual("passed");
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-passed");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_123");
|
||||
});
|
||||
|
||||
@@ -173,12 +173,40 @@ describe("New HtmlReporter", function() {
|
||||
passedExpectations: []
|
||||
});
|
||||
|
||||
var specEl = container.querySelector(".symbol-summary li");
|
||||
expect(specEl.getAttribute("class")).toEqual("failed");
|
||||
var specEl = container.querySelector(".jasmine-symbol-summary li");
|
||||
expect(specEl.getAttribute("class")).toEqual("jasmine-failed");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_345");
|
||||
});
|
||||
});
|
||||
|
||||
describe("when there are suite failures", function () {
|
||||
it("displays the exceptions in their own alert bars", 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.jasmineStarted({});
|
||||
reporter.suiteDone({ status: 'failed', failedExpectations: [{ message: 'My After All Exception' }] });
|
||||
reporter.suiteDone({ status: 'failed', failedExpectations: [{ message: 'My Other Exception' }] });
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(3);
|
||||
expect(alertBars[1].innerHTML).toMatch(/My After All Exception/);
|
||||
expect(alertBars[1].getAttribute("class")).toEqual('jasmine-bar jasmine-errored');
|
||||
expect(alertBars[2].innerHTML).toMatch(/My Other Exception/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when Jasmine is done", function() {
|
||||
it("adds EMPTY to the link title of specs that have no expectations", function() {
|
||||
if (!window.console) {
|
||||
@@ -210,7 +238,7 @@ describe("New HtmlReporter", function() {
|
||||
reporter.suiteDone({id: 1});
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var summary = container.querySelector('.summary');
|
||||
var summary = container.querySelector('.jasmine-summary');
|
||||
var suite = summary.childNodes[0];
|
||||
var specs = suite.childNodes[1];
|
||||
var spec = specs.childNodes[0];
|
||||
@@ -238,7 +266,7 @@ describe("New HtmlReporter", function() {
|
||||
timer.elapsed.and.returnValue(100);
|
||||
reporter.jasmineDone();
|
||||
|
||||
var duration = container.querySelector(".banner .duration");
|
||||
var duration = container.querySelector(".jasmine-alert .jasmine-duration");
|
||||
expect(duration.innerHTML).toMatch(/finished in 0.1s/);
|
||||
});
|
||||
|
||||
@@ -250,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();
|
||||
|
||||
@@ -305,7 +334,7 @@ describe("New HtmlReporter", function() {
|
||||
reporter.suiteDone({id: 1});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
var summary = container.querySelector(".summary");
|
||||
var summary = container.querySelector(".jasmine-summary");
|
||||
|
||||
expect(summary.childNodes.length).toEqual(1);
|
||||
|
||||
@@ -317,24 +346,58 @@ describe("New HtmlReporter", function() {
|
||||
var node = outerSuite.childNodes[i];
|
||||
classes.push(node.getAttribute("class"));
|
||||
}
|
||||
expect(classes).toEqual(["suite-detail", "specs", "suite", "specs"]);
|
||||
expect(classes).toEqual(["jasmine-suite-detail", "jasmine-specs", "jasmine-suite", "jasmine-specs"]);
|
||||
|
||||
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];
|
||||
expect(spec.getAttribute("class")).toEqual("passed");
|
||||
expect(spec.getAttribute("class")).toEqual("jasmine-passed");
|
||||
expect(spec.getAttribute("id")).toEqual("spec-123");
|
||||
|
||||
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('.jasmine-run-options .jasmine-trigger'),
|
||||
payload = container.querySelector('.jasmine-run-options .jasmine-payload');
|
||||
|
||||
expect(payload.className).not.toContain('jasmine-open');
|
||||
|
||||
trigger.onclick();
|
||||
|
||||
expect(payload.className).toContain('jasmine-open');
|
||||
|
||||
trigger.onclick();
|
||||
|
||||
expect(payload.className).not.toContain('jasmine-open');
|
||||
});
|
||||
|
||||
describe("UI for raising/catching exceptions", function() {
|
||||
it("should be unchecked if the env is catching", function() {
|
||||
var env = new j$.Env(),
|
||||
@@ -356,7 +419,7 @@ describe("New HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var raisingExceptionsUI = container.querySelector(".raise");
|
||||
var raisingExceptionsUI = container.querySelector(".jasmine-raise");
|
||||
expect(raisingExceptionsUI.checked).toBe(false);
|
||||
});
|
||||
|
||||
@@ -381,7 +444,7 @@ describe("New HtmlReporter", function() {
|
||||
env.catchExceptions(false);
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var raisingExceptionsUI = container.querySelector(".raise");
|
||||
var raisingExceptionsUI = container.querySelector(".jasmine-raise");
|
||||
expect(raisingExceptionsUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
@@ -407,12 +470,228 @@ describe("New HtmlReporter", function() {
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var input = container.querySelector(".raise");
|
||||
var input = container.querySelector(".jasmine-raise");
|
||||
input.click();
|
||||
expect(exceptionsClickHandler).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
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(".jasmine-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(".jasmine-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(".jasmine-throw");
|
||||
throwingExpectationsUI.click();
|
||||
|
||||
expect(throwingExceptionHandler).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("UI for running tests in random order", function() {
|
||||
it("should be unchecked if not randomizing", 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 randomUI = container.querySelector(".jasmine-random");
|
||||
expect(randomUI.checked).toBe(false);
|
||||
});
|
||||
|
||||
it("should be checked if randomizing", 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.randomizeTests(true);
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var randomUI = container.querySelector(".jasmine-random");
|
||||
expect(randomUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("should affect the query param for random tests", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
randomHandler = jasmine.createSpy('randomHandler'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
onRandomClick: randomHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var randomUI = container.querySelector(".jasmine-random");
|
||||
randomUI.click();
|
||||
|
||||
expect(randomHandler).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should show the seed bar if randomizing", 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({
|
||||
order: {
|
||||
random: true,
|
||||
seed: '424242'
|
||||
}
|
||||
});
|
||||
|
||||
var seedBar = container.querySelector(".jasmine-seed-bar");
|
||||
var seedBarText = 'textContent' in seedBar ? seedBar.textContent : seedBar.innerText;
|
||||
expect(seedBarText).toBe(', randomized with seed 424242');
|
||||
var seedLink = container.querySelector(".jasmine-seed-bar a");
|
||||
expect(seedLink.getAttribute('href')).toBe('?seed=424242');
|
||||
});
|
||||
|
||||
it("should not show the current seed bar if not randomizing", 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 seedBar = container.querySelector(".jasmine-seed-bar");
|
||||
expect(seedBar).toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("shows a message if no specs are run", function(){
|
||||
var env, container, reporter;
|
||||
env = new j$.Env();
|
||||
@@ -429,8 +708,8 @@ describe("New HtmlReporter", function() {
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var alertBars = container.querySelectorAll(".alert .bar");
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/skipped/);
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/jasmine-skipped/);
|
||||
expect(alertBars[0].innerHTML).toMatch(/No specs found/);
|
||||
});
|
||||
|
||||
@@ -469,21 +748,21 @@ describe("New HtmlReporter", function() {
|
||||
});
|
||||
|
||||
it("reports the specs counts", function() {
|
||||
var alertBars = container.querySelectorAll(".alert .bar");
|
||||
var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBars.length).toEqual(1);
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/passed/);
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/jasmine-passed/);
|
||||
expect(alertBars[0].innerHTML).toMatch(/2 specs, 0 failures/);
|
||||
});
|
||||
|
||||
it("reports no failure details", function() {
|
||||
var specFailure = container.querySelector(".failures");
|
||||
var specFailure = container.querySelector(".jasmine-failures");
|
||||
|
||||
expect(specFailure.childNodes.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("reports no pending specs", function() {
|
||||
var alertBar = container.querySelector(".alert .bar");
|
||||
var alertBar = container.querySelector(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBar.innerHTML).not.toMatch(/pending spec[s]/);
|
||||
});
|
||||
@@ -504,28 +783,37 @@ 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({});
|
||||
});
|
||||
|
||||
it("reports the pending specs count", function() {
|
||||
var alertBar = container.querySelector(".alert .bar");
|
||||
var alertBar = container.querySelector(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBar.innerHTML).toMatch(/1 spec, 0 failures, 1 pending spec/);
|
||||
});
|
||||
|
||||
it("reports no failure details", function() {
|
||||
var specFailure = container.querySelector(".failures");
|
||||
var specFailure = container.querySelector(".jasmine-failures");
|
||||
|
||||
expect(specFailure.childNodes.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("displays the custom pending reason", function() {
|
||||
var pendingDetails = container.querySelector(".jasmine-summary .jasmine-pending");
|
||||
|
||||
expect(pendingDetails.innerHTML).toContain("my custom pending reason");
|
||||
});
|
||||
});
|
||||
|
||||
describe("and some tests fail", function() {
|
||||
@@ -539,7 +827,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();
|
||||
|
||||
@@ -568,37 +857,37 @@ describe("New HtmlReporter", function() {
|
||||
});
|
||||
|
||||
it("reports the specs counts", function() {
|
||||
var alertBar = container.querySelector(".alert .bar");
|
||||
var alertBar = container.querySelector(".jasmine-alert .jasmine-bar");
|
||||
|
||||
expect(alertBar.getAttribute('class')).toMatch(/failed/);
|
||||
expect(alertBar.getAttribute('class')).toMatch(/jasmine-failed/);
|
||||
expect(alertBar.innerHTML).toMatch(/2 specs, 1 failure/);
|
||||
});
|
||||
|
||||
it("reports failure messages and stack traces", function() {
|
||||
var specFailures = container.querySelector(".failures");
|
||||
var specFailures = container.querySelector(".jasmine-failures");
|
||||
|
||||
var failure = specFailures.childNodes[0];
|
||||
expect(failure.getAttribute("class")).toMatch(/failed/);
|
||||
expect(failure.getAttribute("class")).toMatch(/spec-detail/);
|
||||
expect(failure.getAttribute("class")).toMatch(/jasmine-failed/);
|
||||
expect(failure.getAttribute("class")).toMatch(/jasmine-spec-detail/);
|
||||
|
||||
var specDiv = failure.childNodes[0];
|
||||
expect(specDiv.getAttribute("class")).toEqual("description");
|
||||
expect(specDiv.getAttribute("class")).toEqual("jasmine-description");
|
||||
|
||||
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");
|
||||
expect(message.getAttribute("class")).toEqual("jasmine-result-message");
|
||||
expect(message.innerHTML).toEqual("a failure message");
|
||||
|
||||
var stackTrace = failure.childNodes[1].childNodes[1];
|
||||
expect(stackTrace.getAttribute("class")).toEqual("stack-trace");
|
||||
expect(stackTrace.getAttribute("class")).toEqual("jasmine-stack-trace");
|
||||
expect(stackTrace.innerHTML).toEqual("a stack trace");
|
||||
});
|
||||
|
||||
it("allows switching between failure details and the spec summary", function() {
|
||||
var menuBar = container.querySelectorAll(".bar")[1];
|
||||
var menuBar = container.querySelectorAll(".jasmine-bar")[1];
|
||||
|
||||
expect(menuBar.getAttribute("class")).not.toMatch(/hidden/);
|
||||
|
||||
@@ -609,7 +898,7 @@ describe("New HtmlReporter", function() {
|
||||
|
||||
it("sets the reporter to 'Failures List' mode", function() {
|
||||
var reporterNode = container.querySelector(".jasmine_html-reporter");
|
||||
expect(reporterNode.getAttribute("class")).toMatch("failure-list");
|
||||
expect(reporterNode.getAttribute("class")).toMatch("jasmine-failure-list");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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() {
|
||||
|
||||
195
spec/node_suite.js
Normal file
195
spec/node_suite.js
Normal file
@@ -0,0 +1,195 @@
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
|
||||
// boot code for jasmine
|
||||
var jasmineRequire = require('../lib/jasmine-core/jasmine.js');
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../lib/console/console.js');
|
||||
extend(jasmineRequire, consoleFns);
|
||||
jasmineRequire.console(jasmineRequire, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = {
|
||||
describe: function(description, specDefinitions) {
|
||||
return env.describe(description, specDefinitions);
|
||||
},
|
||||
|
||||
xdescribe: function(description, specDefinitions) {
|
||||
return env.xdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
}),
|
||||
|
||||
beforeAll: function(beforeAllFunction) {
|
||||
return env.beforeAll(beforeAllFunction);
|
||||
},
|
||||
|
||||
afterAll: function(afterAllFunction) {
|
||||
return env.afterAll(afterAllFunction);
|
||||
}
|
||||
};
|
||||
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
jasmine.addCustomEqualityTester = function(tester) {
|
||||
env.addCustomEqualityTester(tester);
|
||||
};
|
||||
|
||||
jasmine.addMatchers = function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
jasmine.clock = function() {
|
||||
return env.clock;
|
||||
};
|
||||
|
||||
// Jasmine "runner"
|
||||
function executeSpecs(specs, done, isVerbose, showColors) {
|
||||
global.jasmine = jasmine;
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var filename = specs[i];
|
||||
require(filename.replace(/\.\w+$/, ""));
|
||||
}
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
var consoleReporter = new jasmine.ConsoleReporter({
|
||||
print: util.print,
|
||||
onComplete: done,
|
||||
showColors: showColors,
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
env.addReporter(consoleReporter);
|
||||
env.execute();
|
||||
}
|
||||
|
||||
function getFiles(dir, matcher) {
|
||||
var allFiles = [];
|
||||
|
||||
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
|
||||
allFiles.push(dir);
|
||||
} else {
|
||||
var files = fs.readdirSync(dir);
|
||||
for (var i = 0, len = files.length; i < len; ++i) {
|
||||
var filename = dir + '/' + files[i];
|
||||
if (fs.statSync(filename).isFile() && filename.match(matcher)) {
|
||||
allFiles.push(filename);
|
||||
} else if (fs.statSync(filename).isDirectory()) {
|
||||
var subfiles = getFiles(filename);
|
||||
subfiles.forEach(function(result) {
|
||||
allFiles.push(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return allFiles;
|
||||
}
|
||||
|
||||
function getSpecFiles(dir) {
|
||||
return getFiles(dir, new RegExp("Spec.js$"));
|
||||
}
|
||||
|
||||
var j$require = (function() {
|
||||
var exported = {},
|
||||
j$req;
|
||||
|
||||
global.getJasmineRequireObj = getJasmineRequireObj;
|
||||
|
||||
j$req = require(__dirname + "/../src/core/requireCore.js");
|
||||
extend(j$req, require(__dirname + "/../src/console/requireConsole.js"));
|
||||
|
||||
var srcFiles = getFiles(__dirname + "/../src/core");
|
||||
srcFiles.push(__dirname + "/../src/version.js");
|
||||
srcFiles.push(__dirname + "/../src/console/ConsoleReporter.js");
|
||||
|
||||
for (var i = 0; i < srcFiles.length; i++) {
|
||||
require(srcFiles[i]);
|
||||
}
|
||||
extend(j$req, exported);
|
||||
|
||||
delete global.getJasmineRequireObj;
|
||||
|
||||
return j$req;
|
||||
|
||||
function getJasmineRequireObj() {
|
||||
return exported;
|
||||
}
|
||||
}());
|
||||
|
||||
j$ = j$require.core(j$require);
|
||||
j$require.console(j$require, j$);
|
||||
|
||||
// options from command line
|
||||
var isVerbose = false;
|
||||
var showColors = true;
|
||||
var perfSuite = false;
|
||||
|
||||
process.argv.forEach(function(arg) {
|
||||
switch (arg) {
|
||||
case '--color':
|
||||
showColors = true;
|
||||
break;
|
||||
case '--noColor':
|
||||
showColors = false;
|
||||
break;
|
||||
case '--verbose':
|
||||
isVerbose = true;
|
||||
break;
|
||||
case '--perf':
|
||||
perfSuite = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
specs = [];
|
||||
|
||||
if (perfSuite) {
|
||||
specs = getFiles(__dirname + '/performance', new RegExp("test.js$"));
|
||||
} else {
|
||||
var consoleSpecs = getSpecFiles(__dirname + "/console"),
|
||||
coreSpecs = getSpecFiles(__dirname + "/core"),
|
||||
specs = consoleSpecs.concat(coreSpecs);
|
||||
}
|
||||
|
||||
executeSpecs(specs, function(passed) {
|
||||
if (passed) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
}, isVerbose, showColors);
|
||||
101
spec/npmPackage/npmPackageSpec.js
Normal file
101
spec/npmPackage/npmPackageSpec.js
Normal file
@@ -0,0 +1,101 @@
|
||||
describe('npm package', function() {
|
||||
var path = require('path'),
|
||||
temp = require('temp').track(),
|
||||
fs = require('fs');
|
||||
|
||||
beforeAll(function() {
|
||||
var shell = require('shelljs'),
|
||||
pack = shell.exec('npm pack', { silent: true });
|
||||
|
||||
this.tarball = pack.output.split('\n')[0];
|
||||
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);
|
||||
|
||||
this.packagedCore = require(path.join(this.tmpDir, 'package/lib/jasmine-core.js'));
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
jasmine.addMatchers({
|
||||
toExistInPath: function(util, customEquality) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var fullPath = path.resolve(expected, actual);
|
||||
return {
|
||||
pass: fs.existsSync(fullPath)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(function() {
|
||||
var cleanup = function (parent, fileOrFolder) {
|
||||
var fullPath = path.join(parent, fileOrFolder);
|
||||
if (fs.statSync(fullPath).isFile()) {
|
||||
fs.unlinkSync(fullPath);
|
||||
} else {
|
||||
fs.readdirSync(fullPath).forEach(cleanup.bind(null, fullPath));
|
||||
fs.rmdirSync(fullPath);
|
||||
}
|
||||
};
|
||||
|
||||
fs.unlink(this.tarball);
|
||||
});
|
||||
|
||||
it('has a root path', function() {
|
||||
expect(this.packagedCore.files.path).toEqual(fs.realpathSync(path.resolve(this.tmpDir, 'package/lib/jasmine-core')));
|
||||
});
|
||||
|
||||
it('has a bootDir', function() {
|
||||
expect(this.packagedCore.files.bootDir).toEqual(fs.realpathSync(path.resolve(this.tmpDir, 'package/lib/jasmine-core')));
|
||||
});
|
||||
|
||||
it('has jsFiles', function() {
|
||||
expect(this.packagedCore.files.jsFiles).toEqual([
|
||||
'jasmine.js',
|
||||
'jasmine-html.js',
|
||||
'json2.js'
|
||||
]);
|
||||
|
||||
var packagedCore = this.packagedCore;
|
||||
this.packagedCore.files.jsFiles.forEach(function(fileName) {
|
||||
expect(fileName).toExistInPath(packagedCore.files.path);
|
||||
});
|
||||
});
|
||||
|
||||
it('has cssFiles', function() {
|
||||
expect(this.packagedCore.files.cssFiles).toEqual(['jasmine.css']);
|
||||
|
||||
var packagedCore = this.packagedCore;
|
||||
this.packagedCore.files.cssFiles.forEach(function(fileName) {
|
||||
expect(fileName).toExistInPath(packagedCore.files.path);
|
||||
});
|
||||
});
|
||||
|
||||
it('has bootFiles', function() {
|
||||
expect(this.packagedCore.files.bootFiles).toEqual(['boot.js']);
|
||||
expect(this.packagedCore.files.nodeBootFiles).toEqual(['node_boot.js']);
|
||||
|
||||
var packagedCore = this.packagedCore;
|
||||
this.packagedCore.files.bootFiles.forEach(function(fileName) {
|
||||
expect(fileName).toExistInPath(packagedCore.files.bootDir);
|
||||
});
|
||||
|
||||
var packagedCore = this.packagedCore;
|
||||
this.packagedCore.files.nodeBootFiles.forEach(function(fileName) {
|
||||
expect(fileName).toExistInPath(packagedCore.files.bootDir);
|
||||
});
|
||||
});
|
||||
|
||||
it('has an imagesDir', function() {
|
||||
expect(this.packagedCore.files.imagesDir).toEqual(fs.realpathSync(path.resolve(this.tmpDir, 'package/images')));
|
||||
var images = fs.readdirSync(path.resolve(this.tmpDir, 'package/images'));
|
||||
|
||||
expect(images).toContain('jasmine-horizontal.png');
|
||||
expect(images).toContain('jasmine-horizontal.svg');
|
||||
expect(images).toContain('jasmine_favicon.png');
|
||||
});
|
||||
});
|
||||
@@ -5,5 +5,6 @@
|
||||
],
|
||||
"helper_files": [
|
||||
"helpers/nodeDefineJasmineUnderTest.js"
|
||||
]
|
||||
],
|
||||
"random": true
|
||||
}
|
||||
|
||||
@@ -7,3 +7,4 @@ helpers:
|
||||
spec_files:
|
||||
- 'performance/performance_test.js'
|
||||
spec_dir: spec
|
||||
random: true
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
"spec_dir": "spec",
|
||||
"spec_files": [
|
||||
"core/**/*.js",
|
||||
"console/**/*.js"
|
||||
"console/**/*.js",
|
||||
"npmPackage/**/*.js"
|
||||
],
|
||||
"helpers": [
|
||||
"helpers/nodeDefineJasmineUnderTest.js"
|
||||
]
|
||||
],
|
||||
"random": true
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ helpers:
|
||||
- 'helpers/defineJasmineUnderTest.js'
|
||||
spec_files:
|
||||
- '**/*[Ss]pec.js'
|
||||
- '!npmPackage/**/*'
|
||||
spec_dir: spec
|
||||
|
||||
random: true
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
};
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
print('ConsoleReporter is deprecated and will be removed in a future version.');
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
@@ -54,9 +57,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
@@ -81,6 +87,13 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
@@ -119,11 +132,23 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var failedExpectation = result.failedExpectations[i];
|
||||
printNewline();
|
||||
print(indent(failedExpectation.message, 2));
|
||||
print(indent(failedExpectation.stack, 2));
|
||||
}
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
|
||||
@@ -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,14 +124,15 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
|
||||
var funcsToRun = scheduledFunctions[currentTime];
|
||||
delete scheduledFunctions[currentTime];
|
||||
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
var funcToRun = funcsToRun[i];
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
|
||||
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
|
||||
|
||||
386
src/core/Env.js
386
src/core/Env.js
@@ -11,14 +11,25 @@ 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 spies = [];
|
||||
var runnableResources = {};
|
||||
|
||||
var currentSpec = null;
|
||||
var currentSuite = null;
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
var throwOnExpectationFailure = false;
|
||||
var random = false;
|
||||
var seed = null;
|
||||
|
||||
var currentSuite = function() {
|
||||
return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
|
||||
};
|
||||
|
||||
var currentRunnable = function() {
|
||||
return currentSpec || currentSuite();
|
||||
};
|
||||
|
||||
var reporter = new j$.ReportDispatcher([
|
||||
'jasmineStarted',
|
||||
@@ -33,11 +44,21 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return true;
|
||||
};
|
||||
|
||||
var equalityTesters = [];
|
||||
|
||||
var customEqualityTesters = [];
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
customEqualityTesters.push(tester);
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Custom Equalities must be added in a before function or a spec');
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Matchers must be added in a before function or a spec');
|
||||
}
|
||||
var customMatchers = runnableResources[currentRunnable().id].customMatchers;
|
||||
for (var matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
@@ -55,7 +76,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.Factory({
|
||||
util: j$.matchersUtil,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -65,30 +87,38 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
var specStarted = function(spec) {
|
||||
currentSpec = spec;
|
||||
reporter.specStarted(spec.result);
|
||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
|
||||
|
||||
if(runnableResources[parentRunnableId]){
|
||||
resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
|
||||
resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
};
|
||||
|
||||
var beforeFns = function(suite) {
|
||||
var clearResourcesForRunnable = function(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
};
|
||||
|
||||
var beforeAndAfterFns = function(suite) {
|
||||
return function() {
|
||||
var befores = [];
|
||||
var befores = [],
|
||||
afters = [];
|
||||
|
||||
while(suite) {
|
||||
befores = befores.concat(suite.beforeFns);
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return befores.reverse();
|
||||
};
|
||||
};
|
||||
|
||||
var afterFns = function(suite) {
|
||||
return function() {
|
||||
var afters = [];
|
||||
while(suite) {
|
||||
afters = afters.concat(suite.afterFns);
|
||||
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return afters;
|
||||
|
||||
return {
|
||||
befores: befores.reverse(),
|
||||
afters: afters
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -133,10 +163,34 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return j$.Spec.isPendingSpecException(e) || catchExceptions;
|
||||
};
|
||||
|
||||
this.throwOnExpectationFailure = function(value) {
|
||||
throwOnExpectationFailure = !!value;
|
||||
};
|
||||
|
||||
this.throwingExpectationFailures = function() {
|
||||
return throwOnExpectationFailure;
|
||||
};
|
||||
|
||||
this.randomizeTests = function(value) {
|
||||
random = !!value;
|
||||
};
|
||||
|
||||
this.randomTests = function() {
|
||||
return random;
|
||||
};
|
||||
|
||||
this.seed = function(value) {
|
||||
if (value) {
|
||||
seed = value;
|
||||
}
|
||||
return seed;
|
||||
};
|
||||
|
||||
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();
|
||||
};
|
||||
@@ -145,66 +199,79 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
env: this,
|
||||
id: getNextSuiteId(),
|
||||
description: 'Jasmine__TopLevel__Suite',
|
||||
queueRunner: queueRunnerFactory,
|
||||
resultCallback: function() {} // TODO - hook this up
|
||||
queueRunner: queueRunnerFactory
|
||||
});
|
||||
runnableLookupTable[topSuite.id] = topSuite;
|
||||
currentSuite = topSuite;
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
runnablesToRun = runnablesToRun || [topSuite.id];
|
||||
if(!runnablesToRun) {
|
||||
if (focusedRunnables.length) {
|
||||
runnablesToRun = focusedRunnables;
|
||||
} else {
|
||||
runnablesToRun = [topSuite.id];
|
||||
}
|
||||
}
|
||||
|
||||
var allFns = [];
|
||||
for(var i = 0; i < runnablesToRun.length; i++) {
|
||||
var runnable = runnableLookupTable[runnablesToRun[i]];
|
||||
allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));
|
||||
var order = new j$.Order({
|
||||
random: random,
|
||||
seed: seed
|
||||
});
|
||||
|
||||
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);
|
||||
},
|
||||
orderChildren: function(node) {
|
||||
return order.sort(node.children);
|
||||
}
|
||||
});
|
||||
|
||||
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({fns: allFns, onComplete: reporter.jasmineDone});
|
||||
processor.execute(function() {
|
||||
reporter.jasmineDone({
|
||||
order: order
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.addReporter = function(reporterToAdd) {
|
||||
reporter.addReporter(reporterToAdd);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
j$.Expectation.addMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.spyOn = function(obj, methodName) {
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
|
||||
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Spies must be created in a before function or a spec');
|
||||
}
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
}});
|
||||
|
||||
if (j$.util.isUndefined(obj[methodName])) {
|
||||
throw new Error(methodName + '() method does not exist');
|
||||
}
|
||||
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName])) {
|
||||
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
|
||||
throw new Error(methodName + ' has already been spied upon');
|
||||
}
|
||||
|
||||
var spy = j$.createSpy(methodName, obj[methodName]);
|
||||
|
||||
spies.push({
|
||||
spy: spy,
|
||||
baseObj: obj,
|
||||
methodName: methodName,
|
||||
originalValue: obj[methodName]
|
||||
});
|
||||
|
||||
obj[methodName] = spy;
|
||||
|
||||
return spy;
|
||||
this.spyOn = function() {
|
||||
return spyRegistry.spyOn.apply(spyRegistry, arguments);
|
||||
};
|
||||
|
||||
var suiteFactory = function(description) {
|
||||
@@ -212,12 +279,10 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
env: self,
|
||||
id: getNextSuiteId(),
|
||||
description: description,
|
||||
parentSuite: currentSuite,
|
||||
queueRunner: queueRunnerFactory,
|
||||
onStart: suiteStarted,
|
||||
resultCallback: function(attrs) {
|
||||
reporter.suiteDone(attrs);
|
||||
}
|
||||
parentSuite: currentDeclarationSuite,
|
||||
expectationFactory: expectationFactory,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
throwOnExpectationFailure: throwOnExpectationFailure
|
||||
});
|
||||
|
||||
runnableLookupTable[suite.id] = suite;
|
||||
@@ -226,10 +291,40 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
this.describe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
if (specDefinitions.length > 0) {
|
||||
throw new Error('describe does not expect a done parameter');
|
||||
}
|
||||
if (currentDeclarationSuite.markedPending) {
|
||||
suite.pend();
|
||||
}
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
return suite;
|
||||
};
|
||||
|
||||
var parentSuite = currentSuite;
|
||||
this.xdescribe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
suite.pend();
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
return suite;
|
||||
};
|
||||
|
||||
var focusedRunnables = [];
|
||||
|
||||
this.fdescribe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
suite.isFocused = true;
|
||||
|
||||
focusedRunnables.push(suite.id);
|
||||
unfocusAncestor();
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
|
||||
return suite;
|
||||
};
|
||||
|
||||
function addSpecsToSuite(suite, specDefinitions) {
|
||||
var parentSuite = currentDeclarationSuite;
|
||||
parentSuite.addChild(suite);
|
||||
currentSuite = suite;
|
||||
currentDeclarationSuite = suite;
|
||||
|
||||
var declarationError = null;
|
||||
try {
|
||||
@@ -239,31 +334,43 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
this.it('encountered a declaration exception', function() {
|
||||
self.it('encountered a declaration exception', function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
currentSuite = parentSuite;
|
||||
currentDeclarationSuite = parentSuite;
|
||||
}
|
||||
|
||||
return suite;
|
||||
};
|
||||
function findFocusedAncestor(suite) {
|
||||
while (suite) {
|
||||
if (suite.isFocused) {
|
||||
return suite.id;
|
||||
}
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
|
||||
this.xdescribe = function(description, specDefinitions) {
|
||||
var suite = this.describe(description, specDefinitions);
|
||||
suite.disable();
|
||||
return suite;
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
var specFactory = function(description, fn, suite) {
|
||||
function unfocusAncestor() {
|
||||
var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
|
||||
if (focusedAncestor) {
|
||||
for (var i = 0; i < focusedRunnables.length; i++) {
|
||||
if (focusedRunnables[i] === focusedAncestor) {
|
||||
focusedRunnables.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var specFactory = function(description, fn, suite, timeout) {
|
||||
totalSpecsDefined++;
|
||||
|
||||
var spec = new j$.Spec({
|
||||
id: getNextSpecId(),
|
||||
beforeFns: beforeFns(suite),
|
||||
afterFns: afterFns(suite),
|
||||
beforeAndAfterFns: beforeAndAfterFns(suite),
|
||||
expectationFactory: expectationFactory,
|
||||
exceptionFormatter: exceptionFormatter,
|
||||
resultCallback: specResultCallback,
|
||||
getSpecName: function(spec) {
|
||||
return getSpecName(spec, suite);
|
||||
@@ -272,7 +379,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
description: description,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
queueRunnerFactory: queueRunnerFactory,
|
||||
fn: fn
|
||||
userContext: function() { return suite.clonedSharedUserContext(); },
|
||||
queueableFn: {
|
||||
fn: fn,
|
||||
timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
|
||||
},
|
||||
throwOnExpectationFailure: throwOnExpectationFailure
|
||||
});
|
||||
|
||||
runnableLookupTable[spec.id] = spec;
|
||||
@@ -283,57 +395,101 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
return spec;
|
||||
|
||||
function removeAllSpies() {
|
||||
for (var i = 0; i < spies.length; i++) {
|
||||
var spyEntry = spies[i];
|
||||
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
|
||||
}
|
||||
spies = [];
|
||||
}
|
||||
|
||||
function specResultCallback(result) {
|
||||
removeAllSpies();
|
||||
j$.Expectation.resetMatchers();
|
||||
customEqualityTesters = [];
|
||||
clearResourcesForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
reporter.specDone(result);
|
||||
}
|
||||
|
||||
function specStarted(spec) {
|
||||
currentSpec = spec;
|
||||
defaultResourcesForRunnable(spec.id, suite.id);
|
||||
reporter.specStarted(spec.result);
|
||||
}
|
||||
};
|
||||
|
||||
var suiteStarted = function(suite) {
|
||||
reporter.suiteStarted(suite.result);
|
||||
};
|
||||
|
||||
this.it = function(description, fn) {
|
||||
var spec = specFactory(description, fn, currentSuite);
|
||||
currentSuite.addChild(spec);
|
||||
this.it = function(description, fn, timeout) {
|
||||
var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
|
||||
if (currentDeclarationSuite.markedPending) {
|
||||
spec.pend();
|
||||
}
|
||||
currentDeclarationSuite.addChild(spec);
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.xit = function(description, fn) {
|
||||
var spec = this.it(description, fn);
|
||||
spec.pend();
|
||||
this.xit = function() {
|
||||
var spec = this.it.apply(this, arguments);
|
||||
spec.pend('Temporarily disabled with xit');
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.fit = function(description, fn, timeout){
|
||||
var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
|
||||
currentDeclarationSuite.addChild(spec);
|
||||
focusedRunnables.push(spec.id);
|
||||
unfocusAncestor();
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.expect = function(actual) {
|
||||
if (!currentSpec) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
|
||||
}
|
||||
|
||||
return currentSpec.expect(actual);
|
||||
return currentRunnable().expect(actual);
|
||||
};
|
||||
|
||||
this.beforeEach = function(beforeEachFunction) {
|
||||
currentSuite.beforeEach(beforeEachFunction);
|
||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||
currentDeclarationSuite.beforeEach({
|
||||
fn: beforeEachFunction,
|
||||
timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
|
||||
});
|
||||
};
|
||||
|
||||
this.afterEach = function(afterEachFunction) {
|
||||
currentSuite.afterEach(afterEachFunction);
|
||||
this.beforeAll = function(beforeAllFunction, timeout) {
|
||||
currentDeclarationSuite.beforeAll({
|
||||
fn: beforeAllFunction,
|
||||
timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
|
||||
});
|
||||
};
|
||||
|
||||
this.pending = function() {
|
||||
throw j$.Spec.pendingSpecExceptionMessage;
|
||||
this.afterEach = function(afterEachFunction, timeout) {
|
||||
currentDeclarationSuite.afterEach({
|
||||
fn: afterEachFunction,
|
||||
timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
|
||||
});
|
||||
};
|
||||
|
||||
this.afterAll = function(afterAllFunction, timeout) {
|
||||
currentDeclarationSuite.afterAll({
|
||||
fn: afterAllFunction,
|
||||
timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
|
||||
});
|
||||
};
|
||||
|
||||
this.pending = function(message) {
|
||||
var fullMessage = j$.Spec.pendingSpecExceptionMessage;
|
||||
if(message) {
|
||||
fullMessage += message;
|
||||
}
|
||||
throw fullMessage;
|
||||
};
|
||||
|
||||
this.fail = function(error) {
|
||||
var message = 'Failed';
|
||||
if (error) {
|
||||
message += ': ';
|
||||
message += error.message || error;
|
||||
}
|
||||
|
||||
currentRunnable().addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
message: message,
|
||||
error: error && error.message ? error : null
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
getJasmineRequireObj().Expectation = function() {
|
||||
|
||||
var matchers = {};
|
||||
|
||||
function Expectation(options) {
|
||||
this.util = options.util || { buildFailureMessage: function() {} };
|
||||
this.customEqualityTesters = options.customEqualityTesters || [];
|
||||
@@ -9,8 +7,9 @@ getJasmineRequireObj().Expectation = function() {
|
||||
this.addExpectationResult = options.addExpectationResult || function(){};
|
||||
this.isNot = options.isNot;
|
||||
|
||||
for (var matcherName in matchers) {
|
||||
this[matcherName] = matchers[matcherName];
|
||||
var customMatchers = options.customMatchers || {};
|
||||
for (var matcherName in customMatchers) {
|
||||
this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,19 +76,6 @@ getJasmineRequireObj().Expectation = function() {
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.addMatchers = function(matchersToAdd) {
|
||||
for (var name in matchersToAdd) {
|
||||
var matcher = matchersToAdd[name];
|
||||
matchers[name] = Expectation.prototype.wrapCompare(name, matcher);
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.resetMatchers = function() {
|
||||
for (var name in matchers) {
|
||||
delete matchers[name];
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.Factory = function(options) {
|
||||
options = options || {};
|
||||
|
||||
|
||||
@@ -4,15 +4,20 @@ getJasmineRequireObj().buildExpectationResult = function() {
|
||||
var messageFormatter = options.messageFormatter || function() {},
|
||||
stackFormatter = options.stackFormatter || function() {};
|
||||
|
||||
return {
|
||||
var result = {
|
||||
matcherName: options.matcherName,
|
||||
expected: options.expected,
|
||||
actual: options.actual,
|
||||
message: message(),
|
||||
stack: stack(),
|
||||
passed: options.passed
|
||||
};
|
||||
|
||||
if(!result.passed) {
|
||||
result.expected = options.expected;
|
||||
result.actual = options.actual;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function message() {
|
||||
if (options.passed) {
|
||||
return 'Passed.';
|
||||
|
||||
@@ -11,6 +11,7 @@ getJasmineRequireObj().JsApiReporter = function() {
|
||||
|
||||
this.started = false;
|
||||
this.finished = false;
|
||||
this.runDetails = {};
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
this.started = true;
|
||||
@@ -20,8 +21,9 @@ getJasmineRequireObj().JsApiReporter = function() {
|
||||
|
||||
var executionTime;
|
||||
|
||||
this.jasmineDone = function() {
|
||||
this.jasmineDone = function(runDetails) {
|
||||
this.finished = true;
|
||||
this.runDetails = runDetails;
|
||||
executionTime = timer.elapsed();
|
||||
status = 'done';
|
||||
};
|
||||
@@ -30,26 +32,31 @@ getJasmineRequireObj().JsApiReporter = function() {
|
||||
return status;
|
||||
};
|
||||
|
||||
var suites = {};
|
||||
var suites = [],
|
||||
suites_hash = {};
|
||||
|
||||
this.suiteStarted = function(result) {
|
||||
storeSuite(result);
|
||||
suites_hash[result.id] = result;
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
storeSuite(result);
|
||||
};
|
||||
|
||||
this.suiteResults = function(index, length) {
|
||||
return suites.slice(index, index + length);
|
||||
};
|
||||
|
||||
function storeSuite(result) {
|
||||
suites[result.id] = result;
|
||||
suites.push(result);
|
||||
suites_hash[result.id] = result;
|
||||
}
|
||||
|
||||
this.suites = function() {
|
||||
return suites;
|
||||
return suites_hash;
|
||||
};
|
||||
|
||||
var specs = [];
|
||||
this.specStarted = function(result) { };
|
||||
|
||||
this.specDone = function(result) {
|
||||
specs.push(result);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user