Compare commits
293 Commits
v1.1.0.rc4
...
v2.0.0.rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be0e6222c5 | ||
|
|
8c696ffc71 | ||
|
|
3dda67fe60 | ||
|
|
66d9b3d690 | ||
|
|
c350694c1b | ||
|
|
25d674f2c5 | ||
|
|
35bc200e31 | ||
|
|
9e886b3972 | ||
|
|
edd7e3932b | ||
|
|
0420e295f4 | ||
|
|
8d295a2612 | ||
|
|
d10b93cd28 | ||
|
|
358b9424b5 | ||
|
|
2571a6fbbb | ||
|
|
00f88edc04 | ||
|
|
98fa58ee49 | ||
|
|
984074ec95 | ||
|
|
6bb8a91301 | ||
|
|
97ce396008 | ||
|
|
051f3499ec | ||
|
|
8f5d0beb8c | ||
|
|
9609aba25f | ||
|
|
30aec66ce5 | ||
|
|
663a58d617 | ||
|
|
3847557bbc | ||
|
|
18c30566bd | ||
|
|
f2306729cd | ||
|
|
2165d71dc5 | ||
|
|
8c1881053c | ||
|
|
61a1f93488 | ||
|
|
d4f78922cd | ||
|
|
04ac41d911 | ||
|
|
75b9dc64af | ||
|
|
2d7fe0b6ce | ||
|
|
44feee57ac | ||
|
|
1394899c3c | ||
|
|
d0825a37a3 | ||
|
|
fc3d08bf40 | ||
|
|
990cc41f45 | ||
|
|
03ffe5ce6a | ||
|
|
1b0b4f22a0 | ||
|
|
a6953df28c | ||
|
|
5e71f3031e | ||
|
|
4ea4ed25ee | ||
|
|
39d40a1cad | ||
|
|
d40e0cebac | ||
|
|
89a54ea2bb | ||
|
|
bc9c857f43 | ||
|
|
24a7f55fa6 | ||
|
|
182cff4bd4 | ||
|
|
5dce5b1272 | ||
|
|
7c17b06856 | ||
|
|
6569176cc9 | ||
|
|
0f803430e4 | ||
|
|
821f13dff5 | ||
|
|
3e2d9baec2 | ||
|
|
f637c1f833 | ||
|
|
82b6904093 | ||
|
|
0daae4d7b4 | ||
|
|
f68657f14e | ||
|
|
c91df21a96 | ||
|
|
5b986c953c | ||
|
|
a932320d6c | ||
|
|
aabf8cec82 | ||
|
|
ccdcb293f4 | ||
|
|
ec7d58fce0 | ||
|
|
7f6b16ccf2 | ||
|
|
34b8bf5fb0 | ||
|
|
179e54b9fb | ||
|
|
09fe7b0540 | ||
|
|
264b1fea50 | ||
|
|
dcf7a0867e | ||
|
|
f5bc9faf63 | ||
|
|
2916a8a1ff | ||
|
|
8ac33ff6c2 | ||
|
|
661a884416 | ||
|
|
7acc6b327a | ||
|
|
e40e0c9170 | ||
|
|
7ae3fa9fef | ||
|
|
e73b9e7902 | ||
|
|
ffdf1eb16d | ||
|
|
d5f1264416 | ||
|
|
579fddc2d2 | ||
|
|
313e607135 | ||
|
|
b6599d52aa | ||
|
|
582ad6512a | ||
|
|
600be098af | ||
|
|
b87eb240b3 | ||
|
|
7055d95584 | ||
|
|
1c87060804 | ||
|
|
b4acdbd90a | ||
|
|
fbb9f53524 | ||
|
|
0ac497db6b | ||
|
|
9e31201f1a | ||
|
|
d53002c63a | ||
|
|
3271dc8838 | ||
|
|
475aacbfbb | ||
|
|
8303c79f26 | ||
|
|
5700ace2c9 | ||
|
|
aca43bd3a3 | ||
|
|
7516bba2b0 | ||
|
|
4f19d34ad7 | ||
|
|
c40b64a24c | ||
|
|
baad5ff01f | ||
|
|
bf2adf55eb | ||
|
|
dd8d3f9788 | ||
|
|
9c4467bac0 | ||
|
|
c017257164 | ||
|
|
2445fb36dc | ||
|
|
eec6d7d23e | ||
|
|
3110da62e5 | ||
|
|
d41b281eb1 | ||
|
|
6feb124853 | ||
|
|
3be247ceb1 | ||
|
|
edc2bfae93 | ||
|
|
01b2fc612c | ||
|
|
d8f6aac2cd | ||
|
|
e7a930a5b3 | ||
|
|
6b2d8da55f | ||
|
|
538b32e401 | ||
|
|
e6e8908f49 | ||
|
|
86dafd5d2d | ||
|
|
aa60d5f00d | ||
|
|
079e6e1e08 | ||
|
|
7706512525 | ||
|
|
e09fd40933 | ||
|
|
6eecc562ff | ||
|
|
cf7bb0269b | ||
|
|
b22bf9a031 | ||
|
|
b7af6abca5 | ||
|
|
d6da13a8dd | ||
|
|
dc4563d45c | ||
|
|
92492c0144 | ||
|
|
d6987a6c84 | ||
|
|
43c8fdd33f | ||
|
|
98ae076f0c | ||
|
|
2c06e36b9b | ||
|
|
5a744884fe | ||
|
|
e6888b840d | ||
|
|
e682d18387 | ||
|
|
10b09ea9f5 | ||
|
|
c53b36a9b2 | ||
|
|
af71f4d2f9 | ||
|
|
83227f2163 | ||
|
|
f865758124 | ||
|
|
3fc79bac9e | ||
|
|
05977203a6 | ||
|
|
5bea864e1c | ||
|
|
a9eaa66da5 | ||
|
|
30bf565e69 | ||
|
|
668dd784ef | ||
|
|
4ad43267ab | ||
|
|
be6b87a31b | ||
|
|
43552494ee | ||
|
|
98c99c4ebb | ||
|
|
4318de4647 | ||
|
|
a526ebf261 | ||
|
|
c2e1327f39 | ||
|
|
234f2a1585 | ||
|
|
c584f182ab | ||
|
|
74f928fd54 | ||
|
|
a1011e7748 | ||
|
|
8b02bf731b | ||
|
|
779dee1211 | ||
|
|
1f5e790c41 | ||
|
|
cd3a0c854b | ||
|
|
f9cbad1512 | ||
|
|
f840458b34 | ||
|
|
34bd1969e7 | ||
|
|
dfed37531e | ||
|
|
08f5a8c98f | ||
|
|
8d94d0bfc5 | ||
|
|
3e5da57cf9 | ||
|
|
e2af08e0a6 | ||
|
|
b6c3999c3a | ||
|
|
6785d1a05c | ||
|
|
e74f09df9c | ||
|
|
f7c9aaa996 | ||
|
|
86994b25db | ||
|
|
9a7c76ea23 | ||
|
|
e3a013ae99 | ||
|
|
ead9aa6d5a | ||
|
|
d9467317a8 | ||
|
|
63ad879c12 | ||
|
|
b95c43ab7c | ||
|
|
3685d3199c | ||
|
|
a34077a8af | ||
|
|
ac55e26870 | ||
|
|
acdc497361 | ||
|
|
b527ccd2fa | ||
|
|
cfa95fcf2c | ||
|
|
ae9ddd74a2 | ||
|
|
26f0f6f213 | ||
|
|
c5ba032d28 | ||
|
|
bbc4c70c91 | ||
|
|
c5c57247f8 | ||
|
|
9990eb7b6e | ||
|
|
b5b50182b2 | ||
|
|
4d106c2b33 | ||
|
|
5e594946bb | ||
|
|
6ac4b686a3 | ||
|
|
fd91433792 | ||
|
|
1f9004eaa3 | ||
|
|
58e6747930 | ||
|
|
4c083856be | ||
|
|
b94522193c | ||
|
|
867de62699 | ||
|
|
74cdc5a04f | ||
|
|
ddbee65aa8 | ||
|
|
beeb872a82 | ||
|
|
dbcb0b7983 | ||
|
|
c8436d1d44 | ||
|
|
639f757f6f | ||
|
|
d65bdc7e59 | ||
|
|
a1ed56741b | ||
|
|
7473b455dc | ||
|
|
b6fb23b069 | ||
|
|
386e83b53f | ||
|
|
f2b25f1780 | ||
|
|
5ca2888301 | ||
|
|
147cb36760 | ||
|
|
107463ad57 | ||
|
|
39a55d8f10 | ||
|
|
4b48dc1069 | ||
|
|
921f52862f | ||
|
|
ea2ffb7b01 | ||
|
|
54fbc48eb2 | ||
|
|
06c900ab20 | ||
|
|
3e070e9db6 | ||
|
|
7e04571ec0 | ||
|
|
ddd48f2c88 | ||
|
|
1c2e50d244 | ||
|
|
d2d60a798d | ||
|
|
442f3bf872 | ||
|
|
f910df00bb | ||
|
|
500b856cfa | ||
|
|
dad4865fbf | ||
|
|
1771ec3c63 | ||
|
|
2385acedd8 | ||
|
|
4c28bef387 | ||
|
|
7bbcf51d45 | ||
|
|
b6f96bc121 | ||
|
|
feebfbba68 | ||
|
|
8e4bd86865 | ||
|
|
4f218f7d6a | ||
|
|
bb1a4428db | ||
|
|
079740ca2c | ||
|
|
fbbccf6ef7 | ||
|
|
7ad75c13d4 | ||
|
|
d46ca4f506 | ||
|
|
ee7af4496c | ||
|
|
e22c4492a5 | ||
|
|
d63836afb4 | ||
|
|
06f1edc197 | ||
|
|
3a6b233a2e | ||
|
|
d15964b7dc | ||
|
|
6e22754c10 | ||
|
|
bab4538404 | ||
|
|
06d191af74 | ||
|
|
ad78d0d0d8 | ||
|
|
733a6a4ae4 | ||
|
|
3e0cad41f5 | ||
|
|
885832e920 | ||
|
|
3a0ada034b | ||
|
|
674197aef8 | ||
|
|
626da5a112 | ||
|
|
a3ccd8b0d3 | ||
|
|
4a1a2123a3 | ||
|
|
c87cf71f4f | ||
|
|
e4c557faae | ||
|
|
6559c5b43a | ||
|
|
912397120b | ||
|
|
551464b8d2 | ||
|
|
8a298e5c0e | ||
|
|
94a153ed15 | ||
|
|
b4439f74d5 | ||
|
|
d70e733f70 | ||
|
|
ac096f9911 | ||
|
|
08d72926ff | ||
|
|
67ec0af254 | ||
|
|
4f2fcff15a | ||
|
|
7158fc2426 | ||
|
|
992367dcbc | ||
|
|
ce886e20e4 | ||
|
|
86b0c80cc9 | ||
|
|
7dff84b1dc | ||
|
|
8c22b26d9c | ||
|
|
ad4f48dcd4 | ||
|
|
de9e2abad5 | ||
|
|
41f496001f | ||
|
|
dbcabd397e | ||
|
|
a8b0a0ee4f | ||
|
|
60a5d60f42 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,3 +10,7 @@ site/
|
||||
tags
|
||||
Gemfile.lock
|
||||
pkg/*
|
||||
.sass-cache/*
|
||||
src/html/.sass-cache/*
|
||||
node_modules/
|
||||
*.swp
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "pages"]
|
||||
path = pages
|
||||
url = git@github.com:pivotal/jasmine.git
|
||||
url = https://github.com/pivotal/jasmine.git
|
||||
|
||||
47
.travis.yml
Normal file
47
.travis.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
script: $TEST_COMMAND
|
||||
language: ruby
|
||||
rvm: 1.9.3
|
||||
env:
|
||||
global:
|
||||
- USE_SAUCE=true
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
|
||||
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- env:
|
||||
- JASMINE_BROWSER="firefox"
|
||||
- SAUCE_PLATFORM="Linux"
|
||||
- SAUCE_VERSION=''
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_PLATFORM="OS X 10.8"
|
||||
- SAUCE_VERSION=6
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_PLATFORM="OS X 10.6"
|
||||
- SAUCE_VERSION=5
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_PLATFORM="Windows 8"
|
||||
- SAUCE_VERSION=10
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_PLATFORM="Windows 7"
|
||||
- SAUCE_VERSION=9
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_PLATFORM="Windows 7"
|
||||
- SAUCE_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="chrome"
|
||||
- SAUCE_PLATFORM="Linux"
|
||||
- SAUCE_VERSION=''
|
||||
- env:
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- USE_SAUCE=false
|
||||
@@ -1,10 +1,80 @@
|
||||
# Developing for Jasmine Core
|
||||
|
||||
## How to Contribute
|
||||
# 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.
|
||||
|
||||
## How to write new Jasmine code
|
||||
## General Workflow
|
||||
|
||||
Please submit pull requests via feature branches using the semi-standard workflow of:
|
||||
|
||||
1. Fork it
|
||||
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
|
||||
|
||||
We favor pull requests with very small, single commits with a single purpose.
|
||||
|
||||
## Background
|
||||
|
||||
### Directory Structure
|
||||
|
||||
* `/src` contains all of the source files
|
||||
* `/src/console` - Node.js-specific files
|
||||
* `/src/core` - generic source files
|
||||
* `/src/html` - browser-specific files
|
||||
* `/spec` contains all of the tests
|
||||
* mirrors the source directory
|
||||
* there are some additional files
|
||||
* `/dist` contains the standalone distributions as zip files
|
||||
* `/lib` contains the generated files for distribution as the Jasmine Rubygem and the Python package
|
||||
|
||||
### Self-testing
|
||||
|
||||
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `j$`. So there are two copies of the code loaded under test.
|
||||
|
||||
The tests should always use `j$` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
|
||||
|
||||
### `boot.js`
|
||||
|
||||
__This is new for Jasmine 2.0.__
|
||||
|
||||
This file does all of the setup necessary for Jasmine to work. It loads all of the code, creates an `Env`, attaches the global functions, and builds the reporter. It also sets up the execution of the `Env` - for browsers this is in `window.onload`. While the default in `lib` is appropriate for browsers, projects may wish to customize this file.
|
||||
|
||||
For example, for Jasmine development there is a different `dev_boot.js` for Jasmine development that does more work.
|
||||
|
||||
### Compatibility
|
||||
|
||||
* Browser Minimum
|
||||
* IE8
|
||||
* Firefox 3.x
|
||||
* Chrome ??
|
||||
* Safari 5
|
||||
|
||||
## Development
|
||||
|
||||
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
Jasmine Core relies on Ruby and Node.js.
|
||||
|
||||
To install the Ruby dependencies, you will need Ruby, Rubygems, and Bundler available. Then:
|
||||
|
||||
$ bundle
|
||||
|
||||
...will install all of the Ruby dependencies.
|
||||
|
||||
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
|
||||
|
||||
$ grunt
|
||||
|
||||
...you see that JSHint runs your system is ready.
|
||||
|
||||
### How to write new Jasmine code
|
||||
|
||||
Or, How to make a successful pull request
|
||||
|
||||
@@ -12,33 +82,30 @@ Or, How to make a successful pull request
|
||||
* _Be environment agnostic_ - server-side developers are just as important as browser developers
|
||||
* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully
|
||||
* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it
|
||||
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
|
||||
* _Write code in the style of the rest of the repo_ - Jasmine should look like a cohesive whole
|
||||
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
|
||||
|
||||
Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated.
|
||||
|
||||
## Environment
|
||||
### Running Specs
|
||||
|
||||
Ruby, RubyGems and Rake are used in order to script the various file interactions. You will need to run on a system that supports Ruby in order to run Jasmine's specs.
|
||||
Jasmine uses the [Jasmine Ruby gem](http://github.com/pivotal/jasmine-gem) to test itself in browser.
|
||||
|
||||
Node.js is used to run most of the specs (the HTML-independent code) and should be present. Additionally, the JS Hint project scrubs the source code as part of the spec process.
|
||||
$ rake jasmine
|
||||
|
||||
## Development
|
||||
...and then visit `http://localhost:8888` to run specs.
|
||||
|
||||
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
Jasmine uses Node.js with a custom runner to test outside of a browser.
|
||||
|
||||
Please respect the code patterns as possible. For example, using `jasmine.getGlobal()` to get the global object so as to remain environment agnostic.
|
||||
$ grunt execSpecsInNode
|
||||
|
||||
## Running Specs
|
||||
...and then the results will print to the console. All specs run except those that expect a browser (the specs in `spec/html` are ignored).
|
||||
|
||||
As in all good projects, the `spec/` directory mirrors `src/` and follows the same rules. The browser runner will include and attempt to run all specs. The node runner will exclude any html-dependent specs (those in `spec/html/`).
|
||||
## Before Committing or Submitting a Pull Request
|
||||
|
||||
You will notice that all specs are run against the built `jasmine.js` instead of the component source files. This is intentional as a way to ensure that the concatenation code is working correctly.
|
||||
1. Ensure all specs are green in browser *and* node
|
||||
1. Ensure JSHint is green with `grunt jsHint`
|
||||
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
|
||||
|
||||
Please ensure all specs are green before committing.
|
||||
|
||||
There are rake tasks to help with getting green:
|
||||
* `rake spec` outputs the expected number of specs that should be run and attempts to run in browser and Node
|
||||
* `rake spec:browser` opens `spec/runner.html` in the default browser on MacOS. Please run this in at least Firefox and Chrome before committing
|
||||
* `rake spec:node` runs all the Jasmine specs in Node.js - it will complain if Node is not installed
|
||||
* `rake hint` runs all the files through JSHint and will complain about potential viable issues with your code. Fix them.
|
||||
Note that we use Travis for Continuous Integration. We only accept green pull requests.
|
||||
|
||||
|
||||
61
GOALS_2.0.md
Normal file
61
GOALS_2.0.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# (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
|
||||
* Spies
|
||||
* break these out into their own tests/file
|
||||
* 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?
|
||||
* Matchers improvements
|
||||
* unit testable DONE
|
||||
* better equality (from Underscore) DONE
|
||||
* refactor equals function so that it just loops & recurses over a list of fns (custom and built-in) - 2.1?
|
||||
* addCustomMatchers doesn't explode stack
|
||||
* 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?)
|
||||
|
||||
## 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,4 +1,11 @@
|
||||
source :rubygems
|
||||
gem "term-ansicolor", :require => "term/ansicolor"
|
||||
source 'https://rubygems.org'
|
||||
gem "rake"
|
||||
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
|
||||
|
||||
gemspec
|
||||
|
||||
48
Gruntfile.js
Normal file
48
Gruntfile.js
Normal file
@@ -0,0 +1,48 @@
|
||||
module.exports = function(grunt) {
|
||||
var pkg = require("./package.json");
|
||||
global.jasmineVersion = pkg.version;
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: pkg,
|
||||
jshint: require('./grunt/config/jshint.js'),
|
||||
concat: require('./grunt/config/concat.js'),
|
||||
compass: require('./grunt/config/compass.js'),
|
||||
compress: require('./grunt/config/compress.js')
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-compass');
|
||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||
|
||||
grunt.loadTasks('grunt/tasks');
|
||||
|
||||
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",
|
||||
version.copyToGem);
|
||||
|
||||
grunt.registerTask('buildDistribution',
|
||||
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
|
||||
[
|
||||
'compass',
|
||||
'jshint:beforeConcat',
|
||||
'concat',
|
||||
'jshint:afterConcat',
|
||||
'build:copyVersionToGem'
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
var spec = require('./grunt/tasks/spec.js');
|
||||
|
||||
grunt.registerTask("execSpecsInNode",
|
||||
"Run Jasmine core specs in Node.js",
|
||||
spec.execSpecsInNode
|
||||
);
|
||||
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
<a name="README">[Jasmine](http://pivotal.github.com/jasmine/)</a>
|
||||
<a name="README">[Jasmine](http://pivotal.github.com/jasmine/)</a> [](https://travis-ci.org/pivotal/jasmine)
|
||||
|
||||
=======
|
||||
**A JavaScript Testing Framework**
|
||||
|
||||
@@ -6,26 +7,21 @@ Jasmine is a Behavior Driven Development testing framework for JavaScript. It do
|
||||
|
||||
Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
|
||||
|
||||
## What's Here?
|
||||
|
||||
*
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/Contribute.markdown)
|
||||
|
||||
## Support
|
||||
|
||||
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
|
||||
* Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
|
||||
* Check the current build status: [ci.pivotallabs.com](http://ci.pivotallabs.com)
|
||||
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
|
||||
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Square
|
||||
|
||||
Copyright (c) 2008-2011 Pivotal Labs. This software is licensed under the MIT License.
|
||||
Copyright (c) 2008-2013 Pivotal Labs. This software is licensed under the MIT License.
|
||||
|
||||
48
Rakefile
48
Rakefile
@@ -1,33 +1,39 @@
|
||||
require "bundler"
|
||||
Bundler::GemHelper.install_tasks
|
||||
require "term/ansicolor"
|
||||
require "json"
|
||||
require "tilt"
|
||||
require "jasmine"
|
||||
|
||||
Dir["#{File.dirname(__FILE__)}/tasks/**/*.rb"].each do |file|
|
||||
require file
|
||||
end
|
||||
|
||||
task :default => :spec
|
||||
|
||||
task :require_pages_submodule do
|
||||
raise "Submodule for Github Pages isn't present. Run git submodule update --init" unless pages_submodule_present
|
||||
# TODO: Is there better way to invoke this using Jasmine gem???
|
||||
task :core_spec do
|
||||
exec "ruby spec/jasmine_self_test_spec.rb"
|
||||
end
|
||||
|
||||
task :require_node do
|
||||
raise "\nNode.js is required to develop code for Jasmine. Please visit http://nodejs.org to install.\n\n" unless node_installed?
|
||||
namespace :jasmine do
|
||||
task :server do
|
||||
port = ENV['JASMINE_PORT'] || 8888
|
||||
jasmine_yml = ENV['JASMINE_YML'] || 'jasmine.yml'
|
||||
Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', jasmine_yml))
|
||||
config = Jasmine.config
|
||||
server = Jasmine::Server.new(port, Jasmine::Application.app(config))
|
||||
server.start
|
||||
|
||||
puts "your tests are here:"
|
||||
puts " http://localhost:#{port}/"
|
||||
end
|
||||
|
||||
desc "Copy examples from Jasmine JS to the gem"
|
||||
task :copy_examples_to_gem do
|
||||
require "fileutils"
|
||||
|
||||
# copy jasmine's example tree into our generator templates dir
|
||||
FileUtils.rm_r('generators/jasmine/templates/jasmine-example', :force => true)
|
||||
FileUtils.cp_r(File.join(Jasmine::Core.path, 'example'), 'generators/jasmine/templates/jasmine-example', :preserve => true)
|
||||
end
|
||||
end
|
||||
|
||||
def pages_submodule_present
|
||||
File.exist?('pages/download.html')
|
||||
end
|
||||
|
||||
def node_installed?
|
||||
`which node` =~ /node/
|
||||
end
|
||||
|
||||
class String
|
||||
include Term::ANSIColor
|
||||
end
|
||||
|
||||
Term::ANSIColor.coloring = STDOUT.isatty
|
||||
desc "Run specs via server"
|
||||
task :jasmine => ['jasmine:server']
|
||||
|
||||
@@ -5,36 +5,43 @@ ___Jasmine Core Maintainers Only___
|
||||
|
||||
Follow the instructions in `Contribute.markdown` during development.
|
||||
|
||||
### Git Commits
|
||||
### Git Rules
|
||||
|
||||
Please work on feature branches.
|
||||
|
||||
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`.
|
||||
|
||||
### Version
|
||||
|
||||
We attempt to stick to [Semantic Versioning](). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
|
||||
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 `src/version.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 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.
|
||||
|
||||
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.
|
||||
|
||||
### Update the Github Pages (as needed)
|
||||
|
||||
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.
|
||||
___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.
|
||||
|
||||
The pages are built with [Frank](https://github.com/blahed/frank). All the source for these pages live in the `pages/pages_source` directory.
|
||||
|
||||
## Release
|
||||
|
||||
When ready to release - specs are all green and the stories are done:
|
||||
|
||||
1. Update the version in `version.json` to a release candidate - add an `rc` property with a value of 1
|
||||
1. Update any comments on the public interfaces
|
||||
1. `rake doc` - builds the `jsdoc` pages
|
||||
1. Update the version in `package.json` to a release candidate
|
||||
1. Update any links or top-level landing page for the Github Pages
|
||||
1. `rake standalone` - builds the standalone distribution ZIP file
|
||||
1. `rake build_pages` - builds the Github Pages
|
||||
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org
|
||||
1. Build the standalone distribution with `grunt buildStandaloneDist`
|
||||
1. Make sure you add the new ZIP file to git
|
||||
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
|
||||
1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile.
|
||||
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release.
|
||||
1. Push these changes to GitHub and verify that this SHA is green
|
||||
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
|
||||
|
||||
|
||||
There should be a post to Pivotal Labs blog and a tweet to that link.
|
||||
|
||||
BIN
dist/jasmine-standalone-2.0.0-alpha.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.0.0-alpha.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.0-rc2.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.0.0-rc2.zip
vendored
Normal file
Binary file not shown.
10
grunt/config/compass.js
Normal file
10
grunt/config/compass.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
jasmine: {
|
||||
options: {
|
||||
cssDir: 'src/html',
|
||||
sassDir: 'src/html',
|
||||
outputStyle: 'compact',
|
||||
lineComments: false
|
||||
}
|
||||
}
|
||||
};
|
||||
57
grunt/config/compress.js
Normal file
57
grunt/config/compress.js
Normal file
@@ -0,0 +1,57 @@
|
||||
var standaloneLibDir = "lib/jasmine-" + jasmineVersion;
|
||||
|
||||
function root(path) { return "./" + path; }
|
||||
function lib(path) { return root("lib/jasmine-core/" + path); }
|
||||
function dist(path) { return root("dist/" + path); }
|
||||
|
||||
module.exports = {
|
||||
standalone: {
|
||||
options: {
|
||||
archive: root("dist/jasmine-standalone-" + global.jasmineVersion + ".zip")
|
||||
},
|
||||
|
||||
files: [
|
||||
{ src: [ root("MIT.LICENSE") ] },
|
||||
{
|
||||
src: [ "jasmine_favicon.png"],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: root("images")
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"jasmine.js",
|
||||
"jasmine-html.js",
|
||||
"jasmine.css"
|
||||
],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: lib("")
|
||||
},
|
||||
{
|
||||
src: [ "boot.js" ],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: lib("boot")
|
||||
},
|
||||
{
|
||||
src: [ "SpecRunner.html" ],
|
||||
dest: root(""),
|
||||
expand: true,
|
||||
cwd: dist("tmp")
|
||||
},
|
||||
{
|
||||
src: [ "*.js" ],
|
||||
dest: "src",
|
||||
expand: true,
|
||||
cwd: lib("example/src/")
|
||||
},
|
||||
{
|
||||
src: [ "*.js" ],
|
||||
dest: "spec",
|
||||
expand: true,
|
||||
cwd: lib("example/spec/")
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
57
grunt/config/concat.js
Normal file
57
grunt/config/concat.js
Normal file
@@ -0,0 +1,57 @@
|
||||
var grunt = require('grunt');
|
||||
|
||||
function license() {
|
||||
var currentYear = "" + new Date(Date.now()).getFullYear();
|
||||
|
||||
return grunt.template.process(
|
||||
grunt.file.read("grunt/templates/licenseBanner.js.jst"),
|
||||
{ data: { currentYear: currentYear}});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'jasmine-html': {
|
||||
src: [
|
||||
'src/html/requireHtml.js',
|
||||
'src/html/HtmlReporter.js',
|
||||
'src/html/HtmlSpecFilter.js',
|
||||
'src/html/ResultsNode.js',
|
||||
'src/html/QueryString.js'
|
||||
],
|
||||
dest: 'lib/jasmine-core/jasmine-html.js'
|
||||
},
|
||||
jasmine: {
|
||||
src: [
|
||||
'src/core/requireCore.js',
|
||||
'src/core/matchers/requireMatchers.js',
|
||||
'src/core/base.js',
|
||||
'src/core/util.js',
|
||||
'src/core/Spec.js',
|
||||
'src/core/Env.js',
|
||||
'src/core/JsApiReporter.js',
|
||||
'src/core/PrettyPrinter',
|
||||
'src/core/Suite',
|
||||
'src/core/**/*.js',
|
||||
'src/version.js'
|
||||
],
|
||||
dest: 'lib/jasmine-core/jasmine.js'
|
||||
},
|
||||
boot: {
|
||||
src: ['lib/jasmine-core/boot/boot.js'],
|
||||
dest: 'lib/jasmine-core/boot.js'
|
||||
},
|
||||
console: {
|
||||
src: [
|
||||
'src/console/requireConsole.js',
|
||||
'src/console/ConsoleReporter.js'
|
||||
],
|
||||
dest: 'src/console/console.js'
|
||||
},
|
||||
options: {
|
||||
banner: license(),
|
||||
process: {
|
||||
data: {
|
||||
version: global.jasmineVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
17
grunt/config/jshint.js
Normal file
17
grunt/config/jshint.js
Normal file
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
beforeConcat: ['src/**/*.js'],
|
||||
afterConcat: [
|
||||
'lib/jasmine-core/jasmine-html.js',
|
||||
'lib/jasmine-core/jasmine.js'
|
||||
],
|
||||
options: {
|
||||
/* While it's possible that we could be considering unwanted prototype methods, mostly
|
||||
* we're doing this because the objects are being used as maps.
|
||||
*/
|
||||
forin: false,
|
||||
|
||||
/* We're fine with functions defined inside loops (setTimeout functions, etc) */
|
||||
loopfunc: true
|
||||
},
|
||||
all: ['src/**/*.js']
|
||||
};
|
||||
30
grunt/tasks/build_standalone.js
Normal file
30
grunt/tasks/build_standalone.js
Normal file
@@ -0,0 +1,30 @@
|
||||
var grunt = require("grunt");
|
||||
|
||||
function standaloneTmpDir(path) { return "dist/tmp/" + path; }
|
||||
|
||||
grunt.registerTask("build:compileSpecRunner",
|
||||
"Processes the spec runner template and writes to a tmp file",
|
||||
function() {
|
||||
var runnerHtml = grunt.template.process(
|
||||
grunt.file.read("grunt/templates/SpecRunner.html.jst"),
|
||||
{ data: { jasmineVersion: global.jasmineVersion }});
|
||||
|
||||
grunt.file.write(standaloneTmpDir("SpecRunner.html"), runnerHtml);
|
||||
}
|
||||
);
|
||||
|
||||
grunt.registerTask("build:cleanSpecRunner",
|
||||
"Deletes the tmp spec runner file",
|
||||
function() {
|
||||
grunt.file.delete(standaloneTmpDir(""));
|
||||
}
|
||||
);
|
||||
|
||||
grunt.registerTask("buildStandaloneDist",
|
||||
"Builds a standalone distribution",
|
||||
[
|
||||
"build:compileSpecRunner",
|
||||
"compress:standalone",
|
||||
"build:cleanSpecRunner"
|
||||
]
|
||||
);
|
||||
11
grunt/tasks/spec.js
Normal file
11
grunt/tasks/spec.js
Normal file
@@ -0,0 +1,11 @@
|
||||
var shell = require('shelljs');
|
||||
var grunt = require('grunt');
|
||||
|
||||
module.exports = {
|
||||
execSpecsInNode: function() {
|
||||
var exit_code = shell.exec("node spec/node_suite.js --color=true").code;
|
||||
if (exit_code !== 0) {
|
||||
grunt.fail.fatal("Specs Failed", exit_code);
|
||||
}
|
||||
}
|
||||
};
|
||||
14
grunt/tasks/version.js
Normal file
14
grunt/tasks/version.js
Normal file
@@ -0,0 +1,14 @@
|
||||
var grunt = require("grunt");
|
||||
|
||||
function gemLib(path) { return './lib/jasmine-core/' + path; }
|
||||
function nodeToRuby(version) { return version.replace('-', '.'); }
|
||||
|
||||
module.exports = {
|
||||
copyToGem: function() {
|
||||
var versionRb = grunt.template.process(
|
||||
grunt.file.read("grunt/templates/version.rb.jst"),
|
||||
{ data: { jasmineVersion: nodeToRuby(global.jasmineVersion) }});
|
||||
|
||||
grunt.file.write(gemLib("version.rb"), versionRb);
|
||||
}
|
||||
};
|
||||
26
grunt/templates/SpecRunner.html.jst
Normal file
26
grunt/templates/SpecRunner.html.jst
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; 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">
|
||||
|
||||
<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>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" 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>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
22
grunt/templates/licenseBanner.js.jst
Normal file
22
grunt/templates/licenseBanner.js.jst
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (c) 2008-<%= currentYear %> Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
9
grunt/templates/version.rb.jst
Normal file
9
grunt/templates/version.rb.jst
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# DO NOT Edit this file. Canonical version of Jasmine lives in the repo's package.json. This file is generated
|
||||
# by a grunt task when the standalone release is built.
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "<%= jasmineVersion %>"
|
||||
end
|
||||
end
|
||||
@@ -6,17 +6,22 @@ Gem::Specification.new do |s|
|
||||
s.name = "jasmine-core"
|
||||
s.version = Jasmine::Core::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Rajan Agaskar", "Davis Frank", "Christian Williams"]
|
||||
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Christian Williams"]
|
||||
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.rubyforge_project = "jasmine-core"
|
||||
s.license = "MIT"
|
||||
|
||||
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
|
||||
s.require_paths = ["lib"]
|
||||
s.add_development_dependency "term-ansicolor"
|
||||
s.add_development_dependency "json_pure", ">= 1.4.3"
|
||||
s.add_development_dependency "frank"
|
||||
s.add_development_dependency "ragaskar-jsdoc_helper"
|
||||
s.add_development_dependency "sass"
|
||||
s.add_development_dependency "compass"
|
||||
s.add_development_dependency "rspec"
|
||||
s.add_development_dependency "fuubar"
|
||||
s.add_development_dependency "awesome_print"
|
||||
s.add_development_dependency "nokogiri"
|
||||
s.add_development_dependency "sauce-connect"
|
||||
end
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<div align="center">{+new Link().toFile("index.html").withText("Class Index")+}
|
||||
| {+new Link().toFile("files.html").withText("File Index")+}</div>
|
||||
<hr />
|
||||
<h2>Classes</h2>
|
||||
<ul class="classList">
|
||||
<for each="thisClass" in="data">
|
||||
<li>{!
|
||||
if (thisClass.alias == "_global_") {
|
||||
output += "<i>"+new Link().toClass(thisClass.alias)+"</i>";
|
||||
}
|
||||
else {
|
||||
output += new Link().toClass(thisClass.alias);
|
||||
}
|
||||
!}</li>
|
||||
</for>
|
||||
</ul>
|
||||
<hr />
|
||||
@@ -1,56 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
|
||||
{! Link.base = ""; /* all generated links will be relative to this */ !}
|
||||
<title>JsDoc Reference - File Index</title>
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{+include("static/header.html")+}
|
||||
|
||||
<div id="index">
|
||||
{+publish.classesIndex+}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1 class="classTitle">File Index</h1>
|
||||
|
||||
<for each="item" in="data">
|
||||
<div>
|
||||
<h2>{+new Link().toSrc(item.alias).withText(item.name)+}</h2>
|
||||
<if test="item.desc">{+resolveLinks(summarize(item.desc))+}</if>
|
||||
<dl>
|
||||
<if test="item.author">
|
||||
<dt class="heading">Author:</dt>
|
||||
<dd>{+item.author+}</dd>
|
||||
</if>
|
||||
<if test="item.version">
|
||||
<dt class="heading">Version:</dt>
|
||||
<dd>{+item.version+}</dd>
|
||||
</if>
|
||||
{! var locations = item.comment.getTag('location').map(function($){return $.toString().replace(/(^\$ ?| ?\$$)/g, '').replace(/^HeadURL: https:/g, 'http:');}) !}
|
||||
<if test="locations.length">
|
||||
<dt class="heading">Location:</dt>
|
||||
<for each="location" in="locations">
|
||||
<dd><a href="{+location+}">{+location+}</a></dd>
|
||||
</for>
|
||||
</if>
|
||||
</dl>
|
||||
</div>
|
||||
<hr />
|
||||
</for>
|
||||
|
||||
</div>
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,646 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}" />
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
{! Link.base = "../"; /* all generated links will be relative to this */ !}
|
||||
<title>JsDoc Reference - {+data.alias+}</title>
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- ============================== header ================================= -->
|
||||
<!-- begin static/header.html -->
|
||||
{+include("static/header.html")+}
|
||||
<!-- end static/header.html -->
|
||||
|
||||
<!-- ============================== classes index ============================ -->
|
||||
<div id="index">
|
||||
<!-- begin publish.classesIndex -->
|
||||
{+publish.classesIndex+}
|
||||
<!-- end publish.classesIndex -->
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<!-- ============================== class title ============================ -->
|
||||
<h1 class="classTitle">
|
||||
{!
|
||||
var classType = "";
|
||||
|
||||
if (data.isBuiltin()) {
|
||||
classType += "Built-In ";
|
||||
}
|
||||
|
||||
if (data.isNamespace) {
|
||||
if (data.is('FUNCTION')) {
|
||||
classType += "Function ";
|
||||
}
|
||||
classType += "Namespace ";
|
||||
}
|
||||
else {
|
||||
classType += "Class ";
|
||||
}
|
||||
!}
|
||||
{+classType+}{+data.alias+}
|
||||
</h1>
|
||||
|
||||
<!-- ============================== class summary ========================== -->
|
||||
<p class="description">
|
||||
<if test="data.augments.length"><br />Extends
|
||||
{+
|
||||
data.augments
|
||||
.sort()
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($); }
|
||||
)
|
||||
.join(", ")
|
||||
+}.<br />
|
||||
</if>
|
||||
|
||||
{+resolveLinks(data.classDesc)+}
|
||||
|
||||
<if test="!data.isBuiltin()">{# isn't defined in any file #}
|
||||
<br /><i>Defined in: </i> {+new Link().toSrc(data.srcFile)+}.
|
||||
</if>
|
||||
</p>
|
||||
|
||||
<!-- ============================== constructor summary ==================== -->
|
||||
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the constructor documented in the class {+data.alias+}.">
|
||||
<caption>{+classType+}Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Constructor Attributes</th>
|
||||
<th scope="col">Constructor Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (data.isPrivate) output += "<private> ";
|
||||
if (data.isInner) output += "<inner> ";
|
||||
!} </td>
|
||||
<td class="nameDescription" {!if (data.comment.getTag("hilited").length){output += 'style="color: red"'}!}>
|
||||
<div class="fixedFont">
|
||||
<b>{+ new Link().toSymbol(data.alias).inner('constructor')+}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(data.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<!-- ============================== properties summary ===================== -->
|
||||
<if test="data.properties.length">
|
||||
{! var ownProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownProperties.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the fields documented in the class {+data.alias+}.">
|
||||
<caption>Field Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Field Attributes</th>
|
||||
<th scope="col">Field Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownProperties">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
if (member.isConstant) output += "<constant> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont">
|
||||
<if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.properties.filter(function($) {return $.memberOf != data.alias});
|
||||
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Fields borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
|
||||
<!-- ============================== methods summary ======================== -->
|
||||
<if test="data.methods.length">
|
||||
{! var ownMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownMethods.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the methods documented in the class {+data.alias+}.">
|
||||
<caption>Method Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Method Attributes</th>
|
||||
<th scope="col">Method Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownMethods">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.methods.filter(function($) {return $.memberOf != data.alias});
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Methods borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
<!-- ============================== events summary ======================== -->
|
||||
<if test="data.events.length">
|
||||
{! var ownEvents = data.events.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownEvents.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the events documented in the class {+data.alias+}.">
|
||||
<caption>Event Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Event Attributes</th>
|
||||
<th scope="col">Event Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownEvents">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.events.filter(function($) {return $.memberOf != data.alias});
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Events borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
|
||||
<!-- ============================== constructor details ==================== -->
|
||||
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
|
||||
<div class="details"><a name="constructor"> </a>
|
||||
<div class="sectionTitle">
|
||||
{+classType+}Detail
|
||||
</div>
|
||||
|
||||
<div class="fixedFont">{!
|
||||
if (data.isPrivate) output += "<private> ";
|
||||
if (data.isInner) output += "<inner> ";
|
||||
!}
|
||||
<b>{+ data.alias +}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
{+resolveLinks(data.desc)+}
|
||||
<if test="data.author"><br /><i>Author: </i>{+data.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="data.example.length">
|
||||
<for each="example" in="data.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
|
||||
<if test="data.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="data.params">
|
||||
<dt>
|
||||
{+((item.type)?""+("<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type)+"}</span> ")) : "")+} <b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+resolveLinks(data.deprecated)+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ data.since +}</dd>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="data.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="data.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="data.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="data.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<!-- ============================== field details ========================== -->
|
||||
<if test="defined(ownProperties) && ownProperties.length">
|
||||
<div class="sectionTitle">
|
||||
Field Detail
|
||||
</div>
|
||||
<for each="member" in="ownProperties">
|
||||
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
if (member.isConstant) output += "<constant> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+ member.deprecated +}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.defaultValue">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Default Value:</dt>
|
||||
<dd>
|
||||
{+resolveLinks(member.defaultValue)+}
|
||||
</dd>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<!-- ============================== method details ========================= -->
|
||||
<if test="defined(ownMethods) && ownMethods.length">
|
||||
<div class="sectionTitle">
|
||||
Method Detail
|
||||
</div>
|
||||
<for each="member" in="ownMethods">
|
||||
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="member.params">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+member.deprecated+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="member.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="member.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="member.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<!-- ============================== event details ========================= -->
|
||||
<if test="defined(ownEvents) && ownEvents.length">
|
||||
<div class="sectionTitle">
|
||||
Event Detail
|
||||
</div>
|
||||
<for each="member" in="ownEvents">
|
||||
<a name="event:{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="member.params">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+member.deprecated+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="member.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="member.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="member.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================== footer ================================= -->
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
|
||||
|
||||
<title>JsDoc Reference - Index</title>
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{+include("static/header.html")+}
|
||||
|
||||
<div id="index">
|
||||
{+publish.classesIndex+}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1 class="classTitle">Class Index</h1>
|
||||
|
||||
<for each="thisClass" in="data">
|
||||
<div>
|
||||
<h2>{+(new Link().toSymbol(thisClass.alias))+}</h2>
|
||||
{+resolveLinks(summarize(thisClass.classDesc))+}
|
||||
</div>
|
||||
<hr />
|
||||
</for>
|
||||
|
||||
</div>
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,184 +0,0 @@
|
||||
/** Called automatically by JsDoc Toolkit. */
|
||||
function publish(symbolSet) {
|
||||
publish.conf = { // trailing slash expected for dirs
|
||||
ext: ".html",
|
||||
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
|
||||
templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
|
||||
symbolsDir: "symbols/",
|
||||
srcDir: "symbols/src/"
|
||||
};
|
||||
|
||||
// is source output is suppressed, just display the links to the source file
|
||||
if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
|
||||
Link.prototype._makeSrcLink = function(srcFilePath) {
|
||||
return "<"+srcFilePath+">";
|
||||
}
|
||||
}
|
||||
|
||||
// create the folders and subfolders to hold the output
|
||||
IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));
|
||||
|
||||
// used to allow Link to check the details of things being linked to
|
||||
Link.symbolSet = symbolSet;
|
||||
|
||||
// create the required templates
|
||||
try {
|
||||
var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl");
|
||||
var classesTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
|
||||
}
|
||||
catch(e) {
|
||||
print("Couldn't create the required templates: "+e);
|
||||
quit();
|
||||
}
|
||||
|
||||
// some ustility filters
|
||||
function hasNoParent($) {return ($.memberOf == "")}
|
||||
function isaFile($) {return ($.is("FILE"))}
|
||||
function isaClass($) {return ($.is("CONSTRUCTOR") || $.isNamespace)}
|
||||
|
||||
// get an array version of the symbolset, useful for filtering
|
||||
var symbols = symbolSet.toArray();
|
||||
|
||||
// create the hilited source code files
|
||||
var files = JSDOC.opt.srcFiles;
|
||||
for (var i = 0, l = files.length; i < l; i++) {
|
||||
var file = files[i];
|
||||
var srcDir = publish.conf.outDir + "symbols/src/";
|
||||
makeSrcFile(file, srcDir);
|
||||
}
|
||||
|
||||
// get a list of all the classes in the symbolset
|
||||
var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
|
||||
|
||||
// create a class index, displayed in the left-hand column of every class page
|
||||
Link.base = "../";
|
||||
publish.classesIndex = classesTemplate.process(classes); // kept in memory
|
||||
|
||||
// create each of the class pages
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var symbol = classes[i];
|
||||
|
||||
symbol.events = symbol.getEvents(); // 1 order matters
|
||||
symbol.methods = symbol.getMethods(); // 2
|
||||
|
||||
var output = "";
|
||||
output = classTemplate.process(symbol);
|
||||
|
||||
IO.saveFile(publish.conf.outDir+"symbols/", symbol.alias+publish.conf.ext, output);
|
||||
}
|
||||
|
||||
// regenerate the index with different relative links, used in the index pages
|
||||
Link.base = "";
|
||||
publish.classesIndex = classesTemplate.process(classes);
|
||||
|
||||
// create the class index page
|
||||
try {
|
||||
var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"index.tmpl");
|
||||
}
|
||||
catch(e) { print(e.message); quit(); }
|
||||
|
||||
var classesIndex = classesindexTemplate.process(classes);
|
||||
IO.saveFile(publish.conf.outDir, "index"+publish.conf.ext, classesIndex);
|
||||
classesindexTemplate = classesIndex = classes = null;
|
||||
|
||||
// create the file index page
|
||||
try {
|
||||
var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
|
||||
}
|
||||
catch(e) { print(e.message); quit(); }
|
||||
|
||||
var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
|
||||
var allFiles = []; // not all files have file-level docs, but we need to list every one
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
|
||||
}
|
||||
|
||||
for (var i = 0; i < documentedFiles.length; i++) {
|
||||
var offset = files.indexOf(documentedFiles[i].alias);
|
||||
allFiles[offset] = documentedFiles[i];
|
||||
}
|
||||
|
||||
allFiles = allFiles.sort(makeSortby("name"));
|
||||
|
||||
// output the file index page
|
||||
var filesIndex = fileindexTemplate.process(allFiles);
|
||||
IO.saveFile(publish.conf.outDir, "files"+publish.conf.ext, filesIndex);
|
||||
fileindexTemplate = filesIndex = files = null;
|
||||
}
|
||||
|
||||
|
||||
/** Just the first sentence (up to a full stop). Should not break on dotted variable names. */
|
||||
function summarize(desc) {
|
||||
if (typeof desc != "undefined")
|
||||
return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc;
|
||||
}
|
||||
|
||||
/** Make a symbol sorter by some attribute. */
|
||||
function makeSortby(attribute) {
|
||||
return function(a, b) {
|
||||
if (a[attribute] != undefined && b[attribute] != undefined) {
|
||||
a = a[attribute].toLowerCase();
|
||||
b = b[attribute].toLowerCase();
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Pull in the contents of an external file at the given path. */
|
||||
function include(path) {
|
||||
var path = publish.conf.templatesDir+path;
|
||||
return IO.readFile(path);
|
||||
}
|
||||
|
||||
/** Turn a raw source file into a code-hilited page in the docs. */
|
||||
function makeSrcFile(path, srcDir, name) {
|
||||
if (JSDOC.opt.s) return;
|
||||
|
||||
if (!name) {
|
||||
name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
|
||||
name = name.replace(/\:/g, "_");
|
||||
}
|
||||
|
||||
var src = {path: path, name:name, charset: IO.encoding, hilited: ""};
|
||||
|
||||
if (defined(JSDOC.PluginManager)) {
|
||||
JSDOC.PluginManager.run("onPublishSrc", src);
|
||||
}
|
||||
|
||||
if (src.hilited) {
|
||||
IO.saveFile(srcDir, name+publish.conf.ext, src.hilited);
|
||||
}
|
||||
}
|
||||
|
||||
/** Build output for displaying function parameters. */
|
||||
function makeSignature(params) {
|
||||
if (!params) return "()";
|
||||
var signature = "("
|
||||
+
|
||||
params.filter(
|
||||
function($) {
|
||||
return $.name.indexOf(".") == -1; // don't show config params in signature
|
||||
}
|
||||
).map(
|
||||
function($) {
|
||||
return $.name;
|
||||
}
|
||||
).join(", ")
|
||||
+
|
||||
")";
|
||||
return signature;
|
||||
}
|
||||
|
||||
/** Find symbol {@link ...} strings in text and turn into html links */
|
||||
function resolveLinks(str, from) {
|
||||
str = str.replace(/\{@link ([^} ]+) ?\}/gi,
|
||||
function(match, symbolName) {
|
||||
return new Link().toSymbol(symbolName);
|
||||
}
|
||||
);
|
||||
|
||||
return str;
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
/* default.css */
|
||||
body
|
||||
{
|
||||
font: 12px "Lucida Grande", Tahoma, Arial, Helvetica, sans-serif;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.header
|
||||
{
|
||||
clear: both;
|
||||
background-color: #ccc;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
padding: 0;
|
||||
margin: 1em 0 0 .3em;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: none 0;
|
||||
border-top: 1px solid #7F8FB1;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
pre.code
|
||||
{
|
||||
display: block;
|
||||
padding: 8px;
|
||||
border: 1px dashed #ccc;
|
||||
}
|
||||
|
||||
#index
|
||||
{
|
||||
margin-top: 24px;
|
||||
float: left;
|
||||
width: 160px;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
background-color: #F3F3F3;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#content
|
||||
{
|
||||
margin-left: 190px;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.classList
|
||||
{
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0 0 0 8px;
|
||||
font-family: arial, sans-serif;
|
||||
font-size: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.classList li
|
||||
{
|
||||
padding: 0;
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.summaryTable { width: 100%; }
|
||||
|
||||
h1.classTitle
|
||||
{
|
||||
font-size:170%;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
h2 { font-size: 110%; }
|
||||
caption, div.sectionTitle
|
||||
{
|
||||
background-color: #7F8FB1;
|
||||
color: #fff;
|
||||
font-size:130%;
|
||||
text-align: left;
|
||||
padding: 2px 6px 2px 6px;
|
||||
border: 1px #7F8FB1 solid;
|
||||
}
|
||||
|
||||
div.sectionTitle { margin-bottom: 8px; }
|
||||
.summaryTable thead { display: none; }
|
||||
|
||||
.summaryTable td
|
||||
{
|
||||
vertical-align: top;
|
||||
padding: 4px;
|
||||
border-bottom: 1px #7F8FB1 solid;
|
||||
border-right: 1px #7F8FB1 solid;
|
||||
}
|
||||
|
||||
/*col#summaryAttributes {}*/
|
||||
.summaryTable td.attributes
|
||||
{
|
||||
border-left: 1px #7F8FB1 solid;
|
||||
width: 140px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.attributes, .fixedFont
|
||||
{
|
||||
line-height: 15px;
|
||||
color: #002EBE;
|
||||
font-family: "Courier New",Courier,monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.summaryTable td.nameDescription
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.summaryTable td.nameDescription, .description
|
||||
{
|
||||
line-height: 15px;
|
||||
padding: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.summaryTable { margin-bottom: 8px; }
|
||||
|
||||
ul.inheritsList
|
||||
{
|
||||
list-style: square;
|
||||
margin-left: 20px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.detailList {
|
||||
margin-left: 20px;
|
||||
line-height: 15px;
|
||||
}
|
||||
.detailList dt { margin-left: 20px; }
|
||||
|
||||
.detailList .heading
|
||||
{
|
||||
font-weight: bold;
|
||||
padding-bottom: 6px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.light, td.attributes, .light a:link, .light a:visited
|
||||
{
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.fineprint
|
||||
{
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<div id="header">
|
||||
</div>
|
||||
@@ -1,19 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>Generated Javascript Documentation</title>
|
||||
</head>
|
||||
<frameset cols="20%,80%">
|
||||
<frame src="allclasses-frame.html" name="packageFrame" />
|
||||
<frame src="splash.html" name="classFrame" />
|
||||
<noframes>
|
||||
<body>
|
||||
<p>
|
||||
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
|
||||
</p>
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
<symbol alias="{+data.alias+}">
|
||||
<name>{+data.name+}</name>
|
||||
<memberOf>{+data.memberOf+}</memberOf>
|
||||
<isStatic>{+data.isStatic+}</isStatic>
|
||||
<isa>{+data.isa+}</isa>
|
||||
<desc>{+data.desc+}</desc>
|
||||
<classDesc>{+data.classDesc+}</classDesc>
|
||||
|
||||
<methods><for each="method" in="data.methods">
|
||||
<method>
|
||||
<name>{+method.name+}</name>
|
||||
<memberOf>{+method.memberOf+}</memberOf>
|
||||
<isStatic>{+method.isStatic+}</isStatic>
|
||||
<desc>{+method.desc+}</desc>
|
||||
<params><for each="param" in="method.params">
|
||||
<param>
|
||||
<type>{+param.type+}</type>
|
||||
<name>{+param.name+}</name>
|
||||
<desc>{+param.desc+}</desc>
|
||||
<defaultValue>{+param.defaultValue+}</defaultValue>
|
||||
</param></for>
|
||||
</params>
|
||||
</method></for>
|
||||
</methods>
|
||||
|
||||
<properties><for each="property" in="data.properties">
|
||||
<property>
|
||||
<name>{+property.name+}</name>
|
||||
<memberOf>{+property.memberOf+}</memberOf>
|
||||
<isStatic>{+property.isStatic+}</isStatic>
|
||||
<desc>{+property.desc+}</desc>
|
||||
<type>{+property.type+}</type>
|
||||
</property></for>
|
||||
</properties>
|
||||
</symbol>
|
||||
5919
jshint/jshint.js
5919
jshint/jshint.js
File diff suppressed because it is too large
Load Diff
@@ -1,99 +0,0 @@
|
||||
var fs = require("fs");
|
||||
var sys = require("sys");
|
||||
var path = require("path");
|
||||
var JSHINT = require("./jshint").JSHINT;
|
||||
|
||||
// DWF TODO: Standardize this?
|
||||
function isExcluded(fullPath) {
|
||||
var fileName = path.basename(fullPath);
|
||||
var excludeFiles = ["json2.js", "jshint.js", "publish.js", "node_suite.js", "jasmine.js", "jasmine-html.js"];
|
||||
for (var i = 0; i < excludeFiles.length; i++) {
|
||||
if (fileName == excludeFiles[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// DWF TODO: This function could/should be re-written
|
||||
function allJasmineJsFiles(rootDir) {
|
||||
var files = [];
|
||||
fs.readdirSync(rootDir).filter(function(filename) {
|
||||
|
||||
var fullPath = rootDir + "/" + filename;
|
||||
if (fs.statSync(fullPath).isDirectory() && !fullPath.match(/pages/)) {
|
||||
var subDirFiles = allJasmineJsFiles(fullPath);
|
||||
if (subDirFiles.length > 0) {
|
||||
files = files.concat();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (fullPath.match(/\.js$/) && !isExcluded(fullPath)) {
|
||||
files.push(fullPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
var jasmineJsFiles = allJasmineJsFiles(".");
|
||||
jasmineJsFiles.reverse(); //cheap way to do the stuff in src stuff first
|
||||
|
||||
var jasmineJsHintConfig = {
|
||||
|
||||
forin:true, //while it's possible that we could be
|
||||
//considering unwanted prototype methods, mostly
|
||||
//we're doing this because the jsobjects are being
|
||||
//used as maps.
|
||||
|
||||
loopfunc:true //we're fine with functions defined inside loops (setTimeout functions, etc)
|
||||
|
||||
};
|
||||
|
||||
var jasmineGlobals = {};
|
||||
|
||||
|
||||
//jasmine.undefined is a jasmine-ism, let's let it go...
|
||||
function removeJasmineUndefinedErrors(errors) {
|
||||
var keepErrors = [];
|
||||
for (var i = 0; i < errors.length; i++) {
|
||||
if (!(errors[i] &&
|
||||
errors[i].raw &&
|
||||
errors[i].evidence &&
|
||||
( errors[i].evidence.match(/jasmine\.undefined/) ||
|
||||
errors[i].evidence.match(/diz be undefined yo/) )
|
||||
)) {
|
||||
keepErrors.push(errors[i]);
|
||||
}
|
||||
}
|
||||
return keepErrors;
|
||||
}
|
||||
|
||||
(function() {
|
||||
var ansi = {
|
||||
green: '\033[32m',
|
||||
red: '\033[31m',
|
||||
yellow: '\033[33m',
|
||||
none: '\033[0m'
|
||||
};
|
||||
|
||||
for (var i = 0; i < jasmineJsFiles.length; i++) {
|
||||
var file = jasmineJsFiles[i];
|
||||
JSHINT(fs.readFileSync(file, "utf8"), jasmineJsHintConfig);
|
||||
var errors = JSHINT.data().errors || [];
|
||||
errors = removeJasmineUndefinedErrors(errors);
|
||||
|
||||
if (errors.length >= 1) {
|
||||
console.log(ansi.red + "Jasmine JSHint failure: " + ansi.none);
|
||||
console.log(file);
|
||||
console.log(errors);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(ansi.green + "Jasmine JSHint PASSED." + ansi.none);
|
||||
})();
|
||||
|
||||
@@ -6,7 +6,7 @@ module Jasmine
|
||||
end
|
||||
|
||||
def js_files
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files
|
||||
end
|
||||
|
||||
SPEC_TYPES = ["core", "html", "node"]
|
||||
@@ -23,6 +23,14 @@ module Jasmine
|
||||
spec_files("node")
|
||||
end
|
||||
|
||||
def boot_files
|
||||
["boot.js"]
|
||||
end
|
||||
|
||||
def boot_dir
|
||||
File.join(path, 'boot')
|
||||
end
|
||||
|
||||
def spec_files(type)
|
||||
raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type)
|
||||
(Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq
|
||||
@@ -31,6 +39,11 @@ module Jasmine
|
||||
def css_files
|
||||
Dir.glob(File.join(path, "*.css")).map { |f| File.basename(f) }
|
||||
end
|
||||
|
||||
def images_dir
|
||||
File.join(File.dirname(__FILE__), '../images')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
131
lib/jasmine-core/boot.js
Normal file
131
lib/jasmine-core/boot.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright (c) 2008-2013 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
// Jasmine boot.js for browser runners - exposes external/global interface, builds the Jasmine environment and executes it.
|
||||
(function() {
|
||||
window.jasmine = jasmineRequire.core(jasmineRequire);
|
||||
jasmineRequire.html(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);
|
||||
},
|
||||
|
||||
pending: function() {
|
||||
return env.pending();
|
||||
},
|
||||
|
||||
addMatchers: function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
clock: env.clock,
|
||||
setTimeout: env.clock.setTimeout,
|
||||
clearTimeout: env.clock.clearTimeout,
|
||||
setInterval: env.clock.setInterval,
|
||||
clearInterval: env.clock.clearInterval,
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
})
|
||||
};
|
||||
|
||||
if (typeof window == "undefined" && typeof exports == "object") {
|
||||
extend(exports, jasmineInterface);
|
||||
} else {
|
||||
extend(window, jasmineInterface);
|
||||
}
|
||||
|
||||
var queryString = new jasmine.QueryString({
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
// TODO: move all of catching to raise so we don't break our brains
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
queryString: queryString,
|
||||
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
env.addReporter(jasmineInterface.jsApiReporter);
|
||||
env.addReporter(htmlReporter);
|
||||
|
||||
var specFilter = new jasmine.HtmlSpecFilter({
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
htmlReporter.initialize();
|
||||
env.execute();
|
||||
};
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
}());
|
||||
109
lib/jasmine-core/boot/boot.js
Normal file
109
lib/jasmine-core/boot/boot.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// Jasmine boot.js for browser runners - exposes external/global interface, builds the Jasmine environment and executes it.
|
||||
(function() {
|
||||
window.jasmine = jasmineRequire.core(jasmineRequire);
|
||||
jasmineRequire.html(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);
|
||||
},
|
||||
|
||||
pending: function() {
|
||||
return env.pending();
|
||||
},
|
||||
|
||||
addMatchers: function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
clock: env.clock,
|
||||
setTimeout: env.clock.setTimeout,
|
||||
clearTimeout: env.clock.clearTimeout,
|
||||
setInterval: env.clock.setInterval,
|
||||
clearInterval: env.clock.clearInterval,
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
})
|
||||
};
|
||||
|
||||
if (typeof window == "undefined" && typeof exports == "object") {
|
||||
extend(exports, jasmineInterface);
|
||||
} else {
|
||||
extend(window, jasmineInterface);
|
||||
}
|
||||
|
||||
var queryString = new jasmine.QueryString({
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
// TODO: move all of catching to raise so we don't break our brains
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
queryString: queryString,
|
||||
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
env.addReporter(jasmineInterface.jsApiReporter);
|
||||
env.addReporter(htmlReporter);
|
||||
|
||||
var specFilter = new jasmine.HtmlSpecFilter({
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
htmlReporter.initialize();
|
||||
env.execute();
|
||||
};
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
}());
|
||||
@@ -1,54 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.1.0.rc1/jasmine_favicon.png">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0.rc1/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine-html.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.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 type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -52,7 +52,7 @@ describe("Player", function() {
|
||||
|
||||
expect(function() {
|
||||
player.resume();
|
||||
}).toThrow("song is already playing");
|
||||
}).toThrowError("song is already playing");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
beforeEach(function() {
|
||||
this.addMatchers({
|
||||
toBePlaying: function(expectedSong) {
|
||||
var player = this.actual;
|
||||
return player.currentlyPlayingSong === expectedSong &&
|
||||
player.isPlaying;
|
||||
}
|
||||
});
|
||||
beforeEach(function () {
|
||||
jasmine.Expectation.addMatchers({
|
||||
toBePlaying: function () {
|
||||
return {
|
||||
compare: function (actual, expected) {
|
||||
var player = actual;
|
||||
|
||||
return {
|
||||
pass: player.currentlyPlayingSong === expected && player.isPlaying
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,190 +1,354 @@
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
/*
|
||||
Copyright (c) 2008-2013 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
jasmineRequire.html = function(j$) {
|
||||
j$.ResultsNode = jasmineRequire.ResultsNode();
|
||||
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
|
||||
j$.QueryString = jasmineRequire.QueryString();
|
||||
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
|
||||
};
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
function HtmlReporter(options) {
|
||||
var env = options.env || {},
|
||||
getContainer = options.getContainer,
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols;
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
this.initialize = function() {
|
||||
htmlReporterMain = createDom("div", {className: "html-reporter"},
|
||||
createDom("div", {className: "banner"},
|
||||
createDom("span", {className: "title"}, "Jasmine"),
|
||||
createDom("span", {className: "version"}, j$.version)
|
||||
),
|
||||
createDom("ul", {className: "symbol-summary"}),
|
||||
createDom("div", {className: "alert"}),
|
||||
createDom("div", {className: "results"},
|
||||
createDom("div", {className: "failures"})
|
||||
)
|
||||
);
|
||||
getContainer().appendChild(htmlReporterMain);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
symbols = find(".symbol-summary");
|
||||
};
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
var totalSpecsDefined;
|
||||
this.jasmineStarted = function(options) {
|
||||
totalSpecsDefined = options.totalSpecsDefined || 0;
|
||||
timer.start();
|
||||
};
|
||||
|
||||
this.startedAt = new Date();
|
||||
var summary = createDom("div", {className: "summary"});
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
var topResults = new j$.ResultsNode({}, "", null),
|
||||
currentParent = topResults;
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
this.suiteStarted = function(result) {
|
||||
currentParent.addChild(result, "suite");
|
||||
currentParent = currentParent.last();
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
this.suiteDone = function(result) {
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentParent = currentParent.parent;
|
||||
};
|
||||
|
||||
this.specStarted = function(result) {
|
||||
currentParent.addChild(result, "spec");
|
||||
};
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
if (result.status != "disabled") {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
symbols.appendChild(createDom("li", {
|
||||
className: result.status,
|
||||
id: "spec_" + result.id,
|
||||
title: result.fullName}
|
||||
));
|
||||
|
||||
if (result.status == "failed") {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom("div", {className: "spec-detail failed"},
|
||||
createDom("a", {className: "description", title: result.fullName, href: specHref(result)}, result.fullName),
|
||||
createDom("div", {className: "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));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
if (result.status == "pending") {
|
||||
pendingSpecCount++;
|
||||
}
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
var banner = find(".banner");
|
||||
banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s"));
|
||||
|
||||
var alert = find(".alert");
|
||||
|
||||
alert.appendChild(createDom("span", { className: "exceptions" },
|
||||
createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
|
||||
createDom("input", {
|
||||
className: "raise",
|
||||
id: "raise-exceptions",
|
||||
type: "checkbox"
|
||||
})
|
||||
));
|
||||
var checkbox = find("input");
|
||||
|
||||
checkbox.checked = !env.catchingExceptions();
|
||||
checkbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
|
||||
alert.appendChild(
|
||||
createDom("span", {className: "bar skipped"},
|
||||
createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
|
||||
)
|
||||
);
|
||||
}
|
||||
var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
|
||||
|
||||
var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
|
||||
alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
|
||||
|
||||
var results = find(".results");
|
||||
results.appendChild(summary);
|
||||
|
||||
summaryList(topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
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"},
|
||||
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type == "spec") {
|
||||
if (domParent.getAttribute("class") != "specs") {
|
||||
specListNode = createDom("ul", {className: "specs"});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom("li", {
|
||||
className: resultNode.result.status,
|
||||
id: "spec-" + resultNode.result.id
|
||||
},
|
||||
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: "menu bar spec-list"},
|
||||
createDom("span", {}, "Spec List | "),
|
||||
createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
|
||||
alert.appendChild(
|
||||
createDom('span', {className: "menu bar failure-list"},
|
||||
createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
|
||||
createDom("span", {}, " | Failures ")));
|
||||
|
||||
find(".failures-menu").onclick = function() {
|
||||
setMenuModeTo('failure-list');
|
||||
};
|
||||
find(".spec-list-menu").onclick = function() {
|
||||
setMenuModeTo('spec-list');
|
||||
};
|
||||
|
||||
setMenuModeTo('failure-list');
|
||||
|
||||
var failureNode = find(".failures");
|
||||
for (var i = 0; i < failures.length; i++) {
|
||||
failureNode.appendChild(failures[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector(selector);
|
||||
}
|
||||
|
||||
function createDom(type, attrs, childrenVarArgs) {
|
||||
var el = createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
function pluralize(singular, count) {
|
||||
var word = (count == 1 ? singular : singular + "s");
|
||||
|
||||
return "" + count + " " + word;
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return "?spec=" + encodeURIComponent(result.fullName);
|
||||
}
|
||||
|
||||
function setMenuModeTo(mode) {
|
||||
htmlReporterMain.setAttribute("class", "html-reporter " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
return HtmlReporter;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
jasmineRequire.HtmlSpecFilter = function() {
|
||||
function HtmlSpecFilter(options) {
|
||||
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
var filterPattern = new RegExp(filterString);
|
||||
|
||||
this.matches = function(specName) {
|
||||
return filterPattern.test(specName);
|
||||
};
|
||||
}
|
||||
|
||||
return HtmlSpecFilter;
|
||||
};
|
||||
|
||||
jasmineRequire.ResultsNode = function() {
|
||||
function ResultsNode(result, type, parent) {
|
||||
this.result = result;
|
||||
this.type = type;
|
||||
this.parent = parent;
|
||||
|
||||
this.children = [];
|
||||
|
||||
this.addChild = function(result, type) {
|
||||
this.children.push(new ResultsNode(result, type, this));
|
||||
};
|
||||
|
||||
this.last = function() {
|
||||
return this.children[this.children.length - 1];
|
||||
};
|
||||
}
|
||||
|
||||
return ResultsNode;
|
||||
};
|
||||
jasmineRequire.QueryString = function() {
|
||||
function QueryString(options) {
|
||||
|
||||
this.setParam = function(key, value) {
|
||||
var paramMap = queryStringToParamMap();
|
||||
paramMap[key] = value;
|
||||
options.getWindowLocation().search = toQueryString(paramMap);
|
||||
};
|
||||
|
||||
this.getParam = function(key) {
|
||||
return queryStringToParamMap()[key];
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function toQueryString(paramMap) {
|
||||
var qStrPairs = [];
|
||||
for (var prop in paramMap) {
|
||||
qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
|
||||
}
|
||||
return "?" + qStrPairs.join('&');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
return this.document.location;
|
||||
};
|
||||
function queryStringToParamMap() {
|
||||
var paramStr = options.getWindowLocation().search.substring(1),
|
||||
params = [],
|
||||
paramMap = {};
|
||||
|
||||
if (paramStr.length > 0) {
|
||||
params = paramStr.split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
var value = decodeURIComponent(p[1]);
|
||||
if (value === "true" || value === "false") {
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
paramMap[decodeURIComponent(p[0])] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
return QueryString;
|
||||
};
|
||||
|
||||
@@ -1,166 +1,54 @@
|
||||
body {
|
||||
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
}
|
||||
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
|
||||
|
||||
|
||||
.jasmine_reporter a:visited, .jasmine_reporter a {
|
||||
color: #303;
|
||||
}
|
||||
|
||||
.jasmine_reporter a:hover, .jasmine_reporter a:active {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.run_spec {
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-size: .8em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jasmine_reporter {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
color: #303;
|
||||
background-color: #fef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
font-size: 1.1em;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.logo .version {
|
||||
font-size: .6em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.runner.running {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
|
||||
.options {
|
||||
text-align: right;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.suite {
|
||||
border: 1px outset gray;
|
||||
margin: 5px 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.suite .suite {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.suite.passed {
|
||||
background-color: #dfd;
|
||||
}
|
||||
|
||||
.suite.failed {
|
||||
background-color: #fdd;
|
||||
}
|
||||
|
||||
.spec {
|
||||
margin: 5px;
|
||||
padding-left: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.spec.failed, .spec.passed, .spec.skipped {
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.spec.failed {
|
||||
background-color: #fbb;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.spec.passed {
|
||||
background-color: #bfb;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.spec.skipped {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.messages {
|
||||
border-left: 1px dashed gray;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.passed {
|
||||
background-color: #cfc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: #fbb;
|
||||
}
|
||||
|
||||
.skipped {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*.resultMessage {*/
|
||||
/*white-space: pre;*/
|
||||
/*}*/
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.resultMessage .mismatch {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
white-space: pre;
|
||||
font-size: .8em;
|
||||
margin-left: 10px;
|
||||
max-height: 5em;
|
||||
overflow: auto;
|
||||
border: 1px inset red;
|
||||
padding: 1em;
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.finished-at {
|
||||
padding-left: 1em;
|
||||
font-size: .6em;
|
||||
}
|
||||
|
||||
.show-passed .passed,
|
||||
.show-skipped .skipped {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#jasmine_content {
|
||||
position:fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.runner {
|
||||
border: 1px solid gray;
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
.html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
|
||||
.html-reporter a { text-decoration: none; }
|
||||
.html-reporter a:hover { text-decoration: underline; }
|
||||
.html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
|
||||
.html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
|
||||
.html-reporter .banner .version { margin-left: 14px; }
|
||||
.html-reporter #jasmine_content { position: fixed; right: 100%; }
|
||||
.html-reporter .version { color: #aaaaaa; }
|
||||
.html-reporter .banner { margin-top: 14px; }
|
||||
.html-reporter .duration { color: #aaaaaa; float: right; }
|
||||
.html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
|
||||
.html-reporter .symbol-summary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
|
||||
.html-reporter .symbol-summary li.passed { font-size: 14px; }
|
||||
.html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
|
||||
.html-reporter .symbol-summary li.failed { line-height: 9px; }
|
||||
.html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
|
||||
.html-reporter .symbol-summary li.disabled { font-size: 14px; }
|
||||
.html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
|
||||
.html-reporter .symbol-summary li.pending { line-height: 17px; }
|
||||
.html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
|
||||
.html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
|
||||
.html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
.html-reporter .bar.failed { background-color: #b03911; }
|
||||
.html-reporter .bar.passed { background-color: #a6b779; }
|
||||
.html-reporter .bar.skipped { background-color: #bababa; }
|
||||
.html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
|
||||
.html-reporter .bar.menu a { color: #333333; }
|
||||
.html-reporter .bar a { color: white; }
|
||||
.html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
|
||||
.html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
|
||||
.html-reporter .running-alert { background-color: #666666; }
|
||||
.html-reporter .results { margin-top: 14px; }
|
||||
.html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
|
||||
.html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
|
||||
.html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
.html-reporter.showDetails .summary { display: none; }
|
||||
.html-reporter.showDetails #details { display: block; }
|
||||
.html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
.html-reporter .summary { margin-top: 14px; }
|
||||
.html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
|
||||
.html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
|
||||
.html-reporter .summary li.passed a { color: #5e7d00; }
|
||||
.html-reporter .summary li.failed a { color: #b03911; }
|
||||
.html-reporter .summary li.pending a { color: #ba9d37; }
|
||||
.html-reporter .description + .suite { margin-top: 0; }
|
||||
.html-reporter .suite { margin-top: 14px; }
|
||||
.html-reporter .suite a { color: #333333; }
|
||||
.html-reporter .failures .spec-detail { margin-bottom: 28px; }
|
||||
.html-reporter .failures .spec-detail .description { display: block; color: white; background-color: #b03911; }
|
||||
.html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
|
||||
.html-reporter .result-message span.result { display: block; }
|
||||
.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #dddddd; background: white; white-space: pre; }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,9 @@
|
||||
#
|
||||
# DO NOT Edit this file. Canonical version of Jasmine lives in the repo's package.json. This file is generated
|
||||
# by a grunt task when the standalone release is built.
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "1.1.0.rc4"
|
||||
VERSION = "2.0.0.rc2"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
13
package.json
Normal file
13
package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "2.0.0-rc2",
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-contrib-jshint": "~0.2.0",
|
||||
"grunt-contrib-concat": "~0.1.3",
|
||||
"grunt-contrib-compass": "~0.1.3",
|
||||
"grunt-contrib-compress": "~0.4.1",
|
||||
"shelljs": "~0.1.2"
|
||||
}
|
||||
}
|
||||
1
pages
1
pages
Submodule pages deleted from a9d577eb45
138
release_notes/20rc1.md
Normal file
138
release_notes/20rc1.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Jasmine Core 2.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
These notes are for RC1 of Jasmine Core 2.0.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
These changes have breaking interface changes and are not backwards compatible with 1.x.
|
||||
|
||||
* New syntax for asynchronous specs
|
||||
* New syntax for spies
|
||||
* New interface for reporters
|
||||
* Better Equality testing
|
||||
* Easier custom matchers
|
||||
* Change to `toThrow` matcher
|
||||
|
||||
### New syntax for asynchronous specs
|
||||
|
||||
Similar to [Mocha][mocha], Jasmine befores, specs, and afters can take an optional "done" callback in order to force asynchronous tests. The next function, whether it's a before, spec or after, will wait until this function is called or if a timeout is reached.
|
||||
|
||||
### New syntax for spies
|
||||
|
||||
Spies have a slightly modified syntax. The ideas came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
|
||||
|
||||
### New interface for reporters
|
||||
|
||||
The reporter interface has changed. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to Jasmine implementation. The full suite execution time is also reported.
|
||||
|
||||
### Better Equality testing
|
||||
|
||||
We have tossed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
|
||||
|
||||
### Easier custom matchers
|
||||
|
||||
Custom matchers have always been possible, but this was barely documented and clunky to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that as custom matchers use. Dogfooding FTW.
|
||||
|
||||
### Change to `toThrow` matcher
|
||||
|
||||
We've changed the behavior of the `toThrow` matcher, moving some functionality to the `toThrowError` matcher. This should allow more of the requested use cases.
|
||||
|
||||
## Other Changes
|
||||
|
||||
* Massive refactoring and better testing
|
||||
* Environment setup now in `boot.js`
|
||||
* Development & Build moved to Grunt
|
||||
* Change in how Jasmine is loaded
|
||||
* Change in how Jasmine is tested
|
||||
* Better node.js support
|
||||
* Better Continuous Integration Environment at Travis
|
||||
* Support matrix updated
|
||||
* Removed JsDoc Pages
|
||||
|
||||
## Massive refactoring and better testing
|
||||
|
||||
This is the biggest set of changes. We've touched nearly every file and every object. We've slammed objects back together and pulled out new extractions. We've made the code more consistently styled. We've improved the tests nearly everywhere.
|
||||
|
||||
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to write, read, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
|
||||
|
||||
## Environment setup now in `boot.js`
|
||||
|
||||
Instantiation and setup of the Jasmine environment, including building reporters, exposing the "global" functions, and executing tests has moved into its own file: `boot.js`. This should make it easier to add custom reporters, configure some objects, or just in general change how you use Jasmine from the outside.
|
||||
|
||||
For example, during development, Jasmine uses it's own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
|
||||
|
||||
## Development & Build moved to Grunt
|
||||
|
||||
We've moved away from Ruby and embraced Node.js and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browser and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
|
||||
|
||||
## Change in how Jasmine is loaded
|
||||
|
||||
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests that add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
|
||||
|
||||
## Change in how Jasmine is tested with Jasmine
|
||||
|
||||
Writing a custom require system helped enforce self-testing - the built `jasmine.js` testing Jasmine from the source directories. Overall this has improved the stability of the code. When you look at Jasmine's tests, you'll see both `jasmine` and `j$` used. The former, `jasmine`, will always be used to test the code from source, which is loaded into the reference `j$`. Please adhere to this pattern when writing tests for contributions.
|
||||
|
||||
## Better node.js support
|
||||
|
||||
Node.js is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official npm is coming.
|
||||
|
||||
## Better Continuous Integration Environment at Travis
|
||||
|
||||
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, Phantom.js, Node.js, and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
|
||||
|
||||
## Support Matrix Updated
|
||||
|
||||
We're dropping support for IE < 8. Jasmine 1.x remains for projects supporting earlier versions of browsers.
|
||||
|
||||
## Removed JsDoc Pages
|
||||
|
||||
Comments in code are lies waiting to happen. Jasmine's JsDoc comments were no exception. The comments were out of date, the generated pages were even more out of date, and frankly they were not helpful. So they're gone.
|
||||
|
||||
Last year saw the posting of the [`introduction.js`][intro] page to document the real, practical interface for projects to use. This page has received a lot of positive feedback so expect more pages like this one.
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
The following Pull Requests were merged:
|
||||
|
||||
* ObjectContaining wrong filed value error message #[394](https://github.com/pivotal/jasmine/issues/394) from albertandrejev
|
||||
* Removed unnecessary parameter from `suiteFactory()` call #[397](https://github.com/pivotal/jasmine/issues/397) from valera-rozuvan
|
||||
* `jasmine.Any` supports `Boolean` #[392](https://github.com/pivotal/jasmine/issues/392) from albertandrejev
|
||||
* Reporters get execution time #[30](https://github.com/pivotal/jasmine/issues/30)
|
||||
* `toThrow` matchers handle falsy exceptions #[317](https://github.com/pivotal/jasmine/issues/371)
|
||||
* Removed deprecated `jasmine.Matchers.pp` #[363](https://github.com/pivotal/jasmine/issues/363) from robinboehm
|
||||
* Fix for Clock ticking to default to 0 #[340](https://github.com/pivotal/jasmine/issues/340) from Caio Cunha
|
||||
* Whitespace failures should be easier to understand #[332](https://github.com/pivotal/jasmine/issues/332) from bjornblomqvist
|
||||
* Fix for more markdown-y image for Build status #[329](https://github.com/pivotal/jasmine/issues/329) from sunliwen
|
||||
* UTF-8 encoding fixes #[333](https://github.com/pivotal/jasmine/issues/333) from bjornblomqvist
|
||||
|
||||
There were several other pull requests that either had already been fixed, or were good starting points for the various changes above. Thank you for all of the hard work to keep Jasmine awesome.
|
||||
|
||||
## Other Bugs & Features
|
||||
|
||||
There were a few small changes and fixes that didn't fit into any of the above categories:
|
||||
|
||||
* HTML Reporter refactored for simplicity and performance
|
||||
* Default character encoding on the HTML runner page is UTF-8
|
||||
* [Escape special regex characters from the spec param](http://www.pivotaltracker.com/story/52731407)
|
||||
* Favicon returns
|
||||
* [Clock supports `eval`'d strings as functions](http://www.pivotaltracker.com/story/40853563)
|
||||
* There should always be stack traces on failures
|
||||
* Removed references to unused `jasmine.VERBOSE`
|
||||
* Removed references to unused `jasmine.XmlHttpRequest`
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
|
||||
|
||||
[mocha]: http://visionmedia.github.io/mocha/
|
||||
[underscore]: http://underscorejs.org/
|
||||
[grunt]: http://gruntjs.com
|
||||
[contrib]: https://github.com/pivotal/jasmine/blob/master/Contribute.markdown
|
||||
[travis]: http://travis-ci.org
|
||||
[travis_jasmine]: http://travis-ci.org/jasmine
|
||||
[sauce]: http://saucelabs.com
|
||||
[node_suite]: https://github.com/pivotal/jasmine/blob/master/spec/node_suite.js
|
||||
[intro]: http://pivotal.github.com/jasmine/
|
||||
@@ -1,451 +1,226 @@
|
||||
describe("ConsoleReporter", function() {
|
||||
//keep these literal. otherwise the test loses value as a test.
|
||||
function green(str) {
|
||||
return '\033[32m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function red(str) {
|
||||
return '\033[31m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function yellow(str) {
|
||||
return '\033[33m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function prefixGreen(str) {
|
||||
return '\033[32m' + str;
|
||||
}
|
||||
|
||||
function prefixRed(str) {
|
||||
return '\033[31m' + str;
|
||||
}
|
||||
|
||||
var newline = "\n";
|
||||
|
||||
var passingSpec = {
|
||||
results: function() {
|
||||
return {
|
||||
passed: function() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
failingSpec = {
|
||||
results: function() {
|
||||
return {
|
||||
passed: function() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
skippedSpec = {
|
||||
results: function() {
|
||||
return {skipped: true};
|
||||
}
|
||||
},
|
||||
passingRun = {
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results: function() {
|
||||
return {failedCount: 0, items_: [null, null, null]};
|
||||
}
|
||||
},
|
||||
failingRun = {
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results: function() {
|
||||
return {
|
||||
failedCount: 7, items_: [null, null, null]};
|
||||
}
|
||||
};
|
||||
|
||||
function repeatedlyInvoke(f, times) {
|
||||
for (var i = 0; i < times; i++) f(times + 1);
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) arr.push(thing);
|
||||
return arr;
|
||||
}
|
||||
|
||||
function simulateRun(reporter, specResults, suiteResults, finalRunner, startTime, endTime) {
|
||||
reporter.reportRunnerStarting();
|
||||
for (var i = 0; i < specResults.length; i++) {
|
||||
reporter.reportSpecResults(specResults[i]);
|
||||
}
|
||||
for (i = 0; i < suiteResults.length; i++) {
|
||||
reporter.reportSuiteResults(suiteResults[i]);
|
||||
}
|
||||
reporter.runnerStartTime = startTime;
|
||||
reporter.now = function() {
|
||||
return endTime;
|
||||
};
|
||||
reporter.reportRunnerResults(finalRunner);
|
||||
}
|
||||
|
||||
var reporter, out, done;
|
||||
var out;
|
||||
|
||||
beforeEach(function() {
|
||||
out = (function() {
|
||||
var output = "";
|
||||
return {
|
||||
print:function(str) {
|
||||
print: function(str) {
|
||||
output += str;
|
||||
},
|
||||
getOutput:function() {
|
||||
getOutput: function() {
|
||||
return output;
|
||||
},
|
||||
clear: function() {
|
||||
output = "";
|
||||
}
|
||||
};
|
||||
})();
|
||||
}());
|
||||
});
|
||||
|
||||
done = false;
|
||||
reporter = new jasmine.ConsoleReporter(out.print, function(runner) {
|
||||
done = true
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
it("starts the provided timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start']),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual(".");
|
||||
});
|
||||
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "disabled"});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "failed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("F");
|
||||
});
|
||||
|
||||
it("reports a pending spec as a '*'", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "pending"});
|
||||
|
||||
expect(out.getOutput()).toEqual("*");
|
||||
});
|
||||
|
||||
it("reports a summary when done (singluar spec and time)", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
timerSpy.elapsed.and.callReturn(1000);
|
||||
|
||||
out.clear();
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/1 spec, 0 failures/);
|
||||
expect(out.getOutput()).not.toMatch(/0 pending specs/);
|
||||
expect(out.getOutput()).toMatch("Finished in 1 second\n");
|
||||
});
|
||||
|
||||
it("reports a summary when done (pluralized specs and seconds)", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.specDone({status: "pending"});
|
||||
reporter.specDone({
|
||||
status: "failed",
|
||||
description: "with a failing spec",
|
||||
fullName: "A suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
passed: false,
|
||||
message: "Expected true to be false.",
|
||||
expected: false,
|
||||
actual: true,
|
||||
stack: "foo\nbar\nbaz"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
out.clear();
|
||||
|
||||
timerSpy.elapsed.and.callReturn(100);
|
||||
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/3 specs, 1 failure, 1 pending spec/);
|
||||
expect(out.getOutput()).toMatch("Finished in 0.1 seconds\n");
|
||||
});
|
||||
|
||||
it("reports a summary when done that includes stack traces for a failing suite", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.specDone({
|
||||
status: "failed",
|
||||
description: "with a failing spec",
|
||||
fullName: "A suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
passed: false,
|
||||
message: "Expected true to be false.",
|
||||
expected: false,
|
||||
actual: true,
|
||||
stack: "foo bar baz"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
out.clear();
|
||||
|
||||
reporter.jasmineDone({});
|
||||
|
||||
expect(out.getOutput()).toMatch(/foo bar baz/);
|
||||
});
|
||||
|
||||
it("calls the onComplete callback when the suite is done", function() {
|
||||
var onComplete = jasmine.createSpy('onComplete'),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
onComplete: onComplete
|
||||
});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
describe('Integration', function() {
|
||||
it("prints the proper output under a pass scenario - small numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 3),
|
||||
[],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777
|
||||
);
|
||||
describe("with color", function() {
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
it("prints the proper output under a pass scenario. large numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 57),
|
||||
[],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777);
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("\033[32m.\033[0m");
|
||||
});
|
||||
|
||||
it("prints the proper output under a failure scenario.", function() {
|
||||
simulateRun(reporter,
|
||||
[failingSpec, passingSpec, failingSpec],
|
||||
[
|
||||
{description:"The oven",
|
||||
results:function() {
|
||||
return {
|
||||
items_:[
|
||||
{failedCount:2,
|
||||
description:"heats up",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one\n second line"}},
|
||||
{trace:{stack:"stack trace two"}}
|
||||
]}
|
||||
]
|
||||
};
|
||||
}},
|
||||
{description:"The washing machine",
|
||||
results:function() {
|
||||
return {
|
||||
items_:[
|
||||
{failedCount:2,
|
||||
description:"washes clothes",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one"}}
|
||||
]}
|
||||
]
|
||||
};
|
||||
}}
|
||||
],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 2
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777);
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/F\.F/);
|
||||
expect(output).toMatch(/The oven heats up\n stack trace one\n second line\n stack trace two/);
|
||||
expect(output).toMatch(/The washing machine washes clothes\n stack trace one/);
|
||||
expect(output).toMatch(/3 specs, 2 failures/);
|
||||
reporter.specDone({status: 'disabled'});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: 'failed'});
|
||||
|
||||
expect(out.getOutput()).toEqual("\033[31mF\033[0m");
|
||||
});
|
||||
});
|
||||
|
||||
describe('When a Jasmine environment executes', function() {
|
||||
beforeEach(function() {
|
||||
reporter.reportRunnerStarting();
|
||||
});
|
||||
|
||||
it("should print 'Started' to the console", function() {
|
||||
expect(out.getOutput()).toEqual("Started" + newline);
|
||||
});
|
||||
|
||||
describe('when a spec reports', function() {
|
||||
beforeEach(function() {
|
||||
out.clear();
|
||||
});
|
||||
|
||||
it("prints a green dot if the spec passes", function() {
|
||||
reporter.reportSpecResults(passingSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/\./);
|
||||
});
|
||||
|
||||
it("prints a red dot if the spec fails", function() {
|
||||
reporter.reportSpecResults(failingSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/F/);
|
||||
});
|
||||
|
||||
it("prints a yellow star if the spec was skipped", function() {
|
||||
reporter.reportSpecResults(skippedSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/\*/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a suite reports', function() {
|
||||
var emptyResults;
|
||||
beforeEach(function() {
|
||||
emptyResults = function() {
|
||||
return {
|
||||
items_:[]
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it("remembers suite results", function() {
|
||||
reporter.reportSuiteResults({description: "Oven", results: emptyResults});
|
||||
reporter.reportSuiteResults({description: "Mixer", results: emptyResults});
|
||||
|
||||
expect(reporter.suiteResults[0].description).toEqual('Oven');
|
||||
expect(reporter.suiteResults[1].description).toEqual('Mixer');
|
||||
});
|
||||
|
||||
it("creates a description out of the current suite and any parent suites", function() {
|
||||
var grandparentSuite = {
|
||||
description: "My house",
|
||||
results: emptyResults
|
||||
};
|
||||
var parentSuite = {
|
||||
description: "kitchen",
|
||||
parentSuite: grandparentSuite,
|
||||
results: emptyResults
|
||||
};
|
||||
reporter.reportSuiteResults({ description: "oven", parentSuite: parentSuite, results: emptyResults });
|
||||
|
||||
expect(reporter.suiteResults[0].description).toEqual("My house kitchen oven");
|
||||
});
|
||||
|
||||
it("gathers failing spec results from the suite - the spec must have a description.", function() {
|
||||
reporter.reportSuiteResults({description:"Oven",
|
||||
results: function() {
|
||||
return {
|
||||
items_:[
|
||||
{ failedCount: 0, description: "specOne" },
|
||||
{ failedCount: 99, description: "specTwo" },
|
||||
{ failedCount: 0, description: "specThree" },
|
||||
{ failedCount: 88, description: "specFour" },
|
||||
{ failedCount: 3 }
|
||||
]
|
||||
};
|
||||
}});
|
||||
|
||||
expect(reporter.suiteResults[0].failedSpecResults).
|
||||
toEqual([
|
||||
{ failedCount: 99, description: "specTwo" },
|
||||
{ failedCount: 88, description: "specFour" }
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('and finishes', function() {
|
||||
|
||||
describe('when reporting spec failure information', function() {
|
||||
|
||||
it("prints suite and spec descriptions together as a sentence", function() {
|
||||
reporter.suiteResults = [
|
||||
{description:"The oven", failedSpecResults:[
|
||||
{description:"heats up", items_:[]},
|
||||
{description:"cleans itself", items_:[]}
|
||||
]},
|
||||
{description:"The mixer", failedSpecResults:[
|
||||
{description:"blends things together", items_:[]}
|
||||
]}
|
||||
];
|
||||
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
|
||||
expect(out.getOutput()).toContain("The oven heats up");
|
||||
expect(out.getOutput()).toContain("The oven cleans itself");
|
||||
expect(out.getOutput()).toContain("The mixer blends things together");
|
||||
});
|
||||
|
||||
it("prints stack trace of spec failure", function() {
|
||||
reporter.suiteResults = [
|
||||
{description:"The oven", failedSpecResults:[
|
||||
{description:"heats up",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one"}},
|
||||
{trace:{stack:"stack trace two"}}
|
||||
]}
|
||||
]}
|
||||
];
|
||||
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
|
||||
expect(out.getOutput()).toContain("The oven heats up");
|
||||
expect(out.getOutput()).toContain("stack trace one");
|
||||
expect(out.getOutput()).toContain("stack trace two");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when reporting the execution time', function() {
|
||||
|
||||
it("prints the full finished message", function() {
|
||||
reporter.now = function() {
|
||||
return 1000;
|
||||
};
|
||||
reporter.reportRunnerStarting();
|
||||
reporter.now = function() {
|
||||
return 1777;
|
||||
};
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
expect(out.getOutput()).toContain("Finished in 0.777 seconds");
|
||||
});
|
||||
|
||||
it("prints round time numbers correctly", function() {
|
||||
function run(startTime, endTime) {
|
||||
out.clear();
|
||||
reporter.runnerStartTime = startTime;
|
||||
reporter.now = function() {
|
||||
return endTime;
|
||||
};
|
||||
reporter.reportRunnerResults(passingRun);
|
||||
}
|
||||
|
||||
run(1000, 11000);
|
||||
expect(out.getOutput()).toContain("10 seconds");
|
||||
|
||||
run(1000, 2000);
|
||||
expect(out.getOutput()).toContain("1 seconds");
|
||||
|
||||
run(1000, 1100);
|
||||
expect(out.getOutput()).toContain("0.1 seconds");
|
||||
|
||||
run(1000, 1010);
|
||||
expect(out.getOutput()).toContain("0.01 seconds");
|
||||
|
||||
run(1000, 1001);
|
||||
expect(out.getOutput()).toContain("0.001 seconds");
|
||||
});
|
||||
});
|
||||
|
||||
describe("when reporting the results summary", function() {
|
||||
it("prints statistics in green if there were no failures", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("3 specs, 0 failures");
|
||||
});
|
||||
|
||||
it("prints statistics in red if there was a failure", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 3};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("3 specs, 3 failures");
|
||||
});
|
||||
|
||||
it("handles pluralization with 1's ones appropriately", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null], totalCount: 1, failedCount: 1};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("1 spec, 1 failure");
|
||||
});
|
||||
});
|
||||
|
||||
describe("done callback", function() {
|
||||
it("calls back when done", function() {
|
||||
expect(done).toBeFalsy();
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
|
||||
}
|
||||
});
|
||||
expect(done).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
45
spec/core/AnySpec.js
Normal file
45
spec/core/AnySpec.js
Normal file
@@ -0,0 +1,45 @@
|
||||
describe("Any", function() {
|
||||
it("matches a string", function() {
|
||||
var any = new j$.Any(String);
|
||||
|
||||
expect(any.jasmineMatches("foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a number", function() {
|
||||
var any = new j$.Any(Number);
|
||||
|
||||
expect(any.jasmineMatches(1)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a function", function() {
|
||||
var any = new j$.Any(Function);
|
||||
|
||||
expect(any.jasmineMatches(function(){})).toBe(true);
|
||||
});
|
||||
|
||||
it("matches an Object", function() {
|
||||
var any = new j$.Any(Object);
|
||||
|
||||
expect(any.jasmineMatches({})).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Boolean", function() {
|
||||
var any = new j$.Any(Boolean);
|
||||
|
||||
expect(any.jasmineMatches(true)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches another constructed object", function() {
|
||||
var Thing = function() {},
|
||||
any = new j$.Any(Thing);
|
||||
|
||||
expect(any.jasmineMatches(new Thing())).toBe(true);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var any = new j$.Any(Number);
|
||||
|
||||
expect(any.jasmineToString()).toMatch('<jasmine.any');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
describe("base.js", function() {
|
||||
describe("jasmine.MessageResult", function() {
|
||||
it("#toString should pretty-print and concatenate each part of the message", function() {
|
||||
var values = ["log", "message", 123, {key: "value"}, "FTW!"];
|
||||
var messageResult = new jasmine.MessageResult(values);
|
||||
expect(messageResult.toString()).toEqual("log message 123 { key : 'value' } FTW!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("jasmine.log", function() {
|
||||
it("should accept n arguments", function() {
|
||||
spyOn(jasmine.getEnv().currentSpec, 'log');
|
||||
jasmine.log(1, 2, 3);
|
||||
expect(jasmine.getEnv().currentSpec.log).toHaveBeenCalledWith(1, 2, 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("jasmine.getGlobal", function() {
|
||||
it("should return the global object", function() {
|
||||
var globalObject = (function() {
|
||||
return this;
|
||||
})();
|
||||
|
||||
expect(jasmine.getGlobal()).toBe(globalObject);
|
||||
});
|
||||
});
|
||||
});
|
||||
105
spec/core/CallTrackerSpec.js
Normal file
105
spec/core/CallTrackerSpec.js
Normal file
@@ -0,0 +1,105 @@
|
||||
describe("CallTracker", function() {
|
||||
it("tracks that it was called when executed", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.any()).toBe(false);
|
||||
|
||||
callTracker.track();
|
||||
|
||||
expect(callTracker.any()).toBe(true);
|
||||
});
|
||||
|
||||
it("tracks that number of times that it is executed", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.count()).toEqual(0);
|
||||
|
||||
callTracker.track();
|
||||
|
||||
expect(callTracker.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("tracks the params from each execution", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: void 0, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
|
||||
expect(callTracker.argsFor(1)).toEqual([0, "foo"]);
|
||||
});
|
||||
|
||||
it("returns any empty array when there was no call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
});
|
||||
|
||||
it("allows access for the arguments for all calls", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.allArgs()).toEqual([[], [0, "foo"]]);
|
||||
});
|
||||
|
||||
it("tracks the context and arguments for each call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.all()[0]).toEqual({object: {}, args: []});
|
||||
|
||||
expect(callTracker.all()[1]).toEqual({object: {}, args: [0, "foo"]});
|
||||
});
|
||||
|
||||
it("simplifies access to the arguments for the last (most recent) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track();
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.mostRecent()).toEqual({
|
||||
object: {},
|
||||
args: [0, "foo"]
|
||||
});
|
||||
});
|
||||
|
||||
it("returns a useful falsy value when there isn't a last (most recent) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.mostRecent()).toBeFalsy();
|
||||
});
|
||||
|
||||
it("simplifies access to the arguments for the first (oldest) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.first()).toEqual({object: {}, args: [0, "foo"]})
|
||||
});
|
||||
|
||||
it("returns a useful falsy value when there isn't a first (oldest) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.first()).toBeFalsy();
|
||||
});
|
||||
|
||||
|
||||
it("allows the tracking to be reset", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track();
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.reset();
|
||||
|
||||
expect(callTracker.any()).toBe(false);
|
||||
expect(callTracker.count()).toEqual(0);
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
expect(callTracker.all()).toEqual([]);
|
||||
expect(callTracker.mostRecent()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
314
spec/core/ClockSpec.js
Normal file
314
spec/core/ClockSpec.js
Normal file
@@ -0,0 +1,314 @@
|
||||
describe("Clock", function() {
|
||||
|
||||
it("calls the global setTimeout directly if Clock is not installed", function() {
|
||||
var setTimeout = jasmine.createSpy('setTimeout'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
|
||||
global = { setTimeout: setTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
expect(setTimeout).toHaveBeenCalledWith(delayedFn, 0);
|
||||
});
|
||||
|
||||
it("schedules the delayed function with the fake timer", function() {
|
||||
var setTimeout = jasmine.createSpy('setTimeout'),
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction'),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
global = { setTimeout: setTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn, 0, 'a', 'b');
|
||||
|
||||
expect(setTimeout).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
|
||||
});
|
||||
|
||||
it("returns an id for the delayed function", function() {
|
||||
var setTimeout = jasmine.createSpy('setTimeout'),
|
||||
scheduleId = 123,
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction').and.callReturn(scheduleId),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
global = { setTimeout: setTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler),
|
||||
timeoutId;
|
||||
|
||||
clock.install();
|
||||
timeoutId = clock.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(timeoutId).toEqual(123);
|
||||
});
|
||||
|
||||
it("calls the global clearTimeout directly if Clock is not installed", function() {
|
||||
var clearTimeout = jasmine.createSpy('clearTimeout'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
|
||||
global = { clearTimeout: clearTimeout },
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.clearTimeout(123);
|
||||
|
||||
expect(clearTimeout).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
it("clears the scheduled function with the scheduler", function() {
|
||||
var clearTimeout = jasmine.createSpy('clearTimeout'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
|
||||
global = { setTimeout: clearTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
clock.clearTimeout(123);
|
||||
|
||||
expect(clearTimeout).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
it("calls the global setInterval directly if Clock is not installed", function() {
|
||||
var setInterval = jasmine.createSpy('setInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
|
||||
global = { setInterval: setInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.setInterval(delayedFn, 0);
|
||||
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
expect(setInterval).toHaveBeenCalledWith(delayedFn, 0);
|
||||
});
|
||||
|
||||
it("schedules the delayed function with the fake timer", function() {
|
||||
var setInterval = jasmine.createSpy('setInterval'),
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction'),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
global = { setInterval: setInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
clock.setInterval(delayedFn, 0, 'a', 'b');
|
||||
|
||||
expect(setInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
|
||||
});
|
||||
|
||||
it("returns an id for the delayed function", function() {
|
||||
var setInterval = jasmine.createSpy('setInterval'),
|
||||
scheduleId = 123,
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction').and.callReturn(scheduleId),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
global = { setInterval: setInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler),
|
||||
intervalId;
|
||||
|
||||
clock.install();
|
||||
intervalId = clock.setInterval(delayedFn, 0);
|
||||
|
||||
expect(intervalId).toEqual(123);
|
||||
});
|
||||
|
||||
it("calls the global clearInterval directly if Clock is not installed", function() {
|
||||
var clearInterval = jasmine.createSpy('clearInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearInterval']),
|
||||
global = { clearInterval: clearInterval },
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.clearInterval(123);
|
||||
|
||||
expect(clearInterval).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
it("clears the scheduled function with the scheduler", function() {
|
||||
var clearInterval = jasmine.createSpy('clearInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
|
||||
global = { setInterval: clearInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
clock.clearInterval(123);
|
||||
|
||||
expect(clearInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
it("gives you a friendly reminder if the Clock is not installed and you tick", function() {
|
||||
var clock = new j$.Clock({}, jasmine.createSpyObj('delayedFunctionScheduler', ['tick']));
|
||||
expect(function() {
|
||||
clock.tick(50);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("can be uninstalled", function() {
|
||||
var setTimeout = jasmine.createSpy('setTimeout'),
|
||||
setInterval = jasmine.createSpy('setInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction', 'tick', 'reset']),
|
||||
global = { setTimeout: setTimeout, setInterval: setInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn, 0);
|
||||
expect(setTimeout).not.toHaveBeenCalled();
|
||||
|
||||
clock.setInterval(delayedFn, 0);
|
||||
expect(setInterval).not.toHaveBeenCalled();
|
||||
|
||||
expect(function() {
|
||||
clock.tick(0);
|
||||
}).not.toThrow();
|
||||
|
||||
clock.uninstall();
|
||||
|
||||
expect(delayedFunctionScheduler.reset).toHaveBeenCalled();
|
||||
|
||||
clock.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(setTimeout).toHaveBeenCalled();
|
||||
|
||||
clock.setInterval(delayedFn, 0);
|
||||
expect(setInterval).toHaveBeenCalled();
|
||||
|
||||
expect(function() {
|
||||
clock.tick(0);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
|
||||
it("on IE < 9, fails if extra args are passed to fake clock", function() {
|
||||
//fail, because this would break in IE9.
|
||||
var setTimeout = jasmine.createSpy('setTimeout'),
|
||||
setInterval = jasmine.createSpy('setInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
global = { setTimeout: setTimeout, setInterval: setInterval },
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
setTimeout.apply = null;
|
||||
setInterval.apply = null;
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.setTimeout(fn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, []);
|
||||
expect(function() {
|
||||
clock.setTimeout(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
|
||||
clock.setInterval(fn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true);
|
||||
expect(function() {
|
||||
clock.setInterval(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Clock (acceptance)", function() {
|
||||
it("can run setTimeouts/setIntervals synchronously", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFn3 = jasmine.createSpy('delayedFn3'),
|
||||
recurring1 = jasmine.createSpy('recurring1'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.setTimeout(delayedFn1, 0, 'some', 'arg');
|
||||
var intervalId = clock.setInterval(recurring1, 50, 'some', 'other', 'args');
|
||||
clock.setTimeout(delayedFn2, 100);
|
||||
clock.setTimeout(delayedFn3, 200);
|
||||
|
||||
expect(delayedFn1).not.toHaveBeenCalled();
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(0);
|
||||
|
||||
expect(delayedFn1).toHaveBeenCalledWith('some', 'arg');
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(recurring1).toHaveBeenCalledWith('some', 'other', 'args');
|
||||
expect(recurring1.calls.count()).toBe(1);
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(recurring1.calls.count()).toBe(2);
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(recurring1.calls.count()).toBe(4);
|
||||
expect(delayedFn3).toHaveBeenCalled();
|
||||
|
||||
clock.clearInterval(intervalId);
|
||||
clock.tick(50);
|
||||
|
||||
expect(recurring1.calls.count()).toBe(4);
|
||||
});
|
||||
|
||||
it("can clear a previously set timeout", function() {
|
||||
var clearedFn = jasmine.createSpy('clearedFn'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler),
|
||||
timeoutId;
|
||||
|
||||
clock.install();
|
||||
|
||||
timeoutId = clock.setTimeout(clearedFn, 100);
|
||||
expect(clearedFn).not.toHaveBeenCalled();
|
||||
|
||||
clock.clearTimeout(timeoutId);
|
||||
clock.tick(100);
|
||||
|
||||
expect(clearedFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("correctly schedules functions after the Clock has advanced", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
clock = new j$.Clock({setTimeout: function(){}}, delayedFunctionScheduler);
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.tick(100);
|
||||
clock.setTimeout(delayedFn1, 10, ['some', 'arg']);
|
||||
clock.tick(5);
|
||||
expect(delayedFn1).not.toHaveBeenCalled();
|
||||
clock.tick(5);
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls the global clearTimeout correctly when not installed", function () {
|
||||
var delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
|
||||
global = jasmine.getGlobal(),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
expect(function() {
|
||||
clock.clearTimeout(123)
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("calls the global clearTimeout correctly when not installed", function () {
|
||||
var delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
|
||||
global = jasmine.getGlobal(),
|
||||
clock = new j$.Clock(global, delayedFunctionScheduler);
|
||||
|
||||
expect(function() {
|
||||
clock.clearInterval(123)
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
@@ -1,97 +1,96 @@
|
||||
describe("Custom Matchers", function() {
|
||||
var env;
|
||||
var fakeTimer;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
});
|
||||
|
||||
it("should be easy to add more matchers local to a spec, suite, etc.", function() {
|
||||
var spec1, spec2, spec1Matcher, spec2Matcher;
|
||||
var suite = env.describe('some suite', function() {
|
||||
env.beforeEach(function() {
|
||||
this.addMatchers({
|
||||
matcherForSuite: function(expected) {
|
||||
this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
spec1 = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({
|
||||
matcherForSpec: function(expected) {
|
||||
this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
spec1Matcher = this.expect("xxx");
|
||||
});
|
||||
|
||||
spec2 = env.it('spec with failing expectation').runs(function () {
|
||||
spec2Matcher = this.expect("yyy");
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
|
||||
spec1Matcher.matcherForSuite("expected");
|
||||
expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
|
||||
spec1Matcher.matcherForSpec("expected");
|
||||
expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
|
||||
|
||||
spec2Matcher.matcherForSuite("expected");
|
||||
expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
|
||||
expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
|
||||
});
|
||||
|
||||
it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() {
|
||||
var spec;
|
||||
var suite = env.describe('some suite', function() {
|
||||
spec = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({
|
||||
toBeTrue: function() {
|
||||
return this.actual === true;
|
||||
}
|
||||
});
|
||||
this.expect(true).toBeTrue();
|
||||
this.expect(false).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var passResult = new jasmine.ExpectationResult({passed: true, matcherName: 'toBeTrue',
|
||||
actual: true, expected: jasmine.undefined, message: "Passed." });
|
||||
var failResult = new jasmine.ExpectationResult({passed: false, matcherName: 'toBeTrue',
|
||||
actual: false, expected: jasmine.undefined, message: "Expected false to be true." });
|
||||
failResult.trace = jasmine.any(Object);
|
||||
expect(spec.results().getItems()).toEqual([passResult, failResult]);
|
||||
});
|
||||
|
||||
it("should pass args", function() {
|
||||
var matcherCallArgs = [];
|
||||
var spec;
|
||||
var suite = env.describe('some suite', function() {
|
||||
spec = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({
|
||||
toBeTrue: function() {
|
||||
matcherCallArgs.push(jasmine.util.argsToArray(arguments));
|
||||
return this.actual === true;
|
||||
}
|
||||
});
|
||||
this.expect(true).toBeTrue();
|
||||
this.expect(false).toBeTrue('arg');
|
||||
this.expect(true).toBeTrue('arg1', 'arg2');
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var results = spec.results().getItems();
|
||||
expect(results[0].expected).toEqual(jasmine.undefined);
|
||||
expect(results[1].expected).toEqual('arg');
|
||||
expect(results[2].expected).toEqual(['arg1', 'arg2']);
|
||||
|
||||
expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]);
|
||||
});
|
||||
});
|
||||
////TODO: matchers should be add-able to the env, not to the spec.
|
||||
//describe("Custom Matchers", function() {
|
||||
// var env;
|
||||
// var fakeTimer;
|
||||
//
|
||||
// beforeEach(function() {
|
||||
// env = new jasmine.Env();
|
||||
// env.updateInterval = 0;
|
||||
// });
|
||||
//
|
||||
// it("should be easy to add more matchers local to a spec, suite, etc.", function() {
|
||||
// var spec1, spec2, spec1Matcher, spec2Matcher;
|
||||
// var suite = env.describe('some suite', function() {
|
||||
// env.beforeEach(function() {
|
||||
// this.addMatchers({
|
||||
// matcherForSuite: function(expected) {
|
||||
// this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// spec1 = env.it('spec with an expectation').runs(function () {
|
||||
// this.addMatchers({
|
||||
// matcherForSpec: function(expected) {
|
||||
// this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
// spec1Matcher = this.expect("xxx");
|
||||
// });
|
||||
//
|
||||
// spec2 = env.it('spec with failing expectation').runs(function () {
|
||||
// spec2Matcher = this.expect("yyy");
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// suite.execute();
|
||||
//
|
||||
// spec1Matcher.matcherForSuite("expected");
|
||||
// expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
|
||||
// spec1Matcher.matcherForSpec("expected");
|
||||
// expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
|
||||
//
|
||||
// spec2Matcher.matcherForSuite("expected");
|
||||
// expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
|
||||
// expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
|
||||
// });
|
||||
//
|
||||
// it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() {
|
||||
// var spec;
|
||||
// var suite = env.describe('some suite', function() {
|
||||
// spec = env.it('spec with an expectation').runs(function () {
|
||||
// this.addMatchers({
|
||||
// toBeTrue: function() {
|
||||
// return this.actual === true;
|
||||
// }
|
||||
// });
|
||||
// this.expect(true).toBeTrue();
|
||||
// this.expect(false).toBeTrue();
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// suite.execute();
|
||||
//
|
||||
// var results = spec.results().getItems();
|
||||
// expect(results[0].message).toEqual("Passed.");
|
||||
// expect(results[1].message).toEqual("Expected false to be true.");
|
||||
// });
|
||||
//
|
||||
// it("should pass args", function() {
|
||||
// var matcherCallArgs = [];
|
||||
// var spec;
|
||||
// var suite = env.describe('some suite', function() {
|
||||
// spec = env.it('spec with an expectation').runs(function () {
|
||||
// this.addMatchers({
|
||||
// toBeTrue: function() {
|
||||
// matcherCallArgs.push(jasmine.util.argsToArray(arguments));
|
||||
// return this.actual === true;
|
||||
// }
|
||||
// });
|
||||
// this.expect(true).toBeTrue();
|
||||
// this.expect(false).toBeTrue('arg');
|
||||
// this.expect(true).toBeTrue('arg1', 'arg2');
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// suite.execute();
|
||||
// var results = spec.results().getItems();
|
||||
// expect(results[0].expected).toEqual(jasmine.undefined);
|
||||
// expect(results[1].expected).toEqual('arg');
|
||||
// expect(results[2].expected).toEqual(['arg1', 'arg2']);
|
||||
//
|
||||
// expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]);
|
||||
// });
|
||||
//});
|
||||
|
||||
179
spec/core/DelayedFunctionSchedulerSpec.js
Normal file
179
spec/core/DelayedFunctionSchedulerSpec.js
Normal file
@@ -0,0 +1,179 @@
|
||||
describe("DelayedFunctionScheduler", function() {
|
||||
it("schedules a function for later execution", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules a string for later execution", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
strfn = "horrible = true;";
|
||||
|
||||
scheduler.scheduleFunction(strfn, 0);
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(horrible).toEqual(true);
|
||||
});
|
||||
|
||||
it("#tick defaults to 0", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick();
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("defaults delay to 0", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("optionally passes params to scheduled functions", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0, ['foo', 'bar']);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).toHaveBeenCalledWith('foo', 'bar');
|
||||
});
|
||||
|
||||
it("scheduled fns can optionally reoccur", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 20, [], true);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(20);
|
||||
|
||||
expect(fn.calls.count()).toBe(1);
|
||||
|
||||
scheduler.tick(40);
|
||||
|
||||
expect(fn.calls.count()).toBe(3);
|
||||
|
||||
scheduler.tick(21);
|
||||
|
||||
expect(fn.calls.count()).toBe(4);
|
||||
|
||||
});
|
||||
|
||||
it("increments scheduled fns ids unless one is passed", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler();
|
||||
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0)).toBe(1);
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0)).toBe(2);
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0, [], false, 123)).toBe(123);
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0)).toBe(3);
|
||||
});
|
||||
|
||||
it("#removeFunctionWithId removes a previously scheduled function with a given id", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
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'),
|
||||
recurringCallCount = 0,
|
||||
recurring = jasmine.createSpy('recurring').and.callFake(function() {
|
||||
recurringCallCount++;
|
||||
if (recurringCallCount < 5) {
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
scheduler.scheduleFunction(fn, 50);
|
||||
|
||||
scheduler.tick(60);
|
||||
|
||||
expect(recurring).toHaveBeenCalled();
|
||||
expect(recurring.calls.count()).toBe(6);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
describe("jasmine.Env", function() {
|
||||
// TODO: Fix these unit tests!
|
||||
describe("Env", function() {
|
||||
var env;
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env = new j$.Env();
|
||||
env.updateInterval = 0;
|
||||
});
|
||||
|
||||
describe('ids', function () {
|
||||
it('nextSpecId should return consecutive integers, starting at 0', function () {
|
||||
describe('ids', function() {
|
||||
it('nextSpecId should return consecutive integers, starting at 0', function() {
|
||||
expect(env.nextSpecId()).toEqual(0);
|
||||
expect(env.nextSpecId()).toEqual(1);
|
||||
expect(env.nextSpecId()).toEqual(2);
|
||||
@@ -17,143 +18,494 @@ describe("jasmine.Env", function() {
|
||||
var fakeReporter;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeReporter = jasmine.createSpyObj("fakeReporter", ["log"]);
|
||||
});
|
||||
|
||||
describe('version', function () {
|
||||
var oldVersion;
|
||||
|
||||
beforeEach(function () {
|
||||
oldVersion = jasmine.version_;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
jasmine.version_ = oldVersion;
|
||||
});
|
||||
|
||||
it('should raise an error if version is not set', function () {
|
||||
jasmine.version_ = null;
|
||||
var exception;
|
||||
try {
|
||||
env.version();
|
||||
}
|
||||
catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
expect(exception.message).toEqual('Version not set');
|
||||
});
|
||||
|
||||
it("version should return the current version as an int", function() {
|
||||
jasmine.version_ = {
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"revision": 8
|
||||
};
|
||||
expect(env.version()).toEqual({
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"revision": 8
|
||||
});
|
||||
});
|
||||
|
||||
describe("versionString", function() {
|
||||
it("should return a stringified version number", function() {
|
||||
jasmine.version_ = {
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"release_candidate": "1",
|
||||
"revision": 8
|
||||
};
|
||||
expect(env.versionString()).toEqual("1.9.7.rc1 revision 8");
|
||||
});
|
||||
|
||||
it("should return a nice string when version is unknown", function() {
|
||||
jasmine.version_ = null;
|
||||
expect(env.versionString()).toEqual("version unknown");
|
||||
});
|
||||
});
|
||||
fakeReporter = jasmine.createSpyObj("fakeReporter", ["jasmineStarted"]);
|
||||
});
|
||||
|
||||
it("should allow reporters to be registered", function() {
|
||||
env.addReporter(fakeReporter);
|
||||
env.reporter.log("message");
|
||||
expect(fakeReporter.log).toHaveBeenCalledWith("message");
|
||||
env.reporter.jasmineStarted();
|
||||
expect(fakeReporter.jasmineStarted).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('removes all spies when env is executed', function(done) {
|
||||
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 existance of the object", function() {
|
||||
expect(function() {
|
||||
env.spyOn(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it("checks for the existance 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; } };
|
||||
|
||||
originalFunc = subject.spiedFunc;
|
||||
|
||||
var spy = env.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
|
||||
expect(subject.spiedFunc.calls.any()).toEqual(false);
|
||||
expect(subject.spiedFunc.calls.count()).toEqual(0);
|
||||
|
||||
subject.spiedFunc('foo');
|
||||
|
||||
expect(subject.spiedFunc.calls.any()).toEqual(true);
|
||||
expect(subject.spiedFunc.calls.count()).toEqual(1);
|
||||
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['foo']);
|
||||
expect(subject.spiedFunc.calls.mostRecent().object).toEqual(subject);
|
||||
expect(originalFunctionWasCalled).toEqual(false);
|
||||
|
||||
subject.spiedFunc('bar');
|
||||
expect(subject.spiedFunc.calls.count()).toEqual(2);
|
||||
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['bar']);
|
||||
});
|
||||
});
|
||||
|
||||
describe("equality testing", function() {
|
||||
describe("with custom equality testers", function() {
|
||||
var aObj, bObj, isEqual;
|
||||
describe("#catchException", function() {
|
||||
it("returns true if the exception is a pending spec exception", function() {
|
||||
env.catchExceptions(false);
|
||||
|
||||
beforeEach(function() {
|
||||
env.addEqualityTester(function(a, b) {
|
||||
aObj = a;
|
||||
bObj = b;
|
||||
return isEqual;
|
||||
});
|
||||
expect(env.catchException(new Error(j$.Spec.pendingSpecExceptionMessage))).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false if the exception is not a pending spec exception and not catching exceptions", function() {
|
||||
env.catchExceptions(false);
|
||||
|
||||
expect(env.catchException(new Error("external error"))).toBe(false);
|
||||
expect(env.catchException(new Error(j$.Spec.pendingSpecExceptionMessage))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#pending", function() {
|
||||
it("throws the Pending Spec exception", function() {
|
||||
expect(function() {
|
||||
env.pending();
|
||||
}).toThrow(j$.Spec.pendingSpecExceptionMessage);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// TODO: move these into a separate file
|
||||
describe("Env integration", function() {
|
||||
|
||||
it("Suites execute as expected (no nesting)", function(done) {
|
||||
var env = new j$.Env(),
|
||||
calls = [];
|
||||
|
||||
var assertions = function() {
|
||||
expect(calls).toEqual([
|
||||
"with a spec",
|
||||
"and another spec"
|
||||
]);
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions});
|
||||
|
||||
env.describe("A Suite", function() {
|
||||
env.it("with a spec", function() {
|
||||
calls.push("with a spec");
|
||||
});
|
||||
|
||||
it("should call the custom equality tester with two objects for comparison", function() {
|
||||
env.equals_("1", "2");
|
||||
expect(aObj).toEqual("1");
|
||||
expect(bObj).toEqual("2");
|
||||
});
|
||||
|
||||
describe("when the custom equality tester returns false", function() {
|
||||
beforeEach(function() {
|
||||
isEqual = false;
|
||||
});
|
||||
|
||||
it("should give custom equality testers precedence", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeFalsy();
|
||||
var o = {};
|
||||
expect(env.equals_(o, o)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("when the custom equality tester returns true", function() {
|
||||
beforeEach(function() {
|
||||
isEqual = true;
|
||||
});
|
||||
|
||||
it("should give custom equality testers precedence", function() {
|
||||
expect(env.equals_('abc', 'def')).toBeTruthy();
|
||||
expect(env.equals_(true, false)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the custom equality tester returns undefined", function() {
|
||||
beforeEach(function() {
|
||||
isEqual = jasmine.undefined;
|
||||
});
|
||||
|
||||
it("should use normal equality rules", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeTruthy();
|
||||
expect(env.equals_('abc', 'def')).toBeFalsy();
|
||||
});
|
||||
|
||||
describe("even if there are several", function() {
|
||||
beforeEach(function() {
|
||||
env.addEqualityTester(function(a, b) { return jasmine.undefined; });
|
||||
env.addEqualityTester(function(a, b) { return jasmine.undefined; });
|
||||
});
|
||||
|
||||
it("should use normal equality rules", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeTruthy();
|
||||
expect(env.equals_('abc', 'def')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should evaluate custom equality testers in the order they are declared", function() {
|
||||
isEqual = false;
|
||||
env.addEqualityTester(function(a, b) { return true; });
|
||||
expect(env.equals_('abc', 'abc')).toBeFalsy();
|
||||
env.it("and another spec", function() {
|
||||
calls.push("and another spec");
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Nested Suites execute as expected", function(done) {
|
||||
var env = new j$.Env(),
|
||||
calls = [];
|
||||
|
||||
var assertions = function() {
|
||||
expect(calls).toEqual([
|
||||
'an outer spec',
|
||||
'an inner spec',
|
||||
'another inner spec'
|
||||
]);
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
|
||||
env.describe("Outer suite", function() {
|
||||
env.it("an outer spec", function() {
|
||||
calls.push('an outer spec')
|
||||
});
|
||||
env.describe("Inner suite", function() {
|
||||
env.it("an inner spec", function() {
|
||||
calls.push('an inner spec');
|
||||
});
|
||||
env.it("another inner spec", function() {
|
||||
calls.push('another inner spec');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Multiple top-level Suites execute as expected", function(done) {
|
||||
var env = new j$.Env(),
|
||||
calls = [];
|
||||
|
||||
var assertions = function() {
|
||||
expect(calls).toEqual([
|
||||
'an outer spec',
|
||||
'an inner spec',
|
||||
'another inner spec',
|
||||
'a 2nd outer spec'
|
||||
]);
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
|
||||
|
||||
env.describe("Outer suite", function() {
|
||||
env.it("an outer spec", function() {
|
||||
calls.push('an outer spec')
|
||||
});
|
||||
env.describe("Inner suite", function() {
|
||||
env.it("an inner spec", function() {
|
||||
calls.push('an inner spec');
|
||||
});
|
||||
env.it("another inner spec", function() {
|
||||
calls.push('another inner spec');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.describe("Another outer suite", function() {
|
||||
env.it("a 2nd outer spec", function() {
|
||||
calls.push('a 2nd outer spec')
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Mock clock can be installed and used in tests", function(done) {
|
||||
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
|
||||
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
|
||||
delayedFunctionForMockClock = jasmine.createSpy('delayedFunctionForMockClock'),
|
||||
env = new j$.Env({global: { setTimeout: globalSetTimeout }});
|
||||
|
||||
var assertions = function() {
|
||||
expect(delayedFunctionForMockClock).toHaveBeenCalled();
|
||||
expect(globalSetTimeout).toHaveBeenCalledWith(delayedFunctionForGlobalClock, 100);
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
|
||||
env.describe("tests", function() {
|
||||
env.it("test with mock clock", function() {
|
||||
env.clock.install();
|
||||
env.clock.setTimeout(delayedFunctionForMockClock, 100);
|
||||
env.clock.tick(100);
|
||||
});
|
||||
env.it("test without mock clock", function() {
|
||||
env.clock.setTimeout(delayedFunctionForGlobalClock, 100);
|
||||
});
|
||||
});
|
||||
|
||||
expect(globalSetTimeout).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionForMockClock).not.toHaveBeenCalled();
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should run async specs in order, waiting for them to complete", function(done) {
|
||||
var env = new j$.Env(), mutatedVar;
|
||||
|
||||
env.describe("tests", function() {
|
||||
env.beforeEach(function() {
|
||||
mutatedVar = 2;
|
||||
});
|
||||
|
||||
env.it("async spec", function(underTestCallback) {
|
||||
setTimeout(function() {
|
||||
expect(mutatedVar).toEqual(2);
|
||||
underTestCallback();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
env.it("after async spec", function() {
|
||||
mutatedVar = 3;
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
describe("with a mock clock", function() {
|
||||
beforeEach(function() {
|
||||
jasmine.getEnv().clock.install();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.getEnv().clock.uninstall();
|
||||
});
|
||||
|
||||
it("should not hang on async specs that forget to call done()", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("tests", function() {
|
||||
env.it("async spec that will hang", function(underTestCallback) {
|
||||
env.expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
env.it("after async spec", function() {
|
||||
env.expect(true).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
|
||||
totalSpecsDefined: 2
|
||||
});
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'passed'}));
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'failed'}));
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
jasmine.getEnv().clock.tick(60001);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: something is wrong with this spec
|
||||
it("should report as expected", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
|
||||
totalSpecsDefined: 3
|
||||
});
|
||||
var suiteResult = reporter.suiteStarted.calls.first().args[0];
|
||||
expect(suiteResult.description).toEqual("A Suite");
|
||||
expect(reporter.jasmineDone).toHaveBeenCalled();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("A Suite", function() {
|
||||
env.it("with a top level spec", function() {
|
||||
env.expect(true).toBe(true);
|
||||
});
|
||||
env.describe("with a nested suite", function() {
|
||||
env.xit("with a pending spec", function() {
|
||||
env.expect(true).toBe(true);
|
||||
});
|
||||
env.it("with a spec", function() {
|
||||
env.expect(true).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should be possible to get full name from a spec", function() {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
topLevelSpec, nestedSpec, doublyNestedSpec;
|
||||
|
||||
env.describe("my tests", function() {
|
||||
topLevelSpec = env.it("are sometimes top level", function() {
|
||||
});
|
||||
env.describe("are sometimes", function() {
|
||||
nestedSpec = env.it("singly nested", function() {
|
||||
});
|
||||
env.describe("even", function() {
|
||||
doublyNestedSpec = env.it("doubly nested", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level.");
|
||||
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested.");
|
||||
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested.");
|
||||
});
|
||||
|
||||
it("Custom equality testers should be per spec", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
reporter = jasmine.createSpyObj('fakeReproter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var firstSpecResult = reporter.specDone.calls.first().args[0],
|
||||
secondSpecResult = reporter.specDone.calls.mostRecent().args[0];
|
||||
|
||||
expect(firstSpecResult.status).toEqual("passed");
|
||||
expect(secondSpecResult.status).toEqual("failed");
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("testing custom equality testers", function() {
|
||||
env.it("with a custom tester", function() {
|
||||
env.addCustomEqualityTester(function(a, b) { return true; });
|
||||
env.expect("a").toEqual("b");
|
||||
});
|
||||
|
||||
env.it("without a custom tester", function() {
|
||||
env.expect("a").toEqual("b");
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Custom matchers should be per spec", function() {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
matchers = {
|
||||
toFoo: function() {}
|
||||
},
|
||||
reporter = jasmine.createSpyObj('fakeReproter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("testing custom matchers", function() {
|
||||
env.it("with a custom matcher", function() {
|
||||
env.addMatchers(matchers);
|
||||
expect(env.expect().toFoo).toBeDefined();
|
||||
});
|
||||
|
||||
env.it("without a custom matcher", function() {
|
||||
expect(env.expect().toFoo).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Custom equality testers for toContain should be per spec", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
reporter = jasmine.createSpyObj('fakeReproter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var firstSpecResult = reporter.specDone.calls.first().args[0],
|
||||
secondSpecResult = reporter.specDone.calls.mostRecent().args[0];
|
||||
|
||||
expect(firstSpecResult.status).toEqual("passed");
|
||||
expect(secondSpecResult.status).toEqual("failed");
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("testing custom equality testers", function() {
|
||||
env.it("with a custom tester", function() {
|
||||
env.addCustomEqualityTester(function(a, b) { return true; });
|
||||
env.expect(["a"]).toContain("b");
|
||||
});
|
||||
|
||||
env.it("without a custom tester", function() {
|
||||
env.expect("a").toContain("b");
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
56
spec/core/ExceptionFormatterSpec.js
Normal file
56
spec/core/ExceptionFormatterSpec.js
Normal file
@@ -0,0 +1,56 @@
|
||||
describe("ExceptionFormatter", function() {
|
||||
describe("#message", function() {
|
||||
it('formats Firefox exception messages', function() {
|
||||
var sampleFirefoxException = {
|
||||
fileName: 'foo.js',
|
||||
lineNumber: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
},
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleFirefoxException);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
|
||||
});
|
||||
|
||||
it('formats Webkit exception messages', function() {
|
||||
var sampleWebkitException = {
|
||||
sourceURL: 'foo.js',
|
||||
line: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
},
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleWebkitException);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
|
||||
});
|
||||
|
||||
it('formats V8 exception messages', function() {
|
||||
var sampleV8 = {
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
},
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleV8);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("#stack", function() {
|
||||
it("formats stack traces from Webkit, Firefox, node.js or IE10+", function() {
|
||||
if (jasmine.getEnv().ieVersion < 10 || jasmine.getEnv().safariVersion < 6) { return; }
|
||||
|
||||
var error;
|
||||
try { throw new Error("an error") } catch(e) { error = e; }
|
||||
|
||||
expect(new j$.ExceptionFormatter().stack(error)).toMatch(/ExceptionFormatterSpec\.js.*\d+/)
|
||||
});
|
||||
|
||||
it("returns null if no Error provided", function() {
|
||||
expect(new j$.ExceptionFormatter().stack()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,149 +1,64 @@
|
||||
describe('Exceptions:', function() {
|
||||
xdescribe('Exceptions:', function() {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env = new j$.Env();
|
||||
env.updateInterval = 0;
|
||||
});
|
||||
|
||||
it('jasmine.formatException formats Firefox exception messages as expected', function() {
|
||||
var sampleFirefoxException = {
|
||||
fileName: 'foo.js',
|
||||
line: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
};
|
||||
describe('with break on exception', function() {
|
||||
it('should not catch the exception', function() {
|
||||
env.catchExceptions(false);
|
||||
var suite = env.describe('suite for break on exceptions', function() {
|
||||
env.it('should break when an exception is thrown', function() {
|
||||
throw new Error('I should hit a breakpoint!');
|
||||
});
|
||||
});
|
||||
var runner = env.currentRunner();
|
||||
var dont_change = 'I will never change!';
|
||||
|
||||
var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
|
||||
try {
|
||||
suite.execute();
|
||||
dont_change = 'oops I changed';
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
expect(jasmine.util.formatException(sampleFirefoxException)).toEqual(expected);
|
||||
expect(dont_change).toEqual('I will never change!');
|
||||
});
|
||||
});
|
||||
|
||||
it('jasmine.formatException formats Webkit exception messages as expected', function() {
|
||||
var sampleWebkitException = {
|
||||
sourceURL: 'foo.js',
|
||||
lineNumber: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
};
|
||||
|
||||
var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
|
||||
|
||||
expect(jasmine.util.formatException(sampleWebkitException)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle exceptions thrown, but continue', function() {
|
||||
var fakeTimer = new jasmine.FakeTimer();
|
||||
env.setTimeout = fakeTimer.setTimeout;
|
||||
env.clearTimeout = fakeTimer.clearTimeout;
|
||||
env.setInterval = fakeTimer.setInterval;
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
|
||||
//we run two exception tests to make sure we continue after throwing an exception
|
||||
var suite = env.describe('Suite for handles exceptions', function () {
|
||||
env.it('should be a test that fails because it throws an exception', function() {
|
||||
throw new Error('fake error 1');
|
||||
});
|
||||
|
||||
env.it('should be another test that fails because it throws an exception', function() {
|
||||
this.runs(function () {
|
||||
throw new Error('fake error 2');
|
||||
describe("with catch on exception", function() {
|
||||
it('should handle exceptions thrown, but continue', function() {
|
||||
var ranSecondTest = false,
|
||||
suite = env.describe('Suite for handles exceptions', function () {
|
||||
env.it('should be a test that fails because it throws an exception', function() {
|
||||
throw new Error();
|
||||
});
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
env.it('should be a passing test that runs after exceptions are thrown from a async test', function() {
|
||||
ranSecondTest = true;
|
||||
});
|
||||
});
|
||||
|
||||
env.it('should be a passing test that runs after exceptions are thrown', function() {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
env.it('should be another test that fails because it throws an exception after a wait', function() {
|
||||
this.runs(function () {
|
||||
var foo = 'foo';
|
||||
});
|
||||
this.waits(250);
|
||||
this.runs(function () {
|
||||
throw new Error('fake error 3');
|
||||
});
|
||||
});
|
||||
|
||||
env.it('should be a passing test that runs after exceptions are thrown from a async test', function() {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
suite.execute();
|
||||
expect(ranSecondTest).toBe(true);
|
||||
});
|
||||
|
||||
var runner = env.currentRunner();
|
||||
suite.execute();
|
||||
fakeTimer.tick(2500);
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
|
||||
var ranSecondDescribe = false, suite, suite2, runner = env.currentRunner();
|
||||
suite = env.describe("a suite that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
throw new Error("top level error");
|
||||
});
|
||||
suite2 = env.describe("a suite that doesn't throw an exception", function () {
|
||||
ranSecondDescribe = true;
|
||||
});
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
//
|
||||
expect(specResults.length).toEqual(5);
|
||||
expect(specResults[0].passed()).toMatch(false);
|
||||
var blockResults = specResults[0].getItems();
|
||||
expect(blockResults[0].passed()).toEqual(false);
|
||||
expect(blockResults[0].message).toMatch(/fake error 1/);
|
||||
|
||||
expect(specResults[1].passed()).toEqual(false);
|
||||
blockResults = specResults[1].getItems();
|
||||
expect(blockResults[0].passed()).toEqual(false);
|
||||
expect(blockResults[0].message).toMatch(/fake error 2/);
|
||||
expect(blockResults[1].passed()).toEqual(true);
|
||||
|
||||
expect(specResults[2].passed()).toEqual(true);
|
||||
|
||||
expect(specResults[3].passed()).toEqual(false);
|
||||
blockResults = specResults[3].getItems();
|
||||
expect(blockResults[0].message).toMatch(/fake error 3/);
|
||||
|
||||
expect(specResults[4].passed()).toEqual(true);
|
||||
runner.execute();
|
||||
expect(ranSecondDescribe).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
|
||||
var suite = env.describe("a top level describe block that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
throw new Error("top level error");
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
expect(specResults.length).toEqual(2);
|
||||
|
||||
expect(specResults[1].description).toMatch(/encountered a declaration exception/);
|
||||
});
|
||||
|
||||
it("should handle exceptions thrown directly in nested describe blocks and continue", function () {
|
||||
var suite = env.describe("a top level describe", function () {
|
||||
env.describe("a mid-level describe that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
throw new Error("a mid-level error");
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
expect(specResults.length).toEqual(1);
|
||||
|
||||
var nestedSpecResults = specResults[0].getItems();
|
||||
|
||||
expect(nestedSpecResults.length).toEqual(2);
|
||||
expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
61
spec/core/ExpectationResultSpec.js
Normal file
61
spec/core/ExpectationResultSpec.js
Normal file
@@ -0,0 +1,61 @@
|
||||
describe("buildExpectationResult", function() {
|
||||
it("defaults to passed", function() {
|
||||
var result = j$.buildExpectationResult({passed: 'some-value'});
|
||||
expect(result.passed).toBe('some-value');
|
||||
});
|
||||
|
||||
it("message defaults to Passed for passing specs", function() {
|
||||
var result = j$.buildExpectationResult({passed: true, message: 'some-value'});
|
||||
expect(result.message).toBe('Passed.');
|
||||
});
|
||||
|
||||
it("message returns the message for failing expecations", function() {
|
||||
var result = j$.buildExpectationResult({passed: false, message: 'some-value'});
|
||||
expect(result.message).toBe('some-value');
|
||||
});
|
||||
|
||||
it("delegates message formatting to the provided formatter if there was an Error", function() {
|
||||
var fakeError = {message: 'foo'},
|
||||
messageFormatter = jasmine.createSpy("exception message formatter").and.callReturn(fakeError.message);
|
||||
|
||||
var result = j$.buildExpectationResult(
|
||||
{
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
messageFormatter: messageFormatter
|
||||
});
|
||||
|
||||
expect(messageFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.message).toEqual('foo');
|
||||
});
|
||||
|
||||
it("delegates stack formatting to the provided formatter if there was an Error", function() {
|
||||
var fakeError = {stack: 'foo'},
|
||||
stackFormatter = jasmine.createSpy("stack formatter").and.callReturn(fakeError.stack);
|
||||
|
||||
var result = j$.buildExpectationResult(
|
||||
{
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
});
|
||||
|
||||
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.stack).toEqual('foo');
|
||||
});
|
||||
|
||||
it("matcherName returns passed matcherName", function() {
|
||||
var result = j$.buildExpectationResult({matcherName: 'some-value'});
|
||||
expect(result.matcherName).toBe('some-value');
|
||||
});
|
||||
|
||||
it("expected returns passed expected", function() {
|
||||
var result = j$.buildExpectationResult({expected: 'some-value'});
|
||||
expect(result.expected).toBe('some-value');
|
||||
});
|
||||
|
||||
it("actual returns passed actual", function() {
|
||||
var result = j$.buildExpectationResult({actual: 'some-value'});
|
||||
expect(result.actual).toBe('some-value');
|
||||
});
|
||||
});
|
||||
320
spec/core/ExpectationSpec.js
Normal file
320
spec/core/ExpectationSpec.js
Normal file
@@ -0,0 +1,320 @@
|
||||
describe("Expectation", function() {
|
||||
it(".addMatchers makes matchers available to any expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {},
|
||||
toBar: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
|
||||
expect(expectation.toFoo).toBeDefined();
|
||||
expect(expectation.toBar).toBeDefined();
|
||||
});
|
||||
|
||||
it(".addCoreMatchers makes matchers available to any expectation", function() {
|
||||
var coreMatchers = {
|
||||
toQuux: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addCoreMatchers(coreMatchers);
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
|
||||
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 expectaion/negative expectation", function() {
|
||||
var builtExpectation = j$.Expectation.Factory();
|
||||
|
||||
expect(builtExpectation instanceof j$.Expectation).toBe(true);
|
||||
expect(builtExpectation.not instanceof j$.Expectation).toBe(true);
|
||||
expect(builtExpectation.not.isNot).toBe(true);
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing in matcher dependencies", function() {
|
||||
var fakeCompare = function() { return { pass: true }; },
|
||||
matcherFactory = jasmine.createSpy("matcher").and.callReturn({ compare: fakeCompare }),
|
||||
matchers = {
|
||||
toFoo: matcherFactory
|
||||
},
|
||||
util = {},
|
||||
customEqualityTesters = ['a'],
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(matcherFactory).toHaveBeenCalledWith(util, customEqualityTesters)
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing the actual and expected", function() {
|
||||
var fakeCompare = jasmine.createSpy('fake-compare').and.callReturn({pass: true}),
|
||||
matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: fakeCompare
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(fakeCompare).toHaveBeenCalledWith("an actual", "hello");
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the comparison passes", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
passed: true,
|
||||
message: "",
|
||||
expected: "hello",
|
||||
actual: "an actual"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result to the spec when the comparison fails", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: false }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return ""; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: ""
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the comparison fails", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: "I am a custom message"
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: "I am a custom message"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the comparison fails for a negative expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: false }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return ""; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
passed: true,
|
||||
message: "",
|
||||
expected: "hello",
|
||||
actual: actual
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result to the spec when the comparison passes for a negative expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return "default messge"; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
actual: "an actual",
|
||||
util: util,
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: actual,
|
||||
message: "default messge"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the comparison passes for a negative expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: true,
|
||||
message: "I am a custom message"
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: actual,
|
||||
message: "I am a custom message"
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +1,11 @@
|
||||
describe('jasmine.jsApiReporter', function() {
|
||||
describe('results', function () {
|
||||
var reporter, spec1, spec2, spec3, expectedSpec1Results, expectedSpec2Results;
|
||||
xdescribe('JsApiReporter (integration specs)', function() {
|
||||
describe('results', function() {
|
||||
var reporter, spec1, spec2;
|
||||
var env;
|
||||
var suite, nestedSuite, nestedSpec;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env = new j$.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
suite = env.describe("top-level suite", function() {
|
||||
@@ -24,34 +24,24 @@ describe('jasmine.jsApiReporter', function() {
|
||||
});
|
||||
});
|
||||
|
||||
spec3 = env.it("spec 3", function() {
|
||||
this.log('some debug message');
|
||||
});
|
||||
});
|
||||
|
||||
reporter = new jasmine.JsApiReporter();
|
||||
reporter = new j$.JsApiReporter({});
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.execute();
|
||||
|
||||
expectedSpec1Results = {
|
||||
messages: spec1.results().getItems(),
|
||||
result: "passed"
|
||||
};
|
||||
expectedSpec2Results = {
|
||||
messages: spec2.results().getItems(),
|
||||
result: "failed"
|
||||
};
|
||||
});
|
||||
|
||||
it('resultForSpec() should return the result for the given spec', function () {
|
||||
expect(reporter.resultsForSpec(spec1.id)).toEqual(expectedSpec1Results);
|
||||
expect(reporter.resultsForSpec(spec2.id)).toEqual(expectedSpec2Results);
|
||||
});
|
||||
|
||||
it('results() should return a hash of all results, indexed by spec id', function () {
|
||||
expect(reporter.results()[spec1.id]).toEqual(expectedSpec1Results);
|
||||
expect(reporter.results()[spec2.id]).toEqual(expectedSpec2Results);
|
||||
it('results() should return a hash of all results, indexed by spec id', function() {
|
||||
var expectedSpec1Results = {
|
||||
result: "passed"
|
||||
},
|
||||
expectedSpec2Results = {
|
||||
result: "failed"
|
||||
};
|
||||
expect(reporter.results()[spec1.id].result).toEqual('passed');
|
||||
expect(reporter.results()[spec2.id].result).toEqual('failed');
|
||||
});
|
||||
|
||||
it("should return nested suites as children of their parents", function() {
|
||||
@@ -65,7 +55,6 @@ describe('jasmine.jsApiReporter', function() {
|
||||
{ id: 2, name: 'nested spec', type: 'spec', children: [ ] }
|
||||
]
|
||||
},
|
||||
{ id: 3, name: 'spec 3', type: 'spec', children: [ ] }
|
||||
]
|
||||
}
|
||||
]);
|
||||
@@ -76,12 +65,7 @@ describe('jasmine.jsApiReporter', function() {
|
||||
var result = reporter.results()[spec1.id];
|
||||
var summarizedResult = reporter.summarizeResult_(result);
|
||||
expect(summarizedResult.result).toEqual('passed');
|
||||
expect(summarizedResult.messages.length).toEqual(1);
|
||||
expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message);
|
||||
expect(summarizedResult.messages[0].passed).toBeTruthy();
|
||||
expect(summarizedResult.messages[0].type).toEqual('expect');
|
||||
expect(summarizedResult.messages[0].text).toBeUndefined();
|
||||
expect(summarizedResult.messages[0].trace.stack).toBeUndefined();
|
||||
expect(summarizedResult.messages.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should have a stack trace for failing specs", function() {
|
||||
@@ -91,13 +75,141 @@ describe('jasmine.jsApiReporter', function() {
|
||||
expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack);
|
||||
});
|
||||
|
||||
it("should have messages for specs with messages", function() {
|
||||
var result = reporter.results()[spec3.id];
|
||||
var summarizedResult = reporter.summarizeResult_(result);
|
||||
expect(summarizedResult.result).toEqual('passed');
|
||||
expect(summarizedResult.messages[0].type).toEqual('log');
|
||||
expect(summarizedResult.messages[0].text).toEqual('some debug message');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("JsApiReporter", function() {
|
||||
|
||||
it("knows when a full environment is started", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
expect(reporter.started).toBe(false);
|
||||
expect(reporter.finished).toBe(false);
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(reporter.started).toBe(true);
|
||||
expect(reporter.finished).toBe(false);
|
||||
});
|
||||
|
||||
it("knows when a full environment is done", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
expect(reporter.started).toBe(false);
|
||||
expect(reporter.finished).toBe(false);
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
expect(reporter.finished).toBe(true);
|
||||
});
|
||||
|
||||
it("defaults to 'loaded' status", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
expect(reporter.status()).toEqual('loaded');
|
||||
});
|
||||
|
||||
it("reports 'started' when Jasmine has started", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(reporter.status()).toEqual('started');
|
||||
});
|
||||
|
||||
it("reports 'done' when Jasmine is done", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
|
||||
expect(reporter.status()).toEqual('done');
|
||||
});
|
||||
|
||||
it("tracks a suite", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
reporter.suiteStarted({
|
||||
id: 123,
|
||||
description: "A suite"
|
||||
});
|
||||
|
||||
var suites = reporter.suites();
|
||||
|
||||
expect(suites).toEqual({123: {id: 123, description: "A suite"}});
|
||||
|
||||
reporter.suiteDone({
|
||||
id: 123,
|
||||
description: "A suite",
|
||||
status: 'passed'
|
||||
});
|
||||
|
||||
expect(suites).toEqual({123: {id: 123, description: "A suite", status: 'passed'}});
|
||||
});
|
||||
|
||||
describe("#specResults", function() {
|
||||
var reporter, specResult1, specResult2;
|
||||
beforeEach(function() {
|
||||
reporter = new j$.JsApiReporter({});
|
||||
specResult1 = {
|
||||
id: 1,
|
||||
description: "A spec"
|
||||
};
|
||||
specResult2 = {
|
||||
id: 2,
|
||||
description: "Another spec"
|
||||
};
|
||||
|
||||
reporter.specDone(specResult1);
|
||||
reporter.specDone(specResult2);
|
||||
});
|
||||
|
||||
it("should return a slice of results", function() {
|
||||
expect(reporter.specResults(0, 1)).toEqual([specResult1]);
|
||||
expect(reporter.specResults(1, 1)).toEqual([specResult2]);
|
||||
});
|
||||
|
||||
describe("when the results do not exist", function() {
|
||||
it("should return a slice of shorter length", function() {
|
||||
expect(reporter.specResults(0, 3)).toEqual([specResult1, specResult2]);
|
||||
expect(reporter.specResults(2, 3)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#executionTime", function() {
|
||||
it("should start the timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should return the time it took the specs to run, in ms", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
timerSpy.elapsed.and.callReturn(1000);
|
||||
reporter.jasmineDone();
|
||||
expect(reporter.executionTime()).toEqual(1000);
|
||||
});
|
||||
|
||||
describe("when the specs haven't finished being run", function() {
|
||||
it("should return undefined", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
expect(reporter.executionTime()).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,838 +0,0 @@
|
||||
describe("jasmine.Matchers", function() {
|
||||
var env, spec;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
var suite = env.describe("suite", function() {
|
||||
spec = env.it("spec", function() {
|
||||
});
|
||||
});
|
||||
spyOn(spec, 'addMatcherResult');
|
||||
|
||||
this.addMatchers({
|
||||
toPass: function() {
|
||||
return lastResult().passed();
|
||||
},
|
||||
toFail: function() {
|
||||
return !lastResult().passed();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function match(value) {
|
||||
return spec.expect(value);
|
||||
}
|
||||
|
||||
function lastResult() {
|
||||
return spec.addMatcherResult.mostRecentCall.args[0];
|
||||
}
|
||||
|
||||
function catchException(fn) {
|
||||
try {
|
||||
fn.call();
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
throw new Error("expected function to throw an exception");
|
||||
}
|
||||
|
||||
it("toEqual with primitives, objects, dates, etc.", function() {
|
||||
expect(match(true).toEqual(true)).toPass();
|
||||
|
||||
expect(match({foo:'bar'}).toEqual(null)).toFail();
|
||||
|
||||
var functionA = function() {
|
||||
return 'hi';
|
||||
};
|
||||
var functionB = function() {
|
||||
return 'hi';
|
||||
};
|
||||
expect(match({foo:functionA}).toEqual({foo:functionB})).toFail();
|
||||
expect(match({foo:functionA}).toEqual({foo:functionA})).toPass();
|
||||
|
||||
expect((match(false).toEqual(true))).toFail();
|
||||
|
||||
var circularGraph = {};
|
||||
circularGraph.referenceToSelf = circularGraph;
|
||||
expect((match(circularGraph).toEqual(circularGraph))).toPass();
|
||||
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2009, 1, 3, 15, 17, 19, 1234)))).toFail();
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2008, 1, 3, 15, 17, 19, 1234)))).toPass();
|
||||
|
||||
|
||||
expect(match(true).toNotEqual(false)).toPass();
|
||||
expect((match(true).toNotEqual(true))).toFail();
|
||||
|
||||
expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toFail();
|
||||
expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toFail();
|
||||
|
||||
expect((match("cat").toEqual("cat"))).toPass();
|
||||
expect((match("cat").toNotEqual("cat"))).toFail();
|
||||
|
||||
expect((match(5).toEqual(5))).toPass();
|
||||
expect((match(parseInt('5', 10)).toEqual(5))).toPass();
|
||||
expect((match(5).toNotEqual(5))).toFail();
|
||||
expect((match(parseInt('5', 10)).toNotEqual(5))).toFail();
|
||||
});
|
||||
|
||||
it("toEqual to build an Expectation Result", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = 'b';
|
||||
matcher.toEqual(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toEqual");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotEqual to build an Expectation Result", function() {
|
||||
var str = 'a';
|
||||
var matcher = match(str);
|
||||
matcher.toNotEqual(str);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotEqual");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(str));
|
||||
expect(result.message).toMatch('not');
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it('toBe should return true only if the expected and actual items === each other', function() {
|
||||
var a = {};
|
||||
var b = {};
|
||||
//noinspection UnnecessaryLocalVariableJS
|
||||
var c = a;
|
||||
expect((match(a).toBe(b))).toFail();
|
||||
expect((match(a).toBe(a))).toPass();
|
||||
expect((match(a).toBe(c))).toPass();
|
||||
expect((match(a).toNotBe(b))).toPass();
|
||||
expect((match(a).toNotBe(a))).toFail();
|
||||
expect((match(a).toNotBe(c))).toFail();
|
||||
});
|
||||
|
||||
it("toBe to build an ExpectationResult", function() {
|
||||
var expected = 'b';
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
matcher.toBe(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBe");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotBe to build an ExpectationResult", function() {
|
||||
var str = 'a';
|
||||
var matcher = match(str);
|
||||
matcher.toNotBe(str);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotBe");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(str);
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it("toMatch and #toNotMatch should perform regular expression matching on strings", function() {
|
||||
expect((match('foobarbel').toMatch(/bar/))).toPass();
|
||||
expect((match('foobazbel').toMatch(/bar/))).toFail();
|
||||
|
||||
expect((match('foobarbel').toMatch("bar"))).toPass();
|
||||
expect((match('foobazbel').toMatch("bar"))).toFail();
|
||||
|
||||
expect((match('foobarbel').toNotMatch(/bar/))).toFail();
|
||||
expect((match('foobazbel').toNotMatch(/bar/))).toPass();
|
||||
|
||||
expect((match('foobarbel').toNotMatch("bar"))).toFail();
|
||||
expect((match('foobazbel').toNotMatch("bar"))).toPass();
|
||||
});
|
||||
|
||||
it("toMatch w/ RegExp to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = /b/;
|
||||
matcher.toMatch(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(expected.toString());
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toMatch w/ String to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = 'b';
|
||||
matcher.toMatch(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to match 'b'.");
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotMatch w/ RegExp to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = /a/;
|
||||
matcher.toNotMatch(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to not match /a/.");
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotMatch w/ String to build an ExpectationResult", function() {
|
||||
var str = 'a';
|
||||
var matcher = match(str);
|
||||
matcher.toNotMatch(str);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to not match 'a'.");
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it("toBeDefined", function() {
|
||||
expect(match('foo').toBeDefined()).toPass();
|
||||
expect(match(jasmine.undefined).toBeDefined()).toFail();
|
||||
});
|
||||
|
||||
it("toBeDefined to build an ExpectationResult", function() {
|
||||
var matcher = match(jasmine.undefined);
|
||||
matcher.toBeDefined();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeDefined");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual('Expected undefined to be defined.');
|
||||
expect(result.actual).toEqual(jasmine.undefined);
|
||||
});
|
||||
|
||||
it("toBeUndefined", function() {
|
||||
expect(match('foo').toBeUndefined()).toFail();
|
||||
expect(match(jasmine.undefined).toBeUndefined()).toPass();
|
||||
});
|
||||
|
||||
it("toBeNull", function() {
|
||||
expect(match(null).toBeNull()).toPass();
|
||||
expect(match(jasmine.undefined).toBeNull()).toFail();
|
||||
expect(match("foo").toBeNull()).toFail();
|
||||
});
|
||||
|
||||
it("toBeNull w/ String to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
matcher.toBeNull();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeNull");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('null');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeNull w/ Object to build an ExpectationResult", function() {
|
||||
var actual = {a: 'b'};
|
||||
var matcher = match(actual);
|
||||
matcher.toBeNull();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeNull");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('null');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeFalsy", function() {
|
||||
expect(match(false).toBeFalsy()).toPass();
|
||||
expect(match(true).toBeFalsy()).toFail();
|
||||
expect(match(jasmine.undefined).toBeFalsy()).toPass();
|
||||
expect(match(0).toBeFalsy()).toPass();
|
||||
expect(match("").toBeFalsy()).toPass();
|
||||
});
|
||||
|
||||
it("toBeFalsy to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
matcher.toBeFalsy();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeFalsy");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('falsy');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeTruthy", function() {
|
||||
expect(match(false).toBeTruthy()).toFail();
|
||||
expect(match(true).toBeTruthy()).toPass();
|
||||
expect(match(jasmine.undefined).toBeTruthy()).toFail();
|
||||
expect(match(0).toBeTruthy()).toFail();
|
||||
expect(match("").toBeTruthy()).toFail();
|
||||
expect(match("hi").toBeTruthy()).toPass();
|
||||
expect(match(5).toBeTruthy()).toPass();
|
||||
expect(match({foo: 1}).toBeTruthy()).toPass();
|
||||
});
|
||||
|
||||
it("toBeTruthy to build an ExpectationResult", function() {
|
||||
var matcher = match(false);
|
||||
matcher.toBeTruthy();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeTruthy");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected false to be truthy.");
|
||||
expect(result.actual).toFail();
|
||||
});
|
||||
|
||||
it("toEqual", function() {
|
||||
expect(match(jasmine.undefined).toEqual(jasmine.undefined)).toPass();
|
||||
expect(match({foo:'bar'}).toEqual({foo:'bar'})).toPass();
|
||||
expect(match("foo").toEqual({bar: jasmine.undefined})).toFail();
|
||||
expect(match({foo: jasmine.undefined}).toEqual("goo")).toFail();
|
||||
expect(match({foo: {bar :jasmine.undefined}}).toEqual("goo")).toFail();
|
||||
});
|
||||
|
||||
it("toEqual with jasmine.any()", function() {
|
||||
expect(match("foo").toEqual(jasmine.any(String))).toPass();
|
||||
expect(match(3).toEqual(jasmine.any(Number))).toPass();
|
||||
expect(match("foo").toEqual(jasmine.any(Function))).toFail();
|
||||
expect(match("foo").toEqual(jasmine.any(Object))).toFail();
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toPass();
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail();
|
||||
expect(match(
|
||||
function() {
|
||||
}).toEqual(jasmine.any(Object))).toFail();
|
||||
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass();
|
||||
expect(match(
|
||||
function() {
|
||||
}).toEqual(jasmine.any(Function))).toPass();
|
||||
expect(match(["a", function() {
|
||||
}]).toEqual(["a", jasmine.any(Function)])).toPass();
|
||||
});
|
||||
|
||||
it("toEqual handles circular objects ok", function() {
|
||||
expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toPass();
|
||||
expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toPass();
|
||||
expect(match({foo: {bar:'baz'}, quux:'corge'}).toEqual({foo:{bar:'baz'}, quux:'corge'})).toPass();
|
||||
|
||||
var circularObject = {};
|
||||
var secondCircularObject = {};
|
||||
circularObject.field = circularObject;
|
||||
secondCircularObject.field = secondCircularObject;
|
||||
expect(match(circularObject).toEqual(secondCircularObject)).toPass();
|
||||
});
|
||||
|
||||
it("toNotEqual as slightly surprising behavior, but is it intentional?", function() {
|
||||
expect(match({x:"x", y:"y", z:"w"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({x:"x", y:"y", w:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({x:"x", y:"y", z:"z"}).toNotEqual({w: "w", x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({w: "w", x:"x", y:"y", z:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
});
|
||||
|
||||
it("toEqual handles arrays", function() {
|
||||
expect(match([1, "A"]).toEqual([1, "A"])).toPass();
|
||||
});
|
||||
|
||||
it("toContain and toNotContain", function() {
|
||||
expect(match('ABC').toContain('A')).toPass();
|
||||
expect(match('ABC').toContain('X')).toFail();
|
||||
|
||||
expect(match(['A', 'B', 'C']).toContain('A')).toPass();
|
||||
expect(match(['A', 'B', 'C']).toContain('F')).toFail();
|
||||
expect(match(['A', 'B', 'C']).toNotContain('F')).toPass();
|
||||
expect(match(['A', 'B', 'C']).toNotContain('A')).toFail();
|
||||
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'object'})).toPass();
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'other object'})).toFail();
|
||||
});
|
||||
|
||||
it("toContain to build an ExpectationResult", function() {
|
||||
var actual = ['a','b','c'];
|
||||
var matcher = match(actual);
|
||||
var expected = 'x';
|
||||
matcher.toContain(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toContain");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('contain');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toNotContain to build an ExpectationResult", function() {
|
||||
var actual = ['a','b','c'];
|
||||
var matcher = match(actual);
|
||||
var expected = 'b';
|
||||
matcher.toNotContain(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotContain");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('not contain');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toBeLessThan should pass if actual is less than expected", function() {
|
||||
expect(match(37).toBeLessThan(42)).toPass();
|
||||
expect(match(37).toBeLessThan(-42)).toFail();
|
||||
expect(match(37).toBeLessThan(37)).toFail();
|
||||
});
|
||||
|
||||
it("toBeLessThan to build an ExpectationResult", function() {
|
||||
var actual = 3;
|
||||
var matcher = match(actual);
|
||||
var expected = 1;
|
||||
matcher.toBeLessThan(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeLessThan");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toBeGreaterThan should pass if actual is greater than expected", function() {
|
||||
expect(match(37).toBeGreaterThan(42)).toFail();
|
||||
expect(match(37).toBeGreaterThan(-42)).toPass();
|
||||
expect(match(37).toBeGreaterThan(37)).toFail();
|
||||
});
|
||||
|
||||
it("toBeGreaterThan to build an ExpectationResult", function() {
|
||||
var actual = 1;
|
||||
var matcher = match(actual);
|
||||
var expected = 3;
|
||||
matcher.toBeGreaterThan(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeGreaterThan");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
describe("toBeCloseTo", function() {
|
||||
it("returns 'true' iff actual and expected are equal within 2 decimal points of precision", function() {
|
||||
expect(0).toBeCloseTo(0);
|
||||
expect(1).toBeCloseTo(1);
|
||||
expect(1).not.toBeCloseTo(1.1);
|
||||
expect(1).not.toBeCloseTo(1.01);
|
||||
expect(1).toBeCloseTo(1.001);
|
||||
|
||||
expect(1.23).toBeCloseTo(1.234);
|
||||
expect(1.23).toBeCloseTo(1.233);
|
||||
expect(1.23).toBeCloseTo(1.232);
|
||||
expect(1.23).not.toBeCloseTo(1.24);
|
||||
|
||||
expect(-1.23).toBeCloseTo(-1.234);
|
||||
expect(-1.23).not.toBeCloseTo(-1.24);
|
||||
});
|
||||
|
||||
it("accepts an optional precision argument", function() {
|
||||
expect(1).toBeCloseTo(1.1, 0);
|
||||
expect(1.2).toBeCloseTo(1.23, 1);
|
||||
|
||||
expect(1.234).toBeCloseTo(1.2343, 3);
|
||||
expect(1.234).not.toBeCloseTo(1.233, 3);
|
||||
});
|
||||
|
||||
it("rounds", function() {
|
||||
expect(1.23).toBeCloseTo(1.229);
|
||||
expect(1.23).toBeCloseTo(1.226);
|
||||
expect(1.23).toBeCloseTo(1.225);
|
||||
expect(1.23).not.toBeCloseTo(1.2249999);
|
||||
|
||||
expect(1.23).toBeCloseTo(1.234);
|
||||
expect(1.23).toBeCloseTo(1.2349999);
|
||||
expect(1.23).not.toBeCloseTo(1.235);
|
||||
|
||||
expect(-1.23).toBeCloseTo(-1.234);
|
||||
expect(-1.23).not.toBeCloseTo(-1.235);
|
||||
expect(-1.23).not.toBeCloseTo(-1.236);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toThrow", function() {
|
||||
describe("when code block throws an exception", function() {
|
||||
var throwingFn;
|
||||
|
||||
beforeEach(function() {
|
||||
throwingFn = function() {
|
||||
throw new Error("Fake Error");
|
||||
};
|
||||
});
|
||||
|
||||
it("should match any exception", function() {
|
||||
expect(match(throwingFn).toThrow()).toPass();
|
||||
});
|
||||
|
||||
it("should match exceptions specified by message", function() {
|
||||
expect(match(throwingFn).toThrow("Fake Error")).toPass();
|
||||
expect(match(throwingFn).toThrow("Other Error")).toFail();
|
||||
expect(lastResult().message).toMatch("Other Error");
|
||||
});
|
||||
|
||||
it("should match exceptions specified by Error", function() {
|
||||
expect(match(throwingFn).toThrow(new Error("Fake Error"))).toPass();
|
||||
expect(match(throwingFn).toThrow(new Error("Other Error"))).toFail();
|
||||
expect(lastResult().message).toMatch("Other Error");
|
||||
});
|
||||
|
||||
describe("and matcher is inverted with .not", function() {
|
||||
it("should match any exception", function() {
|
||||
expect(match(throwingFn).not.toThrow()).toFail();
|
||||
expect(lastResult().message).toMatch(/Expected function not to throw an exception/);
|
||||
});
|
||||
|
||||
it("should match exceptions specified by message", function() {
|
||||
expect(match(throwingFn).not.toThrow("Fake Error")).toFail();
|
||||
// expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./);
|
||||
expect(match(throwingFn).not.toThrow("Other Error")).toPass();
|
||||
});
|
||||
|
||||
it("should match exceptions specified by Error", function() {
|
||||
expect(match(throwingFn).not.toThrow(new Error("Fake Error"))).toFail();
|
||||
// expect(lastResult().message).toMatch("Other Error");
|
||||
expect(match(throwingFn).not.toThrow(new Error("Other Error"))).toPass();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when actual is not a function", function() {
|
||||
it("should fail with an exception", function() {
|
||||
var exception = catchException(function() {
|
||||
match('not-a-function').toThrow();
|
||||
});
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
});
|
||||
|
||||
describe("and matcher is inverted with .not", function() {
|
||||
it("should fail with an exception", function() {
|
||||
var exception = catchException(function() {
|
||||
match('not-a-function').not.toThrow();
|
||||
});
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("when code block does not throw an exception", function() {
|
||||
it("should fail (or pass when inverted with .not)", function() {
|
||||
expect(match(
|
||||
function() {
|
||||
}).toThrow()).toFail();
|
||||
expect(lastResult().message).toEqual('Expected function to throw an exception.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(".not.matcher", function() {
|
||||
it("should invert the sense of any matcher", function() {
|
||||
expect(match(37).not.toBeGreaterThan(42)).toPass();
|
||||
expect(match(42).not.toBeGreaterThan(37)).toFail();
|
||||
expect(match("abc").not.toEqual("def")).toPass();
|
||||
expect(match("abc").not.toEqual("abc")).toFail();
|
||||
});
|
||||
|
||||
it("should provide an inverted default message", function() {
|
||||
match(37).not.toBeGreaterThan(42);
|
||||
expect(lastResult().message).toEqual("Passed.");
|
||||
|
||||
match(42).not.toBeGreaterThan(37);
|
||||
expect(lastResult().message).toEqual("Expected 42 not to be greater than 37.");
|
||||
});
|
||||
|
||||
it("should use the second message when the matcher sets an array of custom messages", function() {
|
||||
spec.addMatchers({
|
||||
custom: function() {
|
||||
this.message = function() {
|
||||
return ['Expected it was called.', 'Expected it wasn\'t called.'];
|
||||
};
|
||||
return this.actual;
|
||||
}
|
||||
});
|
||||
|
||||
match(true).custom();
|
||||
expect(lastResult().message).toEqual("Passed.");
|
||||
match(false).custom();
|
||||
expect(lastResult().message).toEqual("Expected it was called.");
|
||||
match(true).not.custom();
|
||||
expect(lastResult().message).toEqual("Expected it wasn't called.");
|
||||
match(false).not.custom();
|
||||
expect(lastResult().message).toEqual("Passed.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("spy matchers >>", function() {
|
||||
var TestClass;
|
||||
beforeEach(function() {
|
||||
TestClass = {
|
||||
normalFunction: function() {
|
||||
},
|
||||
spyFunction: jasmine.createSpy("My spy")
|
||||
};
|
||||
});
|
||||
|
||||
function shouldThrowAnExceptionWhenInvokedOnANonSpy(methodName) {
|
||||
return function() {
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction)[methodName]();
|
||||
}).toThrow('Expected a spy, but got Function.');
|
||||
|
||||
expect(
|
||||
function() {
|
||||
match(jasmine.undefined)[methodName]();
|
||||
}).toThrow('Expected a spy, but got undefined.');
|
||||
|
||||
expect(
|
||||
function() {
|
||||
match({some:'object'})[methodName]();
|
||||
}).toThrow('Expected a spy, but got { some : \'object\' }.');
|
||||
|
||||
expect(
|
||||
function() {
|
||||
match("<b>")[methodName]();
|
||||
}).toThrow('Expected a spy, but got \'<b>\'.');
|
||||
};
|
||||
}
|
||||
|
||||
describe("toHaveBeenCalled", function() {
|
||||
it("should pass if the spy was called", function() {
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toFail();
|
||||
|
||||
TestClass.spyFunction();
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toPass();
|
||||
});
|
||||
|
||||
it("should throw an exception when invoked with any arguments", function() {
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
|
||||
}).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalled'));
|
||||
});
|
||||
|
||||
describe("wasCalled", function() {
|
||||
it("should alias toHaveBeenCalled", function() {
|
||||
spyOn(TestClass, 'normalFunction');
|
||||
|
||||
TestClass.normalFunction();
|
||||
|
||||
expect(TestClass.normalFunction).wasCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("wasNotCalled", function() {
|
||||
it("should pass iff the spy was not called", function() {
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toPass();
|
||||
|
||||
TestClass.spyFunction();
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toFail();
|
||||
});
|
||||
|
||||
it("should throw an exception when invoked with any arguments", function() {
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction).wasNotCalled("unwanted argument");
|
||||
}).toThrow('wasNotCalled does not take arguments');
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalled'));
|
||||
});
|
||||
|
||||
describe("toHaveBeenCalledWith", function() {
|
||||
it('toHaveBeenCalledWith should return true if it was called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalledWith('a', 'b', 'c')).toPass();
|
||||
});
|
||||
|
||||
it('should return false if it was not called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['c', 'b', 'a']);
|
||||
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
expect(result.message).toContain(jasmine.pp(result.actual.mostRecentCall.args));
|
||||
});
|
||||
|
||||
it('should return false if it was not called', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['c', 'b', 'a']);
|
||||
expect(result.actual.argsForCall).toEqual([]);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
});
|
||||
|
||||
it('should allow matches across multiple calls', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b', 'c')).toPass();
|
||||
expect(expected.toHaveBeenCalledWith('d', 'e', 'f')).toPass();
|
||||
expect(expected.toHaveBeenCalledWith('x', 'y', 'z')).toFail();
|
||||
});
|
||||
|
||||
it("should return a decent message", function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b')).toFail();
|
||||
expect(lastResult().message).toEqual("Expected spy My spy to have been called with [ 'a', 'b' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
|
||||
});
|
||||
|
||||
it("should return a decent message when inverted", function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.not.toHaveBeenCalledWith('a', 'b', 'c')).toFail();
|
||||
expect(lastResult().message).toEqual("Expected spy My spy not to have been called with [ 'a', 'b', 'c' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalledWith'));
|
||||
|
||||
describe("to build an ExpectationResult", function () {
|
||||
beforeEach(function() {
|
||||
var currentSuite;
|
||||
var spec;
|
||||
currentSuite = env.describe('default current suite', function() {
|
||||
spec = env.it();
|
||||
}, spec);
|
||||
TestClass = { someFunction: function(a, b) {
|
||||
} };
|
||||
spec.spyOn(TestClass, 'someFunction');
|
||||
});
|
||||
|
||||
it("should should handle the case of a spy", function() {
|
||||
TestClass.someFunction('a', 'c');
|
||||
var matcher = match(TestClass.someFunction);
|
||||
matcher.toHaveBeenCalledWith('a', 'b');
|
||||
|
||||
var result = lastResult();
|
||||
expect(result.matcherName).toEqual("toHaveBeenCalledWith");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toContain(jasmine.pp(['a', 'b']));
|
||||
expect(result.message).toContain(jasmine.pp(['a', 'c']));
|
||||
expect(result.actual).toEqual(TestClass.someFunction);
|
||||
expect(result.expected).toEqual(['a','b']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("wasCalledWith", function() {
|
||||
it("should alias toHaveBeenCalledWith", function() {
|
||||
spyOn(TestClass, 'normalFunction');
|
||||
|
||||
TestClass.normalFunction(123);
|
||||
|
||||
expect(TestClass.normalFunction).wasCalledWith(123);
|
||||
});
|
||||
});
|
||||
|
||||
describe("wasNotCalledWith", function() {
|
||||
it('should return true if the spy was NOT called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
expect(match(TestClass.spyFunction).wasNotCalledWith('c', 'b', 'a')).toPass();
|
||||
});
|
||||
|
||||
it('should return false if it WAS called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['a', 'b', 'c']);
|
||||
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
});
|
||||
|
||||
it('should return true if it was not called', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.wasNotCalledWith('c', 'b', 'a')).toPass();
|
||||
});
|
||||
|
||||
it('should allow matches across multiple calls', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
|
||||
expect(expected.wasNotCalledWith('d', 'e', 'f')).toFail();
|
||||
expect(expected.wasNotCalledWith('x', 'y', 'z')).toPass();
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalledWith'));
|
||||
});
|
||||
});
|
||||
|
||||
describe("all matchers", function() {
|
||||
it("should return null, for future-proofing, since we might eventually allow matcher chaining", function() {
|
||||
expect(match(true).toBe(true)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,38 +0,0 @@
|
||||
describe("MockClock", function () {
|
||||
|
||||
beforeEach(function() {
|
||||
jasmine.Clock.useMock();
|
||||
});
|
||||
|
||||
describe("setTimeout", function () {
|
||||
it("should mock the clock when useMock is in a beforeEach", function() {
|
||||
var expected = false;
|
||||
setTimeout(function() {
|
||||
expected = true;
|
||||
}, 30000);
|
||||
expect(expected).toBe(false);
|
||||
jasmine.Clock.tick(30001);
|
||||
expect(expected).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setInterval", function () {
|
||||
it("should mock the clock when useMock is in a beforeEach", function() {
|
||||
var interval = 0;
|
||||
setInterval(function() {
|
||||
interval++;
|
||||
}, 30000);
|
||||
expect(interval).toEqual(0);
|
||||
jasmine.Clock.tick(30001);
|
||||
expect(interval).toEqual(1);
|
||||
jasmine.Clock.tick(30001);
|
||||
expect(interval).toEqual(2);
|
||||
jasmine.Clock.tick(1);
|
||||
expect(interval).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
it("shouldn't complain if you call jasmine.Clock.useMock() more than once", function() {
|
||||
jasmine.Clock.useMock();
|
||||
});
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
describe("jasmine.MultiReporter", function() {
|
||||
var multiReporter, fakeReporter1, fakeReporter2;
|
||||
|
||||
beforeEach(function() {
|
||||
multiReporter = new jasmine.MultiReporter();
|
||||
fakeReporter1 = jasmine.createSpyObj("fakeReporter1", ["reportSpecResults"]);
|
||||
fakeReporter2 = jasmine.createSpyObj("fakeReporter2", ["reportSpecResults", "reportRunnerStarting"]);
|
||||
multiReporter.addReporter(fakeReporter1);
|
||||
multiReporter.addReporter(fakeReporter2);
|
||||
});
|
||||
|
||||
it("should support all the method calls that jasmine.Reporter supports", function() {
|
||||
var delegate = {};
|
||||
multiReporter.addReporter(delegate);
|
||||
|
||||
this.addMatchers({
|
||||
toDelegateMethod: function(methodName) {
|
||||
delegate[methodName] = jasmine.createSpy(methodName);
|
||||
this.actual[methodName]("whatever argument");
|
||||
|
||||
return delegate[methodName].wasCalled &&
|
||||
delegate[methodName].mostRecentCall.args.length == 1 &&
|
||||
delegate[methodName].mostRecentCall.args[0] == "whatever argument";
|
||||
}
|
||||
});
|
||||
|
||||
expect(multiReporter).toDelegateMethod('reportRunnerStarting');
|
||||
expect(multiReporter).toDelegateMethod('reportRunnerResults');
|
||||
expect(multiReporter).toDelegateMethod('reportSuiteResults');
|
||||
expect(multiReporter).toDelegateMethod('reportSpecStarting');
|
||||
expect(multiReporter).toDelegateMethod('reportSpecResults');
|
||||
expect(multiReporter).toDelegateMethod('log');
|
||||
});
|
||||
|
||||
it("should delegate to any and all subreporters", function() {
|
||||
multiReporter.reportSpecResults('blah', 'foo');
|
||||
expect(fakeReporter1.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
|
||||
expect(fakeReporter2.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
|
||||
});
|
||||
|
||||
it("should quietly skip delegating to any subreporters which lack the given method", function() {
|
||||
multiReporter.reportRunnerStarting('blah', 'foo');
|
||||
expect(fakeReporter2.reportRunnerStarting).toHaveBeenCalledWith('blah', 'foo');
|
||||
});
|
||||
});
|
||||
@@ -1,54 +0,0 @@
|
||||
describe('jasmine.NestedResults', function() {
|
||||
it('#addResult increments counters', function() {
|
||||
// Leaf case
|
||||
var results = new jasmine.NestedResults();
|
||||
|
||||
results.addResult(new jasmine.ExpectationResult({
|
||||
matcherName: "foo", passed: true, message: 'Passed.', actual: 'bar', expected: 'bar'}
|
||||
));
|
||||
|
||||
expect(results.getItems().length).toEqual(1);
|
||||
expect(results.totalCount).toEqual(1);
|
||||
expect(results.passedCount).toEqual(1);
|
||||
expect(results.failedCount).toEqual(0);
|
||||
|
||||
results.addResult(new jasmine.ExpectationResult({
|
||||
matcherName: "baz", passed: false, message: 'FAIL.', actual: "corge", expected: "quux"
|
||||
}));
|
||||
|
||||
expect(results.getItems().length).toEqual(2);
|
||||
expect(results.totalCount).toEqual(2);
|
||||
expect(results.passedCount).toEqual(1);
|
||||
expect(results.failedCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should roll up counts for nested results', function() {
|
||||
// Branch case
|
||||
var leafResultsOne = new jasmine.NestedResults();
|
||||
leafResultsOne.addResult(new jasmine.ExpectationResult({
|
||||
matcherName: "toSomething", passed: true, message: 'message', actual: '', expected:''
|
||||
}));
|
||||
|
||||
leafResultsOne.addResult(new jasmine.ExpectationResult({
|
||||
matcherName: "toSomethingElse", passed: false, message: 'message', actual: 'a', expected: 'b'
|
||||
}));
|
||||
|
||||
var leafResultsTwo = new jasmine.NestedResults();
|
||||
leafResultsTwo.addResult(new jasmine.ExpectationResult({
|
||||
matcherName: "toSomething", passed: true, message: 'message', actual: '', expected: ''
|
||||
}));
|
||||
leafResultsTwo.addResult(new jasmine.ExpectationResult({
|
||||
matcherName: "toSomethineElse", passed: false, message: 'message', actual: 'c', expected: 'd'
|
||||
}));
|
||||
|
||||
var branchResults = new jasmine.NestedResults();
|
||||
branchResults.addResult(leafResultsOne);
|
||||
branchResults.addResult(leafResultsTwo);
|
||||
|
||||
expect(branchResults.getItems().length).toEqual(2);
|
||||
expect(branchResults.totalCount).toEqual(4);
|
||||
expect(branchResults.passedCount).toEqual(2);
|
||||
expect(branchResults.failedCount).toEqual(2);
|
||||
});
|
||||
|
||||
});
|
||||
64
spec/core/ObjectContainingSpec.js
Normal file
64
spec/core/ObjectContainingSpec.js
Normal file
@@ -0,0 +1,64 @@
|
||||
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");
|
||||
});
|
||||
});
|
||||
@@ -1,45 +1,75 @@
|
||||
describe("jasmine.pp", function () {
|
||||
describe("j$.pp", function () {
|
||||
it("should wrap strings in single quotes", function() {
|
||||
expect(jasmine.pp("some string")).toEqual("'some string'");
|
||||
expect(jasmine.pp("som' string")).toEqual("'som' string'");
|
||||
expect(j$.pp("some string")).toEqual("'some string'");
|
||||
expect(j$.pp("som' string")).toEqual("'som' string'");
|
||||
});
|
||||
|
||||
it("should stringify primitives properly", function() {
|
||||
expect(jasmine.pp(true)).toEqual("true");
|
||||
expect(jasmine.pp(false)).toEqual("false");
|
||||
expect(jasmine.pp(null)).toEqual("null");
|
||||
expect(jasmine.pp(jasmine.undefined)).toEqual("undefined");
|
||||
expect(jasmine.pp(3)).toEqual("3");
|
||||
expect(jasmine.pp(-3.14)).toEqual("-3.14");
|
||||
expect(j$.pp(true)).toEqual("true");
|
||||
expect(j$.pp(false)).toEqual("false");
|
||||
expect(j$.pp(null)).toEqual("null");
|
||||
expect(j$.pp(jasmine.undefined)).toEqual("undefined");
|
||||
expect(j$.pp(3)).toEqual("3");
|
||||
expect(j$.pp(-3.14)).toEqual("-3.14");
|
||||
});
|
||||
|
||||
it("should stringify arrays properly", function() {
|
||||
expect(jasmine.pp([1, 2])).toEqual("[ 1, 2 ]");
|
||||
expect(jasmine.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', { }, undefined, null ]");
|
||||
expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
|
||||
expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', { }, undefined, null ]");
|
||||
});
|
||||
|
||||
it("should indicate circular array references", function() {
|
||||
var array1 = [1, 2];
|
||||
var array2 = [array1];
|
||||
array1.push(array2);
|
||||
expect(jasmine.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
|
||||
expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
|
||||
});
|
||||
|
||||
it("should stringify objects properly", function() {
|
||||
expect(jasmine.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
|
||||
expect(jasmine.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
|
||||
expect(jasmine.pp({foo: 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: function () {
|
||||
}, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
|
||||
});
|
||||
|
||||
it("should not include inherited properties when stringifying an object", function() {
|
||||
var SomeClass = function() {};
|
||||
SomeClass.prototype.foo = "inherited foo";
|
||||
var instance = new SomeClass();
|
||||
instance.bar = "my own bar";
|
||||
expect(j$.pp(instance)).toEqual("{ bar : 'my own bar' }");
|
||||
});
|
||||
|
||||
it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
|
||||
var originalMaxDepth = j$.MAX_PRETTY_PRINT_DEPTH;
|
||||
var nestedObject = { level1: { level2: { level3: { level4: "leaf" } } } };
|
||||
var nestedArray = [1, [2, [3, [4, "leaf"]]]];
|
||||
|
||||
try {
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 2;
|
||||
expect(j$.pp(nestedObject)).toEqual("{ level1 : { 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(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(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
|
||||
} finally {
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify RegExp objects properly", function() {
|
||||
expect(jasmine.pp(/x|y|z/)).toEqual("/x|y|z/");
|
||||
expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
|
||||
});
|
||||
|
||||
it("should indicate circular object references", function() {
|
||||
var sampleValue = {foo: 'hello'};
|
||||
sampleValue.nested = sampleValue;
|
||||
expect(jasmine.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
|
||||
expect(j$.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
|
||||
});
|
||||
|
||||
it("should indicate getters on objects as such", function() {
|
||||
@@ -51,37 +81,45 @@ describe("jasmine.pp", function () {
|
||||
});
|
||||
}
|
||||
if (sampleValue.__defineGetter__) {
|
||||
expect(jasmine.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
|
||||
expect(j$.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
|
||||
}
|
||||
else {
|
||||
expect(jasmine.pp(sampleValue)).toEqual("{ id : 1 }");
|
||||
expect(j$.pp(sampleValue)).toEqual("{ id : 1 }");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('should not do HTML escaping of strings', function() {
|
||||
expect(jasmine.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
|
||||
expect(j$.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
|
||||
});
|
||||
|
||||
it("should abbreviate the global (usually window) object", function() {
|
||||
expect(jasmine.pp(jasmine.getGlobal())).toEqual("<global>");
|
||||
expect(j$.pp(jasmine.getGlobal())).toEqual("<global>");
|
||||
});
|
||||
|
||||
it("should stringify Date objects properly", function() {
|
||||
var now = new Date();
|
||||
expect(jasmine.pp(now)).toEqual("Date(" + now.toString() + ")");
|
||||
expect(j$.pp(now)).toEqual("Date(" + now.toString() + ")");
|
||||
});
|
||||
|
||||
it("should stringify spy objects properly", function() {
|
||||
var TestObject = {
|
||||
someFunction: function() {
|
||||
}
|
||||
};
|
||||
spyOn(TestObject, 'someFunction');
|
||||
expect(jasmine.pp(TestObject.someFunction)).toEqual("spy on someFunction");
|
||||
someFunction: function() {}
|
||||
},
|
||||
env = new j$.Env();
|
||||
|
||||
expect(jasmine.pp(jasmine.createSpy("something"))).toEqual("spy on something");
|
||||
env.spyOn(TestObject, 'someFunction');
|
||||
expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
|
||||
|
||||
expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
|
||||
});
|
||||
|
||||
it("should stringify objects that implement jasmineToString", function () {
|
||||
var obj = {
|
||||
jasmineToString: function () { return "strung"; }
|
||||
};
|
||||
|
||||
expect(j$.pp(obj)).toEqual("strung");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
147
spec/core/QueueRunnerSpec.js
Normal file
147
spec/core/QueueRunnerSpec.js
Normal file
@@ -0,0 +1,147 @@
|
||||
describe("QueueRunner", function() {
|
||||
|
||||
it("runs all the functions it's passed", function() {
|
||||
var calls = [],
|
||||
fn1 = jasmine.createSpy('fn1'),
|
||||
fn2 = jasmine.createSpy('fn2'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2]
|
||||
});
|
||||
fn1.and.callFake(function() {
|
||||
calls.push('fn1');
|
||||
});
|
||||
fn2.and.callFake(function() {
|
||||
calls.push('fn2');
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(calls).toEqual(['fn1', 'fn2']);
|
||||
});
|
||||
|
||||
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
|
||||
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
|
||||
//createSpy('asyncfn').and.callFake(function(done) {});
|
||||
|
||||
var onComplete = jasmine.createSpy('onComplete'),
|
||||
beforeCallback = jasmine.createSpy('beforeCallback'),
|
||||
fnCallback = jasmine.createSpy('fnCallback'),
|
||||
afterCallback = jasmine.createSpy('afterCallback'),
|
||||
fn1 = function(done) {
|
||||
beforeCallback();
|
||||
setTimeout(function() {
|
||||
done()
|
||||
}, 100);
|
||||
},
|
||||
fn2 = function(done) {
|
||||
fnCallback();
|
||||
setTimeout(function() {
|
||||
done()
|
||||
}, 100);
|
||||
},
|
||||
fn3 = function(done) {
|
||||
afterCallback();
|
||||
setTimeout(function() {
|
||||
done()
|
||||
}, 100);
|
||||
},
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2, fn3],
|
||||
onComplete: onComplete
|
||||
});
|
||||
|
||||
clock.install();
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(beforeCallback).toHaveBeenCalled();
|
||||
expect(fnCallback).not.toHaveBeenCalled();
|
||||
expect(afterCallback).not.toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(fnCallback).toHaveBeenCalled();
|
||||
expect(afterCallback).not.toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(afterCallback).toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls an exception handler when an exception is thrown in a fn", function() {
|
||||
var fn = function() {
|
||||
throw new Error('fake error');
|
||||
},
|
||||
exceptionCallback = jasmine.createSpy('exception callback'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
onException: exceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
});
|
||||
|
||||
it("rethrows an exception if told to", function() {
|
||||
var fn = function() {
|
||||
throw new Error('fake error');
|
||||
},
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
catchException: function(e) { return false; }
|
||||
});
|
||||
|
||||
expect(function() { queueRunner.execute(); }).toThrow();
|
||||
});
|
||||
|
||||
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");
|
||||
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided complete callback when done", function() {
|
||||
var fn = jasmine.createSpy('fn'),
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
onComplete: completeCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(completeCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided stack clearing function when done", function() {
|
||||
var asyncFn = function(done) { done() },
|
||||
afterFn = jasmine.createSpy('afterFn'),
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
clearStack = jasmine.createSpy('clearStack'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [asyncFn, afterFn],
|
||||
clearStack: clearStack,
|
||||
onComplete: completeCallback
|
||||
});
|
||||
|
||||
clearStack.and.callFake(function(fn) { fn(); });
|
||||
|
||||
queueRunner.execute();
|
||||
expect(afterFn).toHaveBeenCalled();
|
||||
expect(clearStack).toHaveBeenCalledWith(completeCallback);
|
||||
});
|
||||
});
|
||||
@@ -1,23 +0,0 @@
|
||||
describe("jasmine.Queue", function() {
|
||||
it("should not call itself recursively, so we don't get stack overflow errors", function() {
|
||||
var queue = new jasmine.Queue(new jasmine.Env());
|
||||
queue.add(new jasmine.Block(null, function() {}));
|
||||
queue.add(new jasmine.Block(null, function() {}));
|
||||
queue.add(new jasmine.Block(null, function() {}));
|
||||
queue.add(new jasmine.Block(null, function() {}));
|
||||
|
||||
var nestCount = 0;
|
||||
var maxNestCount = 0;
|
||||
var nextCallCount = 0;
|
||||
queue.next_ = function() {
|
||||
nestCount++;
|
||||
if (nestCount > maxNestCount) maxNestCount = nestCount;
|
||||
|
||||
jasmine.Queue.prototype.next_.apply(queue, arguments);
|
||||
nestCount--;
|
||||
};
|
||||
|
||||
queue.start();
|
||||
expect(maxNestCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
40
spec/core/ReportDispatcherSpec.js
Normal file
40
spec/core/ReportDispatcherSpec.js
Normal file
@@ -0,0 +1,40 @@
|
||||
describe("ReportDispatcher", function() {
|
||||
|
||||
it("builds an interface of requested methods", function() {
|
||||
var dispatcher = new j$.ReportDispatcher(['foo', 'bar', 'baz']);
|
||||
|
||||
expect(dispatcher.foo).toBeDefined();
|
||||
expect(dispatcher.bar).toBeDefined();
|
||||
expect(dispatcher.baz).toBeDefined();
|
||||
});
|
||||
|
||||
it("dispatches requested methods to added reporters", function() {
|
||||
var dispatcher = new j$.ReportDispatcher(['foo', 'bar']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
|
||||
|
||||
dispatcher.addReporter(reporter);
|
||||
dispatcher.addReporter(anotherReporter);
|
||||
|
||||
dispatcher.foo(123, 456);
|
||||
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
|
||||
dispatcher.bar('a', 'b');
|
||||
|
||||
expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
|
||||
expect(anotherReporter.bar).toHaveBeenCalledWith('a', 'b');
|
||||
});
|
||||
|
||||
it("does not dispatch to a reporter if the reporter doesn't accept the method", function() {
|
||||
var dispatcher = new j$.ReportDispatcher(['foo']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['baz']);
|
||||
|
||||
dispatcher.addReporter(reporter);
|
||||
|
||||
expect(function() {
|
||||
dispatcher.foo(123, 456);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
@@ -1,56 +0,0 @@
|
||||
describe('jasmine.Reporter', function() {
|
||||
var env;
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
});
|
||||
|
||||
it('should get called from the test runner', function() {
|
||||
env.describe('Suite for JSON Reporter with Callbacks', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.it('should be a failing test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(false).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
env.describe('Suite for JSON Reporter with Callbacks 2', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var foo = 0;
|
||||
var bar = 0;
|
||||
var baz = 0;
|
||||
|
||||
env.addReporter({
|
||||
reportSpecResults: function() {
|
||||
foo++;
|
||||
},
|
||||
reportSuiteResults: function() {
|
||||
bar++;
|
||||
},
|
||||
reportRunnerResults: function() {
|
||||
baz++;
|
||||
}
|
||||
});
|
||||
|
||||
var runner = env.currentRunner();
|
||||
runner.execute();
|
||||
|
||||
expect(foo).toEqual(3); // 'foo was expected to be 3, was ' + foo);
|
||||
expect(bar).toEqual(2); // 'bar was expected to be 2, was ' + bar);
|
||||
expect(baz).toEqual(1); // 'baz was expected to be 1, was ' + baz);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,267 +0,0 @@
|
||||
describe('RunnerTest', function() {
|
||||
var fakeTimer;
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
fakeTimer = new jasmine.FakeTimer();
|
||||
env.setTimeout = fakeTimer.setTimeout;
|
||||
env.clearTimeout = fakeTimer.clearTimeout;
|
||||
env.setInterval = fakeTimer.setInterval;
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
});
|
||||
|
||||
describe('beforeEach', function() {
|
||||
it('should run before each spec for all suites', function () {
|
||||
var foo;
|
||||
env.beforeEach(function () {
|
||||
foo = 0;
|
||||
});
|
||||
|
||||
env.describe('suite 1', function () {
|
||||
env.it('test 1-1', function() {
|
||||
foo++;
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
env.it('test 1-2', function() {
|
||||
foo++;
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('suite 2', function () {
|
||||
env.it('test 2-1', function() {
|
||||
foo++;
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
|
||||
var runnerResults = env.currentRunner().results();
|
||||
expect(runnerResults.totalCount).toEqual(3);
|
||||
expect(runnerResults.passedCount).toEqual(3);
|
||||
});
|
||||
|
||||
|
||||
it('should provide all specs', function () {
|
||||
var foo;
|
||||
env.beforeEach(function () {
|
||||
foo = 0;
|
||||
});
|
||||
|
||||
env.describe('suite 1', function () {
|
||||
env.it('test 1-1', function() {
|
||||
foo++;
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
env.it('test 1-2', function() {
|
||||
foo++;
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('suite 2', function () {
|
||||
env.it('test 2-1', function() {
|
||||
foo++;
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
|
||||
|
||||
expect(env.currentRunner().specs().length).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('afterEach', function() {
|
||||
it('should run after each spec for all suites', function () {
|
||||
var foo = 3;
|
||||
env.afterEach(function () {
|
||||
foo = foo - 1;
|
||||
});
|
||||
|
||||
env.describe('suite 1', function () {
|
||||
env.it('test 1-1', function() {
|
||||
this.expect(foo).toEqual(3);
|
||||
});
|
||||
env.it('test 1-2', function() {
|
||||
this.expect(foo).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('suite 2', function () {
|
||||
env.it('test 2-1', function() {
|
||||
this.expect(foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
|
||||
var runnerResults = env.currentRunner().results();
|
||||
expect(runnerResults.totalCount).toEqual(3);
|
||||
expect(runnerResults.passedCount).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should run child suites and specs and generate results when execute is called', function() {
|
||||
env.describe('one suite description', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('another suite description', function () {
|
||||
env.it('should be another test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
|
||||
var runnerResults = env.currentRunner().results();
|
||||
expect(runnerResults.totalCount).toEqual(2);
|
||||
expect(runnerResults.passedCount).toEqual(1);
|
||||
expect(runnerResults.failedCount).toEqual(1);
|
||||
});
|
||||
|
||||
|
||||
it('should ignore suites that have been x\'d', function() {
|
||||
env.xdescribe('one suite description', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('another suite description', function () {
|
||||
env.it('should be another test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
|
||||
var runnerResults = env.currentRunner().results();
|
||||
expect(runnerResults.totalCount).toEqual(1);
|
||||
expect(runnerResults.passedCount).toEqual(0);
|
||||
expect(runnerResults.failedCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should roll up results from all specs', function() {
|
||||
env.describe('one suite description', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('another suite description', function () {
|
||||
env.it('should be another test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
|
||||
var results = env.currentRunner().results();
|
||||
expect(results.totalCount).toEqual(2);
|
||||
expect(results.passedCount).toEqual(1);
|
||||
expect(results.failedCount).toEqual(1);
|
||||
});
|
||||
|
||||
describe('reporting', function () {
|
||||
var fakeReporter;
|
||||
beforeEach(function () {
|
||||
fakeReporter = jasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting", "reportRunnerResults"]);
|
||||
env.addReporter(fakeReporter);
|
||||
});
|
||||
|
||||
it('should report runner results when the runner has completed running', function() {
|
||||
env.describe('one suite description', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('another suite description', function () {
|
||||
env.it('should be another test', function() {
|
||||
this.waits(200);
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.currentRunner().execute();
|
||||
expect(fakeReporter.reportRunnerResults).not.toHaveBeenCalled();
|
||||
fakeTimer.tick(200);
|
||||
//This blows up the JSApiReporter.
|
||||
//expect(fakeReporter.reportRunnerResults).toHaveBeenCalledWith(env.currentRunner);
|
||||
expect(fakeReporter.reportRunnerResults).toHaveBeenCalled();
|
||||
expect(fakeReporter.reportRunnerResults.mostRecentCall.args[0].results()).toEqual(env.currentRunner().results());
|
||||
});
|
||||
});
|
||||
|
||||
it("should report when the tests start running", function() {
|
||||
var fakeReporter = jasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting"]);
|
||||
env.addReporter(fakeReporter);
|
||||
|
||||
|
||||
var runner = new jasmine.Runner(env);
|
||||
runner.arbitraryVariable = 'foo';
|
||||
spyOn(runner.queue, 'start');
|
||||
expect(fakeReporter.reportRunnerStarting).not.toHaveBeenCalled();
|
||||
runner.execute();
|
||||
expect(fakeReporter.reportRunnerStarting).toHaveBeenCalled();
|
||||
var reportedRunner = fakeReporter.reportRunnerStarting.mostRecentCall.args[0];
|
||||
expect(reportedRunner.arbitraryVariable).toEqual('foo');
|
||||
expect(runner.queue.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("when suites are nested", function() {
|
||||
var suite1, suite2, suite3;
|
||||
|
||||
function suiteNames(suites) {
|
||||
var suiteDescriptions = [];
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
suiteDescriptions.push(suites[i].getFullName());
|
||||
}
|
||||
return suiteDescriptions;
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
suite1 = env.describe("suite 1", function() {
|
||||
suite2 = env.describe("suite 2", function() {
|
||||
});
|
||||
});
|
||||
suite3 = env.describe("suite 3", function() {});
|
||||
});
|
||||
|
||||
it("#suites should return a flat array of all suites, including nested suites", function() {
|
||||
var suites = env.currentRunner().suites();
|
||||
expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite2.getFullName(), suite3.getFullName()]);
|
||||
});
|
||||
|
||||
it("#topLevelSuites should return a flat array of all top-level suites only", function() {
|
||||
var suites = env.currentRunner().topLevelSuites();
|
||||
expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite3.getFullName()]);
|
||||
});
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,124 +1,244 @@
|
||||
describe('Spec', function () {
|
||||
var env, suite;
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
suite = new jasmine.Suite(env, 'suite 1');
|
||||
describe("Spec", function() {
|
||||
|
||||
it("#isPendingSpecException returns true for a pending spec exception", function() {
|
||||
var e = new Error(j$.Spec.pendingSpecExceptionMessage);
|
||||
|
||||
expect(j$.Spec.isPendingSpecException(e)).toBe(true);
|
||||
});
|
||||
|
||||
describe('initialization', function () {
|
||||
it("#isPendingSpecException returns true for a pending spec exception (even when FF bug is present)", function() {
|
||||
var fakeError = {
|
||||
toString: function() { return "Error: " + j$.Spec.pendingSpecExceptionMessage; }
|
||||
};
|
||||
|
||||
it('should raise an error if an env is not passed', function () {
|
||||
try {
|
||||
new jasmine.Spec();
|
||||
}
|
||||
catch (e) {
|
||||
expect(e.message).toEqual('jasmine.Env() required');
|
||||
}
|
||||
});
|
||||
|
||||
it('should raise an error if a suite is not passed', function () {
|
||||
try {
|
||||
new jasmine.Spec(env);
|
||||
}
|
||||
catch (e) {
|
||||
expect(e.message).toEqual('jasmine.Suite() required');
|
||||
}
|
||||
});
|
||||
|
||||
it('should assign sequential ids for specs belonging to the same env', function () {
|
||||
var spec1 = new jasmine.Spec(env, suite);
|
||||
var spec2 = new jasmine.Spec(env, suite);
|
||||
var spec3 = new jasmine.Spec(env, suite);
|
||||
expect(spec1.id).toEqual(0);
|
||||
expect(spec2.id).toEqual(1);
|
||||
expect(spec3.id).toEqual(2);
|
||||
});
|
||||
expect(j$.Spec.isPendingSpecException(fakeError)).toBe(true);
|
||||
});
|
||||
|
||||
it('getFullName returns suite & spec description', function () {
|
||||
var spec = new jasmine.Spec(env, suite, 'spec 1');
|
||||
expect(spec.getFullName()).toEqual('suite 1 spec 1.');
|
||||
it("#isPendingSpecException returns true for a pending spec exception", function() {
|
||||
var e = new Error("foo");
|
||||
|
||||
expect(j$.Spec.isPendingSpecException(e)).toBe(false);
|
||||
});
|
||||
|
||||
describe('results', function () {
|
||||
var spec, results;
|
||||
beforeEach(function () {
|
||||
spec = new jasmine.Spec(env, suite);
|
||||
results = spec.results();
|
||||
expect(results.totalCount).toEqual(0);
|
||||
spec.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
this.expect(true).toEqual(true);
|
||||
it("delegates execution to a QueueRunner", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
fn: function() {},
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
it('results shows the total number of expectations for each spec after execution', function () {
|
||||
expect(results.totalCount).toEqual(0);
|
||||
spec.execute();
|
||||
expect(results.totalCount).toEqual(2);
|
||||
});
|
||||
expect(fakeQueueRunner).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('results shows the number of passed expectations for each spec after execution', function () {
|
||||
expect(results.passedCount).toEqual(0);
|
||||
spec.execute();
|
||||
expect(results.passedCount).toEqual(2);
|
||||
});
|
||||
|
||||
it('results shows the number of failed expectations for each spec after execution', function () {
|
||||
spec.runs(function () {
|
||||
this.expect(true).toEqual(false);
|
||||
it("should call the start callback on execution", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
beforesWereCalled = false,
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
spec = new j$.Spec({
|
||||
id: 123,
|
||||
description: 'foo bar',
|
||||
fn: function() {},
|
||||
onStart: startCallback,
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
expect(results.failedCount).toEqual(0);
|
||||
spec.execute();
|
||||
expect(results.failedCount).toEqual(1);
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(startCallback).toHaveBeenCalledWith(spec);
|
||||
});
|
||||
|
||||
it("should call the start callback on execution but before any befores are called", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
beforesWereCalled = false,
|
||||
startCallback = jasmine.createSpy('start-callback').and.callFake(function() {
|
||||
expect(beforesWereCalled).toBe(false);
|
||||
}),
|
||||
spec = new j$.Spec({
|
||||
fn: function() {},
|
||||
beforeFns: function() {
|
||||
return [function() {
|
||||
beforesWereCalled = true
|
||||
}]
|
||||
},
|
||||
onStart: startCallback,
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("provides all before fns and after fns to be run", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
before = jasmine.createSpy('before'),
|
||||
after = jasmine.createSpy('after'),
|
||||
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]
|
||||
},
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].fns;
|
||||
expect(allSpecFns).toEqual([before, fn, after]);
|
||||
});
|
||||
|
||||
it("is marked pending if created without a function body", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart: startCallback,
|
||||
fn: null,
|
||||
resultCallback: resultCallback,
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
|
||||
|
||||
expect(spec.status()).toBe('pending');
|
||||
});
|
||||
|
||||
it("can be disabled, but still calls callbacks", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
specBody = jasmine.createSpy('specBody'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart:startCallback,
|
||||
fn: specBody,
|
||||
resultCallback: resultCallback,
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.disable();
|
||||
|
||||
expect(spec.status()).toBe('disabled');
|
||||
|
||||
spec.execute();
|
||||
|
||||
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'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart: startCallback,
|
||||
resultCallback: resultCallback,
|
||||
description: "with a spec",
|
||||
getSpecName: function() {
|
||||
return "a suite with a spec"
|
||||
},
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.pend();
|
||||
|
||||
expect(spec.status()).toBe('pending');
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
expect(resultCallback).toHaveBeenCalledWith({
|
||||
id: spec.id,
|
||||
status: 'pending',
|
||||
description: 'with a spec',
|
||||
fullName: 'a suite with a spec',
|
||||
failedExpectations: []
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the done callback on execution complete", function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new j$.Spec({
|
||||
fn: function() {},
|
||||
catchExceptions: function() { return false; },
|
||||
resultCallback: function() {},
|
||||
queueRunner: function(attrs) { attrs.onComplete(); }
|
||||
});
|
||||
|
||||
spec.execute(done);
|
||||
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("#status returns pending by default", function() {
|
||||
var spec = new j$.Spec({fn: jasmine.createSpy("spec body")});
|
||||
expect(spec.status()).toEqual('pending');
|
||||
});
|
||||
|
||||
it("#status returns pending if no expectations were encountered", function() {
|
||||
var specBody = jasmine.createSpy("spec body"),
|
||||
spec = new j$.Spec({fn: specBody});
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(spec.status()).toEqual('pending');
|
||||
});
|
||||
|
||||
it("#status returns passed if all expectations in the spec have passed", function() {
|
||||
var spec = new j$.Spec({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") });
|
||||
spec.addExpectationResult(true);
|
||||
spec.addExpectationResult(false);
|
||||
expect(spec.status()).toBe('failed');
|
||||
});
|
||||
|
||||
it("can return its full name", function() {
|
||||
var spec;
|
||||
spec = new j$.Spec({
|
||||
getSpecName: function(passedVal) {
|
||||
// expect(passedVal).toBe(spec); TODO: a exec time, spec is undefined WTF?
|
||||
return 'expected val';
|
||||
}
|
||||
});
|
||||
|
||||
describe('results.passed', function () {
|
||||
it('is true if all spec expectations pass', function () {
|
||||
spec.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
expect(spec.getFullName()).toBe('expected val');
|
||||
});
|
||||
|
||||
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));
|
||||
},
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
fn: function() { },
|
||||
queueRunner: fakeQueueRunner
|
||||
});
|
||||
spec.execute();
|
||||
expect(results.passed()).toEqual(true);
|
||||
});
|
||||
|
||||
it('is false if one spec expectation fails', function () {
|
||||
spec.runs(function () {
|
||||
this.expect(true).toEqual(false);
|
||||
});
|
||||
spec.execute();
|
||||
expect(results.passed()).toEqual(false);
|
||||
});
|
||||
|
||||
it('a spec with no expectations will return true', function () {
|
||||
var specWithoutExpectations = new jasmine.Spec(env, suite);
|
||||
specWithoutExpectations.runs(function() {
|
||||
|
||||
});
|
||||
specWithoutExpectations.execute();
|
||||
expect(results.passed()).toEqual(true);
|
||||
});
|
||||
|
||||
it('an unexecuted spec will return true', function () {
|
||||
expect(results.passed()).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("includes log messages, which may contain arbitary objects", function() {
|
||||
spec.runs(function() {
|
||||
this.log("here's some log message", {key: 'value'}, 123);
|
||||
});
|
||||
spec.execute();
|
||||
var items = results.getItems();
|
||||
expect(items).toEqual([
|
||||
jasmine.any(jasmine.ExpectationResult),
|
||||
jasmine.any(jasmine.ExpectationResult),
|
||||
jasmine.any(jasmine.MessageResult)
|
||||
]);
|
||||
var logResult = items[2];
|
||||
expect(logResult.values).toEqual(["here's some log message", {key: 'value'}, 123]);
|
||||
|
||||
expect(spec.status()).toEqual("pending");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,201 +1,48 @@
|
||||
describe('Spies', function () {
|
||||
it('should replace the specified function with a spy object', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
}
|
||||
};
|
||||
this.spyOn(TestClass, 'someFunction');
|
||||
describe("createSpy", function() {
|
||||
var TestClass;
|
||||
|
||||
expect(TestClass.someFunction.wasCalled).toEqual(false);
|
||||
expect(TestClass.someFunction.callCount).toEqual(0);
|
||||
TestClass.someFunction('foo');
|
||||
expect(TestClass.someFunction.wasCalled).toEqual(true);
|
||||
expect(TestClass.someFunction.callCount).toEqual(1);
|
||||
expect(TestClass.someFunction.mostRecentCall.args).toEqual(['foo']);
|
||||
expect(TestClass.someFunction.mostRecentCall.object).toEqual(TestClass);
|
||||
expect(originalFunctionWasCalled).toEqual(false);
|
||||
beforeEach(function() {
|
||||
TestClass = 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);
|
||||
|
||||
TestClass.someFunction('bar');
|
||||
expect(TestClass.someFunction.callCount).toEqual(2);
|
||||
expect(TestClass.someFunction.mostRecentCall.args).toEqual(['bar']);
|
||||
});
|
||||
|
||||
it('should allow you to view args for a particular call', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
}
|
||||
};
|
||||
this.spyOn(TestClass, 'someFunction');
|
||||
|
||||
TestClass.someFunction('foo');
|
||||
TestClass.someFunction('bar');
|
||||
expect(TestClass.someFunction.calls[0].args).toEqual(['foo']);
|
||||
expect(TestClass.someFunction.calls[1].args).toEqual(['bar']);
|
||||
expect(TestClass.someFunction.mostRecentCall.args).toEqual(['bar']);
|
||||
});
|
||||
|
||||
it('should be possible to call through to the original method, or return a specific result', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var passedArgs;
|
||||
var passedObj;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
passedArgs = arguments;
|
||||
passedObj = this;
|
||||
return "return value from original function";
|
||||
}
|
||||
};
|
||||
|
||||
this.spyOn(TestClass, 'someFunction').andCallThrough();
|
||||
var result = TestClass.someFunction('arg1', 'arg2');
|
||||
expect(result).toEqual("return value from original function");
|
||||
expect(originalFunctionWasCalled).toEqual(true);
|
||||
expect(passedArgs).toEqual(['arg1', 'arg2']);
|
||||
expect(passedObj).toEqual(TestClass);
|
||||
expect(TestClass.someFunction.wasCalled).toEqual(true);
|
||||
});
|
||||
|
||||
it('should be possible to return a specific value', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
return "return value from original function";
|
||||
}
|
||||
};
|
||||
|
||||
this.spyOn(TestClass, 'someFunction').andReturn("some value");
|
||||
originalFunctionWasCalled = false;
|
||||
var result = TestClass.someFunction('arg1', 'arg2');
|
||||
expect(result).toEqual("some value");
|
||||
expect(originalFunctionWasCalled).toEqual(false);
|
||||
});
|
||||
|
||||
it('should be possible to throw a specific error', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
return "return value from original function";
|
||||
}
|
||||
};
|
||||
|
||||
this.spyOn(TestClass, 'someFunction').andThrow(new Error('fake error'));
|
||||
var exception;
|
||||
try {
|
||||
TestClass.someFunction('arg1', 'arg2');
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
expect(exception.message).toEqual('fake error');
|
||||
expect(originalFunctionWasCalled).toEqual(false);
|
||||
});
|
||||
|
||||
it('should be possible to call a specified function', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var fakeFunctionWasCalled = false;
|
||||
var passedArgs;
|
||||
var passedObj;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
return "return value from original function";
|
||||
}
|
||||
};
|
||||
|
||||
this.spyOn(TestClass, 'someFunction').andCallFake(function() {
|
||||
fakeFunctionWasCalled = true;
|
||||
passedArgs = arguments;
|
||||
passedObj = this;
|
||||
return "return value from fake function";
|
||||
expect(spy.bob).toEqual("test");
|
||||
});
|
||||
|
||||
var result = TestClass.someFunction('arg1', 'arg2');
|
||||
expect(result).toEqual("return value from fake function");
|
||||
expect(originalFunctionWasCalled).toEqual(false);
|
||||
expect(fakeFunctionWasCalled).toEqual(true);
|
||||
expect(passedArgs).toEqual(['arg1', 'arg2']);
|
||||
expect(passedObj).toEqual(TestClass);
|
||||
expect(TestClass.someFunction.wasCalled).toEqual(true);
|
||||
});
|
||||
it("warns the user that we indend to overwrite an existing property", function() {
|
||||
TestClass.prototype.someFunction.and = "turkey";
|
||||
|
||||
it('is torn down when this.removeAllSpies is called', function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var TestClass = {
|
||||
someFunction: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
}
|
||||
};
|
||||
this.spyOn(TestClass, 'someFunction');
|
||||
expect(function() {
|
||||
j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
}).toThrowError("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon");
|
||||
});
|
||||
|
||||
TestClass.someFunction('foo');
|
||||
expect(originalFunctionWasCalled).toEqual(false);
|
||||
it("adds a spyStrategy and callTracker to the spy", function() {
|
||||
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
|
||||
this.removeAllSpies();
|
||||
|
||||
TestClass.someFunction('foo');
|
||||
expect(originalFunctionWasCalled).toEqual(true);
|
||||
});
|
||||
|
||||
it('calls removeAllSpies during spec finish', function() {
|
||||
var test = new jasmine.Spec(new jasmine.Env(), {}, 'sample test');
|
||||
|
||||
this.spyOn(test, 'removeAllSpies');
|
||||
|
||||
test.finish();
|
||||
|
||||
expect(test.removeAllSpies).wasCalled();
|
||||
});
|
||||
|
||||
it('throws an exception when some method is spied on twice', function() {
|
||||
var TestClass = { someFunction: function() {
|
||||
} };
|
||||
this.spyOn(TestClass, 'someFunction');
|
||||
var exception;
|
||||
try {
|
||||
this.spyOn(TestClass, 'someFunction');
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
expect(exception).toBeDefined();
|
||||
});
|
||||
|
||||
it('should be able to reset a spy', function() {
|
||||
var TestClass = { someFunction: function() {} };
|
||||
this.spyOn(TestClass, 'someFunction');
|
||||
|
||||
expect(TestClass.someFunction).not.toHaveBeenCalled();
|
||||
TestClass.someFunction();
|
||||
expect(TestClass.someFunction).toHaveBeenCalled();
|
||||
TestClass.someFunction.reset();
|
||||
expect(TestClass.someFunction).not.toHaveBeenCalled();
|
||||
expect(TestClass.someFunction.callCount).toEqual(0);
|
||||
expect(spy.and).toEqual(jasmine.any(j$.SpyStrategy));
|
||||
expect(spy.calls).toEqual(jasmine.any(j$.CallTracker));
|
||||
});
|
||||
});
|
||||
|
||||
describe("createSpyObj", function() {
|
||||
it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
|
||||
var spyObj = jasmine.createSpyObj('BaseName', ['method1', 'method2']);
|
||||
var spyObj = j$.createSpyObj('BaseName', ['method1', 'method2']);
|
||||
|
||||
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
|
||||
expect(spyObj.method1.identity).toEqual('BaseName.method1');
|
||||
expect(spyObj.method2.identity).toEqual('BaseName.method2');
|
||||
expect(spyObj.method1.and.identity()).toEqual('BaseName.method1');
|
||||
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
|
||||
});
|
||||
|
||||
it("should throw if you do not pass an array argument", function() {
|
||||
expect(function() {
|
||||
jasmine.createSpyObj('BaseName');
|
||||
}).toThrow('createSpyObj requires a non-empty array of method names to create spies for');
|
||||
});
|
||||
|
||||
it("should throw if you pass an empty array argument", function() {
|
||||
expect(function() {
|
||||
jasmine.createSpyObj('BaseName');
|
||||
}).toThrow('createSpyObj requires a non-empty array of method names to create spies for');
|
||||
j$.createSpyObj('BaseName');
|
||||
}).toThrow("createSpyObj requires a non-empty array of method names to create spies for");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
101
spec/core/SpyStrategySpec.js
Normal file
101
spec/core/SpyStrategySpec.js
Normal file
@@ -0,0 +1,101 @@
|
||||
describe("SpyStrategy", function() {
|
||||
|
||||
it("defaults its name to unknown", function() {
|
||||
var spyStrategy = new j$.SpyStrategy();
|
||||
|
||||
expect(spyStrategy.identity()).toEqual("unknown");
|
||||
});
|
||||
|
||||
it("takes a name", function() {
|
||||
var spyStrategy = new j$.SpyStrategy({name: "foo"});
|
||||
|
||||
expect(spyStrategy.identity()).toEqual("foo");
|
||||
});
|
||||
|
||||
it("stubs an original function, if provided", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn});
|
||||
|
||||
spyStrategy.exec();
|
||||
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows an original function to be called, passed through the params and returns it's value", function() {
|
||||
var originalFn = jasmine.createSpy("original").and.callReturn(42),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
|
||||
returnValue;
|
||||
|
||||
spyStrategy.callThrough();
|
||||
returnValue = spyStrategy.exec("foo");
|
||||
|
||||
expect(originalFn).toHaveBeenCalled();
|
||||
expect(originalFn.calls.mostRecent().args).toEqual(["foo"]);
|
||||
expect(returnValue).toEqual(42);
|
||||
});
|
||||
|
||||
it("can return a specified value when executed", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
|
||||
returnValue;
|
||||
|
||||
spyStrategy.callReturn(17);
|
||||
returnValue = spyStrategy.exec();
|
||||
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
expect(returnValue).toEqual(17);
|
||||
});
|
||||
|
||||
it("allows an exception to be thrown when executed", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn});
|
||||
|
||||
spyStrategy.callThrow("bar");
|
||||
|
||||
expect(function() { spyStrategy.exec(); }).toThrow("bar");
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows a fake function to be called instead", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
fakeFn = jasmine.createSpy("fake").and.callReturn(67),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
|
||||
returnValue;
|
||||
|
||||
spyStrategy.callFake(fakeFn);
|
||||
returnValue = spyStrategy.exec();
|
||||
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
expect(returnValue).toEqual(67);
|
||||
});
|
||||
|
||||
it("allows a return to plan stubbing after another strategy", function() {
|
||||
var originalFn = jasmine.createSpy("original"),
|
||||
fakeFn = jasmine.createSpy("fake").and.callReturn(67),
|
||||
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
|
||||
returnValue;
|
||||
|
||||
spyStrategy.callFake(fakeFn);
|
||||
returnValue = spyStrategy.exec();
|
||||
|
||||
expect(originalFn).not.toHaveBeenCalled();
|
||||
expect(returnValue).toEqual(67);
|
||||
|
||||
spyStrategy.stub();
|
||||
returnValue = spyStrategy.exec();
|
||||
|
||||
expect(returnValue).toEqual(void 0);
|
||||
});
|
||||
|
||||
it("returns the spy after changing the strategy", function(){
|
||||
var spy = {},
|
||||
spyFn = jasmine.createSpy('spyFn').and.callReturn(spy),
|
||||
spyStrategy = new j$.SpyStrategy({getSpy: spyFn});
|
||||
|
||||
expect(spyStrategy.callThrough()).toBe(spy);
|
||||
expect(spyStrategy.callReturn()).toBe(spy);
|
||||
expect(spyStrategy.callThrow()).toBe(spy);
|
||||
expect(spyStrategy.callFake()).toBe(spy);
|
||||
expect(spyStrategy.stub()).toBe(spy);
|
||||
});
|
||||
});
|
||||
@@ -1,120 +1,230 @@
|
||||
describe('Suite', function() {
|
||||
var fakeTimer;
|
||||
var env;
|
||||
describe("Suite", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
fakeTimer = new jasmine.FakeTimer();
|
||||
env.setTimeout = fakeTimer.setTimeout;
|
||||
env.clearTimeout = fakeTimer.clearTimeout;
|
||||
env.setInterval = fakeTimer.setInterval;
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
});
|
||||
|
||||
describe('Specs', function () {
|
||||
var suite;
|
||||
|
||||
beforeEach(function() {
|
||||
suite = env.describe('Suite 1', function () {
|
||||
env.it('Spec 1', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.it('Spec 2', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.describe('Suite 2', function () {
|
||||
env.it('Spec 3', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
env.it('Spec 4', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('#specs should return all immediate children that are specs.', function () {
|
||||
var suiteSpecs = suite.specs();
|
||||
expect(suiteSpecs.length).toEqual(3);
|
||||
expect(suiteSpecs[0].description).toEqual('Spec 1');
|
||||
expect(suiteSpecs[1].description).toEqual('Spec 2');
|
||||
expect(suiteSpecs[2].description).toEqual('Spec 4');
|
||||
});
|
||||
|
||||
it("#suites should return all immediate children that are suites.", function() {
|
||||
var nestedSuites = suite.suites();
|
||||
expect(nestedSuites.length).toEqual(1);
|
||||
expect(nestedSuites[0].description).toEqual('Suite 2');
|
||||
});
|
||||
|
||||
it("#children should return all immediate children including suites and specs.", function() {
|
||||
var children = suite.children();
|
||||
expect(children.length).toEqual(4);
|
||||
expect(children[0].description).toEqual('Spec 1');
|
||||
expect(children[1].description).toEqual('Spec 2');
|
||||
expect(children[2].description).toEqual('Suite 2');
|
||||
expect(children[3].description).toEqual('Spec 4');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SpecCount', function () {
|
||||
|
||||
it('should keep a count of the number of specs that are run', function() {
|
||||
var suite = env.describe('one suite description', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.it('should be another test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.it('should be a third test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
it("keeps its id", function() {
|
||||
var env = new j$.Env(),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
id: 456,
|
||||
description: "I am a suite"
|
||||
});
|
||||
|
||||
expect(suite.specs().length).toEqual(3);
|
||||
});
|
||||
expect(suite.id).toEqual(456);
|
||||
});
|
||||
|
||||
it('specCount should be correct even with runs/waits blocks', function() {
|
||||
var suite = env.describe('one suite description', function () {
|
||||
env.it('should be a test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.it('should be another test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
this.waits(10);
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
env.it('should be a third test', function() {
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
it("returns its full name", function() {
|
||||
var env = new j$.Env(),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite"
|
||||
});
|
||||
|
||||
expect(suite.specs().length).toEqual(3);
|
||||
expect(suite.getFullName()).toEqual("I am a suite");
|
||||
});
|
||||
|
||||
it("returns its full name when it has parent suites", function() {
|
||||
var env = new j$.Env(),
|
||||
parentSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a parent suite",
|
||||
parentSuite: jasmine.createSpy('pretend top level suite')
|
||||
}),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
parentSuite: parentSuite
|
||||
});
|
||||
|
||||
expect(suite.getFullName()).toEqual("I am a parent suite I am a suite");
|
||||
});
|
||||
|
||||
it("adds before functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite"
|
||||
}),
|
||||
outerBefore = jasmine.createSpy('outerBeforeEach'),
|
||||
innerBefore = jasmine.createSpy('insideBeforeEach');
|
||||
|
||||
suite.beforeEach(outerBefore);
|
||||
suite.beforeEach(innerBefore);
|
||||
|
||||
expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
|
||||
});
|
||||
|
||||
it("adds after functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite"
|
||||
}),
|
||||
outerAfter = jasmine.createSpy('outerAfterEach'),
|
||||
innerAfter = jasmine.createSpy('insideAfterEach');
|
||||
|
||||
suite.afterEach(outerAfter);
|
||||
suite.afterEach(innerAfter);
|
||||
|
||||
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
|
||||
});
|
||||
|
||||
it("adds specs", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueue = {
|
||||
add: jasmine.createSpy()
|
||||
},
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueFactory: function() {
|
||||
return fakeQueue
|
||||
}
|
||||
}),
|
||||
fakeSpec = {};
|
||||
|
||||
expect(suite.specs.length).toEqual(0);
|
||||
|
||||
suite.addSpec(fakeSpec);
|
||||
|
||||
expect(suite.specs.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("adds suites", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueue = {
|
||||
add: jasmine.createSpy()
|
||||
},
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueFactory: function() {
|
||||
return fakeQueue
|
||||
}
|
||||
}),
|
||||
anotherSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am another suite",
|
||||
queueFactory: function() {
|
||||
return fakeQueue
|
||||
}
|
||||
});
|
||||
|
||||
expect(suite.suites.length).toEqual(0);
|
||||
|
||||
suite.addSuite(anotherSuite);
|
||||
|
||||
expect(suite.suites.length).toEqual(1);
|
||||
});
|
||||
|
||||
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
|
||||
});
|
||||
|
||||
suite.disable();
|
||||
|
||||
expect(suite.disabled).toBe(true);
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
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')
|
||||
};
|
||||
|
||||
spyOn(suite, "execute");
|
||||
|
||||
parentSuite.addSpec(fakeSpec1);
|
||||
parentSuite.addSuite(suite);
|
||||
|
||||
parentSuite.execute(parentSuiteDone);
|
||||
|
||||
var parentSuiteFns = fakeQueueRunnerForParent.calls.mostRecent().args[0].fns;
|
||||
|
||||
parentSuiteFns[0]();
|
||||
expect(fakeSpec1.execute).toHaveBeenCalled();
|
||||
parentSuiteFns[1]();
|
||||
expect(suite.execute).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
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')
|
||||
};
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(suiteStarted).toHaveBeenCalledWith(suite);
|
||||
});
|
||||
|
||||
it("calls a provided onComplete callback when done", function() {
|
||||
var env = new j$.Env(),
|
||||
suiteCompleted = jasmine.createSpy('parent suite done'),
|
||||
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
};
|
||||
|
||||
suite.execute(suiteCompleted);
|
||||
|
||||
expect(suiteCompleted).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided result callback when done", function() {
|
||||
var env = new j$.Env(),
|
||||
suiteResultsCallback = jasmine.createSpy('suite result callback'),
|
||||
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "with a child suite",
|
||||
queueRunner: fakeQueueRunner,
|
||||
resultCallback: suiteResultsCallback
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
};
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(suiteResultsCallback).toHaveBeenCalledWith({
|
||||
id: suite.id,
|
||||
status: '',
|
||||
description: "with a child suite",
|
||||
fullName: "with a child suite"
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
13
spec/core/TimerSpec.js
Normal file
13
spec/core/TimerSpec.js
Normal file
@@ -0,0 +1,13 @@
|
||||
describe("Timer", function() {
|
||||
it("reports the time elapsed", function() {
|
||||
var fakeNow = jasmine.createSpy('fake Date.now'),
|
||||
timer = new j$.Timer({now: fakeNow});
|
||||
|
||||
fakeNow.and.callReturn(100);
|
||||
timer.start();
|
||||
|
||||
fakeNow.and.callReturn(200);
|
||||
|
||||
expect(timer.elapsed()).toEqual(100);
|
||||
});
|
||||
});
|
||||
@@ -1,39 +1,28 @@
|
||||
describe("jasmine.util", function() {
|
||||
describe("extend", function () {
|
||||
it("should add properies to a destination object ", function() {
|
||||
var destination = {baz: 'baz'};
|
||||
jasmine.util.extend(destination, {
|
||||
foo: 'foo', bar: 'bar'
|
||||
});
|
||||
expect(destination).toEqual({foo: 'foo', bar: 'bar', baz: 'baz'});
|
||||
});
|
||||
|
||||
it("should replace properies that already exist on a destination object", function() {
|
||||
var destination = {foo: 'foo'};
|
||||
jasmine.util.extend(destination, {
|
||||
foo: 'bar'
|
||||
});
|
||||
expect(destination).toEqual({foo: 'bar'});
|
||||
jasmine.util.extend(destination, {
|
||||
foo: null
|
||||
});
|
||||
expect(destination).toEqual({foo: null});
|
||||
});
|
||||
});
|
||||
|
||||
describe("j$.util", function() {
|
||||
describe("isArray_", function() {
|
||||
it("should return true if the argument is an array", function() {
|
||||
expect(jasmine.isArray_([])).toBe(true);
|
||||
expect(jasmine.isArray_(['a'])).toBe(true);
|
||||
expect(j$.isArray_([])).toBe(true);
|
||||
expect(j$.isArray_(['a'])).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if the argument is not an array", function() {
|
||||
expect(jasmine.isArray_(undefined)).toBe(false);
|
||||
expect(jasmine.isArray_({})).toBe(false);
|
||||
expect(jasmine.isArray_(function() {})).toBe(false);
|
||||
expect(jasmine.isArray_('foo')).toBe(false);
|
||||
expect(jasmine.isArray_(5)).toBe(false);
|
||||
expect(jasmine.isArray_(null)).toBe(false);
|
||||
expect(j$.isArray_(undefined)).toBe(false);
|
||||
expect(j$.isArray_({})).toBe(false);
|
||||
expect(j$.isArray_(function() {})).toBe(false);
|
||||
expect(j$.isArray_('foo')).toBe(false);
|
||||
expect(j$.isArray_(5)).toBe(false);
|
||||
expect(j$.isArray_(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isUndefined", function() {
|
||||
it("reports if a variable is defined", function() {
|
||||
var a;
|
||||
expect(j$.util.isUndefined(a)).toBe(true);
|
||||
expect(j$.util.isUndefined(undefined)).toBe(true);
|
||||
|
||||
var undefined = "diz be undefined yo";
|
||||
expect(j$.util.isUndefined(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
describe('WaitsForBlock', function () {
|
||||
var env, suite, timeout, spec, message, onComplete, fakeTimer;
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
suite = new jasmine.Suite(env, 'suite 1');
|
||||
timeout = 1000;
|
||||
spec = new jasmine.Spec(env, suite);
|
||||
message = "some error message";
|
||||
onComplete = jasmine.createSpy("onComplete");
|
||||
});
|
||||
|
||||
describe("jasmine.VERBOSE", function() {
|
||||
var jasmineVerboseOriginal;
|
||||
beforeEach(function() {
|
||||
jasmineVerboseOriginal = jasmine.VERBOSE;
|
||||
spyOn(env.reporter, 'log');
|
||||
|
||||
});
|
||||
it('do not show information if jasmine.VERBOSE is set to false', function () {
|
||||
jasmine.VERBOSE = false;
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(env.reporter.log).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(env.reporter.log).not.toHaveBeenCalled();
|
||||
jasmine.VERBOSE = jasmineVerboseOriginal;
|
||||
});
|
||||
it('show information if jasmine.VERBOSE is set to true', function () {
|
||||
jasmine.VERBOSE = true;
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(env.reporter.log).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(env.reporter.log).toHaveBeenCalled();
|
||||
jasmine.VERBOSE = jasmineVerboseOriginal;
|
||||
});
|
||||
});
|
||||
|
||||
it('onComplete should be called if the latchFunction returns true', function () {
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('latchFunction should run in same scope as spec', function () {
|
||||
var result;
|
||||
var latchFunction = function() {
|
||||
result = this.scopedValue;
|
||||
};
|
||||
spec.scopedValue = 'foo';
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
block.execute(onComplete);
|
||||
expect(result).toEqual('foo');
|
||||
});
|
||||
|
||||
it('should fail spec and call onComplete if there is an error in the latchFunction', function() {
|
||||
var latchFunction = jasmine.createSpy('latchFunction').andThrow('some error');
|
||||
spyOn(spec, 'fail');
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
block.execute(onComplete);
|
||||
expect(spec.fail).toHaveBeenCalledWith('some error');
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("if latchFunction returns false", function() {
|
||||
var latchFunction, fakeTimer;
|
||||
beforeEach(function() {
|
||||
latchFunction = jasmine.createSpy('latchFunction').andReturn(false);
|
||||
fakeTimer = new jasmine.FakeTimer();
|
||||
env.setTimeout = fakeTimer.setTimeout;
|
||||
env.clearTimeout = fakeTimer.clearTimeout;
|
||||
env.setInterval = fakeTimer.setInterval;
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
});
|
||||
|
||||
it('latchFunction should be retried after 10 ms', function () {
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(latchFunction).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(latchFunction.callCount).toEqual(1);
|
||||
fakeTimer.tick(5);
|
||||
expect(latchFunction.callCount).toEqual(1);
|
||||
fakeTimer.tick(5);
|
||||
expect(latchFunction.callCount).toEqual(2);
|
||||
});
|
||||
|
||||
it('onComplete should be called if latchFunction returns true before timeout', function () {
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
latchFunction.andReturn(true);
|
||||
fakeTimer.tick(100);
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('spec should fail with the passed message if the timeout is reached (and not call onComplete)', function () {
|
||||
spyOn(spec, 'fail');
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
block.execute(onComplete);
|
||||
expect(spec.fail).not.toHaveBeenCalled();
|
||||
fakeTimer.tick(timeout);
|
||||
expect(spec.fail).toHaveBeenCalled();
|
||||
var failMessage = spec.fail.mostRecentCall.args[0].message;
|
||||
expect(failMessage).toMatch(message);
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
219
spec/core/matchers/matchersUtilSpec.js
Normal file
219
spec/core/matchers/matchersUtilSpec.js
Normal file
@@ -0,0 +1,219 @@
|
||||
describe("matchersUtil", function() {
|
||||
describe("equals", function() {
|
||||
it("passes for literals that are threequal", function() {
|
||||
expect(j$.matchersUtil.equals(null, null)).toBe(true);
|
||||
expect(j$.matchersUtil.equals(void 0, void 0)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for things that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals({a: "foo"}, 1)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Strings that are equivalent", function() {
|
||||
expect(j$.matchersUtil.equals("foo", "foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Strings that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals("foo", "bar")).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Numbers that are equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(123, 123)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Numbers that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(123, 456)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Dates that are equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Jan 1, 1970"))).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Dates that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(new Date("Jan 1, 1970"), new Date("Feb 3, 1991"))).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Booleans that are equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(true, true)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Booleans that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(true, false)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for RegExps that are equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(/foo/, /foo/)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for RegExps that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals(/foo/, /bar/)).toBe(false);
|
||||
expect(j$.matchersUtil.equals(new RegExp("foo", "i"), new RegExp("foo"))).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Arrays that are equivalent", function() {
|
||||
expect(j$.matchersUtil.equals([1, 2], [1, 2])).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Arrays that are not equivalent", function() {
|
||||
expect(j$.matchersUtil.equals([1, 2], [1, 2, 3])).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);
|
||||
});
|
||||
|
||||
it("fails for Errors that are the same type and have different messages", function() {
|
||||
expect(j$.matchersUtil.equals(new Error("foo"), new Error("bar"))).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Objects that are equivalent (simple case)", function() {
|
||||
expect(j$.matchersUtil.equals({a: "foo"}, {a: "foo"})).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Objects that are not equivalent (simple case)", function() {
|
||||
expect(j$.matchersUtil.equals({a: "foo"}, {a: "bar"})).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Objects that are equivalent (deep case)", function() {
|
||||
expect(j$.matchersUtil.equals({a: "foo", b: { c: "bar"}}, {a: "foo", b: { c: "bar"}})).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Objects that are not equivalent (deep case)", function() {
|
||||
expect(j$.matchersUtil.equals({a: "foo", b: { c: "baz"}}, {a: "foo", b: { c: "bar"}})).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for Objects that are equivalent (with cycles)", function() {
|
||||
var actual = { a: "foo" },
|
||||
expected = { a: "foo" };
|
||||
|
||||
actual.b = actual;
|
||||
expected.b = actual;
|
||||
|
||||
expect(j$.matchersUtil.equals(actual, expected)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for Objects that are not equivalent (with cycles)", function() {
|
||||
var actual = { a: "foo" },
|
||||
expected = { a: "bar" };
|
||||
|
||||
actual.b = actual;
|
||||
expected.b = actual;
|
||||
|
||||
expect(j$.matchersUtil.equals(actual, expected)).toBe(false);
|
||||
});
|
||||
|
||||
it("fails when comparing an empty object to an empty array (issue #114)", function() {
|
||||
var emptyObject = {},
|
||||
emptyArray = [];
|
||||
|
||||
expect(j$.matchersUtil.equals(emptyObject, emptyArray)).toBe(false);
|
||||
expect(j$.matchersUtil.equals(emptyArray, emptyObject)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes for equivalent frozen objects (GitHub issue #266)", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var a = { foo: 1 },
|
||||
b = {foo: 1 };
|
||||
|
||||
Object.freeze(a);
|
||||
Object.freeze(b);
|
||||
|
||||
expect(j$.matchersUtil.equals(a,b)).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when Any is used", function() {
|
||||
var number = 3,
|
||||
anyNumber = new j$.Any(Number);
|
||||
|
||||
expect(j$.matchersUtil.equals(number, anyNumber)).toBe(true);
|
||||
expect(j$.matchersUtil.equals(anyNumber, number)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when Any is compared to something unexpected", function() {
|
||||
var number = 3,
|
||||
anyString = new j$.Any(String);
|
||||
|
||||
expect(j$.matchersUtil.equals(number, anyString)).toBe(false);
|
||||
expect(j$.matchersUtil.equals(anyString, number)).toBe(false);
|
||||
});
|
||||
|
||||
it("passes when ObjectContaining is used", function() {
|
||||
var obj = {
|
||||
foo: 3,
|
||||
bar: 7
|
||||
};
|
||||
|
||||
expect(j$.matchersUtil.equals(obj, new j$.ObjectContaining({foo: 3}))).toBe(true);
|
||||
});
|
||||
|
||||
it("passes when a custom equality matcher returns true", function() {
|
||||
var tester = function(a, b) { return true; };
|
||||
|
||||
expect(j$.matchersUtil.equals(1, 2, [tester])).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for equivalents when a custom equality matcher returns false", function() {
|
||||
var tester = function(a, b) { return false; };
|
||||
|
||||
expect(j$.matchersUtil.equals(1, 2, [tester])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("contains", function() {
|
||||
it("passes when expected is a substring of actual", function() {
|
||||
expect(j$.matchersUtil.contains("ABC", "B")).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when expected is a not substring of actual", function() {
|
||||
expect(j$.matchersUtil.contains("ABC", "X")).toBe(false);
|
||||
});
|
||||
|
||||
it("passes when expected is an element in an actual array", function() {
|
||||
expect(j$.matchersUtil.contains(['foo', 'bar'], 'foo')).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when expected is not an element in an actual array", function() {
|
||||
expect(j$.matchersUtil.contains(['foo', 'bar'], 'baz')).toBe(false);
|
||||
});
|
||||
|
||||
it("passes with mixed-element arrays", function() {
|
||||
expect(j$.matchersUtil.contains(["foo", {some: "bar"}], "foo")).toBe(true);
|
||||
expect(j$.matchersUtil.contains(["foo", {some: "bar"}], {some: "bar"})).toBe(true);
|
||||
});
|
||||
|
||||
it("uses custom equality testers if passed in and actual is an Array", function() {
|
||||
var customTester = function(a, b) {return true;};
|
||||
|
||||
expect(j$.matchersUtil.contains([1, 2], 2, [customTester])).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildMessage", function() {
|
||||
|
||||
it("builds an English sentence for a failure case", function() {
|
||||
var actual = "foo",
|
||||
name = "toBar",
|
||||
message = j$.matchersUtil.buildFailureMessage(name, false, actual);
|
||||
|
||||
expect(message).toEqual("Expected 'foo' to bar.");
|
||||
});
|
||||
|
||||
it("builds an English sentence for a 'not' failure case", function() {
|
||||
var actual = "foo",
|
||||
name = "toBar",
|
||||
isNot = true,
|
||||
message = message = j$.matchersUtil.buildFailureMessage(name, isNot, actual);
|
||||
|
||||
expect(message).toEqual("Expected 'foo' not to bar.");
|
||||
});
|
||||
|
||||
it("builds an English sentence for an arbitrary array of expected arguments", function() {
|
||||
var actual = "foo",
|
||||
name = "toBar",
|
||||
message = j$.matchersUtil.buildFailureMessage(name, false, actual, "quux", "corge");
|
||||
|
||||
expect(message).toEqual("Expected 'foo' to bar 'quux', 'corge'.");
|
||||
});
|
||||
});
|
||||
});
|
||||
51
spec/core/matchers/toBeCloseToSpec.js
Normal file
51
spec/core/matchers/toBeCloseToSpec.js
Normal file
@@ -0,0 +1,51 @@
|
||||
describe("toBeCloseTo", function() {
|
||||
it("passes when within two decimal places by default", function() {
|
||||
var matcher = j$.matchers.toBeCloseTo(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(0, 0);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(0, 0.001);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when not within two decimal places by default", function() {
|
||||
var matcher = j$.matchers.toBeCloseTo(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(0, 0.01);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts an optional precision argument", function() {
|
||||
var matcher = j$.matchers.toBeCloseTo(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(0, 0.1, 0);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(0, 0.0001, 3);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("rounds expected values", function() {
|
||||
var matcher = j$.matchers.toBeCloseTo(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1.23, 1.229);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(1.23, 1.226);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(1.23, 1.225);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(1.23, 1.2249999);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(1.23, 1.234);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
});
|
||||
18
spec/core/matchers/toBeDefinedSpec.js
Normal file
18
spec/core/matchers/toBeDefinedSpec.js
Normal file
@@ -0,0 +1,18 @@
|
||||
describe("toBeDefined", function() {
|
||||
it("matches for defined values", function() {
|
||||
var matcher = j$.matchers.toBeDefined(),
|
||||
result;
|
||||
|
||||
|
||||
result = matcher.compare('foo');
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when matching undefined values", function() {
|
||||
var matcher = j$.matchers.toBeDefined(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(void 0);
|
||||
expect(result.pass).toBe(false);
|
||||
})
|
||||
});
|
||||
38
spec/core/matchers/toBeFalsySpec.js
Normal file
38
spec/core/matchers/toBeFalsySpec.js
Normal file
@@ -0,0 +1,38 @@
|
||||
describe("toBeFalsy", function() {
|
||||
it("passes for 'falsy' values", function() {
|
||||
var matcher = j$.matchers.toBeFalsy(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(false);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(0);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare('');
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(null);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(void 0);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for 'truthy' values", function() {
|
||||
var matcher = j$.matchers.toBeFalsy(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(true);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(1);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare("foo");
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare({});
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
19
spec/core/matchers/toBeGreaterThanSpec.js
Normal file
19
spec/core/matchers/toBeGreaterThanSpec.js
Normal file
@@ -0,0 +1,19 @@
|
||||
describe("toBeGreaterThan", function() {
|
||||
it("passes when actual > expected", function() {
|
||||
var matcher = j$.matchers.toBeGreaterThan(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(2, 1);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when actual <= expected", function() {
|
||||
var matcher = j$.matchers.toBeGreaterThan();
|
||||
|
||||
result = matcher.compare(1, 1);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(1, 2);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
20
spec/core/matchers/toBeLessThanSpec.js
Normal file
20
spec/core/matchers/toBeLessThanSpec.js
Normal file
@@ -0,0 +1,20 @@
|
||||
describe("toBeLessThan", function() {
|
||||
it("passes when actual < expected", function() {
|
||||
var matcher = j$.matchers.toBeLessThan(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1, 2);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when actual <= expected", function() {
|
||||
var matcher = j$.matchers.toBeLessThan(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1, 1);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(2, 1);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
36
spec/core/matchers/toBeNaNSpec.js
Normal file
36
spec/core/matchers/toBeNaNSpec.js
Normal file
@@ -0,0 +1,36 @@
|
||||
describe("toBeNaN", function() {
|
||||
it("passes for NaN with a custom .not fail", function() {
|
||||
var matcher = j$.matchers.toBeNaN(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(Number.NaN);
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected actual not to be NaN.");
|
||||
});
|
||||
|
||||
it("fails for anything not a NaN", function() {
|
||||
var matcher = j$.matchers.toBeNaN();
|
||||
|
||||
result = matcher.compare(1);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(null);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(void 0);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare('');
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(Number.POSITIVE_INFINITY);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("has a custom message on failure", function() {
|
||||
var matcher = j$.matchers.toBeNaN(),
|
||||
result = matcher.compare(0);
|
||||
|
||||
expect(result.message).toEqual("Expected 0 to be NaN.");
|
||||
});
|
||||
});
|
||||
17
spec/core/matchers/toBeNullSpec.js
Normal file
17
spec/core/matchers/toBeNullSpec.js
Normal file
@@ -0,0 +1,17 @@
|
||||
describe("toBeNull", function() {
|
||||
it("passes for null", function() {
|
||||
var matcher = j$.matchers.toBeNull(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(null);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for non-null", function() {
|
||||
var matcher = j$.matchers.toBeNull(),
|
||||
result;
|
||||
|
||||
result = matcher.compare('foo');
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
17
spec/core/matchers/toBeSpec.js
Normal file
17
spec/core/matchers/toBeSpec.js
Normal file
@@ -0,0 +1,17 @@
|
||||
describe("toBe", function() {
|
||||
it("passes when actual === expected", function() {
|
||||
var matcher = j$.matchers.toBe(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1, 1);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when actual !== expected", function() {
|
||||
var matcher = j$.matchers.toBe(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1, 2);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
38
spec/core/matchers/toBeTruthySpec.js
Normal file
38
spec/core/matchers/toBeTruthySpec.js
Normal file
@@ -0,0 +1,38 @@
|
||||
describe("toBeTruthy", function() {
|
||||
it("passes for 'truthy' values", function() {
|
||||
var matcher = j$.matchers.toBeTruthy(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(true);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare(1);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare("foo");
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
result = matcher.compare({});
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails for 'falsy' values", function() {
|
||||
var matcher = j$.matchers.toBeTruthy(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(false);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(0);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare('');
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(null);
|
||||
expect(result.pass).toBe(false);
|
||||
|
||||
result = matcher.compare(void 0);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
17
spec/core/matchers/toBeUndefinedSpec.js
Normal file
17
spec/core/matchers/toBeUndefinedSpec.js
Normal file
@@ -0,0 +1,17 @@
|
||||
describe("toBeUndefined", function() {
|
||||
it("passes for undefined values", function() {
|
||||
var matcher = j$.matchers.toBeUndefined(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(void 0);
|
||||
expect(result.pass).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it("fails when matching defined values", function() {
|
||||
var matcher = j$.matchers.toBeUndefined();
|
||||
|
||||
result = matcher.compare('foo');
|
||||
expect(result.pass).toBe(false);
|
||||
})
|
||||
});
|
||||
24
spec/core/matchers/toContainSpec.js
Normal file
24
spec/core/matchers/toContainSpec.js
Normal file
@@ -0,0 +1,24 @@
|
||||
describe("toContain", function() {
|
||||
it("delegates to j$.matchersUtil.contains", function() {
|
||||
var util = {
|
||||
contains: jasmine.createSpy('delegated-contains').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toContain(util);
|
||||
|
||||
result = matcher.compare("ABC", "B");
|
||||
expect(util.contains).toHaveBeenCalledWith("ABC", "B", []);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("delegates to j$.matchersUtil.contains, passing in equality testers if present", function() {
|
||||
var util = {
|
||||
contains: jasmine.createSpy('delegated-contains').and.callReturn(true)
|
||||
},
|
||||
customEqualityTesters = ['a', 'b'],
|
||||
matcher = j$.matchers.toContain(util, customEqualityTesters);
|
||||
|
||||
result = matcher.compare("ABC", "B");
|
||||
expect(util.contains).toHaveBeenCalledWith("ABC", "B", ['a', 'b']);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
});
|
||||
28
spec/core/matchers/toEqualSpec.js
Normal file
28
spec/core/matchers/toEqualSpec.js
Normal file
@@ -0,0 +1,28 @@
|
||||
describe("toEqual", function() {
|
||||
it("delegates to equals function", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equals').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toEqual(util),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1, 1);
|
||||
|
||||
expect(util.equals).toHaveBeenCalledWith(1, 1, []);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("delegates custom equality testers, if present", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equals').and.callReturn(true)
|
||||
},
|
||||
customEqualityTesters = ['a', 'b'],
|
||||
matcher = j$.matchers.toEqual(util, customEqualityTesters),
|
||||
result;
|
||||
|
||||
result = matcher.compare(1, 1);
|
||||
|
||||
expect(util.equals).toHaveBeenCalledWith(1, 1, ['a', 'b']);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
});
|
||||
46
spec/core/matchers/toHaveBeenCalledSpec.js
Normal file
46
spec/core/matchers/toHaveBeenCalledSpec.js
Normal file
@@ -0,0 +1,46 @@
|
||||
describe("toHaveBeenCalled", function() {
|
||||
it("passes when the actual was called, with a custom .not fail message", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalled(),
|
||||
calledSpy = j$.createSpy('called-spy'),
|
||||
result;
|
||||
|
||||
calledSpy();
|
||||
|
||||
result = matcher.compare(calledSpy);
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected spy called-spy not to have been called.");
|
||||
});
|
||||
|
||||
it("fails when the actual was not called", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalled(),
|
||||
uncalledSpy = j$.createSpy('uncalled spy');
|
||||
|
||||
result = matcher.compare(uncalledSpy);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("throws an exception when the actual is not a spy", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalled(),
|
||||
fn = function() {};
|
||||
|
||||
expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function."));
|
||||
});
|
||||
|
||||
it("throws an exception when invoked with any arguments", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalled(),
|
||||
spy = j$.createSpy('sample spy');
|
||||
|
||||
expect(function() { matcher.compare(spy, 'foo') }).toThrow(new Error("toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith"));
|
||||
});
|
||||
|
||||
it("has a custom message on failure", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalled(),
|
||||
spy = j$.createSpy('sample-spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(spy);
|
||||
|
||||
expect(result.message).toEqual("Expected spy sample-spy to have been called.");
|
||||
});
|
||||
});
|
||||
|
||||
57
spec/core/matchers/toHaveBeenCalledWithSpec.js
Normal file
57
spec/core/matchers/toHaveBeenCalledWithSpec.js
Normal file
@@ -0,0 +1,57 @@
|
||||
describe("toHaveBeenCalledWith", function() {
|
||||
it("passes when the actual was called with matching parameters", function() {
|
||||
var util = {
|
||||
contains: jasmine.createSpy('delegated-contains').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toHaveBeenCalledWith(util),
|
||||
calledSpy = j$.createSpy('called-spy'),
|
||||
result;
|
||||
|
||||
calledSpy('a', 'b');
|
||||
result = matcher.compare(calledSpy, 'a', 'b');
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when the actual was not called", function() {
|
||||
var util = {
|
||||
contains: jasmine.createSpy('delegated-contains').and.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toHaveBeenCalledWith(util),
|
||||
uncalledSpy = j$.createSpy('uncalled spy'),
|
||||
result;
|
||||
|
||||
result = matcher.compare(uncalledSpy);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("fails when the actual was called with different parameters", function() {
|
||||
var util = {
|
||||
contains: jasmine.createSpy('delegated-contains').and.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toHaveBeenCalledWith(util),
|
||||
calledSpy = j$.createSpy('called spy'),
|
||||
result;
|
||||
|
||||
calledSpy('a');
|
||||
result = matcher.compare(calledSpy, 'a', 'b');
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("throws an exception when the actual is not a spy", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledWith(),
|
||||
fn = function() {};
|
||||
|
||||
expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function."));
|
||||
});
|
||||
|
||||
it("has a custom message on failure", function() {
|
||||
var matcher = j$.matchers.toHaveBeenCalledWith(),
|
||||
spy = j$.createSpy('sample-spy'),
|
||||
messages = matcher.message(spy);
|
||||
|
||||
expect(messages.affirmative).toEqual("Expected spy sample-spy to have been called.")
|
||||
expect(messages.negative).toEqual("Expected spy sample-spy not to have been called.")
|
||||
});
|
||||
});
|
||||
34
spec/core/matchers/toMatchSpec.js
Normal file
34
spec/core/matchers/toMatchSpec.js
Normal file
@@ -0,0 +1,34 @@
|
||||
describe("toMatch", function() {
|
||||
it("passes when RegExps are equivalent", function() {
|
||||
var matcher = j$.matchers.toMatch(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(/foo/, /foo/);
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when RegExps are not equivalent", function() {
|
||||
var matcher = j$.matchers.toMatch(),
|
||||
result;
|
||||
|
||||
result = matcher.compare(/bar/, /foo/);
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
|
||||
it("passes when the actual matches the expected string as a pattern", function() {
|
||||
var matcher = j$.matchers.toMatch(),
|
||||
result;
|
||||
|
||||
result = matcher.compare('foosball', 'foo');
|
||||
expect(result.pass).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when the actual matches the expected string as a pattern", function() {
|
||||
var matcher = j$.matchers.toMatch(),
|
||||
result;
|
||||
|
||||
result = matcher.compare('bar', 'foo');
|
||||
expect(result.pass).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
280
spec/core/matchers/toThrowErrorSpec.js
Normal file
280
spec/core/matchers/toThrowErrorSpec.js
Normal file
@@ -0,0 +1,280 @@
|
||||
describe("toThrowError", function() {
|
||||
it("throws an error when the actual is not a function", function() {
|
||||
var matcher = j$.matchers.toThrowError();
|
||||
|
||||
expect(function() {
|
||||
matcher.compare({});
|
||||
}).toThrow(new Error("Actual is not a Function")); // TODO: this needs to change for self-test
|
||||
});
|
||||
|
||||
it("throws an error when the expected is not an Error, string, or RegExp", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("foo");
|
||||
};
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(fn, 1);
|
||||
}).toThrow(new Error("Expected is not an Error, string, or RegExp.")); // TODO: this needs to change for self-test
|
||||
});
|
||||
|
||||
it("throws an error when the expected error type is not an Error", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("foo");
|
||||
};
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(fn, void 0, "foo");
|
||||
}).toThrow(new Error("Expected error type is not an Error.")); // TODO: this needs to change for self-test
|
||||
});
|
||||
|
||||
it("throws an error when the expected error message is not a string or RegExp", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("foo");
|
||||
};
|
||||
|
||||
expect(function() {
|
||||
matcher.compare(fn, Error, 1);
|
||||
}).toThrow(new Error("Expected error message is not a string or RegExp.")); // TODO: this needs to change for self-test
|
||||
});
|
||||
|
||||
it("fails if actual does not throw at all", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
return true;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an Error.");
|
||||
});
|
||||
|
||||
it("fails if thrown is not an instanceof Error", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw 4;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an Error, but it threw 4.");
|
||||
});
|
||||
|
||||
it("fails with the correct message if thrown is a falsy value", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw undefined;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an Error, but it threw undefined.");
|
||||
});
|
||||
|
||||
it("passes if thrown is a type of Error, but there is no expected error", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new TypeError();
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw an Error, but it threw TypeError.");
|
||||
});
|
||||
|
||||
it("passes if thrown is an Error and the expected is the same message", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("foo");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, "foo");
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw an exception with message 'foo'.");
|
||||
});
|
||||
|
||||
it("fails if thrown is an Error and the expected is not the same message", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("foo");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, "bar");
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an exception with message 'bar', but it threw an exception with message 'foo'.");
|
||||
});
|
||||
|
||||
it("passes if thrown is an Error and the expected is a RegExp that matches the message", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("a long message");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, /long/);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw an exception with a message matching /long/.");
|
||||
});
|
||||
|
||||
it("fails if thrown is an Error and the expected is a RegExp that does not match the message", function() {
|
||||
var matcher = j$.matchers.toThrowError(),
|
||||
fn = function() {
|
||||
throw new Error("a long message");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, /foo/);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an exception with a message matching /foo/, but it threw an exception with message 'a long message'.");
|
||||
});
|
||||
|
||||
it("passes if thrown is an Error and the expected the same Error", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
fn = function() {
|
||||
throw new Error();
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, Error);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
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.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
CustomError = function CustomError(arg) { arg.x },
|
||||
fn = function() {
|
||||
throw new CustomError({ x: 1 });
|
||||
},
|
||||
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.");
|
||||
});
|
||||
|
||||
it("fails if thrown is an Error and the expected is a different Error", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
fn = function() {
|
||||
throw new Error();
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, TypeError);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
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.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, TypeError, "foo");
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw TypeError with message \"foo\".");
|
||||
});
|
||||
|
||||
it("passes if thrown is a custom error that takes arguments and it is equal to the expected custom error and message", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
CustomError = function CustomError(arg) { this.message = arg.message },
|
||||
fn = function() {
|
||||
throw new CustomError({message: "foo"});
|
||||
},
|
||||
result;
|
||||
|
||||
CustomError.prototype = new Error();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
|
||||
result = matcher.compare(fn, CustomError, "foo");
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw CustomError with message \"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.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, TypeError, "bar");
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw TypeError with message \"bar\", but it threw TypeError with message \"foo\".");
|
||||
});
|
||||
|
||||
it("passes if thrown is a type of Error and has the same type as the expected Error and the message matches the exepcted message", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
result;
|
||||
|
||||
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/.");
|
||||
});
|
||||
|
||||
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.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrowError(util),
|
||||
fn = function() {
|
||||
throw new TypeError("foo");
|
||||
},
|
||||
result;
|
||||
|
||||
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\".");
|
||||
});
|
||||
});
|
||||
98
spec/core/matchers/toThrowSpec.js
Normal file
98
spec/core/matchers/toThrowSpec.js
Normal file
@@ -0,0 +1,98 @@
|
||||
describe("toThrow", function() {
|
||||
it("throws an error when the actual is not a function", function() {
|
||||
var matcher = j$.matchers.toThrow();
|
||||
|
||||
expect(function() {
|
||||
matcher.compare({});
|
||||
}).toThrow(new Error("Actual is not a Function")); // TODO: this needs to change for self-test
|
||||
});
|
||||
|
||||
it("fails if actual does not throw", function() {
|
||||
var matcher = j$.matchers.toThrow(),
|
||||
fn = function() {
|
||||
return true;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw an exception.");
|
||||
});
|
||||
|
||||
it("passes if it throws but there is no expected", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrow(util),
|
||||
fn = function() {
|
||||
throw 5;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw, but it threw 5.");
|
||||
});
|
||||
|
||||
it("passes even if what is thrown is falsy", function() {
|
||||
var matcher = j$.matchers.toThrow(),
|
||||
fn = function() {
|
||||
throw undefined;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn);
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw, but it threw undefined.");
|
||||
});
|
||||
|
||||
it("passes if what is thrown is equivalent to what is expected", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
|
||||
},
|
||||
matcher = j$.matchers.toThrow(util),
|
||||
fn = function() {
|
||||
throw 5;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, 5);
|
||||
|
||||
expect(result.pass).toBe(true);
|
||||
expect(result.message).toEqual("Expected function not to throw 5.");
|
||||
});
|
||||
|
||||
it("fails if what is thrown is not equivalent to what is expected", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrow(util),
|
||||
fn = function() {
|
||||
throw 5;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, "foo");
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw 'foo', but it threw 5.");
|
||||
});
|
||||
|
||||
it("fails if what is thrown is not equivalent to undefined", function() {
|
||||
var util = {
|
||||
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
|
||||
},
|
||||
matcher = j$.matchers.toThrow(util),
|
||||
fn = function() {
|
||||
throw 5;
|
||||
},
|
||||
result;
|
||||
|
||||
result = matcher.compare(fn, void 0);
|
||||
|
||||
expect(result.pass).toBe(false);
|
||||
expect(result.message).toEqual("Expected function to throw undefined, but it threw 5.");
|
||||
});
|
||||
});
|
||||
19
spec/helpers/BrowserFlags.js
Normal file
19
spec/helpers/BrowserFlags.js
Normal file
@@ -0,0 +1,19 @@
|
||||
(function(env) {
|
||||
env.ieVersion = (function() {
|
||||
var userAgent = jasmine.getGlobal().navigator.userAgent;
|
||||
if (!userAgent) { return Number.MAX_VALUE; }
|
||||
|
||||
var match = /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
|
||||
|
||||
return match ? parseFloat(match[1]) : Number.MAX_VALUE;
|
||||
})();
|
||||
|
||||
env.safariVersion = (function() {
|
||||
var userAgent = jasmine.getGlobal().navigator.userAgent;
|
||||
if (!userAgent) { return Number.MAX_VALUE; }
|
||||
|
||||
var match = /Safari/.exec(userAgent) && /Version\/([0-9]{0,})/.exec(userAgent);
|
||||
|
||||
return match ? parseFloat(match[1]) : Number.MAX_VALUE;
|
||||
})();
|
||||
})(jasmine.getEnv());
|
||||
494
spec/html/HtmlReporterSpec.js
Normal file
494
spec/html/HtmlReporterSpec.js
Normal file
@@ -0,0 +1,494 @@
|
||||
describe("New HtmlReporter", function() {
|
||||
// TODO: Figure out why this isn't rendering...
|
||||
it("builds the initial DOM elements, including the title banner", 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();
|
||||
|
||||
// Main top-level elements
|
||||
expect(container.querySelector("div.html-reporter")).toBeTruthy();
|
||||
expect(container.querySelector("div.banner")).toBeTruthy();
|
||||
expect(container.querySelector("div.alert")).toBeTruthy();
|
||||
expect(container.querySelector("div.results")).toBeTruthy();
|
||||
|
||||
expect(container.querySelector("ul.symbol-summary")).toBeTruthy();
|
||||
|
||||
// title banner
|
||||
var banner = container.querySelector(".banner");
|
||||
|
||||
var title = banner.querySelector(".title");
|
||||
expect(title.innerHTML).toMatch(/Jasmine/);
|
||||
|
||||
var version = banner.querySelector(".version"),
|
||||
versionText = 'textContent' in version ? version.textContent : version.innerText;
|
||||
expect(versionText).toEqual(j$.version);
|
||||
});
|
||||
|
||||
it("starts the timer when jasmine begins", function() {
|
||||
var env = new jasmine.Env(),
|
||||
startTimerSpy = jasmine.createSpy("start-timer-spy"),
|
||||
reporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
timer: { start: startTimerSpy }
|
||||
});
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
|
||||
expect(startTimerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("when a spec is done", function() {
|
||||
it("reports the status symbol of a disabled spec", 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.specDone({id: 789, status: "disabled", fullName: "symbols should have titles"});
|
||||
|
||||
var specEl = container.querySelector('.symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("disabled");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_789");
|
||||
expect(specEl.getAttribute("title")).toEqual("symbols should have titles");
|
||||
});
|
||||
|
||||
it("reports the status symbol of a pending spec", 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.specDone({id: 789, status: "pending"});
|
||||
|
||||
var specEl = container.querySelector('.symbol-summary li');
|
||||
expect(specEl.getAttribute("class")).toEqual("pending");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_789");
|
||||
});
|
||||
|
||||
it("reports the status symbol of a passing spec", 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.specDone({id: 123, status: "passed"});
|
||||
|
||||
var statuses = container.querySelector(".symbol-summary");
|
||||
var specEl = statuses.querySelector("li");
|
||||
expect(specEl.getAttribute("class")).toEqual("passed");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_123");
|
||||
});
|
||||
|
||||
it("reports the status symbol of a failing spec", 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.specDone({
|
||||
id: 345,
|
||||
status: "failed",
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
var specEl = container.querySelector(".symbol-summary li");
|
||||
expect(specEl.getAttribute("class")).toEqual("failed");
|
||||
expect(specEl.getAttribute("id")).toEqual("spec_345");
|
||||
});
|
||||
});
|
||||
|
||||
describe("when Jasmine is done", function() {
|
||||
it("reports the run time", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
timer = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
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); },
|
||||
timer: timer
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
|
||||
timer.elapsed.and.callReturn(100);
|
||||
reporter.jasmineDone();
|
||||
|
||||
var duration = container.querySelector(".banner .duration");
|
||||
expect(duration.innerHTML).toMatch(/finished in 0.1s/);
|
||||
});
|
||||
|
||||
it("reports the suite and spec names with status", 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.suiteStarted({
|
||||
id: 1,
|
||||
description: "A Suite",
|
||||
fullName: "A Suite"
|
||||
});
|
||||
|
||||
var specResult = {
|
||||
id: 123,
|
||||
description: "with a spec",
|
||||
fullName: "A Suite with a spec",
|
||||
status: "passed"
|
||||
};
|
||||
reporter.specStarted(specResult);
|
||||
reporter.specDone(specResult);
|
||||
|
||||
reporter.suiteStarted({
|
||||
id: 2,
|
||||
description: "inner suite",
|
||||
fullName: "A Suite inner suite"
|
||||
});
|
||||
|
||||
var specResult = {
|
||||
id: 124,
|
||||
description: "with another spec",
|
||||
fullName: "A Suite inner suite with another spec",
|
||||
status: "passed"
|
||||
};
|
||||
reporter.specStarted(specResult);
|
||||
reporter.specDone(specResult);
|
||||
|
||||
reporter.suiteDone({id: 2});
|
||||
|
||||
specResult = {
|
||||
id: 209,
|
||||
description: "with a failing spec",
|
||||
fullName: "A Suite inner with a failing spec",
|
||||
status: "failed",
|
||||
failedExpectations: []
|
||||
};
|
||||
reporter.specStarted(specResult);
|
||||
reporter.specDone(specResult);
|
||||
|
||||
reporter.suiteDone({id: 1});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
var summary = container.querySelector(".summary");
|
||||
|
||||
expect(summary.childNodes.length).toEqual(1);
|
||||
|
||||
var outerSuite = summary.childNodes[0];
|
||||
expect(outerSuite.childNodes.length).toEqual(4);
|
||||
|
||||
var classes = [];
|
||||
for (var i = 0; i < outerSuite.childNodes.length; i++) {
|
||||
var node = outerSuite.childNodes[i];
|
||||
classes.push(node.getAttribute("class"));
|
||||
}
|
||||
expect(classes).toEqual(["suite-detail", "specs", "suite", "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");
|
||||
|
||||
var specs = outerSuite.childNodes[1];
|
||||
var spec = specs.childNodes[0];
|
||||
expect(spec.getAttribute("class")).toEqual("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("title")).toEqual("A Suite with a spec");
|
||||
});
|
||||
|
||||
describe("UI for raising/catching exceptions", function() {
|
||||
it("should be unchecked if the env is catching", 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 raisingExceptionsUI = container.querySelector(".raise");
|
||||
expect(raisingExceptionsUI.checked).toBe(false);
|
||||
});
|
||||
|
||||
it("should be checked if the env is not catching", 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();
|
||||
env.catchExceptions(false);
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var raisingExceptionsUI = container.querySelector(".raise");
|
||||
expect(raisingExceptionsUI.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("should affect the query param for catching exceptions", function() {
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
exceptionsClickHandler = jasmine.createSpy("raise exceptions checked"),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
onRaiseExceptionsClick: exceptionsClickHandler,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var input = container.querySelector(".raise");
|
||||
input.click();
|
||||
expect(exceptionsClickHandler).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("and all specs pass", function() {
|
||||
var env, container, reporter;
|
||||
beforeEach(function() {
|
||||
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.specDone({
|
||||
id: 123,
|
||||
description: "with a spec",
|
||||
fullName: "A Suite with a spec",
|
||||
status: "passed"
|
||||
});
|
||||
reporter.specDone({
|
||||
id: 124,
|
||||
description: "with another spec",
|
||||
fullName: "A Suite inner suite with another spec",
|
||||
status: "passed"
|
||||
});
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
it("reports the specs counts", function() {
|
||||
var alertBars = container.querySelectorAll(".alert .bar");
|
||||
|
||||
expect(alertBars.length).toEqual(1);
|
||||
expect(alertBars[0].getAttribute('class')).toMatch(/passed/);
|
||||
expect(alertBars[0].innerHTML).toMatch(/2 specs, 0 failures/);
|
||||
});
|
||||
|
||||
it("reports no failure details", function() {
|
||||
var specFailure = container.querySelector(".failures");
|
||||
|
||||
expect(specFailure.childNodes.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("reports no pending specs", function() {
|
||||
var alertBar = container.querySelector(".alert .bar");
|
||||
|
||||
expect(alertBar.innerHTML).not.toMatch(/pending spec[s]/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("and there are pending specs", function() {
|
||||
var env, container, reporter;
|
||||
beforeEach(function() {
|
||||
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.specDone({
|
||||
id: 123,
|
||||
description: "with a spec",
|
||||
fullName: "A Suite with a spec",
|
||||
status: "pending"
|
||||
});
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
it("reports the pending specs count", function() {
|
||||
var alertBar = container.querySelector(".alert .bar");
|
||||
|
||||
expect(alertBar.innerHTML).toMatch(/1 spec, 0 failures, 1 pending spec/);
|
||||
});
|
||||
|
||||
it("reports no failure details", function() {
|
||||
var specFailure = container.querySelector(".failures");
|
||||
|
||||
expect(specFailure.childNodes.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("and some tests fail", function() {
|
||||
var env, container, reporter;
|
||||
|
||||
beforeEach(function() {
|
||||
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({});
|
||||
|
||||
var passingResult = {id: 123, status: "passed"};
|
||||
reporter.specStarted(passingResult);
|
||||
reporter.specDone(passingResult);
|
||||
|
||||
var failingResult = {
|
||||
id: 124,
|
||||
status: "failed",
|
||||
description: "a failing spec",
|
||||
fullName: "a suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
message: "a failure message",
|
||||
stack: "a stack trace"
|
||||
}
|
||||
]
|
||||
};
|
||||
reporter.specStarted(failingResult);
|
||||
reporter.specDone(failingResult);
|
||||
reporter.jasmineDone({});
|
||||
});
|
||||
|
||||
it("reports the specs counts", function() {
|
||||
var alertBar = container.querySelector(".alert .bar");
|
||||
|
||||
expect(alertBar.getAttribute('class')).toMatch(/failed/);
|
||||
expect(alertBar.innerHTML).toMatch(/2 specs, 1 failure/);
|
||||
});
|
||||
|
||||
it("reports failure messages and stack traces", function() {
|
||||
var specFailures = container.querySelector(".failures");
|
||||
|
||||
var failure = specFailures.childNodes[0];
|
||||
expect(failure.getAttribute("class")).toMatch(/failed/);
|
||||
expect(failure.getAttribute("class")).toMatch(/spec-detail/);
|
||||
|
||||
var specLink = failure.childNodes[0];
|
||||
expect(specLink.getAttribute("class")).toEqual("description");
|
||||
expect(specLink.getAttribute("title")).toEqual("a suite with a failing spec");
|
||||
expect(specLink.getAttribute("href")).toEqual("?spec=a%20suite%20with%20a%20failing%20spec");
|
||||
|
||||
var message = failure.childNodes[1].childNodes[0];
|
||||
expect(message.getAttribute("class")).toEqual("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.innerHTML).toEqual("a stack trace");
|
||||
});
|
||||
|
||||
it("allows switching between failure details and the spec summary", function() {
|
||||
var menuBar = container.querySelectorAll(".bar")[1];
|
||||
|
||||
expect(menuBar.getAttribute("class")).not.toMatch(/hidden/);
|
||||
|
||||
var link = menuBar.querySelector('a');
|
||||
expect(link.innerHTML).toEqual("Failures");
|
||||
expect(link.getAttribute("href")).toEqual("#");
|
||||
});
|
||||
|
||||
it("sets the reporter to 'Failures List' mode", function() {
|
||||
var reporterNode = container.querySelector(".html-reporter");
|
||||
expect(reporterNode.getAttribute("class")).toMatch("failure-list");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user