Compare commits

...

468 Commits

Author SHA1 Message Date
Gregg Van Hove
516fe68759 Merge branch '3.0-features' 2018-02-06 11:22:41 -08:00
Gregg Van Hove
4530f9431f Generate combined file with new version numbers 2018-02-06 10:33:39 -08:00
Gregg Van Hove
d4b76a4d3b version bump to 3.0 2018-02-06 09:33:49 -08:00
Gregg Van Hove
764d58a7f5 Merge branch 'master' into 3.0-features
- cleaning up 2.99 deprecations
2018-02-06 09:31:51 -08:00
Gregg Van Hove
9911d37f06 bump version to 2.99 2018-02-05 16:57:51 -08:00
Gregg Van Hove
32f99ef99d Use Jasmine's arrayContains to look for duplicate deprecations
[#154746527]
2018-02-05 14:24:14 -08:00
Gregg Van Hove
c142490c69 Add deprecation messages for things that will change/break in 3.0
[#154746527]
2018-02-05 14:01:46 -08:00
Gregg Van Hove
24bf3489dc Display deprecation warnings in HTML reporter
- Also no longer check for stack since IE doesn't do that

[#154746527]
2018-02-05 12:11:36 -08:00
Gregg Van Hove
5afe1222f4 Add ability to report deprecation warnings from within the suite
[#154746527]
2018-02-05 11:19:15 -08:00
Gregg Van Hove
274011ed03 Merge branch 'master' into 3.0-features 2018-02-02 16:33:38 -08:00
Gregg Van Hove
42e00b3bc5 Remove node modules from python wheel, and update languages
[finishes #87860474]
2018-01-31 14:23:32 -08:00
Gregg Van Hove
0eca06a33b Now pass a navigation helper to HtmlReporter instead of click handlers 2018-01-30 14:30:28 -08:00
Gregg Van Hove
84953ec210 stop spec on failure should not default to true 2018-01-30 11:48:25 -08:00
Gregg Van Hove
e15f273f06 Replace old "catch exceptions" logic with proper fail fast with error reporting
- Option is called stopOnSpecFailure

[#85966014]
- See #414
- See jasmine/jasmine-npm#16
2018-01-30 11:36:56 -08:00
Gregg Van Hove
e908b67b19 Move explicit fail spec out of mock clock context and re-add the afterAll for IEs 2018-01-29 17:05:54 -08:00
Gregg Van Hove
46cc48ccfa Detect an Error passed to done and add an expectation failure
- See #567
2018-01-29 16:46:30 -08:00
Gregg Van Hove
262a2fe674 Generate compiled jasmine.js for async reporters work 2018-01-29 14:02:02 -08:00
Gregg Van Hove
50cd6fdd68 Allow reporter callbacks to be asynchronous
[finishes #154673961]
- Fixes #842

Signed-off-by: Elenore Bastian <ebastian@pivotal.io>
2018-01-29 11:55:41 -08:00
Gregg Van Hove
341c6df6ea Fix HTML reporter display for excluded specs 2018-01-29 10:00:15 -08:00
Elenore Bastian
3df9cc26d4 Update css for new reporter status
Signed-off-by: Gregg Van Hove <gvanhove@pivotal.io>
2018-01-26 15:27:35 -08:00
Gregg Van Hove
6b156ca6d1 Unify status for xdescribe and xit
- Ensure *All's only execute if at least one child will run
- Specs will report a status of `excluded` instead of disabled

[finishes #153967580]
- #1418

Signed-off-by: Elenore Bastian <ebastian@pivotal.io>
2018-01-25 16:17:31 -08:00
Elenore Bastian
07996b567f Suite level errors are reported in failures list
[#150118881]

Signed-off-by: Gregg Van Hove <gvanhove@pivotal.io>
2018-01-23 15:39:11 -08:00
Gregg Van Hove
9a96396f65 Generate jasmine.js for suite reporting changes
Signed-off-by: Elenore Bastian <ebastian@pivotal.io>
2018-01-23 14:38:40 -08:00
Elenore Bastian
12a47f05bf Suite level errors all report the same way (on suiteDone)
- For `beforeAll`, `afterAll`, and declaration errors

[#150118881] #1409

Signed-off-by: Gregg Van Hove <gvanhove@pivotal.io>
2018-01-23 10:15:28 -08:00
Gregg Van Hove
414e03bded Setup createSpy in all specs where needed and finish renaming params
Signed-off-by: Elenore Bastian <ebastian@pivotal.io>
2018-01-22 14:21:52 -08:00
Gregg Van Hove
038ab87252 Merge branch 'custom-spy-strategy' into 3.0-features 2018-01-22 12:12:59 -08:00
Gregg Van Hove
f20f78f82b Don't clobber previous custom plans with later plans
[finishes #37288941]
2018-01-22 12:10:24 -08:00
Gregg Van Hove
70bce55721 Bump version to 2.9.1 2018-01-19 17:51:18 -08:00
Gregg Van Hove
53529bdc9a Clear timeouts when starting to process a milli instead of at the end
- Fixes #1482
2018-01-19 17:47:28 -08:00
Gregg Van Hove
c82e5947f5 Version bump to 2.9.0 2018-01-16 17:29:34 -08:00
Gregg Van Hove
f76b452816 Correctly check for Symbols, not Sets in AnythingSpec 2018-01-12 17:45:00 -08:00
Gregg Van Hove
91aab8e1b8 Merge branch 'Volox-ie11-sets-support'
- Merges #1478 from @Volox
- Fixes #1355
2018-01-12 17:33:51 -08:00
Volonterio Riccardo
486a64658f Added complete support for Set also for IE11.
Fixes 1355
2018-01-12 12:18:35 +01:00
Gregg Van Hove
1dfdc89ba9 Merge branch 'ie11-maps-support' of https://github.com/Volox/jasmine into Volox-ie11-maps-support
- Merges #1477 from @Volox
- Fixes #1472
2018-01-11 17:50:56 -08:00
Gregg Van Hove
e2a191b116 Refactor QueueRunner and remove references to functions that Jasmine is done with
[finishes #56030214]
2018-01-11 17:20:13 -08:00
Volonterio Riccardo
085a1f8a16 Added complete support for Map also for IE11.
Fixes 1472
2018-01-11 18:13:24 +01:00
Steve Gravrock
cf2f922e30 Merge branch 'master' into 3.0-features 2018-01-10 15:28:55 -08:00
Steve Gravrock
aeeb5b7107 Bumped copyright dates 2018-01-10 10:16:02 -08:00
Steve Gravrock
170a6dce76 Made naming somewhat less confusing 2018-01-10 09:00:09 -08:00
Steve Gravrock
4934e420b2 Allow adding custom spy strategies
[#37288941]
2018-01-10 08:59:19 -08:00
Steve Gravrock
1085914a76 Extracted a SpyFactory to slim Env down a bit 2018-01-09 13:32:28 -08:00
Steve Gravrock
6f119c4e5a Moved createSpy to env so it can be stateful 2018-01-09 10:16:02 -08:00
Steve Gravrock
298b5ba127 Moved createSpyObj to env so it can be stateful 2018-01-09 09:53:45 -08:00
Steve Gravrock
16e07a0e99 Add the ability to specify the strategy to use for a spy based on which parameters are passed
[Finishes #92260826]
2018-01-03 08:49:34 -08:00
Steve Gravrock
cb6de64e58 Fixed DelayedFunctionScheduler IE 8 compatibility issue 2018-01-02 18:17:23 -08:00
Steve Gravrock
f69949ebc0 Merge branch 'fix-1426' of https://github.com/leahciMic/jasmine
- Merges #1427 from @eahciMic
- Fixes #1426
2018-01-02 08:18:32 -08:00
Michael Leaney
1136fddcde Remove .sort() and fix logic in test 2018-01-02 14:51:51 +08:00
Steve Gravrock
b943f6b736 Fixed SPEC HAS NO EXPECTATIONS warning in HTML reporter
[Finishes #153891435]
2017-12-23 11:14:37 -08:00
Steve Gravrock
b439e2fb37 Extracted results state management out of the HTML reporter
[#153891435]
2017-12-23 11:12:38 -08:00
Steve Gravrock
c79ce125c0 Merge branch 'node-timeouts' of https://github.com/chris--young/jasmine
- Merges #1470 from @chris--young
- Fixes #1469
2017-12-21 13:24:21 -08:00
Chris Young
62b815c485 Use timeout objects when in node
Fixes: https://github.com/jasmine/jasmine/issues/1469
2017-12-21 10:51:07 -08:00
Steve Gravrock
65b4499dec In Jasmine's own tests, don't leak between jasmine and jasmineUnderTest 2017-12-20 12:08:22 -08:00
Steve Gravrock
f38527ff15 Removed IE 8 compatibility cruft from HtmlReporterSpec 2017-12-19 11:29:21 -08:00
Steve Gravrock
d742ada71d Added links to re-run the suites containing a failing spec
[Finishes #25508053]
2017-12-19 11:29:18 -08:00
Steve Gravrock
b6cc34d9e9 Correctly remove spies of window.onerror on IE 2017-12-18 16:34:37 -08:00
Steve Gravrock
ef9f82a17d Merge branch 'master' into 3.0-features 2017-12-18 09:48:17 -08:00
Steve Gravrock
d3a3cf1ff3 Collapsed StringPrettyPrinter into PrettyPrinter
We never really took advantage of the potential extensibility that the
split provided, and the boundary between the two was getting muddied
over time.
2017-12-18 09:43:25 -08:00
Steve Gravrock
c0d0513199 Stop serializing objects after hitting jasmine.MAX_PRETTY_PRINT_CHARS 2017-12-15 13:23:59 -08:00
Steve Gravrock
86a38fceb9 Truncate pretty printer output that is more than j$.MAX_PRETTY_PRINT_CHARS long 2017-12-13 08:09:22 -08:00
Steve Gravrock
c74af1d900 Reduced pretty printer limits to much smaller values
This should help prevent out of memory errors when printing large object
graphs. See #1291 and #1422.

[#153257532]
2017-12-13 08:07:43 -08:00
Gregg Van Hove
8ea4c6d3a1 Update contributing for new naming of jasmineUnderTest 2017-12-11 17:25:27 -08:00
Gregg Van Hove
bdbaebc045 Update contributing for new naming of jasmineUnderTest 2017-12-11 17:24:38 -08:00
Steve Gravrock
2d33765cbf Dogfood the toHaveClass matcher
[#153567695]
2017-12-11 16:00:29 -08:00
Steve Gravrock
bb0992bf5f Added a toHaveClass matcher
[#153567695]
2017-12-11 15:59:59 -08:00
Steve Gravrock
ac5d8708b9 More informative pretty-printing of DOM elements
[Finishes ##153562618]
2017-12-11 08:25:13 -08:00
Steve Gravrock
eb93d38294 Allow jasmine-npm to handle its own load errors
[Fixes #153466462]
2017-12-08 09:17:10 -08:00
Steve Gravrock
0b5dce7d84 Removed CodeClimate badge & configuration
CodeClimate's recommendations have been a mix of irrelevant and
actively harmful for some time. The latest problem is that it applies
length and complexity requirements equally to all functions whether
they act as privacy scopes, namespaces, classes or just regular old
functions.

Static analysis tools are only worthwhile if their recommendations add
enough value to offset the cost of slogging through them -- in other
words, if the signal to noise ratio is high enough. CodeClimate hasn't
carried its own weight for a long time, and it's only gotten worse with
each recent update.
2017-12-07 21:29:59 -08:00
Steve Gravrock
d16aa550cb Treat random= as a no-op rather than disabling randomization
[#109197518]
2017-12-01 08:45:58 -08:00
Steve Gravrock
2200dd084d Fixed build 2017-12-01 08:34:12 -08:00
Steve Gravrock
98ead94c51 Fixed spec failure on Chrome 2017-12-01 08:28:55 -08:00
Gregg Van Hove
21655a82c9 Use prototype for spy strategy for better memory management
- Also convert `identity` to a property from a method
2017-11-30 17:30:20 -08:00
Steve Gravrock
0183b1642d Removed stray debugger statement 2017-11-30 07:53:59 -08:00
Steve Gravrock
18ed34e9be Fixed failing specs 2017-11-29 09:32:12 -08:00
Steve Gravrock
f4caf27208 Fixed pending() for async/promise-returning specs
Fixes #1449.
Fixes #1450.
2017-11-29 08:57:29 -08:00
Steve Gravrock
a63172f53f expect(null).toEqual(jasmine.any(Object)) no longer passes
[Finishes #153181443]
Fixes #1255.
2017-11-29 08:10:01 -08:00
Steve Gravrock
9619acf91f Extracted the predicate version of toThrowError into its own matcher
This simplifies the signature of each matcher to something that jsdoc
can actually handle.

[Finishes #20622765]
2017-11-28 14:30:06 -08:00
Gregg Van Hove
b7e4c1e779 Remove console.js altogether
[#80410262]
2017-11-21 17:27:21 -08:00
Gregg Van Hove
e5ada1d010 Add safari 10 and update readme to include edge 2017-11-20 17:24:52 -08:00
Steve Gravrock
d35b65cf79 Set version to 3.0.0-pre 2017-11-17 14:28:20 -08:00
Steve Gravrock
db615e4186 Determine overall status in core, not reporters
[#92261606]
[#78679648]
2017-11-17 14:24:12 -08:00
Steve Gravrock
5906a2c05c Filter Jasmine frames from stack traces
[Finishes #2644992]
2017-11-13 15:49:01 -08:00
Steve Gravrock
59ad217954 Fixed bad travis.yml merge
Re-removed IE 8, IE 9, and Node 0.12.x from the testing matrix
2017-11-10 10:47:08 -08:00
Steve Gravrock
b0ec95c472 Merge branch 'master' into 3.0-features 2017-11-10 10:26:14 -08:00
Steve Gravrock
13b9e669bd Merge branch 'feature/allow-callfake-to-be-async' of https://github.com/mrlannigan/jasmine into merge-test
- Merges #1448 from @mrlannigan
2017-11-10 10:01:45 -08:00
Julian Lannigan
2eef0747a0 Added test steps for other major node versions
addresses https://www.pivotaltracker.com/story/show/152685778
2017-11-10 10:23:02 -05:00
Julian Lannigan
7ac1244f58 changed tests to work in environments that dont support async/await 2017-11-10 10:17:48 -05:00
Steve Gravrock
6ef0e93880 Revert "Removed IE 8 and 9 from the testing matrix"
In case we end doing another 2.x release.

This reverts commit 0e95b04900.
2017-11-09 20:57:01 -08:00
Julian Lannigan
2be5e0a962 Allowed async functions to be passed into spy#callFake 2017-11-09 19:59:23 -05:00
Steve Gravrock
a42f28c734 Removed checks for PhantomJS 1
v2 has been out for a long time, and v1 can no longer be easily installed.
2017-11-09 07:04:06 -08:00
Steve Gravrock
d58f3dac56 Test against multiple Node versions on Travis 2017-11-08 09:17:55 -08:00
Steve Gravrock
676689b063 Test against Node 4.x, not 0.10.x 2017-11-08 09:11:41 -08:00
Steve Gravrock
aaf226b9e3 Removed spec guards for versions of Safari we no longer support 2017-11-08 08:30:35 -08:00
Steve Gravrock
419470e9df Removed support for IE <10
[#150527985]
2017-11-08 08:30:22 -08:00
Steve Gravrock
1526d5e2a8 Treat afterAll errors at any level as failures
[Finishes #152492514]
2017-11-07 20:48:23 -08:00
Steve Gravrock
a3cb010971 Removed remaining traces of the obsolete console reporter
[#80410262]
2017-11-07 20:09:04 -08:00
Steve Gravrock
278ef9228b Removed obsolete console reporter from core
Anyone who was still using this should use the one in jasmine-npm
instead.

[Finishes #80410262]
2017-11-07 12:25:47 -08:00
Steve Gravrock
82eeed3c85 Improved reporting of load errors and afterAll errors
- Pass file and line number to reporters when present
- Show file and line number in the HTML reporter when present
- Visually separate adjacent errors in the HTML reporter

[#24901981]
2017-11-04 10:28:42 -07:00
Steve Gravrock
ae9b95269c Load error handling doesn't depend on browser features, so test it everywher
[#24901981]
2017-11-02 18:17:40 -07:00
Steve Gravrock
285f06d5c4 Merge branch 'promise-matching-1314' of https://github.com/sderickson/jasmine 2017-11-02 17:18:24 -07:00
Steve Gravrock
3aece2ac74 Merge branch 'master' of https://github.com/b-3-n/jasmine
- Merges #1445 from @b-3-n
- Fixes #1444
2017-11-02 08:17:27 -07:00
sgravrock
3a9d4ee08d Merge pull request #1440 from aaronang/patch-1
Add instruction to sync local master with upstream
2017-11-02 08:11:47 -07:00
Steve Gravrock
26a7bc6acf Report loading errors as loading errors, not afterAll errors
[#24901981]
2017-11-01 14:09:29 -07:00
Steve Gravrock
7b8edcb401 HTML reporter reports overall failure if there are any global errors
[#24901981]
2017-11-01 11:44:58 -07:00
Steve Gravrock
395b2b2d97 Test against Edge 2017-10-31 21:50:42 -07:00
Steve Gravrock
bd250f27c7 Fail if error events (e.g. syntax errors) occur during loading
[#24901981]
2017-10-31 21:16:00 -07:00
Benjamin Mularczyk
b4dfdd7a48 Fix equality computation for ES6 Sets. 2017-11-01 01:01:26 +01:00
Steve Gravrock
12ed3bfacd Allow use of a predicate function to validate thrown exceptions
[Finishes #20622765]
2017-10-30 08:51:25 -07:00
Steve Gravrock
324ad0073e Refactored toThrowMatching to facilitate adding more strategies
* Extracted sub-matchers for the two major existing strategies
  (matching all errors, and matching by type and/or message)
* Reduced the use of mutable state
2017-10-30 08:51:25 -07:00
Steve Gravrock
9f7a6ef061 Check truthiness of toThrowError args, not arg count
This enables some useful simplifications at the cost of making it
impossible (for now) to expect a function to throw an error with a falsy
message.

[#20622765]
2017-10-30 08:51:25 -07:00
sgravrock
908583c49b Point CodeClimate at the right repo 2017-10-30 08:51:25 -07:00
Steve Gravrock
e31db20ec7 Default to running tests in random order
[Finishes #109197518]
2017-10-27 08:50:40 -07:00
Aaron Ang
c260c67e7e Add instruction to sync local master with upstream 2017-10-26 04:56:44 -07:00
sgravrock
554d0efab7 Point CodeClimate at the right repo 2017-10-25 11:28:47 -07:00
Steve Gravrock
ea3cf14ef8 Exclude specs from CodeClimate ratings
CodeClimate makes recommendations that, while helpful for production
code, can be harmful for test code. In particular, following its
recommendations would lead us to aggressively de-duplicate even small
amounts of test setup code. That can create unwanted coupling, obscure
the intent of the tests, and make it harder to maintain tests as their
setup needs diverge.
2017-10-25 09:25:52 -07:00
Steve Gravrock
a4bdd47a8a Merge branch 'unittests' of https://github.com/voithos/jasmine
- Merges #1437 from @voithos
2017-10-25 08:49:58 -07:00
Zaven Muradyan
89306551a0 Add some unit tests that exercise jasmine.anything() and Map matching.
Follow-up to some recent commits that fixed issues around
jasmine.anything() matching. This simply adds some extra tests that
exercise usage of Symbols with jasmine.anything() and as Map keys.
2017-10-24 22:39:31 -07:00
Steve Gravrock
0e95b04900 Removed IE 8 and 9 from the testing matrix
[#150527985]
2017-10-24 08:39:00 -07:00
Steve Gravrock
da91294182 Merge branch 'anything-fix' of https://github.com/voithos/jasmine
- Merges #1436 from @voithos
2017-10-24 08:26:13 -07:00
Steve Gravrock
bd41a97cd5 Merge branch 'anysymbol-fix' of https://github.com/voithos/jasmine
- Merge #1435 from @voithos
2017-10-24 08:18:42 -07:00
Zaven Muradyan
6d3953356d Add special handling of asymmetric matcher objects as keys in Maps.
The previous Map equality code was assuming that the set of keys would
be identical between the two Maps. This change adds insertion-order
tracking for each key with its corresponding key. If one of the two keys
is an asymmetric equality obj, the keys are eq()'d, and if it succeeds,
the corresponding values are compared. Otherwise, the "main" key is
looked up directly in the other object; this is to prevent
similar-looking obj keys with different obj identities from comparing
equal.

Fixes #1432.
2017-10-23 23:01:50 -07:00
Zaven Muradyan
62f769767a Add support for jasmine.any(Symbol).
The original asymmetric matcher code for Any did not work with symbols
since `symbolInstance instanceof Symbol` is actually `false` (but,
`symbolInstance.constructor` is `Symbol). This simply adds an extra
clause that explicitly checks for symbol (if available) like the other
primitive types.

Also added some missing specs for other types, like Map, Set, etc.

Fixes #1431.
2017-10-23 20:07:56 -07:00
Steve Gravrock
03f7f76bca Removed Safari 6 from the test matrix
Sauce Labs no longer supports Safari <7.
2017-10-23 12:05:52 -07:00
Steve Gravrock
4c6dadb9b1 Merge branch 'github-1295' of https://github.com/ksvitkovsky/jasmine
- Merges #1411 from @ksvitkovsky
2017-10-23 11:58:30 -07:00
Gregg Van Hove
8973e4e44f Ignore package-lock.json
We want to make sure that Travis checks against the latest version of
our dependencies, and also maintain compatibility across multiple
versions of Node.

Signed-off-by: Steve Gravrock <sgravrock@pivotal.io>
2017-10-23 11:53:48 -07:00
Steve Gravrock
b7e9594c86 Merge branch 'jasmine-deep-clone-args' of https://github.com/aj-dev/jasmine
- Merges #1424 from @aj-dev
2017-10-23 11:32:58 -07:00
Steve Gravrock
6c363f11b3 Merge branch 'lintfix' of https://github.com/voithos/jasmine
- Merges #1428 from @voithos
2017-10-23 11:01:18 -07:00
sgravrock
0f650e1d03 Merge pull request #1429 from voithos/docfix
Fix "Before Committing" section of CONTRIBUTING.md.
2017-10-23 10:46:06 -07:00
Zaven Muradyan
78fe42ac2d Fix "Before Committing" section of CONTRIBUTING.md.
The old contributing docs had a misaligned nested unordered-list, which
resulted in it creating a new list instead of being nested under its
parent.

It also seems like it would be useful to have the "revert your changes"
prose as part of the "Before Committing" section, since otherwise people
may miss it and have to amend.
2017-10-15 22:48:57 -07:00
Zaven Muradyan
20d86b2a00 Fix lint warning in CallTracker.
The previous code was using `== null` to handle both `null` and
`undefined`, resulting in a jshint warning. The conditional is meant to
check for non-primitive values, and it happens to be the case that a
falsey value in JS is always a primitive, or `null` or `undefined`.
2017-10-15 12:31:54 -07:00
Michael Leaney
516e00d7ba Fix #1426 clearTimeout not correctly clearing a timeout
clearTimeout was not correctly handling the case of clearing a
timeout that is also scheduled to run at the same tick.

This fix adds a deletedKeys array that is checked whilst we are
running the scheduled functions for the current clock tick. If
a function exists in deletedKeys it will not be ran. deletedKeys
is then reset to an empty array.
2017-10-11 20:54:56 +08:00
Michael Leaney
c1957ecd7c Add test 2017-10-11 20:29:27 +08:00
Audrius Jakumavicius
1f6c91de7c Deep clone args before passing them to reporters 2017-10-07 01:32:39 +02:00
Gregg Van Hove
f6342ad4fe Add a note about defineProperty for spyOnProperty
- Fixes #1415
2017-08-24 12:22:11 -07:00
Gregg Van Hove
8cf8736cab bump version to 2.8.0 2017-08-24 11:41:41 -07:00
Gregg Van Hove
6d0f0ed915 Only use the extra setTimeout outside of IE8. 2017-08-10 16:38:13 -07:00
ksvitkovsky
7ca571a746 Remove runnable parameter for simplicity 2017-08-10 23:08:59 +04:00
ksvitkovsky
4240b3514b Check runnable instead of suite 2017-08-10 22:58:30 +04:00
ksvitkovsky
ab116fbd0f Throw an error on nested methods 2017-08-10 22:05:13 +04:00
ksvitkovsky
da2673e02f Test nested methods to throw an error 2017-08-10 22:05:13 +04:00
Gregg Van Hove
b2dee5cb1c Create CODE_OF_CONDUCT.md 2017-08-10 10:38:05 -07:00
Gregg Van Hove
1414281cff Merge branch 'github-1221' of https://github.com/ksvitkovsky/jasmine into ksvitkovsky-github-1221
- Merges #1412 from @ksvitkovsky
- Fixes #1221
2017-08-09 17:20:54 -07:00
Gregg Van Hove
2588b442e6 Integration specs that actually execute a suite need to be async 2017-08-09 11:51:26 -07:00
Gregg Van Hove
af41e5ea5c Properly wait until test env has completed before moving on. 2017-08-09 11:43:55 -07:00
Gregg Van Hove
8834142198 Update jsApiReporter docs to link to new suite and spec results 2017-08-09 10:36:53 -07:00
Gregg Van Hove
1926fc11ae Add jsdocs for reporter events 2017-08-09 10:21:59 -07:00
ksvitkovsky
e7049d3183 Add 'nothing' matcher and tests 2017-08-09 16:44:19 +04:00
Gregg Van Hove
80dba1138a Add explicit docs for the callback function passed to it etc. 2017-08-08 17:28:36 -07:00
Gregg Van Hove
9811ff71d2 Update afterAll documentation
- See jasmine/jasmine.github.io#76
2017-08-08 14:37:45 -07:00
Gregg Van Hove
301dd4f6b5 Merge branch 'kiewic-kiewic/toEqualArrayDiff'
- Closes #1375 from @kiewic
2017-08-08 09:55:32 -07:00
Gilberto Stankiewicz
090a6234c3 Make toEqual matcher report the difference between array elements when arrays have different length 2017-08-08 09:55:17 -07:00
Gregg Van Hove
8ad9abb19a Add arrayWithExactContents asymmetric matcher
- Fixes #817
2017-08-04 12:07:09 -07:00
Gregg Van Hove
8c0a8a1b33 Merge branch 'ksvitkovsky-github-1388'
- Closes #1408 from @ksvitkovsky
- Fixes #1388
2017-08-04 10:27:55 -07:00
ksvitkovsky
1db81c334d Ensure no message added on asym. match success 2017-08-04 10:26:51 -07:00
Gregg Van Hove
8dd0ad531c Merge branch 'ksvitkovsky-github-1403'
- Closes #1407 from @ksvitkovsky
- Fixes #1403
2017-08-04 09:55:09 -07:00
ksvitkovsky
f58002f0a6 Better primitives detection for saveArgsByValue 2017-08-04 09:40:42 -07:00
Gregg Van Hove
4d18e63b0f Merge branch 'ksvitkovsky-github-1180'
- Closes #1404 from @ksvitkovsky
- Fixes #1180
2017-08-04 09:34:16 -07:00
ksvitkovsky
4fc177d5ae Better pretty printing for typed arrays 2017-08-04 09:33:05 -07:00
Gregg Van Hove
acc8c23bf4 Merge branch 'theefer-fix-map+set-comparison'
- Merges #1406 from @theefer
- Fixes #1402
2017-08-04 09:23:31 -07:00
Sébastien Cevey
fc6ee243e9 Rewrite ES6 Set and Map comparison to ignore insertion order 2017-08-02 15:22:33 +01:00
Gregg Van Hove
b256741bec bump version to 2.7.0 2017-07-27 17:47:20 -07:00
Gregg Van Hove
1d4a2b5c22 Merge branch 'user-context' of https://github.com/darthjee/jasmine into darthjee-user-context
- Merges #1400 from @darthjee
2017-07-26 17:18:02 -07:00
darthjee
b0aac6b852 Add class UserContext 2017-07-26 23:40:22 +02:00
Gregg Van Hove
543e056056 Merge branch 'jberney-master'
- Merges #1399 from @jberney
2017-07-24 17:13:21 -07:00
Jonathan
7dfc5f506c Send unfocused tests through the same queue as focused tests 2017-07-23 09:01:15 -07:00
Gregg Van Hove
4cce7263c4 Update github issue and PR templates 2017-07-22 09:34:58 -07:00
Gregg Van Hove
31164106e5 Get the casing right for IE8 2017-07-18 21:51:32 -07:00
Gregg Van Hove
f71218a44b Allow IE8 to be weird when pretty printing 2017-07-18 21:07:38 -07:00
Gregg Van Hove
22e9d6df20 PrettyPrinter allows an object to have a toString that isn't a function
- Fixes #1389
2017-07-17 22:01:06 -07:00
Scott Erickson
6ddf64568e Add Promise checking to eq
Fixes #1314
2017-06-26 19:10:19 -07:00
Alpha Chen
aa72b0b7cf Simplified rounding code in toBeCloseTo
Signed-off-by: Steve Gravrock <sgravrock@pivotal.io>
2017-06-26 10:22:54 -07:00
Alpha Chen
9f3952ff87 Merge branch 'vanduynslagerp-fix-tobecloseto'
- Fixes #1382

Signed-off-by: Alpha Chen <achen@pivotal.io>
2017-06-26 10:21:13 -07:00
Pierre Vanduynslager
c604012793 Fix rounding in toBeCloseTo 2017-06-25 16:59:24 -04:00
Gregg Van Hove
6aa069d586 IE 8&9 use setTimeout to clearStack so mock clock gets tricky 2017-06-20 10:29:19 -07:00
Steve Gravrock
585287b9d6 When stop on failure is enabled, skip subsequent it() and beforeEach().
Note: afterEach() functions are still run, because skipping them is
highly likely to pollute specs that run after the failure.

[Finishes #92252330]

- Fixes #577
- Fixes #807
2017-06-19 13:48:43 -07:00
Gregg Van Hove
de862f8133 Only clear out the spec param for Run all link
- Fixes #1369
2017-06-16 14:07:40 -07:00
Gregg Van Hove
4e3ae726aa Bump version to 2.6.4 2017-06-16 13:44:43 -07:00
Steve Gravrock
9ee7b4ee0b Don't setTimeout() every time the stack is cleared via MessageChannel() 2017-06-16 09:58:41 -07:00
Gregg Van Hove
2e737f50ca Don't use window 2017-06-15 14:32:18 -07:00
Gregg Van Hove
c60d669940 Break into a setTimeout every once in a while
- Allows the CPU to run other things that used the real `setTimeout`

- Fixes #1327
- See #1334
- Fixes jasmine/gulp-jasmine-browser#48
2017-06-15 14:24:40 -07:00
Gregg Van Hove
4c491b2dc0 Pretty printer will now use MAX_PRETTY_PRINT_ARRAY_LENGTH for objects
- Fixes #1291
- Fixes #1360
2017-06-14 13:36:35 -07:00
Gregg Van Hove
f9d1e2f280 Merge branch 'EsrefDurna-master'
- Merges #1368 from @EsrefDurna
2017-06-12 14:03:11 -07:00
Esref Durna
270475bc61 updated package glob from 7.0.5 to 7.1.2
Npm link :  https://www.npmjs.com/package/glob
 Repository link : https://github.com/isaacs/node-glob/releases
2017-06-12 00:35:07 +00:00
Gregg Van Hove
acb9989178 Merge branch 'patch-1' of https://github.com/kant/jasmine into kant-patch-1
- Fix bower.json url to be https instead of http
- Merges #1365 from @kant
2017-06-07 14:22:24 -07:00
Gregg Van Hove
1fe1bbb6ed Merge branch 'master' of https://github.com/beatrichartz/jasmine into beatrichartz-master
- Merges #1362 from @beatrichartz
2017-06-07 14:16:48 -07:00
Gregg Van Hove
994878e6f6 bump version to 2.6.3
- cherry-pick release notes, etc.
2017-06-07 14:15:21 -07:00
Steve Gravrock
f7c160d716 Fixed HTML snippet in README
Closes #1366.
2017-06-06 15:57:45 -07:00
Gregg Van Hove
578f63b9bd Make sure the queue runner goes async for async specs
- Even if `done` is called synchronously.

See #1327 #1334 jasmine/gulp-jasmine-browser#48
2017-06-06 14:29:02 -07:00
Darío Hereñú
b1190eefb9 Minor fix 2017-06-04 00:40:53 -03:00
Beat Richartz
271908a2c4 Fail when one of the arguments passed into toBeCloseTo matcher is null 2017-06-02 15:36:39 +01:00
Gregg Van Hove
3372af1cf1 Merge branch 'seed-reporting' of https://github.com/sgravrock/jasmine into sgravrock-seed-reporting
- Merges #1348 from @sgravrock
2017-05-23 14:12:49 -07:00
Gregg Van Hove
d355fa0806 Don't tick extra. It's breaking IE 8 & 9 2017-05-22 14:27:08 -07:00
Steve Gravrock
56a79bef98 Use a less ancient Node on Travis CI 2017-05-19 15:47:54 -07:00
Gregg Van Hove
2ea4e9507c Merge branch 'map-support' of https://github.com/rmehlinger/jasmine into rmehlinger-map-support
- Merges #1340 from @rmehlinger
- Fixes #1257
2017-05-19 14:19:14 -07:00
Gregg Van Hove
c848a66faa Merge branch 'promises' of https://github.com/sgravrock/jasmine into sgravrock-promises
- Merges #1356 from @sgravrock
- Fixes #1336
- Fixes #1270
- Fixes #1350
- Fixes #1320
2017-05-19 14:03:21 -07:00
Gregg Van Hove
99fd7ddb88 Update python release instructions
- so I don't have search my bash history
2017-05-17 17:35:23 -07:00
Gregg Van Hove
5d1d19f494 Bump version to 2.6.2 2017-05-17 17:24:16 -07:00
Steve Gravrock
4f49288f31 Built distribution
- Fixes #1327
- Fixes jasmine/gulp-jasmine-browser#48
2017-05-16 14:36:35 -07:00
Steve Gravrock
b9adc76dc7 Clear the stack if onmessage is called before the previous invocation finishes 2017-05-16 14:08:58 -07:00
Steve Gravrock
9672689d40 Added support for ES2017 async functions 2017-05-12 14:42:14 -07:00
Steve Gravrock
a237ac5386 Added support for async before/it/after functions that return promises 2017-05-11 14:31:09 -07:00
Gregg Van Hove
5ac3e21abb Merge branch 'interleaved-suites' of https://github.com/sgravrock/jasmine into sgravrock-interleaved-suites
- Merges #1352 from @sgravrock
- Fixes #1344
- Fixes #1349
2017-05-10 13:49:05 -07:00
Steve Gravrock
88763012e4 Unified async and async queueable function running code 2017-05-10 10:14:47 -07:00
Steve Gravrock
b1e97cfb09 Correctly route errors that occur while a QueueRunner is clearing stack
Besides surfacing the error in the hopefully-correct place, this also
prevents the queue runners for sibling suites from interleaving, which
in turn prevents all kinds of internal state corruption.

Signed-off-by: Gregg Van Hove <gvanhove@pivotal.io>
2017-05-09 15:01:18 -07:00
Gregg Van Hove
8e5823c0d2 Merge branch 'sgravrock-global-errors-rethrow'
- Merges #1347 from @sgravrock
2017-05-08 14:15:34 -07:00
Steve Gravrock
e6a7932ec1 Report the random seed at the beginning and end of execution
This allows reporters to provide the seed to the user even in cases
where Jasmine crashes before completing.
2017-05-08 12:09:17 -07:00
Steve Gravrock
10f1220e55 Don't mask errors that occur when no handlers are installed
It's possible for async code to cause an error when Jasmine
doesn't have any listeners registered internally. This causes
Jasmine to crash (Node) or log to the console (browser)
because of trying to call the nonexistent handler. This change
doesn't fix the overall problem but it does ensure that the
original error is logged rather than Jasmine's internal error.
2017-05-08 11:09:32 -07:00
rmehlinger
5ee03f02ed Add ES6 map support to Jasmine 2017-05-01 00:12:48 -07:00
Gregg Van Hove
2835ca3cce Bump version to 2.6.1 2017-04-26 14:18:15 -07:00
Gregg Van Hove
120c484419 Merge branch 'patch-1' of https://github.com/reinrl/jasmine into reinrl-patch-1
- Merges #1319 from @reinrl
2017-04-26 14:06:18 -07:00
Gregg Van Hove
1d62504534 Check for process.listeners as well, for GlobalErrors
- Fixes #1333
2017-04-26 13:54:07 -07:00
Gregg Van Hove
055d88eff8 Merge branch 'UziTech-ensure-function-or-undefined'
- Merges #1329 from @UziTech
- Fixes #1328
2017-04-26 13:50:11 -07:00
Tony Brix
d2b33e0c66 allow undefined as function 2017-04-26 13:49:13 -07:00
Gregg Van Hove
0c7f36a181 Merge branch 'UziTech-remove-evil'
- Merges #1330 from @UziTech
- Fixes #1325
2017-04-26 13:36:06 -07:00
Tony Brix
686d8157e5 remove eval to create spy wrapper 2017-04-26 13:34:32 -07:00
Gregg Van Hove
b771c083cb No longer try to use nextTick since node.js gets upset 2017-04-25 14:38:09 -07:00
Gregg Van Hove
fbd2ffc08b Build distribution for keys lookup fix 2017-04-25 14:35:58 -07:00
Gregg Van Hove
b3c8fb9797 Merge branch 'seanparmelee-keys-fix'
- Merges #1326 from @seanparmelee
- Fixes #1321
- Fixes #1324
2017-04-25 13:47:53 -07:00
Sean Parmelee
ef3cfe7f44 skip the test when we can’t get the propertyDescriptor 2017-04-25 12:27:32 -05:00
Sean Parmelee
0d6ecbec17 iterate through keys with a regular for loop 2017-04-25 11:28:16 -05:00
Rich Rein
7e4b8d4531 Update README.md
Made installation instructions more version-agnostic (using {#.#.#} instead of what was hard-coded to 2.0.0), corrected example HTML file (../jasmine-core/... instead of ../jasmine-2.0.0/... in the paths for the core files).
2017-04-24 12:43:40 -05:00
Gregg Van Hove
4b696fbf26 Bump version to 2.6.0 2017-04-19 14:14:39 -07:00
Gregg Van Hove
74511f5425 Merge pull request #1316 from rachelcarmena/update-introduction-url
Updating introduction url to last version
2017-04-17 13:51:33 -07:00
Rachel
3e912f7f4e Updating introduction url to last version 2017-04-17 20:30:13 +02:00
Gregg Van Hove
19b83a7434 Throw a recognizable Error message when fail outside of a spec.
Fixes #1017
2017-04-11 12:02:29 -07:00
Gregg Van Hove
98569ba0f3 Cache installed gems, so they don't need to be installed every time.
- See https://docs.travis-ci.com/user/caching/#Caches-and-build-matrices
2017-04-10 13:52:24 -07:00
Gregg Van Hove
7f11ecb62e Merge branch '1123-custom-error' of https://github.com/deckar01/jasmine into deckar01-1123-custom-error
- Merges #1298 from @deckar01
- Fixes #1123
2017-04-10 13:47:31 -07:00
Gregg Van Hove
97f8db0616 Merge branch 'gdborton-afterAll-order'
- Merges #1312 from @gdborton
- Fixes #1311
2017-04-10 13:37:04 -07:00
Gary Borton
50880fcff7 [lifecycle hooks] Make afterAll hooks operate in the fashion as afterEach.
It was discovered that afterAll hooks run in the same order that you add them,
while afterEach hooks were running in reverse order.  This commit makes their
order consistent, and adds regression tests.

Relevant issue - https://github.com/jasmine/jasmine/issues/1311
2017-04-10 07:03:37 -07:00
Gregg Van Hove
ddcae84480 Merge branch 'issue-1294' of https://github.com/toubou91/jasmine into toubou91-issue-1294
- Merges #1300 from @toubou91
- Fixes #1294
2017-04-07 17:42:17 -07:00
Gregg Van Hove
9d6a95d9ba Merge pull request #1301 from toubou91/gitignore-update
Gitignore update
2017-04-07 17:28:39 -07:00
Thodoris Bais
0d3b2b2f8e Added iml files to gitignore 2017-04-04 07:20:10 +02:00
Thodoris Bais
08f046c24c Added infinity methods, with tests 2017-03-27 00:04:43 +02:00
Jared Deckard
90c87140ac Expect an undefined error to be passed to the expectation result 2017-03-24 14:50:54 -05:00
Jared Deckard
25d9a396aa Test that custom matchers can supply custom errors 2017-03-24 14:12:33 -05:00
Jared Deckard
c42b1972e2 Allow the matcher provide a custom error message 2017-03-24 14:12:33 -05:00
Gregg Van Hove
7f8f2b5e7a Update jsDocs to something close to full coverage for public API
- #596
2017-03-23 12:20:08 -07:00
Gregg Van Hove
9cb2f06aa6 Add a first pass at jsdoc.
[##130415655] #596
2017-03-21 11:36:41 -07:00
Gregg Van Hove
a37b6c0d32 Merge branch 'master' of https://github.com/mmmichl/jasmine into mmmichl-master
- Merges #1283 from @mmmichl
2017-03-14 17:50:28 -07:00
Gregg Van Hove
5533d1a920 Fix casing for PhantomJS is userAgent check 2017-03-14 14:43:44 -07:00
Gregg Van Hove
75e652d6a7 Cleanup toThrowError constructor lookup to work in older IE
- Also use the existing browser detection for phantom
2017-03-14 14:26:17 -07:00
Gregg Van Hove
e1f7ca51da Merge branch 'issue-1252' of https://github.com/anseki/jasmine into anseki-issue-1252
- Merges #1275 from @anseki
- Fixes #1252
2017-03-10 14:36:22 -08:00
Gregg Van Hove
538ae7b9ac Merge branch 'foretagsplatsen-toHaveBeenCalledBefore' 2017-03-10 09:57:21 -08:00
Gregg Van Hove
2ea41d3e27 Merge branch 'toHaveBeenCalledBefore' of https://github.com/foretagsplatsen/jasmine into foretagsplatsen-toHaveBeenCalledBefore
- Merges #1242 from @DamienCassou
2017-03-10 09:57:03 -08:00
Gregg Van Hove
bd9ae3a25b Fix syntax error 2017-03-07 17:05:12 -08:00
Gregg Van Hove
1042c9a2dd Collect unhandled exceptions and pass them to the current runnable
Fixes #529
Fixes #937
2017-03-07 16:32:11 -08:00
Gregg Van Hove
92e7436db2 Make sure the unlink is explicitly synchronous 2017-03-07 14:07:37 -08:00
Gregg Van Hove
74fe7fb85b Only have code climate grade the src 2017-03-01 16:29:10 -10:00
Gregg Van Hove
7e0fd79b3b Exclude some more stuff from codeclimate 2017-03-01 16:18:40 -10:00
mmmichl
8807bbb850 Pretty print objects passed to fail method
Fixes #1090
2017-02-26 19:25:02 +01:00
Damien Cassou
c93f35fbc8 fixup! Add toHaveBeenCalledBefore matcher 2017-02-20 10:55:23 +01:00
Damien Cassou
4cfdd06700 Add toHaveBeenCalledBefore matcher
This matcher makes sure the 'actual' spy is called before the
'expected' spy.

This code has been written in cooperation with Benjamin Van Ryseghem.
2017-02-20 09:52:14 +01:00
anseki
19b89d437e Skip a spec in PhantomJS that has bugs about iframe 2017-02-16 14:50:24 +09:00
Gregg Van Hove
43f96d3ecd Update gem authors 2017-02-15 17:00:17 -08:00
Gregg Van Hove
ac42bd9b35 More emeritus maintainers 2017-02-15 16:54:28 -08:00
Gregg Van Hove
9fbd0ba551 Nicer error messages for spyOn when null is provided
Fixes #1258
2017-02-15 15:55:27 -08:00
Gregg Van Hove
52876a7bf2 Merge branch 'bugfix-non-fn-args' of https://github.com/voithos/jasmine into voithos-bugfix-non-fn-args
- Merges #1222 from @voithos
- Fixes #1004
2017-02-15 15:18:50 -08:00
Gregg Van Hove
2eec3427e8 Re-generate files for new year in copyright
- Also read from env variable for sauce connect path
2017-02-15 15:15:58 -08:00
anseki
ed23254865 fix #1252 2017-02-10 17:17:39 +09:00
Gregg Van Hove
137e7e94d3 Merge pull request #1249 from Scottkao85/patch-1
Update MIT.LICENSE for new year
2017-01-02 12:14:44 -08:00
Gregg Van Hove
923b8fe9c4 Merge pull request #1248 from Nebojsaa/patch-1
Update README.md for new year
2017-01-02 12:14:27 -08:00
Scott Kao
61cc1eec66 Update MIT.LICENSE
update copyright year to 2017
2017-01-02 10:52:58 -08:00
Nebojsa Komnenovic
04be4c4583 Update README.md 2017-01-02 16:13:17 +01:00
Zaven Muradyan
b59ac96b51 Require arguments to beforeEach, it, etc, to be actual functions 2016-12-27 23:53:35 -08:00
Gregg Van Hove
be6ff8b24c Remove unused message param from Suite#pend
- See #1132
2016-12-02 10:08:39 -08:00
Gregg Van Hove
da2005fe97 Merge branch 'beforeall-in-xdescribe' of https://github.com/voithos/jasmine into voithos-beforeall-in-xdescribe
- Merges #1225 from @voithos
- Fixes #1175
2016-12-02 09:56:36 -08:00
Ben Christel
41a813521b Fix tests for toEqual diff output in IE
- Merges #1236 from @benchristel
2016-11-30 15:34:39 -08:00
Gregg Van Hove
54e7a82ef3 Merge branch 'benchristel-eq-diffs'
- Merges #1163 from @benchristel
- Fixes #675
2016-11-16 18:01:42 -08:00
Ben Christel
d5e6bf47ed Make toEqual matcher report the difference between objects
- Mismatches deep within object/array structures are pinpointed with a JsonPath-like syntax.
2016-11-14 22:08:34 -08:00
Gregg Van Hove
5a76e59d5b Merge branch 'spyOnProperty2' of https://github.com/celluj34/jasmine into celluj34-spyOnProperty2
- Merges #1203 from @celluj34
- Merges #1008 from @smacker
- Fixes #943
2016-11-04 14:36:56 -07:00
Gregg Van Hove
f5cfa2a4c1 Merge branch 'master' of https://github.com/d-reinhold/jasmine into d-reinhold-master
- Merges #1046 from @d-reinhold
- Fixes #510
2016-11-04 10:29:09 -07:00
Zaven Muradyan
c21bdaf35d Fix bug where before/afterAll were being executed in disabled suites. 2016-10-23 20:40:58 -07:00
Pivotal
369e8cc08b Merge branch 'mockMethodsShortcut' of https://github.com/mbildner/jasmine into mbildner-mockMethodsShortcut
- Merges #1101 from @mbildner
2016-10-17 15:53:05 -07:00
Gregg Van Hove
0e9b9a11c3 Fix tests for new stack clearing in IE 2016-10-14 15:53:00 -07:00
Gregg Van Hove
9750ae59e7 Update env integration specs now that we're really async 2016-10-14 10:13:27 -07:00
Gregg Van Hove
2f01f64249 Build distribution for clear stack implemenation 2016-10-14 09:48:11 -07:00
Gregg Van Hove
17c89c69d6 Separate clear stack and run it after each spec
[finishes #50197985][fix #109418332]
- Fixes #985
- Fixes #945
- Fixes #366
2016-10-14 09:21:49 -07:00
Gregg Van Hove
d85d6dd4b8 Now that it's valid syntax, make the specs work right with for 2016-09-28 12:19:18 -07:00
Gregg Van Hove
ff85714b24 syntax for a for loop is different than forEach 2016-09-28 11:52:18 -07:00
Gregg Van Hove
0d1a9a72d9 Fix spy arity stuff to work in IE8 2016-09-28 11:49:07 -07:00
Gregg Van Hove
63cc6687ff require newer jasmine-npm 2016-09-28 11:04:01 -07:00
Gregg Van Hove
75a5681c5e Merge branch 'kapke-spy-arity-preservation' 2016-09-28 10:52:17 -07:00
Gregg Van Hove
9df1edbdc9 Use the passed in env to pend browsers so IE8 works 2016-09-28 10:40:53 -07:00
Gregg Van Hove
5279e7a8c4 Checking for Set isn't browser dependant 2016-09-27 16:11:43 -07:00
Gregg Van Hove
c2e2bd7c91 Merge branch 'spy-arity-preservation' of https://github.com/kapke/jasmine into kapke-spy-arity-preservation
- Merges #1055 from @kapke
- Fixes #991
2016-09-27 15:42:45 -07:00
Gregg Van Hove
bad9c63bf7 Properly skip Set tests in browsers that don't really support it 2016-09-27 15:36:01 -07:00
Gregg Van Hove
05097b3e42 Merge branch 'set-equality' of https://github.com/alur/jasmine into alur-set-equality
- Merges #1067 from @alur
2016-09-27 13:37:57 -07:00
Gregg Van Hove
1efed4c156 Update pretty print specs to work in IE8 2016-09-27 12:26:02 -07:00
Gregg Van Hove
f4849f6401 Merge branch 'pretty-print-cross-frame-objects' of https://github.com/thatfulvioguy/jasmine into thatfulvioguy-pretty-print-cross-frame-objects
- Merges #1091 from @thatfulvioguy
- Fixes #1087
2016-09-27 11:40:01 -07:00
Gregg Van Hove
ec2ae4d521 Merge branch 'custom-testers-in-asymmetric-matchers' of https://github.com/joeyparrish/jasmine into joeyparrish-custom-testers-in-asymmetric-matchers 2016-09-27 11:01:45 -07:00
Greg Cobb
ac3d64cf84 Merge pull request #1215 from mattc41190/patch-1
Fix bad url
2016-09-22 23:03:49 -07:00
Matthew Cale
2d3c8c9f26 Fix bad url
Current README returns 404 when contributors guide is clicked.
2016-09-22 21:23:35 -05:00
Gregg Van Hove
6816bc4252 Update to 2.5.2 2016-09-16 17:19:59 -07:00
Gregg Van Hove
04bb56a5b5 Allow currently registered reporters to be cleared
- jasmine/jasmine-npm#88
2016-09-16 16:02:08 -07:00
Greg Cobb
ed31b9b844 Add ISSUE_TEMPLATE for github issues 2016-09-16 10:26:11 -07:00
Gregg Van Hove
4e47b78f1f Use isFunction to check for functionness in callFake
- Fixes #1191
2016-09-14 16:06:44 -07:00
Henry Blyth
8e23c26383 Make spyOnProperty available in tests
Needed adding to the env and require interface
2016-09-12 18:22:58 -05:00
Sukharev Maxim
56191cfb2e Implement spies for get/set functions on accessor properties 2016-09-12 18:22:58 -05:00
Gregg Van Hove
8624a52ee0 Don't auto install phantom since it doesn't seem to work on travis 2016-09-07 15:48:20 -07:00
Gregg Van Hove
a4b92b34f4 Update to 2.5.1 2016-09-07 14:31:18 -07:00
Gregg Van Hove
3486e8d166 Merge branch '1189' of https://github.com/seanparmelee/jasmine into seanparmelee-1189
- Merges #1193 from @seanparmlee
- Fixes #1189
2016-09-01 21:11:07 -07:00
Gregg Van Hove
8366ef9be5 Merge branch 'fix' of https://github.com/logankd/jasmine into logankd-fix
- Merges #1192 from @logankd
- Fixes #1188
2016-09-01 20:44:13 -07:00
Gregg Van Hove
ab0567c665 Generated file for date tick fix 2016-09-01 20:41:51 -07:00
Sean Parmelee
8676bbf11a fallback on assignment when a spy cannot be deleted 2016-09-01 13:39:25 -05:00
Kevin Logan
c0a9d20a02 fix for issue #1188 2016-09-01 10:59:19 -05:00
Gregg Van Hove
c7cc3b4a29 Properly tick date along with clock
- Specifically when there aren't functions scheduled at the ticks

Fixes #1190
2016-08-31 21:24:01 -07:00
Gregg Van Hove
5a2e1b0082 Update to 2.5.0 2016-08-30 21:23:08 -07:00
Gregg Van Hove
f196faf0bb Update anonymous constructor pretty print specs to work in IE 2016-08-25 15:29:32 -07:00
Gregg Van Hove
850204dfb8 Merge branch 'prettyPrintCustomConstructortoString' of https://github.com/mbildner/jasmine into mbildner-prettyPrintCustomConstructortoString
- Fixes #1019
- Merges #1099
2016-08-15 15:50:59 -07:00
Gregg Van Hove
7bda3bd728 Build distribution 2016-08-15 09:41:48 -07:00
Gregg Van Hove
b9c25e88b9 Merge branch 'callfake-better-error' of https://github.com/kapke/jasmine into kapke-callfake-better-error
- Merges #1059
- Fixes #1016
2016-08-15 09:34:03 -07:00
Gregg Van Hove
13228c304e Add gulp-jasmine-browser link to readme
Close #1089
2016-08-15 09:30:38 -07:00
Greg Cobb
da18479422 Merge pull request #1170 from benchristel/how-to-test-in-ie
Add instructions for testing in IE
2016-07-25 21:59:23 -07:00
Greg Cobb
ba211e4913 Update codeclimate.yml
[#1171]
2016-07-25 21:36:57 -07:00
Greg Cobb
5f9a965d7c Exclude lib directory from codeclimate
- Generated files show up as duplicates of src

[#1171]
2016-07-25 21:11:44 -07:00
Ben Christel
3ff59835ea Add instructions for testing in IE 2016-07-25 10:20:43 -07:00
Greg Cobb
9fedf74f32 Build distribution 2016-07-24 22:38:36 -07:00
Greg Cobb
0339fc500a Merge pull request #1169 from benchristel/fix-build
Fix the build in ie8
2016-07-24 22:20:55 -07:00
Ben Christel
227b0c62a3 Make the build pass in ie8
- pending() throws an exception in ie8. I have not dug into the root cause.
- iframe.contentWindow.eval() isn't supported in ie8
2016-07-24 21:48:11 -07:00
Greg Cobb
3de60067f0 Merge pull request #1158 from benchristel/move-functions-to-higher-scope
Restructure eq code and tests
2016-07-21 21:28:45 -07:00
Ben Christel
cb1001e6c2 De-dup test setup
- Move environment-specific tests for toEquals into describe blocks so the check for the environment can be shared
2016-07-21 12:26:43 -07:00
Ben Christel
d9ded15c45 Move functions in to a higher scope
- Prevents them from accessing eq's local vars, which could cause bugs.
2016-07-21 12:10:37 -07:00
Ben Christel
a0bce8031e Test comparison of objects from different frames 2016-07-21 12:10:37 -07:00
Greg Cobb
7f7dda7a2c Merge pull request #1162 from amavisca/update-dev-dependencies
Update devDependencies and fix issues from this
2016-07-20 20:18:57 -07:00
Chris Amavisca
15f92b226c Update devDependencies and fix issues from this
- Point to npm released version of jasmine node runner
2016-07-20 20:11:52 -07:00
Greg Cobb
99aa2247b6 Build distribution 2016-07-19 23:00:25 -07:00
Greg Cobb
314eb63552 Merge pull request #1129 from gregeinfrank/remove-runnable-lookup-table
Remove runnableLookupTable which is no longer used
2016-07-18 23:39:15 -07:00
Greg Cobb
bd6ca98f9d Revert "Merge pull request #1151 from amavisca/update-dev-dependencies"
This reverts commit eee75d8eed, reversing
changes made to 5e0ebadb3d.
2016-07-18 23:28:50 -07:00
Greg Cobb
eee75d8eed Merge pull request #1151 from amavisca/update-dev-dependencies
Upgrade devDependencies glob and shelljs
2016-07-18 23:00:34 -07:00
Greg Cobb
5e0ebadb3d Merge pull request #1155 from benchristel/arrays-properties-bug
Make `toEqual` pass for arrays with equivalent properties
2016-07-18 22:56:20 -07:00
Ben Christel
738c10fd43 Make toEqual pass for arrays with equivalent properties
- Fixes a bug caused by accidental use of a closure variable
2016-07-18 16:48:00 -07:00
Greg Cobb
8c9ffe3144 Merge pull request #1152 from amavisca/update-travis-ruby
Update ruby version on travis to let rack install
2016-07-14 22:28:50 -07:00
Chris Amavisca
ab2c916c3a Update ruby version on travis to let rack install 2016-07-14 19:57:08 -07:00
Chris Amavisca
290fb3fdcd Upgrade devDependencies glob and shelljs 2016-07-14 19:46:32 -07:00
Joey Parrish
de7b7c029e Pass custom testers to asymmetric testers
This allows custom equality testers to affect asymmetric matches.
This avoid suprises when combining addCustomEqualityTester with
objectContaining or arrayContaining.

Closes #1138
2016-06-23 14:33:39 -07:00
Greg Einfrank
e13c7a55a9 Remove runnableLookupTable which is no longer used 2016-06-08 10:59:42 -07:00
Pivotal
7a62969a14 createSpyObj may use object for method->response shorthand
examples:

```JavaScript
var mySpy = jasmine.createSpyObj("mySpy", { getAge: 55, getLanguage: "JavaScrizzle" });

var age = mySpy.getAge();

expect(age).toEqual(55);
expect(mySpy.getAge).toHaveBeenCalled();
```

Also does:

Add "isObject_" method to utils to make it easier for "createSpy" to support an array or object of stubs
2016-04-25 17:10:22 -04:00
Pivotal
604cd6132f Prettyprint objects whose constructors have custom toString method
- when the constructor has a name, print the name
- when the constructor does not have a name, print `<anonymous>`

[Fixes issue 1019](https://github.com/jasmine/jasmine/issues/1019)
2016-04-25 14:23:48 -04:00
Fulvio Valente
2710bdfc5e Correctly pretty print objects from other contexts (e.g. iframes) and which do not override toString
Fixes #1087
2016-04-11 18:51:04 +01:00
Gregg Van Hove
f6da084642 Merge branch 'patch-1' of https://github.com/skupr/jasmine into skupr-patch-1
- Merges #1079 from @skupr
- Fixes #964
2016-03-26 21:28:46 -07:00
Gregg Van Hove
6c0224414c Generate combined file for previous features 2016-03-26 21:27:04 -07:00
Stanislav Kupryakhin
c302545ba4 Fix jasmine setup in Electron environment
Fix for issue  #964
2016-03-21 08:38:27 +06:00
slackersoft
954a6a0091 Merge branch 'feat/improveErrorMessages' of https://github.com/dhoko/jasmine into dhoko-feat/improveErrorMessages
- Merges #1026 from @dhoko
- Fixes #1025
2016-03-18 10:59:31 -07:00
slackersoft
11cfaae42a Merge branch 'marneborn-bluebird3.0-warnings'
- Merges #1062 from @marneborn
- Fixes #992
2016-03-11 09:13:43 -08:00
Erik Welander
927cc011d6 Added support for ES6 sets to toContain and toEqual. 2016-03-04 02:09:59 -08:00
Mikael Arneborn
6cf2d94f73 The done function now returns null 2016-03-03 08:55:01 -08:00
Mikael Arneborn
b578e72c8f Added failing test for done returning null 2016-03-03 08:54:46 -08:00
Gregg Van Hove
1da6c7cf85 Merge branch 'add-editorconfig' of https://github.com/kapke/jasmine into kapke-add-editorconfig
- Merges #1058
- Fixes #1057
2016-03-01 17:50:59 -08:00
Gregg Van Hove
87e808282b Always quote the browser version so nothing converts it to a float 2016-03-01 17:34:24 -08:00
dhoko
14067d0785 Improve errors with the domaine and how to use the API 2016-02-29 10:33:45 +01:00
Dominick Reinhold
d1a94bcf50 When the HtmlReporter has a 'spec' query param, the spec list only shows matching specs/suites 2016-02-28 22:47:10 -08:00
Andrzej Kopeć
bbf3f6825c Improve error message when passing a non-function to callFake 2016-02-28 21:37:28 +01:00
Andrzej Kopeć
9b653b9dcb Add .editorconfig file 2016-02-28 18:33:39 +01:00
Gregg Van Hove
b6798cdb06 Html Reporter shows error bar for errors from a global afterAll
Issue #811
2016-02-25 16:12:15 -08:00
Gregg Van Hove
dbd198f7d0 Allow expectations in a global beforeAll or afterAll
- Report afterAll failures in jasmineDone
- Issue #811
2016-02-25 15:01:47 -08:00
Gregg Van Hove
5583b6f954 Top-level specs should compute fullName the same as Suites
- No longer include "Jasmine__TopLevel__Suite"
2016-02-25 14:29:35 -08:00
Gregg Van Hove
db8e636021 Add combined file for inherited spies 2016-02-25 14:25:40 -08:00
Andrzej Kopeć
90dea9ab38 Now spies preserve original function arity 2016-02-25 21:43:18 +01:00
Gregg Van Hove
ebbefafc26 Turn the describe error spec back on and update for new code 2016-02-25 10:04:31 -08:00
Gregg Van Hove
b66ffc1277 Merge branch 'spy-inherited-methods' of https://github.com/benchristel/jasmine into benchristel-spy-inherited-methods
- Merges #1036
- Fixes #737
2016-02-22 14:11:00 -08:00
Gregg Van Hove
5458f2f18d Array equality treats undefined elements as equal however they got in there
- Fixes #786
2016-02-22 11:06:59 -08:00
Gregg Van Hove
602f5bc08a Merge branch 'fallback-report' of https://github.com/mauricioborges/jasmine into mauricioborges-fallback-report
- Merges #1009
2016-02-22 10:20:48 -08:00
Gregg Van Hove
4e4cd30965 Merge pull request #1047 from d-reinhold/bundle-exec-compass
Grunt task for compass should prefix command with 'bundle exec'

- Merges #1047
2016-02-18 17:48:10 -08:00
Gregg Van Hove
7224c6adf2 Merge branch 'fix-eq-for-edge' of https://github.com/everedifice/jasmine into everedifice-fix-eq-for-edge
- Merges #1041
2016-02-18 16:48:33 -08:00
Gregg Van Hove
5bdd7e8fbf Merge branch 'issue-931-respy' of https://github.com/guy-mograbi-at-gigaspaces/jasmine into guy-mograbi-at-gigaspaces-issue-931-respy
- Merges #953
- Fixes #931
2016-02-18 11:40:01 -08:00
Gregg Van Hove
1e0381a495 Update describe error message to no longer assume errant args are done
Fixes #896
2016-02-18 09:31:31 -08:00
Gregg Van Hove
c454658c54 Merge branch 'rullopat-greater-than-or-equal-less-than-or-equal-matchers'
- Merges #1049
- Fixes #1013
2016-02-17 15:46:05 -08:00
Patrizio Rullo
b7d8b0de71 Add toBeGreatThanOrEqual and toBeLessThanOrEqual matchers
- Implements issue #1013
2016-02-18 00:13:26 +01:00
Gregg Van Hove
342f0eb9a3 Merge branch 'logankd-master'
- Support call count of 0 with toHaveBeenCalledTimes matcher

- Merges #1048
- Fixes #994
2016-02-17 10:33:27 -08:00
Kevin Logan
44b56093e7 #1048 - fixed toThrow expectation 2016-02-17 12:16:54 -06:00
Kevin Logan
bee8132848 #1015 - revert formatting and spacing 2016-02-17 12:09:26 -06:00
Kevin Logan
e5c744f3dc #1015 use isNumber fuction to check for empty expected argument. This will allow 0 to be passed in. 2016-02-17 12:03:06 -06:00
Gregg Van Hove
4fb5aa14b8 Merge branch 'issue1010' of https://github.com/bodawei/jasmine into bodawei-issue1010
- Merges #1011
- Fixes #1010
2016-02-16 15:41:42 -08:00
Gregg Van Hove
43cd73938d Merge branch 'remove-extra-topSuite-constructor-param' of https://github.com/jurko-gospodnetic/jasmine into jurko-gospodnetic-remove-extra-topSuite-constructor-param
- Merges #1006
2016-02-16 15:23:05 -08:00
Gregg Van Hove
f38e8e9235 Merge branch 'cloned-args-on-calltracker' of https://github.com/a-r-d/jasmine into a-r-d-cloned-args-on-calltracker
- Merges #1000
- Fixes #872
2016-02-16 15:00:49 -08:00
Gregg Van Hove
fcd5a1948b Merge branch 'skipped-links-with-random' of https://github.com/basawyer/jasmine into basawyer-skipped-links-with-random 2016-02-16 09:43:33 -08:00
Mauricio Borges Silva
6489b0f400 Add support on Env to provide fallback report 2016-02-15 23:12:05 -02:00
Mauricio Borges Silva
5e3582d8e7 Add support to fallback report providing on ReportDispatcher 2016-02-15 23:12:05 -02:00
Dominick Reinhold
33151ed9eb Grunt task for compass should prefix command with 'bundle exec'
- Since we're stating that compass is a development dependency in our
  gemspec, and we use bundle to install it, we should make sure that
  grunt is using the correct (bundled) version of compass.

- This is especially important since many of the older versions of compass
  are buggy (see https://github.com/gruntjs/grunt-contrib-compass/issues/204)
2016-02-15 11:39:21 -08:00
minhyeong-kim
3f27ff1c7c chore: fix jshint error 2016-02-04 17:47:17 +09:00
minhyeong-kim
b59cacf131 refactor: fix Edge freezing issue for matcherUtils#eq
fix Microsoft Edge freezing when recursive comparing
2016-02-04 17:09:03 +09:00
Ben Christel
d6f1f8dec5 Correctly teardown spies on inherited methods
- If the spied method is not an own property of the object being spied
  upon, the method is deleted from the object on teardown instead of
  being set to the original implementation.

- #737
2016-02-01 17:45:47 -08:00
Gregg Van Hove
e0541eca80 Merge pull request #1021 from pra85/2016
Update license year range to 2016
2016-01-17 15:24:53 -08:00
Prayag Verma
8b7cb21874 Update license year range to 2016 2016-01-18 01:13:22 +05:30
Blake Sawyer
ee0ff3b6c8 Persist randomize param in 'run all' links 2016-01-14 20:58:15 -05:00
DJ Burrowes
65241565c5 Reverse order that spies are cleared up.
Fixes #1010
2016-01-03 19:14:57 -08:00
Jurko Gospodnetić
a047115eef remove extra topSuite queueRunner construction parameter
The `Suite` constructor function does not expect or use the its only `attrs`
parameter's `queueRunner` attribute, so setting it serves no purpose and
only clutters the code and makes it more difficult to understand.
2015-12-26 21:49:45 +01:00
Gregg Van Hove
0d4c8d13bb build distribution file for mockDate changes 2015-12-22 15:25:38 -08:00
Gregg Van Hove
17c5e2b10d Merge branch 'fix-clock-date' of https://github.com/andrewiggins/jasmine into andrewiggins-fix-clock-date
Fixes #915
Merges #980
2015-12-22 15:18:58 -08:00
Aaron DEcker
fa71928cad changed arg cloner to be safe on older browsers 2015-12-22 00:35:36 -05:00
Aaron DEcker
3e91ac0889 add option to shallow clone args in call tracker 2015-12-22 00:27:51 -05:00
Gregg Van Hove
79206ccff5 Rename j$ to jasmineUnderTest for specs
- Clarifies what it is for when writing tests
- No longer named the same as the `jasmine` that is injected into live
  code
2015-12-03 17:23:32 -08:00
Gregg Van Hove
a95c2cfe3f Bump version to 2.4.1 2015-12-03 16:06:51 -08:00
Gregg Van Hove
e2e2d1b343 Revert #908
- Run `afterEach` in reverse order declared as before
2015-12-03 16:02:32 -08:00
Gregg Van Hove
3b53e469fd Bump version to 2.4.0 2015-12-02 22:02:03 -08:00
Andre Wiggins
c8b212f278 make DelayedFunctionScheduler update the mockDate 2015-11-20 03:45:57 -08:00
Gregg Van Hove
b3f69852c1 Merge pull request #973 from brunoqc/patch-1
Syntax highlighting in README.md
2015-11-13 17:05:28 -08:00
Bruno Bigras
1613a376b1 Syntax highlighting in README.md 2015-11-12 12:10:21 -05:00
Gregg Van Hove
1e35e8ba95 Use git:// url for jasmine-npm dependency 2015-11-04 15:12:38 -08:00
Gregg Van Hove
a6b209bc2f Use jasmine-npm straight from github when developing 2015-11-04 15:05:07 -08:00
Gregg Van Hove
2301914549 build combined file for jsApiReporter changes
[#92249258]
2015-11-04 14:11:39 -08:00
Gregg Van Hove
320c42b6cc Run jasmine's specs randomly in node and performance specs
[#92249258]
2015-11-04 12:30:49 -08:00
Gregg Van Hove
df45b4fede Run jasmine's specs in random order
[#92249258]
2015-11-04 12:06:28 -08:00
Gregg Van Hove
c1ab3c9cbe Add support for returning run details for reporting randomness
[#92249258]
2015-11-04 12:05:29 -08:00
Gregg Van Hove
d2f2e2b870 Merge branch 'himajasuman-issue#896'
Fixes #896
2015-10-27 14:13:15 -07:00
Gregg Van Hove
0f6a7f04b3 Merge branch 'issue#896' of https://github.com/himajasuman/jasmine into himajasuman-issue#896 2015-10-27 14:12:31 -07:00
Gregg Van Hove
728af5e556 Remove unused queueableFn arg from onException
Fixes #958
2015-10-27 12:24:32 -07:00
Gregg Van Hove
018fd53c10 Merge branch 'FuzzySockets-to-throw-error-unused-param' 2015-10-27 12:22:09 -07:00
Gregg Van Hove
25d73515f3 Merge branch 'to-throw-error-unused-param' of https://github.com/FuzzySockets/jasmine into FuzzySockets-to-throw-error-unused-param 2015-10-27 12:21:42 -07:00
Gregg Van Hove
8e317d4026 Less verbose for the linter 2015-10-26 17:51:42 -07:00
Gregg Van Hove
ea4c44904d IE 8 doesn't support defineProperty on non-DOM nodes, skip that kindof thing 2015-10-26 17:41:30 -07:00
Gregg Van Hove
77514bbb80 use safari 9 not 8.1 anymore 2015-10-26 17:18:25 -07:00
Gregg Van Hove
a85c3a4da8 Check for descriptor 2015-10-26 17:03:45 -07:00
Gregg Van Hove
0b1e1a0401 Merge branch 'StephanBijzitter-throw-for-constants'
Fixes #948
2015-10-26 16:30:01 -07:00
Gregg Van Hove
3374415add Merge pull request #954 from matthewhuff89/remove_goals_md
Removed GOALS_2.0.md, doesn't seem to be needed anymore
2015-10-26 14:58:03 -07:00
Richard Harrington
c2ae3b6b12 Remove unused parameter from toThrowError 2015-10-26 11:43:31 -04:00
Himaja
110cacab19 Added a throw error block in describe incase a function with arguments is passed in describe 2015-10-25 14:13:14 -04:00
Matthew D. Huff
db7879a478 Removed GOALS_2.0.md, doesn't seem to be needed anymore 2015-10-25 13:03:46 -04:00
guy-mograbi-at-gigaspaces
e7dbc75fc2 feat(spy): add option to respy
will not throw error if spyOn called on a spy

fixes #931
2015-10-24 08:37:33 +03:00
Stephan Bijzitter
a81466d9e7 Abort spying when the target cannot be spied on 2015-10-21 12:44:52 +02:00
Gregg Van Hove
48f42eaa7d Merge branch 'lalunamel-master'
Merges #942
Fixes #930
Fixes #912
2015-10-15 09:21:57 -07:00
Cody Sehl
e5c2572753 Change #xit so that it will output a more BDD-style pending message 2015-10-14 21:03:47 -06:00
Gregg Van Hove
141fd910f2 Use className instead of class when creating DOM elements 2015-10-06 09:10:22 -07:00
Gregg Van Hove
a93bfd2120 Merge branch 'marcioj-random-tests' 2015-10-04 14:03:30 -07:00
Gregg Van Hove
4221b2d2c4 Merge branch 'random-tests' of https://github.com/marcioj/jasmine into marcioj-random-tests 2015-10-04 14:03:17 -07:00
Gregg Van Hove
6ee7fd6ced Merge branch 'toString_fallback' of https://github.com/myitcv/jasmine into myitcv-toString_fallback 2015-10-04 13:47:27 -07:00
Gregg Van Hove
878325e2cf Merge branch 'James-Dunn-patch-1' 2015-10-04 13:45:10 -07:00
James
80c4f87dd5 Fix circles/x from getting cut off on Mac/chrome 2015-09-27 17:01:08 +04:00
Marcio Junior
3f3fa484b2 Allow tests to run in random order 2015-09-26 14:53:08 -03:00
Paul Jolly
d0ad9b98cd Use toString for objects if it has been overriden 2015-09-25 20:19:48 +01:00
Gregg Van Hove
375a6f9fda Merge branch 'danielalexiuc-master'
- Fixes #924
- Fixes #917
2015-09-24 12:58:56 -07:00
danielalexiuc
c017f0000d Postpone find() until it is needed
This is a fix for issue #917.

It seems that 'symbols' was originally included as a performance optimization, to avoid repeated find() calls for '.jasmine-symbol-summary'. However this find() occasionally fails during initialize if the dom has not loaded completely.

This change will not affect performance, as symbols is still cached. However it improves upon the original code in that the find happens at a stage much later than initialize.
2015-09-16 11:52:05 +10:00
Gregg Van Hove
4097718b66 Merge pull request #906 from soycode/master
check for global before assigning
2015-09-03 13:38:21 -07:00
Gregg Van Hove
825dab32ff Merge pull request #908 from mcamac/master
Reverse suite afterEach behavior to match semantics?
2015-09-01 21:33:52 -07:00
Martin Camacho
f3a7396845 afterEach behavior 2015-08-18 17:55:03 -04:00
soycode
850bee5492 check for global before assigning 2015-08-17 14:20:52 -07:00
Gregg Van Hove
6028a5d92c Merge branch 'SimenB-badges' 2015-08-10 10:39:39 -07:00
Simen Bekkhus
93a13ab791 Use badges from shields.io 2015-08-08 07:54:15 +02:00
Greg Chattin-McNichols and Gregg Van Hove
542f483228 Force the safari 8.1 version to be a string for sauce 2015-08-04 15:11:39 -07:00
Greg Chattin-McNichols and Gregg Van Hove
459b4c29b6 Drop Safari 5 on OS-X from the build matrix
- SauceLabs no longer supports it
- Add Safari 8.1
2015-08-04 09:40:37 -07:00
Greg Chattin-McNichols and Gregg Van Hove
750a9aac6d Merge pull request #869 from ljwall/jasmine
Fixes #855
2015-08-03 15:01:43 -07:00
Greg Chattin-McNichols and Gregg Van Hove
cd55f03912 concat files for toHaveBeenCalledTimes matcher 2015-08-03 14:57:52 -07:00
Gregg Van Hove
79954311fb Merge pull request #892 from obastemur/patch-1
Update glob to latest
2015-07-16 12:10:21 -07:00
Oguz Bastemur
3f71bcdb2d Update glob to latest
Fixes https://github.com/jasmine/jasmine/issues/891
2015-07-15 02:37:36 +03:00
Gregg Van Hove
06f05ac57b Add notes about "ready for work" label 2015-07-02 14:52:17 -07:00
Gregg Van Hove
5ea5ec6004 Merge branch 'kkirsche-patch-1' 2015-06-12 13:25:37 -07:00
Kevin Kirsche
f7033f6551 Remove moot version property from bower.json
Per bower/bower.json-spec@a325da3
2015-06-10 18:36:17 -04:00
Gregg Van Hove
7e6e905814 Merge branch 'logankd-toHaveBeenCalledTimes'
Fixes #871
2015-06-05 21:09:51 -07:00
Kevin
a6a1962924 add toHaveBeenCalledTimes matcher
Fix #853
2015-06-05 21:07:24 -07:00
Gregg Van Hove
50944fea6f Mention use of bundle exec for running the jasmine server during dev 2015-06-05 20:36:56 -07:00
Liam Wall
7bfc4c0a45 xdescribe marks pending, plus associated tests. 2015-05-29 17:21:28 +01:00
Gregg Van Hove and Noah Denton
4be2079482 Use the travis sauce connect addon 2015-05-18 17:04:21 -07:00
Gregg Van Hove
d6f47ea886 Merge pull request #856 from lpww/patch-1
Update CONTRIBUTING.md
2015-05-18 14:29:44 -07:00
Gregg Van Hove
5061dd066c Merge branch 'unique-css-classes' of https://github.com/prather-mcs/jasmine into prather-mcs-unique-css-classes 2015-05-18 14:29:03 -07:00
Gregg Van Hove
2a847a67e3 Merge branch 'danfinnie-any-vs-anything-error' 2015-05-18 14:27:27 -07:00
Thomas Treffry
50223d97d6 Update CONTRIBUTING.md
Rephrase confusing statement:

From:
If when you run ($ grunt)...you see that JSHint runs your system is ready.

To:
Now run ($ grunt)...if you see that JSHint runs, your system is ready.
2015-05-17 11:49:39 -07:00
Dan Finnie
302e78f1df Raise an error when jasmine.any() isn't passed a constructor 2015-05-17 02:21:26 -04:00
Matt Prather
42ad12ec52 Make the HtmlReport CSS classes "unique enough"
The only difference between this commit and the previous is that I have
used a difference scheme for naming Jasmine CSS classes.

Instead of appending "_jasmine-css" to all Jasmine CSS selectors, I have
now preprended "jasmine-" instead.
2015-05-14 14:23:06 -07:00
Matt Prather
c41fa7d156 Make the HtmlReport CSS classes "unique enough"
As described in Issue Report 844...
https://github.com/jasmine/jasmine/issues/844

...style rules in the app-being-tested may incidentally affect elements
in the Jasmine HTML Report container, as long as there is a chance that
the app-being-tested has CSS style rules for classes (or IDs) that
Jasmine uses.

This fix attempts to bring Jasmine to a state where each and every class
it uses always ends with "_jasmine-css" which should be unique enough to
ensure that CSS in the app-being-tested won't affect the Jasmine report,
because no app-being-tested is ever likely to use classes that end with
"_jasmine-css"

I'll be surpised if this commit is good enough as it is now, on the
first attempt to fix #844, because of reasons I'll explain in either
the Issue or the Pull Request.
2015-05-13 18:55:44 -07:00
Gregg Van Hove
0b1449228f Bump version to 2.3.4 2015-05-13 14:57:56 -07:00
Gregg Van Hove
65a6decd6d Fix ordering for suites with more than 11 direct children.
- When no specs were focused, they all had the same precedence, and
  `sort`ing them caused some of the nodes to move around

Fixes #850
2015-05-13 14:45:11 -07:00
Gregg Van Hove
7cbd86357d Merge branch 'remove-dead-css' of https://github.com/prather-mcs/jasmine into prather-mcs-remove-dead-css 2015-05-13 11:03:25 -07:00
Gregg Van Hove
4f278be2c2 Update standalone installation instructions to reference the releases page
Fix #603
2015-05-13 10:59:39 -07:00
Matt Prather
f2bc9b5bd8 Remove the style rule for .running-alert CSS class
https://github.com/jasmine/jasmine/issues/847#issuecomment-101446573
2015-05-12 15:51:42 -07:00
Gregg Van Hove
e9d79bc946 Merge branch 'prather-mcs-remove-dead-css' 2015-05-11 10:59:36 -07:00
Gregg Van Hove
0b2097b616 Bump version to 2.3.3 2015-05-11 10:48:58 -07:00
Gregg Van Hove
f02824ae52 Merge branch 'remove-dead-css' of https://github.com/prather-mcs/jasmine into prather-mcs-remove-dead-css 2015-05-11 10:41:18 -07:00
Robert Neumann
225c7bdda3 Set the shared user context correctly when executing the top level suite
Fixes #846
2015-05-11 10:29:51 -07:00
Matt Prather
e855c898d1 Remove dead CSS class styles
I removed the `.showDetails` and `.summaryMenuItem` styles from the Sass
file because I believe that no HTML elements with those classes will
ever be generated by Jasmine and that they are dead code that someone
forgot to remove.

This is my first contribution to the Jasmine project and so I might be
doing something wrong, but I believe just this one change will propagate
to all the generated code when it is built, and that I should not be
altering any other code in any other place to accomplish the change I
intend.

This is related to Jasmine Issue 847:
https://github.com/jasmine/jasmine/issues/847
2015-05-10 16:58:07 -07:00
209 changed files with 16786 additions and 5013 deletions

16
.editorconfig Normal file
View File

@@ -0,0 +1,16 @@
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
[*.{js, json, sh, yml, gemspec}]
indent_style = space
indent_size = 2
[{Rakefile, .jshintrc}]
indent_style = space
indent_size = 2
[*.{py}]
indent_style = space
indent_size = 4

View File

@@ -1,6 +1,6 @@
# 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 before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
We welcome your contributions! Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better. If you want to contribute but don't know what to work on, [issues tagged ready for work](https://github.com/jasmine/jasmine/labels/ready%20for%20work) should have enough detail to get started.
## Links
@@ -16,7 +16,8 @@ Please submit pull requests via feature branches using the semi-standard workflo
git clone git@github.com:yourUserName/jasmine.git # Clone your fork
cd jasmine # Change directory
git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream'
git fetch upstream # Pull in changes not present in your local repository
git fetch upstream # Fetch changes not present in your local repository
git merge upstream/master # Sync local master with upstream repository
git checkout -b my-new-feature # Create your feature branch
git commit -am 'Add some feature' # Commit your changes
git push origin my-new-feature # Push to the branch
@@ -40,9 +41,9 @@ Once you've pushed a feature branch to your forked repo, you're ready to open a
### Self-testing
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `j$`. So there are two copies of the code loaded under test.
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `jasmineUnderTest`. So there are two copies of the code loaded under test.
The tests should always use `j$` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
The tests should always use `jasmineUnderTest` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
### `boot.js`
@@ -82,11 +83,11 @@ To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http:/
$ npm install --local
...will install all of the node modules locally. If when you run
...will install all of the node modules locally. Now run
$ grunt
...you see that JSHint runs your system is ready.
...if you see that JSHint runs, your system is ready.
### How to write new Jasmine code
@@ -105,7 +106,7 @@ Follow these tips and your pull request, patch, or suggestion is much more likel
Jasmine uses the [Jasmine Ruby gem](http://github.com/jasmine/jasmine-gem) to test itself in browser.
$ rake jasmine
$ bundle exec rake jasmine
...and then visit `http://localhost:8888` to run specs.
@@ -115,16 +116,23 @@ Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/jasmine-npm) to
...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).
The easiest way to run the tests in **Internet Explorer** is to run a VM that has IE installed. It's easy to do this with VirtualBox.
1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
1. Download a VM image [from Microsoft](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/). Select "VirtualBox" as the platform.
1. Unzip the downloaded archive. There should be an OVA file inside.
1. In VirtualBox, choose `File > Import Appliance` and select the OVA file. Accept the default settings in the dialog that appears. Now you have a Windows VM!
1. Run the VM and start IE.
1. With `bundle exec rake jasmine` running on your host machine, navigate to `http://10.0.2.2:8888` in IE.
## Before Committing or Submitting a Pull Request
1. Ensure all specs are green in browser *and* node
1. Ensure JSHint is green with `grunt jshint`
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
## Submitting a Pull Request
1. Revert your changes to `jasmine.js` and `jasmine-html.js`
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
Note that we use Travis for Continuous Integration. We only accept green pull requests.

44
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,44 @@
## Are you creating an issue in the correct repository?
- When in doubt, create an issue here.
- If you have an issue with the Jasmine docs, file an issue in the docs repo
here: https://github.com/jasmine/jasmine.github.io
- This repository is for the core Jasmine framework
- If you are using a test runner that wraps Jasmine, consider filing an issue with that library if appropriate:
- [Jasmine npm](https://github.com/jasmine/jasmine-npm/issues)
- [Jasmine gem](https://github.com/jasmine/jasmine-gem/issues)
- [Jasmine py](https://github.com/jasmine/jasmine-py/issues)
- [Gulp Jasmine Browser](https://github.com/jasmine/gulp-jasmine-browser/issues)
- [Karma](https://github.com/karma-runner/karma/issues)
- [Grunt Contrib Jasmine](https://github.com/gruntjs/grunt-contrib-jasmine/issues)
<!--- Provide a general summary of the issue in the Title above -->
## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
## Suite that reproduces the behavior (for bugs)
<!--- Provide a sample suite that reproduces the bug. -->
```javascript
describe("sample", function() {
});
```
## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Version used:
* Environment name and version (e.g. Chrome 39, node.js 5.4):
* Operating System and version (desktop or mobile):
* Link to your project:

30
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,30 @@
<!--- Provide a general summary of your changes in the Title above -->
## Description
<!--- Describe your changes in detail -->
## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the **CONTRIBUTING** document.
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.

2
.gitignore vendored
View File

@@ -11,6 +11,7 @@ site/
.bundle
tags
Gemfile.lock
package-lock.json
pkg/*
.sass-cache/*
src/html/.sass-cache/*
@@ -22,3 +23,4 @@ build/
*.egg-info/
dist
nbproject/
*.iml

View File

@@ -1,8 +1,8 @@
language: ruby
cache: bundler
sudo: false
rvm: 2.2.0
rvm: 2.2.2
script: $TEST_COMMAND
@@ -17,11 +17,28 @@ env:
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
addons:
sauce_connect: true
matrix:
include:
- env:
- USE_SAUCE=false
- TEST_COMMAND="bash travis-node-script.sh"
- TEST_COMMAND="bash travis-node-script.sh v4"
- env:
- USE_SAUCE=false
- TEST_COMMAND="bash travis-node-script.sh v8"
- env:
- USE_SAUCE=false
- TEST_COMMAND="bash travis-node-script.sh v9"
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.12"
- SAUCE_BROWSER_VERSION=10
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.11"
- SAUCE_BROWSER_VERSION=9
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.10"
@@ -31,13 +48,9 @@ matrix:
- SAUCE_OS="OS X 10.9"
- SAUCE_BROWSER_VERSION=7
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.8"
- SAUCE_BROWSER_VERSION=6
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.6"
- SAUCE_BROWSER_VERSION=5
- JASMINE_BROWSER="MicrosoftEdge"
- SAUCE_OS="Windows 10"
- SAUCE_BROWSER_VERSION="15"
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 8.1"
@@ -46,14 +59,6 @@ matrix:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 8"
- SAUCE_BROWSER_VERSION=10
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=9
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=8
- env:
- JASMINE_BROWSER="chrome"
- SAUCE_OS="Linux"

46
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jasmine-maintainers@googlegroups.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -1,64 +0,0 @@
# (Vague) Jasmine 2.0 Goals/(Guidelines)
1. No globals!
* jasmine library is entirely inside `jasmine` namespace
* globals required for backwards compatibility should be added in `boot.js` (EG, var describe = jasmine.getCurrentEnv().describe lives in boot.js)
1. Don't use properties as getters. Use methods.
* Properties aren't encapsulated -- can be mutated, unsafe.
1. Reporters get data objects (no methods).
* easier to refactor as needed
1. More unit tests - fewer nasty integration tests
## Remaining non-story-able work:
* Make a `TODO` list
### Hard
* Finish killing Globals
* Guidelines:
* New objects can have constructors on `jasmine`
* Top level functions can live on `jasmine`
* Top level (i.e., any `jasmine` property) should only be referenced inside the `Env` constructor
* should better allow any object to get jasmine code (Node-friendly)
* review everything in base.js
* Remove isA functions:
* isArray_ - used in matchers and spies
* isString_
* isDOMNode_
* isA_
* unimplementedMethod_, used by PrettyPrinter
* jasmine.util should be util closure inside of env or something
* argsToArray is used for Spies and matching (and can be replaced)
* inherit is only for PrettyPrinter now
* formatException is used only inside Env/spec
* htmlEscape is for messages in matchers - should this be HTML at all?
* Pretty printing
* move away from pretty printer and to a JSON.stringify implementation?
* jasmineToString vs. custom toString ?
### Easy
* unify params to ctors: options vs. attrs.
* This will be a lot of the TODOs, but clean up & simplify Env.js (is this a 2.1 task?)
### DONE
* Matchers improvements
* unit testable DONE
* better equality (from Underscore) DONE
* addCustomMatchers doesn't explode stack DONE
* refactor equals function so that it just loops & recurses over a list of fns (custom and built-in) - 2.1? (Tracker story)
* Spies
* break these out into their own tests/file DONE
## Other Topics
* Docs
* Docco has gone over well. Should we annotate all the sources and then have Pages be more complex, having tutorials and annotated source like Backbone? Are we small enough?
* Need examples for:
* How to build a Custom Matcher
* How to add a custom equality tester

View File

@@ -1,4 +1,5 @@
recursive-include . *.py
prune node_modules
include lib/jasmine-core/*.js
include lib/jasmine-core/*.css
include images/*.png

View File

@@ -1,4 +1,4 @@
Copyright (c) 2008-2014 Pivotal Labs
Copyright (c) 2008-2017 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -1,21 +1,19 @@
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
[![Build Status](https://travis-ci.org/jasmine/jasmine.png?branch=master)](https://travis-ci.org/jasmine/jasmine) [![Code Climate](https://codeclimate.com/github/pivotal/jasmine.png)](https://codeclimate.com/github/pivotal/jasmine)
[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=master)](https://travis-ci.org/jasmine/jasmine)
=======
**A JavaScript Testing Framework**
# A JavaScript Testing Framework
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
For a quick start guide of Jasmine 2.0, see the beginning of [http://jasmine.github.io/2.0/introduction.html](http://jasmine.github.io/2.0/introduction.html)
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
For a quick start guide of Jasmine 2.x, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html)
Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/jasmine/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes). You can also read the [upgrade guide](http://jasmine.github.io/2.0/upgrading.html).
## Contributing
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/CONTRIBUTING.md)
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/.github/CONTRIBUTING.md)
## Installation
@@ -28,26 +26,31 @@ For the Jasmine Ruby Gem:<br>
For the Jasmine Python Egg:<br>
[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py)
To install Jasmine on your local box:
For the Jasmine headless browser gulp plugin:<br>
[https://github.com/jasmine/gulp-jasmine-browser](https://github.com/jasmine/gulp-jasmine-browser)
* Clone Jasmine - `git clone https://github.com/jasmine/jasmine.git`
To install Jasmine standalone on your local box (where **_{#.#.#}_** below is substituted by the release number downloaded):
* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases)
* Create a Jasmine directory in your project - `mkdir my-project/jasmine`
* Move latest dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine`
* Move the dist to your project directory - `mv jasmine/dist/jasmine-standalone-{#.#.#}.zip my-project/jasmine`
* Change directory - `cd my-project/jasmine`
* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip`
* Unzip the dist - `unzip jasmine-standalone-{#.#.#}.zip`
Add the following to your HTML file:
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">
```html
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-{#.#.#}/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-{#.#.#}/jasmine.css">
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/boot.js"></script>
```
## Supported environments
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, Microsoft Edge, and new Internet Explorer) as well as nodejs. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
## Support
@@ -59,13 +62,15 @@ Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, a
## Maintainers
* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs
* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs
* [Gregg Van Hove](mailto:gvanhove@pivotal.io), Pivotal Labs
### Maintainers Emeritus
* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs
* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs
* [Greg Cobb](mailto:gcobb@pivotal.io), Pivotal Labs
* [Chris Amavisca](mailto:camavisca@pivotal.io), Pivotal Labs
* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry
* Sheel Choksi
Copyright (c) 2008-2015 Pivotal Labs. This software is licensed under the MIT License.
Copyright (c) 2008-2017 Pivotal Labs. This software is licensed under the MIT License.

View File

@@ -7,15 +7,13 @@ Follow the instructions in `CONTRIBUTING.md` during development.
### Git Rules
Please work on feature branches.
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`.
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when pushing to `master`.
### Version
We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` and `bower.json` with the new version and `grunt build:copyVersionToGem` to update the gem version number.
The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` with the new version and `grunt build:copyVersionToGem` to update the gem version number.
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
@@ -40,7 +38,10 @@ When ready to release - specs are all green and the stories are done:
### Release the Python egg
1. `python setup.py register sdist upload` You will need pypi credentials to upload the egg.
Install [twine](https://github.com/pypa/twine)
1. `python setup.py sdist`
1. `twine upload dist/jasmine-core-<version>.tar.gz` You will need pypi credentials to upload the egg.
### Release the Ruby gem

View File

@@ -1,7 +1,6 @@
{
"name": "jasmine-core",
"version": "2.3.2",
"homepage": "http://jasmine.github.io",
"homepage": "https://jasmine.github.io",
"authors": [
"slackersoft <gregg@slackersoft.net>"
],

View File

@@ -5,6 +5,7 @@ module.exports = {
sassDir: 'src/html',
outputStyle: 'compact',
noLineComments: true,
bundleExec: true
}
}
};

View File

@@ -2,7 +2,6 @@ var standaloneLibDir = "lib/jasmine-" + jasmineVersion;
function root(path) { return "./" + path; }
function libJasmineCore(path) { return root("lib/jasmine-core/" + path); }
function libConsole() { return "lib/console/" }
function dist(path) { return root("dist/" + path); }
module.exports = {
@@ -29,14 +28,6 @@ module.exports = {
expand: true,
cwd: libJasmineCore("")
},
{
src: [
"console.js"
],
dest: standaloneLibDir,
expand: true,
cwd: libConsole()
},
{
src: [ "boot.js" ],
dest: standaloneLibDir,

View File

@@ -15,7 +15,8 @@ module.exports = {
'src/html/HtmlReporter.js',
'src/html/HtmlSpecFilter.js',
'src/html/ResultsNode.js',
'src/html/QueryString.js'
'src/html/QueryString.js',
'src/html/**/*.js'
],
dest: 'lib/jasmine-core/jasmine-html.js'
},
@@ -26,6 +27,7 @@ module.exports = {
'src/core/base.js',
'src/core/util.js',
'src/core/Spec.js',
'src/core/Order.js',
'src/core/Env.js',
'src/core/JsApiReporter.js',
'src/core/PrettyPrinter',
@@ -43,13 +45,6 @@ module.exports = {
src: ['lib/jasmine-core/boot/node_boot.js'],
dest: 'lib/jasmine-core/node_boot.js'
},
console: {
src: [
'src/console/requireConsole.js',
'src/console/ConsoleReporter.js'
],
dest: 'lib/console/console.js'
},
options: {
banner: license(),
process: {

View File

@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
s.name = "jasmine-core"
s.version = Jasmine::Core::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Gregg Van Hove"]
s.authors = ["Gregg Van Hove"]
s.summary = %q{JavaScript BDD framework}
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
s.email = %q{jasmine-js@googlegroups.com}

View File

@@ -1,190 +0,0 @@
/*
Copyright (c) 2008-2015 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"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.
*/
function getJasmineRequireObj() {
if (typeof module !== 'undefined' && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};
return window.jasmineRequire;
}
}
getJasmineRequireObj().console = function(jRequire, j$) {
j$.ConsoleReporter = jRequire.ConsoleReporter();
};
getJasmineRequireObj().ConsoleReporter = function() {
var noopTimer = {
start: function(){},
elapsed: function(){ return 0; }
};
function ConsoleReporter(options) {
var print = options.print,
showColors = options.showColors || false,
onComplete = options.onComplete || function() {},
timer = options.timer || noopTimer,
specCount,
failureCount,
failedSpecs = [],
pendingCount,
ansi = {
green: '\x1B[32m',
red: '\x1B[31m',
yellow: '\x1B[33m',
none: '\x1B[0m'
},
failedSuites = [];
print('ConsoleReporter is deprecated and will be removed in a future version.');
this.jasmineStarted = function() {
specCount = 0;
failureCount = 0;
pendingCount = 0;
print('Started');
printNewline();
timer.start();
};
this.jasmineDone = function() {
printNewline();
for (var i = 0; i < failedSpecs.length; i++) {
specFailureDetails(failedSpecs[i]);
}
if(specCount > 0) {
printNewline();
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
failureCount + ' ' + plural('failure', failureCount);
if (pendingCount) {
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
}
print(specCounts);
} else {
print('No specs found');
}
printNewline();
var seconds = timer.elapsed() / 1000;
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
for(i = 0; i < failedSuites.length; i++) {
suiteFailureDetails(failedSuites[i]);
}
onComplete(failureCount === 0);
};
this.specDone = function(result) {
specCount++;
if (result.status == 'pending') {
pendingCount++;
print(colored('yellow', '*'));
return;
}
if (result.status == 'passed') {
print(colored('green', '.'));
return;
}
if (result.status == 'failed') {
failureCount++;
failedSpecs.push(result);
print(colored('red', 'F'));
}
};
this.suiteDone = function(result) {
if (result.failedExpectations && result.failedExpectations.length > 0) {
failureCount++;
failedSuites.push(result);
}
};
return this;
function printNewline() {
print('\n');
}
function colored(color, str) {
return showColors ? (ansi[color] + str + ansi.none) : str;
}
function plural(str, count) {
return count == 1 ? str : str + 's';
}
function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) {
arr.push(thing);
}
return arr;
}
function indent(str, spaces) {
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(' ', spaces).join('') + lines[i]);
}
return newArr.join('\n');
}
function specFailureDetails(result) {
printNewline();
print(result.fullName);
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
printNewline();
print(indent(failedExpectation.message, 2));
print(indent(failedExpectation.stack, 2));
}
printNewline();
}
function suiteFailureDetails(result) {
for (var i = 0; i < result.failedExpectations.length; i++) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
printNewline();
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
}
printNewline();
}
}
return ConsoleReporter;
};

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2015 Pivotal Labs
Copyright (c) 2008-2018 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -71,25 +71,38 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
getWindowLocation: function() { return window.location; }
});
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
var filterSpecs = !!queryString.getParam("spec");
var stoppingOnSpecFailure = queryString.getParam("failFast");
env.stopOnSpecFailure(stoppingOnSpecFailure);
var throwingExpectationFailures = queryString.getParam("throwFailures");
env.throwOnExpectationFailure(throwingExpectationFailures);
var random = queryString.getParam("random");
if (random !== undefined && random !== "") {
env.randomizeTests(random);
}
var seed = queryString.getParam("seed");
if (seed) {
env.seed(seed);
}
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
timer: new jasmine.Timer()
timer: new jasmine.Timer(),
filterSpecs: filterSpecs
});
/**

View File

@@ -49,25 +49,38 @@
getWindowLocation: function() { return window.location; }
});
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
var filterSpecs = !!queryString.getParam("spec");
var stoppingOnSpecFailure = queryString.getParam("failFast");
env.stopOnSpecFailure(stoppingOnSpecFailure);
var throwingExpectationFailures = queryString.getParam("throwFailures");
env.throwOnExpectationFailure(throwingExpectationFailures);
var random = queryString.getParam("random");
if (random !== undefined && random !== "") {
env.randomizeTests(random);
}
var seed = queryString.getParam("seed");
if (seed) {
env.seed(seed);
}
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
timer: new jasmine.Timer()
timer: new jasmine.Timer(),
filterSpecs: filterSpecs
});
/**

View File

@@ -1,9 +1,6 @@
module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire);
var consoleFns = require('../console/console.js');
consoleFns.console(consoleFns, jasmine);
var env = jasmine.getEnv();
var jasmineInterface = jasmineRequire.interface(jasmine, env);

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2015 Pivotal Labs
Copyright (c) 2008-2018 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -25,6 +25,7 @@ jasmineRequire.html = function(j$) {
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
j$.QueryString = jasmineRequire.QueryString();
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
j$.matchers.toHaveClass = jasmineRequire.toHaveClass(j$);
};
jasmineRequire.HtmlReporter = function(j$) {
@@ -34,39 +35,78 @@ jasmineRequire.HtmlReporter = function(j$) {
elapsed: function() { return 0; }
};
function ResultsStateBuilder() {
this.topResults = new j$.ResultsNode({}, '', null);
this.currentParent = this.topResults;
this.specsExecuted = 0;
this.failureCount = 0;
this.pendingSpecCount = 0;
}
ResultsStateBuilder.prototype.suiteStarted = function(result) {
this.currentParent.addChild(result, 'suite');
this.currentParent = this.currentParent.last();
};
ResultsStateBuilder.prototype.suiteDone = function(result) {
this.currentParent.updateResult(result);
if (this.currentParent !== this.topResults) {
this.currentParent = this.currentParent.parent;
}
if (result.status === 'failed') {
this.failureCount++;
}
};
ResultsStateBuilder.prototype.specStarted = function(result) {
};
ResultsStateBuilder.prototype.specDone = function(result) {
this.currentParent.addChild(result, 'spec');
if (result.status !== 'excluded') {
this.specsExecuted++;
}
if (result.status === 'failed') {
this.failureCount++;
}
if (result.status == 'pending') {
this.pendingSpecCount++;
}
};
function HtmlReporter(options) {
var env = options.env || {},
getContainer = options.getContainer,
createElement = options.createElement,
createTextNode = options.createTextNode,
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
navigateWithNewParam = options.navigateWithNewParam || function() {},
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
filterSpecs = options.filterSpecs,
timer = options.timer || noopTimer,
results = [],
specsExecuted = 0,
failureCount = 0,
pendingSpecCount = 0,
htmlReporterMain,
symbols,
failedSuites = [];
deprecationWarnings = [];
this.initialize = function() {
clearPrior();
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
createDom('div', {className: 'banner'},
createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
createDom('span', {className: 'version'}, j$.version)
createDom('div', {className: 'jasmine-banner'},
createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
createDom('span', {className: 'jasmine-version'}, j$.version)
),
createDom('ul', {className: 'symbol-summary'}),
createDom('div', {className: 'alert'}),
createDom('div', {className: 'results'},
createDom('div', {className: 'failures'})
createDom('ul', {className: 'jasmine-symbol-summary'}),
createDom('div', {className: 'jasmine-alert'}),
createDom('div', {className: 'jasmine-results'},
createDom('div', {className: 'jasmine-failures'})
)
);
getContainer().appendChild(htmlReporterMain);
symbols = find('.symbol-summary');
};
var totalSpecsDefined;
@@ -75,218 +115,154 @@ jasmineRequire.HtmlReporter = function(j$) {
timer.start();
};
var summary = createDom('div', {className: 'summary'});
var summary = createDom('div', {className: 'jasmine-summary'});
var topResults = new j$.ResultsNode({}, '', null),
currentParent = topResults;
var stateBuilder = new ResultsStateBuilder();
this.suiteStarted = function(result) {
currentParent.addChild(result, 'suite');
currentParent = currentParent.last();
stateBuilder.suiteStarted(result);
};
this.suiteDone = function(result) {
if (result.status == 'failed') {
failedSuites.push(result);
}
stateBuilder.suiteDone(result);
if (currentParent == topResults) {
return;
if (result.status === 'failed') {
failures.push(failureDom(result));
}
currentParent = currentParent.parent;
addDeprecationWarnings(result);
};
this.specStarted = function(result) {
currentParent.addChild(result, 'spec');
stateBuilder.specStarted(result);
};
var failures = [];
this.specDone = function(result) {
stateBuilder.specDone(result);
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
console.error('Spec \'' + result.fullName + '\' has no expectations.');
}
if (result.status != 'disabled') {
specsExecuted++;
if (!symbols){
symbols = find('.jasmine-symbol-summary');
}
symbols.appendChild(createDom('li', {
className: noExpectations(result) ? 'empty' : result.status,
className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
id: 'spec_' + result.id,
title: result.fullName
}
));
if (result.status == 'failed') {
failureCount++;
var failure =
createDom('div', {className: 'spec-detail failed'},
createDom('div', {className: 'description'},
createDom('a', {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 === 'failed') {
failures.push(failureDom(result));
}
if (result.status == 'pending') {
pendingSpecCount++;
}
addDeprecationWarnings(result);
};
this.jasmineDone = function() {
var banner = find('.banner');
var alert = find('.alert');
alert.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
this.jasmineDone = function(doneResult) {
var banner = find('.jasmine-banner');
var alert = find('.jasmine-alert');
var order = doneResult && doneResult.order;
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
banner.appendChild(
createDom('div', { className: 'run-options' },
createDom('span', { className: 'trigger' }, 'Options'),
createDom('div', { className: 'payload' },
createDom('div', { className: 'exceptions' },
createDom('input', {
className: 'raise',
id: 'raise-exceptions',
type: 'checkbox'
}),
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions')),
createDom('div', { className: 'throw-failures' },
createDom('input', {
className: 'throw',
id: 'throw-failures',
type: 'checkbox'
}),
createDom('label', { className: 'label', 'for': 'throw-failures' }, 'stop spec on expectation failure'))
)
));
banner.appendChild(optionsMenu(env));
var raiseCheckbox = find('#raise-exceptions');
raiseCheckbox.checked = !env.catchingExceptions();
raiseCheckbox.onclick = onRaiseExceptionsClick;
var throwCheckbox = find('#throw-failures');
throwCheckbox.checked = env.throwingExpectationFailures();
throwCheckbox.onclick = onThrowExpectationsClick;
var optionsMenu = find('.run-options'),
optionsTrigger = optionsMenu.querySelector('.trigger'),
optionsPayload = optionsMenu.querySelector('.payload'),
isOpen = /\bopen\b/;
optionsTrigger.onclick = function() {
if (isOpen.test(optionsPayload.className)) {
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
} else {
optionsPayload.className += ' open';
}
};
if (specsExecuted < totalSpecsDefined) {
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
if (stateBuilder.specsExecuted < totalSpecsDefined) {
var skippedMessage = 'Ran ' + stateBuilder.specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
var skippedLink = addToExistingQueryString('spec', '');
alert.appendChild(
createDom('span', {className: 'bar skipped'},
createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage)
)
);
}
var statusBarMessage = '';
var statusBarClassName = 'bar ';
var statusBarClassName = 'jasmine-overall-result jasmine-bar ';
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
var failed = stateBuilder.failureCount + globalFailures.length > 0;
if (totalSpecsDefined > 0) {
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
} else {
statusBarClassName += 'skipped';
statusBarMessage += 'No specs found';
if (totalSpecsDefined > 0 || failed) {
statusBarMessage += pluralize('spec', stateBuilder.specsExecuted) + ', ' + pluralize('failure', stateBuilder.failureCount);
if (stateBuilder.pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', stateBuilder.pendingSpecCount); }
}
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
if (doneResult.overallStatus === 'passed') {
statusBarClassName += ' jasmine-passed ';
} else if (doneResult.overallStatus === 'incomplete') {
statusBarClassName += ' jasmine-incomplete ';
statusBarMessage = 'Incomplete: ' + doneResult.incompleteReason + ', ' + statusBarMessage;
} else {
statusBarClassName += ' jasmine-failed ';
}
for(i = 0; i < failedSuites.length; i++) {
var failedSuite = failedSuites[i];
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
var errorBarClassName = 'bar errored';
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
var seedBar;
if (order && order.random) {
seedBar = createDom('span', {className: 'jasmine-seed-bar'},
', randomized with seed ',
createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed)
);
}
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
var errorBarClassName = 'jasmine-bar jasmine-errored';
var afterAllMessagePrefix = 'AfterAll ';
for(i = 0; i < globalFailures.length; i++) {
alert.appendChild(createDom('span', {className: errorBarClassName}, globalFailureMessage(globalFailures[i])));
}
function globalFailureMessage(failure) {
if (failure.globalErrorType === 'load') {
var prefix = 'Error during loading: ' + failure.message;
if (failure.filename) {
return prefix + ' in ' + failure.filename + ' line ' + failure.lineno;
} else {
return prefix;
}
} else {
return afterAllMessagePrefix + failure.message;
}
}
var results = find('.results');
addDeprecationWarnings(doneResult);
var warningBarClassName = 'jasmine-bar jasmine-warning';
for(i = 0; i < deprecationWarnings.length; i++) {
var warning = deprecationWarnings[i];
alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning));
}
var results = find('.jasmine-results');
results.appendChild(summary);
summaryList(topResults, summary);
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);
}
var specDescription = resultNode.result.description;
if(noExpectations(resultNode.result)) {
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
}
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
}
specListNode.appendChild(
createDom('li', {
className: resultNode.result.status,
id: 'spec-' + resultNode.result.id
},
createDom('a', {href: specHref(resultNode.result)}, specDescription)
)
);
}
}
}
summaryList(stateBuilder.topResults, summary);
if (failures.length) {
alert.appendChild(
createDom('span', {className: 'menu bar spec-list'},
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
createDom('span', {}, 'Spec List | '),
createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures')));
alert.appendChild(
createDom('span', {className: 'menu bar failure-list'},
createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'},
createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'),
createDom('span', {}, ' | Failures ')));
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
find('.jasmine-failures-menu').onclick = function() {
setMenuModeTo('jasmine-failure-list');
};
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
find('.jasmine-spec-list-menu').onclick = function() {
setMenuModeTo('jasmine-spec-list');
};
setMenuModeTo('failure-list');
setMenuModeTo('jasmine-failure-list');
var failureNode = find('.failures');
for (var i = 0; i < failures.length; i++) {
var failureNode = find('.jasmine-failures');
for (i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
}
@@ -294,6 +270,164 @@ jasmineRequire.HtmlReporter = function(j$) {
return this;
function failureDom(result) {
var failure =
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
failureDescription(result, stateBuilder.currentParent),
createDom('div', {className: 'jasmine-messages'})
);
var messages = failure.childNodes[1];
for (var i = 0; i < result.failedExpectations.length; i++) {
var expectation = result.failedExpectations[i];
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
}
return failure;
}
function summaryList(resultsTree, domParent) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
var resultNode = resultsTree.children[i];
if (filterSpecs && !hasActiveSpec(resultNode)) {
continue;
}
if (resultNode.type === 'suite') {
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
createDom('li', {className: 'jasmine-suite-detail jasmine-' + resultNode.result.status},
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
summaryList(resultNode, suiteListNode);
domParent.appendChild(suiteListNode);
}
if (resultNode.type === 'spec') {
if (domParent.getAttribute('class') !== 'jasmine-specs') {
specListNode = createDom('ul', {className: 'jasmine-specs'});
domParent.appendChild(specListNode);
}
var specDescription = resultNode.result.description;
if(noExpectations(resultNode.result)) {
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
}
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
}
specListNode.appendChild(
createDom('li', {
className: 'jasmine-' + resultNode.result.status,
id: 'spec-' + resultNode.result.id
},
createDom('a', {href: specHref(resultNode.result)}, specDescription)
)
);
}
}
}
function optionsMenu(env) {
var optionsMenuDom = createDom('div', { className: 'jasmine-run-options' },
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
createDom('div', { className: 'jasmine-payload' },
createDom('div', { className: 'jasmine-stop-on-failure' },
createDom('input', {
className: 'jasmine-fail-fast',
id: 'jasmine-fail-fast',
type: 'checkbox'
}),
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-fail-fast' }, 'stop execution on spec failure')),
createDom('div', { className: 'jasmine-throw-failures' },
createDom('input', {
className: 'jasmine-throw',
id: 'jasmine-throw-failures',
type: 'checkbox'
}),
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
createDom('div', { className: 'jasmine-random-order' },
createDom('input', {
className: 'jasmine-random',
id: 'jasmine-random-order',
type: 'checkbox'
}),
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
)
);
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
failFastCheckbox.checked = env.stoppingOnSpecFailure();
failFastCheckbox.onclick = function() {
navigateWithNewParam('failFast', !env.stoppingOnSpecFailure());
};
var throwCheckbox = optionsMenuDom.querySelector('#jasmine-throw-failures');
throwCheckbox.checked = env.throwingExpectationFailures();
throwCheckbox.onclick = function() {
navigateWithNewParam('throwFailures', !env.throwingExpectationFailures());
};
var randomCheckbox = optionsMenuDom.querySelector('#jasmine-random-order');
randomCheckbox.checked = env.randomTests();
randomCheckbox.onclick = function() {
navigateWithNewParam('random', !env.randomTests());
};
var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'),
optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'),
isOpen = /\bjasmine-open\b/;
optionsTrigger.onclick = function() {
if (isOpen.test(optionsPayload.className)) {
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
} else {
optionsPayload.className += ' jasmine-open';
}
};
return optionsMenuDom;
}
function failureDescription(result, suite) {
var wrapper = createDom('div', {className: 'jasmine-description'},
createDom('a', {title: result.description, href: specHref(result)}, result.description)
);
var suiteLink;
while (suite && suite.parent) {
wrapper.insertBefore(createTextNode(' > '), wrapper.firstChild);
suiteLink = createDom('a', {href: suiteHref(suite)}, suite.result.description);
wrapper.insertBefore(suiteLink, wrapper.firstChild);
suite = suite.parent;
}
return wrapper;
}
function suiteHref(suite) {
var els = [];
while (suite && suite.parent) {
els.unshift(suite.result.description);
suite = suite.parent;
}
return addToExistingQueryString('spec', els.join(' '));
}
function addDeprecationWarnings(result) {
if (result && result.deprecationWarnings) {
for(var i = 0; i < result.deprecationWarnings.length; i++) {
var warning = result.deprecationWarnings[i].message;
if (!j$.util.arrayContains(warning)) {
deprecationWarnings.push(warning);
}
}
}
}
function find(selector) {
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
}
@@ -343,6 +477,10 @@ jasmineRequire.HtmlReporter = function(j$) {
return addToExistingQueryString('spec', result.fullName);
}
function seedHref(seed) {
return addToExistingQueryString('seed', seed);
}
function defaultQueryString(key, value) {
return '?' + key + '=' + value;
}
@@ -355,6 +493,20 @@ jasmineRequire.HtmlReporter = function(j$) {
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
result.status === 'passed';
}
function hasActiveSpec(resultNode) {
if (resultNode.type == 'spec' && resultNode.result.status != 'excluded') {
return true;
}
if (resultNode.type == 'suite') {
for (var i = 0, j = resultNode.children.length; i < j; i++) {
if (hasActiveSpec(resultNode.children[i])) {
return true;
}
}
}
}
}
return HtmlReporter;
@@ -388,6 +540,10 @@ jasmineRequire.ResultsNode = function() {
this.last = function() {
return this.children[this.children.length - 1];
};
this.updateResult = function(result) {
this.result = result;
};
}
return ResultsNode;
@@ -444,3 +600,37 @@ jasmineRequire.QueryString = function() {
return QueryString;
};
jasmineRequire.toHaveClass = function(j$) {
/**
* {@link expect} the actual value to be a DOM element that has the expected class
* @function
* @name matchers#toHaveClass
* @param {Object} expected - The class name to test for
* @example
* var el = document.createElement('div');
* el.className = 'foo bar baz';
* expect(el).toHaveClass('bar');
*/
function toHaveClass(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
if (!isElement(actual)) {
throw new Error(j$.pp(actual) + ' is not a DOM element');
}
return {
pass: actual.classList.contains(expected)
};
}
};
}
function isElement(maybeEl) {
return maybeEl &&
maybeEl.classList &&
j$.isFunction_(maybeEl.classList.contains);
}
return toHaveClass;
};

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2015 Pivotal Labs
Copyright (c) 2008-2018 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -23,9 +23,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire);
var consoleFns = require('../console/console.js');
consoleFns.console(consoleFns, jasmine);
var env = jasmine.getEnv();
var jasmineInterface = jasmineRequire.interface(jasmine, env);

View File

@@ -4,6 +4,6 @@
#
module Jasmine
module Core
VERSION = "2.3.2"
VERSION = "3.0.0"
end
end

View File

@@ -1,7 +1,7 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "2.3.2",
"version": "3.0.0",
"repository": {
"type": "git",
"url": "https://github.com/jasmine/jasmine.git"
@@ -13,22 +13,22 @@
"bdd"
],
"scripts": {
"test": "./node_modules/.bin/grunt jshint execSpecsInNode"
"test": "grunt jshint execSpecsInNode"
},
"description": "Official packaging of Jasmine's core files for use by Node.js projects.",
"homepage": "http://jasmine.github.io",
"main": "./lib/jasmine-core.js",
"devDependencies": {
"glob": "~3.2.9",
"grunt": "~0.4.1",
"grunt-cli": "^0.1.13",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-compress": "~0.5.2",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-jshint": "~0.7.0",
"jasmine": "https://github.com/jasmine/jasmine-npm/archive/master.tar.gz",
"glob": "~7.1.2",
"grunt": "^1.0.1",
"grunt-cli": "^1.2.0",
"grunt-contrib-compass": "^1.1.1",
"grunt-contrib-compress": "^1.3.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-jshint": "^1.0.0",
"jasmine": "^2.5.0",
"load-grunt-tasks": "^0.4.0",
"shelljs": "~0.1.4",
"shelljs": "^0.7.0",
"temp": "~0.8.1"
}
}

14
release_notes/2.3.3.md Normal file
View File

@@ -0,0 +1,14 @@
# Jasmine 2.3.3 Release Notes
## Summary
This is a hotfix release to fix a regression with the execution context for `beforeAll`
## Pull Requests & Issues
* Set the shared user context correctly when executing the top level suite
- Fixes [#846](https://github.com/jasmine/jasmine/issues/846)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

22
release_notes/2.3.4.md Normal file
View File

@@ -0,0 +1,22 @@
# Jasmine 2.3.4 Release Notes
## Summary
This is a hotfix release to fix a regression with execution ordering
## Pull Requests & Issues
* Fix ordering for suites with more than 11 direct children.
- Fixes [#850](https://github.com/jasmine/jasmine/issues/850)
* Update standalone installation instructions to reference the releases page
- Fixes [#603](https://github.com/jasmine/jasmine/issues/603)
* Remove dead CSS class styles
- Merges [#849](https://github.com/jasmine/jasmine/issues/849) from @prather-mcs
- Merges [#848](https://github.com/jasmine/jasmine/issues/848) from @prather-mcs
- Fixes [#847](https://github.com/jasmine/jasmine/issues/847)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

91
release_notes/2.4.0.md Normal file
View File

@@ -0,0 +1,91 @@
# Jasmine Core 2.4.0 Release Notes
## Summary
This release contains a number of fixes and pull requests.
The most notable is probably that Jasmine now supports randomization of spec order
## Changes
* Run jasmine's specs in random order
* Add support for returning run details for reporting randomness
* Use className instead of class when creating DOM elements
## Pull Requests & Issues
* Syntax highlighting in README.md
- Merges [#973](https://github.com/jasmine/jasmine/issues/973) from @brunoqc
* Added a throw error block in describe incase a function with arguments is passed in describe
- Fixes [#896](https://github.com/jasmine/jasmine/issues/896)
- Merges [#955](https://github.com/jasmine/jasmine/issues/955) from @himajasuman
* Remove unused `queueableFn` arg from `onException`
- Fixes [#958](https://github.com/jasmine/jasmine/issues/958)
* Remove unused parameter from toThrowError
- Merges [#957](https://github.com/jasmine/jasmine/issues/957) from @FuzzySockets
* Abort spying when the target cannot be spied upon
- Fixes [#948](https://github.com/jasmine/jasmine/issues/948)
- Merges [#949](https://github.com/jasmine/jasmine/issues/949) from @StephanBijzitter
* Removed GOALS_2.0.md, doesn't seem to be needed anymore
- Merges [#954](https://github.com/jasmine/jasmine/issues/954) from @matthewhuff89
* Change #xit so that it will output a more BDD-style pending message
- Merges [#942](https://github.com/jasmine/jasmine/issues/942) from @lalunamel
- Fixes [#930](https://github.com/jasmine/jasmine/issues/930)
- Fixes [#912](https://github.com/jasmine/jasmine/issues/912)
* Allow tests to run in random order
- Merges [#927](https://github.com/jasmine/jasmine/issues/927) from @marcioj
* Use toString for objects if it has been overriden
- Merges [#929](https://github.com/jasmine/jasmine/issues/929) from @myitcv
- Fixes [#928](https://github.com/jasmine/jasmine/issues/928)
* Fix circles/x from getting cut off on Mac/chrome
- Merges [#932](https://github.com/jasmine/jasmine/issues/932) from @James-Dunn
* Postpone find() until it is needed
- Merges [#924](https://github.com/jasmine/jasmine/issues/924) from @danielalexiuc
- Fixes [#917](https://github.com/jasmine/jasmine/issues/917)
* check for global before assigning
* Reverse suite afterEach behavior to match semantics?
- Merges [#908](https://github.com/jasmine/jasmine/issues/908) from @mcamac
* Use badges from shields.io
- Merges [#902](https://github.com/jasmine/jasmine/issues/902) from @SimenB
* xdescribe marks pending, plus associated tests.
- Merges [#869](https://github.com/jasmine/jasmine/issues/869) from @ljwall
- Fixes [#855](https://github.com/jasmine/jasmine/issues/855)
* Update glob to latest
- Merge [#892](https://github.com/jasmine/jasmine/issues/892) from @obastemur
- Fixes [#891](https://github.com/jasmine/jasmine/issues/891)
* Remove moot `version` property from bower.json
- Merges [#874](https://github.com/jasmine/jasmine/issues/874) from @kkirsche
* add toHaveBeenCalledTimes matcher
- Merges [#871](https://github.com/jasmine/jasmine/issues/871) from @logankd
- Fixes [#853](https://github.com/jasmine/jasmine/issues/853)
* Update CONTRIBUTING.md
- Merges [#856](https://github.com/jasmine/jasmine/issues/856) from @lpww
* Make the HtmlReport CSS classes "unique enough"
- Merges [#851](https://github.com/jasmine/jasmine/issues/851) from @prather-mcs
- Fixes [#844](https://github.com/jasmine/jasmine/issues/844)
* Raise an error when jasmine.any() isn't passed a constructor
- Merges [#854](https://github.com/jasmine/jasmine/issues/854) from @danfinnie
- Fixes [#852](https://github.com/jasmine/jasmine/issues/852)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

11
release_notes/2.4.1.md Normal file
View File

@@ -0,0 +1,11 @@
# Jasmine Core 2.4.1 Release Notes
## Changes
* Run `afterEach` in reverse order declared as before
- Reverts [#908](https://github.com/jasmine/jasmine/issues/908)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

116
release_notes/2.5.0.md Normal file
View File

@@ -0,0 +1,116 @@
# Jasmine 2.5.0 Release Notes
## Summary
This release contains a number of fixes and pull requests.
## Changes
* Rename `j$` to `jasmineUnderTest` for specs
- Please update any pull requests to simplify merging, thanks.
## Pull Requests & Issues
* Prettyprint objects whose constructors have custom toString method
- Fixes [#1019](https://github.com/jasmine/jasmine/issues/1019)
- Merges [#1099](https://github.com/jasmine/jasmine/issues/1099) from @mbildner
* Add gulp-jasmine-browser link to readme
- Fixes [#1089](https://github.com/jasmine/jasmine/issues/1089)
* Exclude lib directory from codeclimate
- Fixes [#1171](https://github.com/jasmine/jasmine/issues/1171)
* Add instructions for testing in IE
- Merges [#1170](https://github.com/jasmine/jasmine/issues/1170) from @benchristel
* Update devDependencies and fix issues from this
- Merges [#1162](https://github.com/jasmine/jasmine/issues/1162) from @amavisca
* Remove runnableLookupTable which is no longer used
- Merges [#1129](https://github.com/jasmine/jasmine/issues/1129) from @gregeninfrank
* Make `toEqual` pass for arrays with equivalent properties
- Merges [#1155](https://github.com/jasmine/jasmine/issues/1155) from @benchristel
* Update ruby version on travis to let rack install
- Merges [#1152](https://github.com/jasmine/jasmine/issues/1152) from @amavisca
* Fix jasmine setup in Electron environment
- Merges [#1079](https://github.com/jasmine/jasmine/issues/1079) from @skupr
- Fixes [#964](https://github.com/jasmine/jasmine/issues/964)
* Improve errors with the domain and how to use the API
- Merges [#1026](https://github.com/jasmine/jasmine/issues/1026) from @dhoko
- Fixes [#1025](https://github.com/jasmine/jasmine/issues/1025)
* The done function now returns null
- Merges [#1062](https://github.com/jasmine/jasmine/issues/1062) from @marneborn
- Fixes [#992](https://github.com/jasmine/jasmine/issues/992)
* Add .editorconfig file
- Merges [#1058](https://github.com/jasmine/jasmine/issues/1058) from @kapke
- Fixes [#1057](https://github.com/jasmine/jasmine/issues/1057)
* Improve error message when passing a non-function to callFake
- Merges [#1059](https://github.com/jasmine/jasmine/issues/1059) from @kapke
- Fixes [#1016](https://github.com/jasmine/jasmine/issues/1016)
* Allow expectations in a global beforeAll or afterAll
- Fixes [#811](https://github.com/jasmine/jasmine/issues/811)
* Correctly tear down spies on inherited methods
- Merges [#1036](https://github.com/jasmine/jasmine/issues/1036) from @benchristel
- Fixes [#737](https://github.com/jasmine/jasmine/issues/737)
* Array equality treats undefined elements as equal however they got in there
- Fixes [#786](https://github.com/jasmine/jasmine/issues/786)
* Add support for a fallback reporter
- Merges [#1009](https://github.com/jasmine/jasmine/issues/1009) from @mauricioborges
* Grunt task for compass should prefix command with 'bundle exec'
- Merges [#1047](https://github.com/jasmine/jasmine/issues/1047) from @d-reinhold
* Fix `toEqual` for Microsoft Edge
- Merges [#1041](https://github.com/jasmine/jasmine/issues/1041) from @everedifice
* Update describe error message to no longer assume errant args are `done`
- Fixes [#896](https://github.com/jasmine/jasmine/issues/896)
* Add toBeGreatThanOrEqual and toBeLessThanOrEqual matchers
- Merges [#1049](https://github.com/jasmine/jasmine/issues/1049) from @rullopat
- Fixes [#1013](https://github.com/jasmine/jasmine/issues/1013)
* Support call count of 0 with toHaveBeenCalledTimes matcher
- Merges [#1048](https://github.com/jasmine/jasmine/issues/1048) from @logankd
- Fixes [#994](https://github.com/jasmine/jasmine/issues/994)
* Correctly clean up spies after a spy is replaced and re-spied upon
- Merges [#1011](https://github.com/jasmine/jasmine/issues/1011) from @bodawei
- Fixes [#1010](https://github.com/jasmine/jasmine/issues/1010)
* remove extra topSuite `queueRunner` construction parameter
- Merges [#1006](https://github.com/jasmine/jasmine/issues/1006) from @jurko-gospodnetic
* add option to shallow clone args in call tracker
- Merges [#1000](https://github.com/jasmine/jasmine/issues/1000) from @a-r-d
- Fixes [#872](https://github.com/jasmine/jasmine/issues/872)
* Update license year range to 2016
- Merges [#1021](https://github.com/jasmine/jasmine/issues/1021) from pra85
* Persist randomize param in 'run all' links
- Merges [#990](https://github.com/jasmine/jasmine/issues/990) from @basawyer
* make DelayedFunctionScheduler update the mockDate
- Fixes [#915](https://github.com/jasmine/jasmine/issues/915)
- Merges [#980](https://github.com/jasmine/jasmine/issues/980) from @andrewiggings
* Allow `spyOn` to allow a respy for functions that have already been spied upon
- Merges [#953](https://github.com/jasmine/jasmine/issues/953) from @guy-mograbi-at-gigaspaces
- Fixes [#931](https://github.com/jasmine/jasmine/issues/931)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

19
release_notes/2.5.1.md Normal file
View File

@@ -0,0 +1,19 @@
# Jasmine 2.5.1 Release Notes
## Pull Requests & Issues
* fallback on assignment when a spy cannot be deleted
- Merges [#1193](https://github.com/jasmine/jasmine/issues/1193) from @seanparmlee
- Fixes [#1189](https://github.com/jasmine/jasmine/issues/1189)
* Fix issue with equality of Arrays in PhantomJS
- Merges [#1192](https://github.com/jasmine/jasmine/issues/1192) from @logankd
- Fixes [#1188](https://github.com/jasmine/jasmine/issues/1188)
* Properly tick date along with clock
- Fixes [#1190](https://github.com/jasmine/jasmine/issues/1190)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

14
release_notes/2.5.2.md Normal file
View File

@@ -0,0 +1,14 @@
# Jasmine 2.5.2 Release Notes
## Pull Requests & Issues
* Allow currently registered reporters to be cleared
- [jasmine/jasmine-npm#88](https://github.com/jasmine/jasmine-npm/issues/88)
* Use `isFunction` to check for functionness in `callFake`
- Fixes [#1191](https://github.com/jasmine/jasmine/issues/1191)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

108
release_notes/2.6.0.md Normal file
View File

@@ -0,0 +1,108 @@
# Jasmine 2.6.0 Release Notes
## Summary
This release contains a number of fixes and pull requests.
## Pull Requests & Issues
Updating introduction url to last version
- Merges [#1316](https://github.com/jasmine/jasmine/issues/1316) from @rachelcarmena
* Throw a recognizable Error message when `fail` outside of a spec.
- Fixes [#1017](https://github.com/jasmine/jasmine/issues/1017)
* Allow the matcher provide a custom error message
- Merges [#1298](https://github.com/jasmine/jasmine/issues/1298) from @deckar01
- Fixes [#1123](https://github.com/jasmine/jasmine/issues/1123)
* Fix the order in which afterAll hooks are run to match afterEach
- Merges [#1312](https://github.com/jasmine/jasmine/issues/1312) from @gdborton
- Fixes [#1311](https://github.com/jasmine/jasmine/issues/1311)
* Add matchers for positive and negative infinity
- Merges [#1300](https://github.com/jasmine/jasmine/issues/1300) from @toubou91
- Fixes [#1294](https://github.com/jasmine/jasmine/issues/1294)
* Add a first pass at JSDocs for the intended public API
- Fixes [#596](https://github.com/jasmine/jasmine/issues/596)
* Pretty print objects passed to fail method
- Merges [#1283](https://github.com/jasmine/jasmine/issues/1283) from @mmmichl
- Fixes [#1090](https://github.com/jasmine/jasmine/issues/1090)
* Properly check for Error constructor from a different frame
- Merges [#1275](https://github.com/jasmine/jasmine/issues/1275) from @anseki
- Fixes [#1252](https://github.com/jasmine/jasmine/issues/1252)
* Add toHaveBeenCalledBefore matcher
- Merges [#1242](https://github.com/jasmine/jasmine/issues/1242) from @DamienCassou
* Collect unhandled exceptions and pass them to the current runnable
- Fixes [#529](https://github.com/jasmine/jasmine/issues/529)
- Fixes [#937](https://github.com/jasmine/jasmine/issues/937)
* Nicer error messages for `spyOn` when `null` is provided
- Fixes [#1258](https://github.com/jasmine/jasmine/issues/1258)
* Require arguments to beforeEach, it, etc, to be actual functions
- Merges [#1222](https://github.com/jasmine/jasmine/issues/1222) from @voithos
- Fixes [#1004](https://github.com/jasmine/jasmine/issues/1004)
* Update MIT.LICENSE for new year
- Merges [#1249](https://github.com/jasmine/jasmine/issues/1249) from @Scottkao85
* Update README.md for new year
- Merges [#1248](https://github.com/jasmine/jasmine/issues/1248) from @Nebojsaa
* Remove unused `message` param from Suite#pend
- See [#1132](https://github.com/jasmine/jasmine/issues/1132)
* Fix bug where before/afterAll were being executed in disabled suites.
- Merges [#1225](https://github.com/jasmine/jasmine/issues/1225) from @voithos
- Fixes [#1175](https://github.com/jasmine/jasmine/issues/1175)
* Make toEqual matcher report the difference between objects
- Merges [#1163](https://github.com/jasmine/jasmine/issues/1163) from @benchristel
- Fixes [#675](https://github.com/jasmine/jasmine/issues/675)
- Merges [#1236](https://github.com/jasmine/jasmine/issues/1236) from @benchristel
* Implement spies for get/set functions on accessor properties
- Merges [#1203](https://github.com/jasmine/jasmine/issues/1203) from @celluj34
- Merges [#1008](https://github.com/jasmine/jasmine/issues/1008) from @smacker
- Fixes [#943](https://github.com/jasmine/jasmine/issues/943)
* When the HtmlReporter has a 'spec' query param, the spec list only shows matching specs/suites
- Merges [#1046](https://github.com/jasmine/jasmine/issues/1046) from @d-reinhold
- Fixes [#510](https://github.com/jasmine/jasmine/issues/510)
* createSpyObj may use object for method/response shorthand
- Merges [#1101](https://github.com/jasmine/jasmine/issues/1101) from @mbildner
* Separate clear stack and run it after each spec
- Fixes [#985](https://github.com/jasmine/jasmine/issues/985)
- Fixes [#945](https://github.com/jasmine/jasmine/issues/945)
- Fixes [#366](https://github.com/jasmine/jasmine/issues/366)
* Now spies preserve original function arity
- Merges [#1055](https://github.com/jasmine/jasmine/issues/1055) from @kapke
- Fixes [#991](https://github.com/jasmine/jasmine/issues/991)
* Added support for ES6 sets to toContain and toEqual.
- Merges [#1067](https://github.com/jasmine/jasmine/issues/1067) from @alur
* Correctly pretty print objects from other contexts (e.g. iframes) and which do not override toString
- Merges [#1091](https://github.com/jasmine/jasmine/issues/1091) from @thatfulvioguy
- Fixes [#1087](https://github.com/jasmine/jasmine/issues/1087)
* Pass custom testers to asymmetric testers
- Merges [#1139](https://github.com/jasmine/jasmine/issues/1139) from @joeyparrish
- Fixes [#1138](https://github.com/jasmine/jasmine/issues/1138)
* Fix bad url in README
- Merges [#1215](https://github.com/jasmine/jasmine/issues/1215) from @mattc41190
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

31
release_notes/2.6.1.md Normal file
View File

@@ -0,0 +1,31 @@
# Jasmine 2.6.1 Release Notes
## Summary
This is a patch release to fix some regressions in the 2.6.0 release
## Pull Requests & Issues
* Update README.md to make installation instructions more version-agnostic
- Merges #1319 from @reinrl
* Check for `process.listeners` as well, for GlobalErrors
- Fixes #1333
* allow explicit undefined as function for `it` and `xit`
- Merges #1329 from @UziTech
- Fixes #1328
* remove eval to create spy wrapper
- Merges #1330 from @UziTech
- Fixes #1325
* iterate through keys with a regular for loop
- Merges #1326 from @seanparmelee
- Fixes #1321
- Fixes #1324
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

23
release_notes/2.6.2.md Normal file
View File

@@ -0,0 +1,23 @@
# Jasmine 2.6.2 Release Notes
## Summary
This is a patch release to fix some regressions and performance problems in the 2.6.0 release
## Changes
* Clear the stack if onmessage is called before the previous invocation finishes
- Fixes #1327
- Fixes jasmine/gulp-jasmine-browser#48
* Correctly route errors that occur while a QueueRunner is clearing stack
- Merges #1352 from @sgravrock
- Fixes #1344
- Fixes #1349
* Don't mask errors that occur when no handlers are installed
- Merges #1347 from @sgravrock
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

17
release_notes/2.6.3.md Normal file
View File

@@ -0,0 +1,17 @@
# Jasmine 2.6.3 Release Notes
## Summary
This is a patch release to fix some regressions and performance problems in the 2.6.0 release
## Changes
* Make sure the queue runner goes async for async specs
- Fixes [#1327](https://github.com/jasmine/jasmine/issues/1327)
- Fixes [#1334](https://github.com/jasmine/jasmine/issues/1334)
- Fixes [jasmine/gulp-jasmine-browser#48](https://github.com/jasmine/gulp-jasmine-browser/issues/48)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

17
release_notes/2.6.4.md Normal file
View File

@@ -0,0 +1,17 @@
# Jasmine 2.6.4 Release Notes
## Summary
This is a patch release to fix some regressions and performance problems in the 2.6.0 release
## Changes
* Break into a `setTimeout` every once in a while allowing the CPU to run other things that used the real `setTimeout`
- Fixes [#1327](https://github.com/jasmine/jasmine/issues/1327)
- See [#1334](https://github.com/jasmine/jasmine/issues/1334)
- Fixes [jasmine/gulp-jasmine-browser#48](https://github.com/jasmine/gulp-jasmine-browser/issues/48)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

61
release_notes/2.7.0.md Normal file
View File

@@ -0,0 +1,61 @@
# Jasmine 2.7.0 Release Notes
## Summary
This release contains a number of fixes and pull requests.
## Pull Requests & Issues
* Add class UserContext
- Merges [#1400](https://github.com/jasmine/jasmine/issues/1400) from @darthjee
* Send unfocused tests through the same queue as focused tests
- Merges [#1399](https://github.com/jasmine/jasmine/issues/1399) from @jberney
* PrettyPrinter allows an object to have a `toString` that isn't a function
- Fixes [#1389](https://github.com/jasmine/jasmine/issues/1389)
* Fix rounding in toBeCloseTo
- Fixes [#1382](https://github.com/jasmine/jasmine/issues/1382)
* When stop on failure is enabled, skip subsequent it() and beforeEach(). Note: afterEach() functions are still run, because skipping them is highly likely to pollute specs that run after the failure.
- Fixes [#577](https://github.com/jasmine/jasmine/issues/577)
- Fixes [#807](https://github.com/jasmine/jasmine/issues/807)
* Only clear out the `spec` param for Run all link
- Fixes [#1369](https://github.com/jasmine/jasmine/issues/1369)
* Pretty printer will now use MAX_PRETTY_PRINT_ARRAY_LENGTH for objects
- Fixes [#1291](https://github.com/jasmine/jasmine/issues/1291)
- Fixes [#1360](https://github.com/jasmine/jasmine/issues/1360)
* updated package glob from 7.0.5 to 7.1.2
- Merges [#1368](https://github.com/jasmine/jasmine/issues/1368) from @EsrefDurna
* Fix bower.json url to be https instead of http
- Merges [#1365](https://github.com/jasmine/jasmine/issues/1365) from @kant
* Fail when one of the arguments passed into toBeCloseTo matcher is null
- Merges [#1362](https://github.com/jasmine/jasmine/issues/1362) from @beatrichartz
* Fixed HTML snippet in README
- Closes [#1366](https://github.com/jasmine/jasmine/issues/1366).
* Report the random seed at the beginning and end of execution. This allows reporters to provide the seed to the user even in cases where Jasmine crashes before completing.
- Merges [#1348](https://github.com/jasmine/jasmine/issues/1348) from @sgravrock
* Add ES6 map support to Jasmine
- Merges [#1340](https://github.com/jasmine/jasmine/issues/1340) from @rmehlinger
- Fixes [#1257](https://github.com/jasmine/jasmine/issues/1257)
* Added support for async before/it/after functions that return promises and added support for ES2017 async functions
- Merges [#1356](https://github.com/jasmine/jasmine/issues/1356) from @sgravrock
- Fixes [#1336](https://github.com/jasmine/jasmine/issues/1336)
- Fixes [#1270](https://github.com/jasmine/jasmine/issues/1270)
- Fixes [#1350](https://github.com/jasmine/jasmine/issues/1350)
- Fixes [#1320](https://github.com/jasmine/jasmine/issues/1320)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

52
release_notes/2.8.0.md Normal file
View File

@@ -0,0 +1,52 @@
# Jasmine 2.8.0 Release Notes
## Summary
This release contains a number of fixes and pull requests.
2.8 should be the last 2.x release of Jasmine, as we aim for 3.0.
## Changes
* Create CODE_OF_CONDUCT.md
* Add jsdocs for reporter events
* Update jsApiReporter docs to link to new suite and spec results
* Add explicit docs for the callback function passed to `it` etc.
* Update afterAll documentation
## Pull Requests & Issues
* Add 'nothing' matcher and tests
- Merges [#1412](https://github.com/jasmine/jasmine/issues/1412) from @ksvitkovsky
- Fixes [#1221](https://github.com/jasmine/jasmine/issues/1221)
* Make toEqual matcher report the difference between array elements when arrays have different length
- Closes [#1375](https://github.com/jasmine/jasmine/issues/1375) from @kiewic
* Add arrayWithExactContents asymmetric matcher
- Fixes [#817](https://github.com/jasmine/jasmine/issues/817)
* Ensure no message added on asym. match success
- Closes [#1408](https://github.com/jasmine/jasmine/issues/1408) from @ksvitkovsky
- Fixes [#1388](https://github.com/jasmine/jasmine/issues/1388)
* Better primitives detection for saveArgsByValue
- Closes [#1407](https://github.com/jasmine/jasmine/issues/1407) from @ksvitkovsky
- Fixes [#1403](https://github.com/jasmine/jasmine/issues/1403)
* Better pretty printing for typed arrays
- Closes [#1404](https://github.com/jasmine/jasmine/issues/1404) from @ksvitkovsky
- Fixes [#1180](https://github.com/jasmine/jasmine/issues/1180)
* Rewrite ES6 Set and Map comparison to ignore insertion order
- Merges [#1406](https://github.com/jasmine/jasmine/issues/1406) from @theefer
- Fixes [#1402](https://github.com/jasmine/jasmine/issues/1402)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

99
release_notes/2.9.0.md Normal file
View File

@@ -0,0 +1,99 @@
# Jasmine 2.9 Release Notes
## Summary
This release contains a number of fixes and pull requests.
## Changes
* Fixed DelayedFunctionScheduler IE 8 compatibility issue
* Fixed SPEC HAS NO EXPECTATIONS warning in HTML reporter
* Correctly remove spies of window.onerror on IE
* Truncate pretty printer output that is more than j$.MAX_PRETTY_PRINT_CHARS long
* Reduced pretty printer limits to much smaller values
* Update contributing for new naming of `jasmineUnderTest`
* Allowed async functions to be passed into spy#callFake
## Pull Requests & Issues
* Added complete support for Set also for IE11.
- Merges [#1478](https://github.com/jasmine/jasmine/issues/1478) from @Volox
- Fixes [#1355](https://github.com/jasmine/jasmine/issues/1355)
* Added complete support for Map also for IE11.
- Merges [#1477](https://github.com/jasmine/jasmine/issues/1477) from @Volox
- Fixes [#1472](https://github.com/jasmine/jasmine/issues/1472)
* Use timeout objects when in node
- Merges [#1470](https://github.com/jasmine/jasmine/issues/1470) from @chris--young
- Fixes [#1469](https://github.com/jasmine/jasmine/issues/1469)
* Fixed `pending()` for `async`/promise-returning specs
- Fixes [#1449](https://github.com/jasmine/jasmine/issues/1449)
- Fixes [#1450](https://github.com/jasmine/jasmine/issues/1450)
* Added test steps for other major node versions
- Merges [#1448](https://github.com/jasmine/jasmine/issues/1448) from @mrlannigan
* Fix equality computation for ES6 Sets.
- Merges [#1445](https://github.com/jasmine/jasmine/issues/1445) from @b-3-n
- Fixes [#1444](https://github.com/jasmine/jasmine/issues/1444)
* Add instruction to sync local master with upstream
- Merges [#1440](https://github.com/jasmine/jasmine/issues/1440) from aaronang
* Add some unit tests that exercise jasmine.anything() and Map matching.
- Merges [#1437](https://github.com/jasmine/jasmine/issues/1437) from @voithos
* Add special handling of asymmetric matcher objects as keys in Maps.
- Merges [#1436](https://github.com/jasmine/jasmine/issues/1436) from @voithos
- Fixes [#1432](https://github.com/jasmine/jasmine/issues/1432)
* Add support for jasmine.any(Symbol).
- Merge [#1435](https://github.com/jasmine/jasmine/issues/1435) from @voithos
- Fixes [#1431](https://github.com/jasmine/jasmine/issues/1431)
* Throw an error for invalid nesting of a suite functions
- Merges [#1411](https://github.com/jasmine/jasmine/issues/1411) from @ksvitkovsky
- Fixes [#1295](https://github.com/jasmine/jasmine/issues/1295)
* Deep clone args before passing them to reporters
- Merges [#1424](https://github.com/jasmine/jasmine/issues/1424) from @aj-dev
* Fix "Before Committing" section of CONTRIBUTING.md.
- Merges [#1429](https://github.com/jasmine/jasmine/issues/1429) from @voithos
* Fix lint warning in CallTracker.
- Merges [#1428](https://github.com/jasmine/jasmine/issues/1428) from @voithos
* clearTimeout should now correctly clear a timeout that is also scheduled to run at the same tick.
- Merges [#1427](https://github.com/jasmine/jasmine/issues/1427) from @leahciMic
- Fixes [#1426](https://github.com/jasmine/jasmine/issues/1426)
* Add a note about `defineProperty` for `spyOnProperty`
- Fixes [#1415](https://github.com/jasmine/jasmine/issues/1415)
* Add Promise checking to eq
- Merges [#1386](https://github.com/jasmine/jasmine/issues/1386) from @sderickson
- Fixes [#1314](https://github.com/jasmine/jasmine/issues/1314)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

15
release_notes/2.9.1.md Normal file
View File

@@ -0,0 +1,15 @@
# Jasmine Core 2.9.1 Release Notes
## Summary
This is a hotfix release to fix a breaking change from the 2.9.0 release
## Changes
* Clear timeouts when starting to process a milli instead of at the end
- Fixes #1482
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

19
release_notes/2.99.md Normal file
View File

@@ -0,0 +1,19 @@
# Jasmine-Core 2.99 Release Notes
## Summary
This release is part of the upgrade path to Jasmine 3.0. It deprecates some functionality that will change.
## Changes
* Add ability to report deprecation warnings from within the suite and display them in the HTML reporter
* Add deprecation messages for things that will change/break in 3.0
* * done for async functionality will now add a failure if it is invoked with an Error
* * Env.catchExceptions and the query param are going away, in favor of a more fully functional fail fast handler
* * jasmine.Any(Object) will no longer match null
* * Unhandled errors during suite load will be caught and reported as failures by Jasmine
* * Calling execute more than once on the same spec will definitely fail in 3.0
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

82
release_notes/3.0.md Normal file
View File

@@ -0,0 +1,82 @@
# Jasmine-Core 3.0 Release Notes
## Summary
Jasmine 3.0 is a major release of Jasmine, and as such includes some breaking changes in addition to various new features.
There is also a 2.99 release of Jasmine that will present deprecation warnings for suites that will encounter different behavior in 3.0.
## Breaking Changes
* Replace old "catch exceptions" logic with proper fail fast with error reporting
- Fixes [#414](https://github.com/jasmine/jasmine/issues/414)
- Fixes [jasmine/jasmine-npm#16](https://github.com/jasmine/jasmine/jasmine-npm/issues/16)
* Detect an Error passed to `done` and add an expectation failure
- Fixes [#567](https://github.com/jasmine/jasmine/issues/567)
* Unify status for xdescribe and xit
- Ensure *All's only execute if at least one child will run
- Specs will report a status of `excluded` instead of disabled
- Fixes [#1418](https://github.com/jasmine/jasmine/issues/1418)
* Suite level errors all report the same way (on suiteDone)
* Refactor QueueRunner and remove references to functions that Jasmine is done with
* expect(null).toEqual(jasmine.any(Object)) no longer passes
- Fixes [#1255](https://github.com/jasmine/jasmine/issues/1255)
* Default to running tests in random order
## Changes
* Remove node modules from python wheel, and update languages
* Allow reporter callbacks to be asynchronous
- Fixes [#842](https://github.com/jasmine/jasmine/issues/842)
* Allow adding custom spy strategies
* Add the ability to specify the strategy to use for a spy based on which parameters are passed
* Added links to re-run the suites containing a failing spec
* Added a toHaveClass matcher
* More informative pretty-printing of DOM elements
* Allow jasmine-npm to handle its own load errors
* Treat random= as a no-op rather than disabling randomization
* Use prototype for spy strategy for better memory management
* Remove console.js altogether
* Add safari 10 and update readme to include edge
* Determine overall status in core, not reporters
* Filter Jasmine frames from stack traces
* Treat afterAll errors at any level as failures
* Improved reporting of load errors and afterAll errors
- Pass file and line number to reporters when present
- Show file and line number in the HTML reporter when present
- Visually separate adjacent errors in the HTML reporter
* Report loading errors as loading errors, not afterAll errors
* HTML reporter reports overall failure if there are any global errors
* Fail if error events (e.g. syntax errors) occur during loading
* Allow use of a predicate function to validate thrown exceptions
* Check truthiness of toThrowError args, not arg count
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

@@ -23,9 +23,6 @@ setup(
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',

View File

@@ -1,270 +0,0 @@
describe("ConsoleReporter", function() {
var out;
beforeEach(function() {
out = (function() {
var output = "";
return {
print: function(str) {
output += str;
},
getOutput: function() {
return output.replace('ConsoleReporter is deprecated and will be removed in a future version.', '');
},
clear: function() {
output = "";
}
};
}());
});
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("alerts user if there are no specs", function(){
var reporter = new j$.ConsoleReporter({
print: out.print
});
reporter.jasmineStarted();
out.clear();
reporter.jasmineDone();
expect(out.getOutput()).toMatch(/No specs found/);
});
it("reports a summary when done (singular 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.returnValue(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.returnValue(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(/true to be false/);
expect(out.getOutput()).toMatch(/foo bar baz/);
});
describe('onComplete callback', function(){
var onComplete, reporter;
beforeEach(function() {
onComplete = jasmine.createSpy('onComplete');
reporter = new j$.ConsoleReporter({
print: out.print,
onComplete: onComplete
});
reporter.jasmineStarted();
});
it("is called when the suite is done", function() {
reporter.jasmineDone();
expect(onComplete).toHaveBeenCalledWith(true);
});
it('calls it with false if there are spec failures', function() {
reporter.specDone({status: "failed", failedExpectations: []});
reporter.jasmineDone();
expect(onComplete).toHaveBeenCalledWith(false);
});
it('calls it with false if there are suite failures', function() {
reporter.specDone({status: "passed"});
reporter.suiteDone({failedExpectations: [{ message: 'bananas' }] });
reporter.jasmineDone();
expect(onComplete).toHaveBeenCalledWith(false);
});
});
describe("with color", function() {
it("reports that the suite has started to the console", function() {
var reporter = new j$.ConsoleReporter({
print: out.print,
showColors: true
});
reporter.jasmineStarted();
expect(out.getOutput()).toEqual("Started\n");
});
it("reports a passing spec as a dot", function() {
var reporter = new j$.ConsoleReporter({
print: out.print,
showColors: true
});
reporter.specDone({status: "passed"});
expect(out.getOutput()).toEqual("\x1B[32m.\x1B[0m");
});
it("does not report a disabled spec", function() {
var reporter = new j$.ConsoleReporter({
print: out.print,
showColors: true
});
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("\x1B[31mF\x1B[0m");
});
it("displays all afterAll exceptions", function() {
var reporter = new j$.ConsoleReporter({
print: out.print,
showColors: true
});
reporter.suiteDone({ failedExpectations: [{ message: 'After All Exception' }] });
reporter.suiteDone({ failedExpectations: [{ message: 'Some Other Exception' }] });
reporter.jasmineDone();
expect(out.getOutput()).toMatch(/After All Exception/);
expect(out.getOutput()).toMatch(/Some Other Exception/);
});
});
});

View File

@@ -1,6 +1,6 @@
describe("CallTracker", function() {
it("tracks that it was called when executed", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
expect(callTracker.any()).toBe(false);
@@ -10,7 +10,7 @@ describe("CallTracker", function() {
});
it("tracks that number of times that it is executed", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
expect(callTracker.count()).toEqual(0);
@@ -20,7 +20,7 @@ describe("CallTracker", function() {
});
it("tracks the params from each execution", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.track({object: void 0, args: []});
callTracker.track({object: {}, args: [0, "foo"]});
@@ -31,13 +31,13 @@ describe("CallTracker", function() {
});
it("returns any empty array when there was no call", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
expect(callTracker.argsFor(0)).toEqual([]);
});
it("allows access for the arguments for all calls", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.track({object: {}, args: []});
callTracker.track({object: {}, args: [0, "foo"]});
@@ -46,7 +46,7 @@ describe("CallTracker", function() {
});
it("tracks the context and arguments for each call", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.track({object: {}, args: []});
callTracker.track({object: {}, args: [0, "foo"]});
@@ -57,7 +57,7 @@ describe("CallTracker", function() {
});
it("simplifies access to the arguments for the last (most recent) call", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.track();
callTracker.track({object: {}, args: [0, "foo"]});
@@ -69,13 +69,13 @@ describe("CallTracker", function() {
});
it("returns a useful falsy value when there isn't a last (most recent) call", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
expect(callTracker.mostRecent()).toBeFalsy();
});
it("simplifies access to the arguments for the first (oldest) call", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.track({object: {}, args: [0, "foo"]});
@@ -83,14 +83,14 @@ describe("CallTracker", function() {
});
it("returns a useful falsy value when there isn't a first (oldest) call", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
expect(callTracker.first()).toBeFalsy();
});
it("allows the tracking to be reset", function() {
var callTracker = new j$.CallTracker();
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.track();
callTracker.track({object: {}, args: [0, "foo"]});
@@ -102,4 +102,29 @@ describe("CallTracker", function() {
expect(callTracker.all()).toEqual([]);
expect(callTracker.mostRecent()).toBeFalsy();
});
it("allows object arguments to be shallow cloned", function() {
var callTracker = new jasmineUnderTest.CallTracker();
callTracker.saveArgumentsByValue();
var objectArg = {"foo": "bar"},
arrayArg = ["foo", "bar"];
callTracker.track({object: {}, args: [objectArg, arrayArg, false, undefined, null, NaN, "", 0, 1.0]});
expect(callTracker.mostRecent().args[0]).not.toBe(objectArg);
expect(callTracker.mostRecent().args[0]).toEqual(objectArg);
expect(callTracker.mostRecent().args[1]).not.toBe(arrayArg);
expect(callTracker.mostRecent().args[1]).toEqual(arrayArg);
});
it('saves primitive arguments by value', function() {
var callTracker = new jasmineUnderTest.CallTracker(),
args = [undefined, null, false, '', /\s/, 0, 1.2, NaN];
callTracker.saveArgumentsByValue();
callTracker.track({ object: {}, args: args });
expect(callTracker.mostRecent().args).toEqual(args);
});
});

137
spec/core/ClearStackSpec.js Normal file
View File

@@ -0,0 +1,137 @@
describe("ClearStack", function() {
it("works in an integrationy way", function(done) {
var clearStack = jasmineUnderTest.getClearStack(jasmineUnderTest.getGlobal());
clearStack(function() {
done();
});
});
it("uses setImmediate when available", function() {
var setImmediate = jasmine.createSpy('setImmediate').and.callFake(function(fn) { fn() }),
global = { setImmediate: setImmediate },
clearStack = jasmineUnderTest.getClearStack(global),
called = false;
clearStack(function() {
called = true;
});
expect(called).toBe(true);
expect(setImmediate).toHaveBeenCalled();
});
it("uses setTimeout instead of setImmediate every 10 calls to make sure we release the CPU", function() {
var setImmediate = jasmine.createSpy('setImmediate'),
setTimeout = jasmine.createSpy('setTimeout'),
global = { setImmediate: setImmediate, setTimeout: setTimeout },
clearStack = jasmineUnderTest.getClearStack(global);
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
expect(setImmediate).toHaveBeenCalled();
expect(setTimeout).not.toHaveBeenCalled();
clearStack(function() { });
expect(setImmediate.calls.count()).toEqual(9);
expect(setTimeout.calls.count()).toEqual(1);
clearStack(function() { });
expect(setImmediate.calls.count()).toEqual(10);
expect(setTimeout.calls.count()).toEqual(1);
});
it("uses MessageChannels when available", function() {
var fakeChannel = {
port1: {},
port2: { postMessage: function() { fakeChannel.port1.onmessage(); } }
},
global = { MessageChannel: function() { return fakeChannel; } },
clearStack = jasmineUnderTest.getClearStack(global),
called = false;
clearStack(function() {
called = true;
});
expect(called).toBe(true);
});
it("uses setTimeout instead of MessageChannel every 10 calls to make sure we release the CPU", function() {
var fakeChannel = {
port1: {},
port2: {
postMessage: jasmine.createSpy('postMessage').and.callFake(function() {
fakeChannel.port1.onmessage();
})
}
},
setTimeout = jasmine.createSpy('setTimeout'),
global = { MessageChannel: function() { return fakeChannel; }, setTimeout: setTimeout },
clearStack = jasmineUnderTest.getClearStack(global);
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
clearStack(function() { });
expect(fakeChannel.port2.postMessage).toHaveBeenCalled();
expect(setTimeout).not.toHaveBeenCalled();
clearStack(function() { });
expect(fakeChannel.port2.postMessage.calls.count()).toEqual(9);
expect(setTimeout.calls.count()).toEqual(1);
clearStack(function() { });
expect(fakeChannel.port2.postMessage.calls.count()).toEqual(10);
expect(setTimeout.calls.count()).toEqual(1);
});
it("calls setTimeout when onmessage is called recursively", function() {
var fakeChannel = {
port1: {},
port2: { postMessage: function() { fakeChannel.port1.onmessage(); } }
},
setTimeout = jasmine.createSpy('setTimeout'),
global = {
MessageChannel: function() { return fakeChannel; },
setTimeout: setTimeout,
},
clearStack = jasmineUnderTest.getClearStack(global),
fn = jasmine.createSpy("second clearStack function");
clearStack(function() {
clearStack(fn);
});
expect(fn).not.toHaveBeenCalled();
expect(setTimeout).toHaveBeenCalledWith(fn, 0);
});
it("falls back to setTimeout", function() {
var setTimeout = jasmine.createSpy('setTimeout').and.callFake(function(fn) { fn() }),
global = { setTimeout: setTimeout },
clearStack = jasmineUnderTest.getClearStack(global),
called = false;
clearStack(function() {
called = true;
});
expect(called).toBe(true);
expect(setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 0);
});
});

View File

@@ -1,12 +1,14 @@
describe("Clock", function() {
var NODE_JS = typeof process !== 'undefined' && process.versions && typeof process.versions.node === 'string';
it("does not replace setTimeout until it is installed", function() {
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.setTimeout(delayedFn, 0);
@@ -28,7 +30,7 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.clearTimeout("foo");
@@ -50,7 +52,7 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.setInterval(delayedFn, 0);
@@ -72,7 +74,7 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.clearInterval("foo");
@@ -94,7 +96,7 @@ describe("Clock", function() {
fakeGlobal = { setTimeout: originalFakeSetTimeout },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.setTimeout = replacedSetTimeout;
@@ -112,7 +114,7 @@ describe("Clock", function() {
fakeGlobal = { clearTimeout: originalFakeClearTimeout },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.clearTimeout = replacedClearTimeout;
@@ -130,7 +132,7 @@ describe("Clock", function() {
fakeGlobal = { setInterval: originalFakeSetInterval },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.setInterval = replacedSetInterval;
@@ -148,7 +150,7 @@ describe("Clock", function() {
fakeGlobal = { clearInterval: originalFakeClearInterval },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.clearInterval = replacedClearInterval;
@@ -174,7 +176,7 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.uninstall();
@@ -204,7 +206,7 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset", "removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
passedFunctionCalled = false;
clock.withMock(function() {
@@ -251,7 +253,7 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset", "removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
passedFunctionCalled = false;
expect(function() {
@@ -294,13 +296,19 @@ describe("Clock", function() {
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
timeout = new clock.FakeTimeout();
clock.install();
clock.setTimeout(delayedFn, 0, 'a', 'b');
expect(fakeSetTimeout).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
if (!NODE_JS) {
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
} else {
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], false, timeout);
}
});
it("returns an id for the delayed function", function() {
@@ -311,13 +319,17 @@ describe("Clock", function() {
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
timeoutId;
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
timeout;
clock.install();
timeoutId = clock.setTimeout(delayedFn, 0);
timeout = clock.setTimeout(delayedFn, 0);
expect(timeoutId).toEqual(123);
if (!NODE_JS) {
expect(timeout).toEqual(123);
} else {
expect(timeout.constructor.name).toEqual('FakeTimeout');
}
});
it("clears the scheduled function with the scheduler", function() {
@@ -326,7 +338,7 @@ describe("Clock", function() {
fakeGlobal = { setTimeout: fakeClearTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.clearTimeout(123);
@@ -342,13 +354,19 @@ describe("Clock", function() {
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
timeout = new clock.FakeTimeout;
clock.install();
clock.setInterval(delayedFn, 0, 'a', 'b');
expect(fakeSetInterval).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
if (!NODE_JS) {
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
} else {
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true, timeout);
}
});
it("returns an id for the delayed function", function() {
@@ -359,13 +377,17 @@ describe("Clock", function() {
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
intervalId;
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
interval;
clock.install();
intervalId = clock.setInterval(delayedFn, 0);
interval = clock.setInterval(delayedFn, 0);
expect(intervalId).toEqual(123);
if (!NODE_JS) {
expect(interval).toEqual(123);
} else {
expect(interval.constructor.name).toEqual('FakeTimeout');
}
});
it("clears the scheduled function with the scheduler", function() {
@@ -374,7 +396,7 @@ describe("Clock", function() {
fakeGlobal = { setInterval: clearInterval },
delayedFn = jasmine.createSpy('delayedFn'),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.clearInterval(123);
@@ -384,42 +406,11 @@ describe("Clock", function() {
});
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']));
var clock = new jasmineUnderTest.Clock({}, jasmine.createSpyObj('delayedFunctionScheduler', ['tick']));
expect(function() {
clock.tick(50);
}).toThrow();
});
it("on IE < 9, fails if extra args are passed to fake clock", function() {
//fail, because this would break in IE9.
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
fakeSetInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
fn = jasmine.createSpy('fn'),
fakeGlobal = {
setTimeout: fakeSetTimeout,
setInterval: fakeSetInterval
},
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeSetTimeout.apply = null;
fakeSetInterval.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() {
@@ -428,9 +419,9 @@ describe("Clock (acceptance)", function() {
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFn3 = jasmine.createSpy('delayedFn3'),
recurring1 = jasmine.createSpy('recurring1'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
@@ -475,9 +466,9 @@ describe("Clock (acceptance)", function() {
it("can clear a previously set timeout", function() {
var clearedFn = jasmine.createSpy('clearedFn'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
clock = new jasmineUnderTest.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
timeoutId;
clock.install();
@@ -493,9 +484,9 @@ describe("Clock (acceptance)", function() {
it("can clear a previously set interval using that interval's handler", function() {
var spy = jasmine.createSpy('spy'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setInterval: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
clock = new jasmineUnderTest.Clock({setInterval: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
intervalId;
clock.install();
@@ -511,9 +502,9 @@ describe("Clock (acceptance)", function() {
it("correctly schedules functions after the Clock has advanced", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
@@ -528,9 +519,9 @@ describe("Clock (acceptance)", function() {
it("correctly schedules functions while the Clock is advancing", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 0); });
clock.install();
@@ -547,9 +538,9 @@ describe("Clock (acceptance)", function() {
it("correctly calls functions scheduled while the Clock is advancing", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 1); });
clock.install();
@@ -563,9 +554,9 @@ describe("Clock (acceptance)", function() {
it("correctly schedules functions scheduled while the Clock is advancing but after the Clock is uninstalled", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
clock = new jasmineUnderTest.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
delayedFn1.and.callFake(function() {
clock.uninstall();
@@ -585,10 +576,10 @@ describe("Clock (acceptance)", function() {
});
it("does not mock the Date object by default", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
@@ -602,10 +593,10 @@ describe("Clock (acceptance)", function() {
});
it("mocks the Date object and sets it to current time", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install().mockDate();
@@ -626,10 +617,10 @@ describe("Clock (acceptance)", function() {
});
it("mocks the Date object and sets it to a given time", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate),
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate),
baseTime = new Date(2013, 9, 23);
@@ -652,4 +643,68 @@ describe("Clock (acceptance)", function() {
expect(timeoutDate).toEqual(baseTime.getTime() + 150);
});
it("mocks the Date object and updates the date per delayed function", function () {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate),
baseTime = new Date();
clock.install().mockDate(baseTime);
var actualTimes = [];
var pushCurrentTime = function() { actualTimes.push(global.Date().getTime()); };
delayedFunctionScheduler.scheduleFunction(pushCurrentTime);
delayedFunctionScheduler.scheduleFunction(pushCurrentTime, 1);
delayedFunctionScheduler.scheduleFunction(pushCurrentTime, 3);
clock.tick(1);
expect(global.Date().getTime()).toEqual(baseTime.getTime() + 1);
clock.tick(3);
expect(global.Date().getTime()).toEqual(baseTime.getTime() + 4);
clock.tick(1);
expect(global.Date().getTime()).toEqual(baseTime.getTime() + 5);
expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]);
})
it('correctly clears a scheduled timeout while the Clock is advancing', function () {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date, setTimeout: undefined},
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
var timerId2;
global.setTimeout(function () {
global.clearTimeout(timerId2);
}, 100);
timerId2 = global.setTimeout(fail, 100);
clock.tick(100);
});
it('correctly clears a scheduled interval while the Clock is advancing', function () {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date, setTimeout: undefined},
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
var timerId2;
var timerId1 = global.setInterval(function () {
global.clearInterval(timerId2);
}, 100);
timerId2 = global.setInterval(fail, 100);
clock.tick(400);
});
});

View File

@@ -1,6 +1,6 @@
describe("DelayedFunctionScheduler", function() {
it("schedules a function for later execution", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0);
@@ -13,7 +13,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("schedules a string for later execution", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
strfn = "horrible = true;";
scheduler.scheduleFunction(strfn, 0);
@@ -24,7 +24,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("#tick defaults to 0", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0);
@@ -37,7 +37,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("defaults delay to 0", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn);
@@ -50,7 +50,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("optionally passes params to scheduled functions", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0, ['foo', 'bar']);
@@ -63,7 +63,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("scheduled fns can optionally reoccur", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 20, [], true);
@@ -85,7 +85,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("increments scheduled fns ids unless one is passed", function() {
var scheduler = new j$.DelayedFunctionScheduler();
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler();
expect(scheduler.scheduleFunction(function() {
}, 0)).toBe(1);
@@ -98,7 +98,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("#removeFunctionWithId removes a previously scheduled function with a given id", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
timeoutKey;
@@ -114,7 +114,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("executes recurring functions interleaved with regular functions in the correct order", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
recurringCallCount = 0,
recurring = jasmine.createSpy('recurring').and.callFake(function() {
@@ -135,7 +135,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("schedules a function for later execution during a tick", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10;
@@ -151,7 +151,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("#removeFunctionWithId removes a previously scheduled function with a given id during a tick", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
@@ -169,7 +169,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("executes recurring functions interleaved with regular functions and functions scheduled during a tick in the correct order", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
recurringCallCount = 0,
recurring = jasmine.createSpy('recurring').and.callFake(function() {
@@ -202,7 +202,7 @@ describe("DelayedFunctionScheduler", function() {
});
it("executes recurring functions after rescheduling them", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
recurring = function() {
expect(scheduler.scheduleFunction).toHaveBeenCalled();
};
@@ -215,26 +215,28 @@ describe("DelayedFunctionScheduler", function() {
});
it("removes functions during a tick that runs the function", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
spy = jasmine.createSpy('fn'),
spyAndRemove = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
scheduler.scheduleFunction(function () {
spyAndRemove.and.callFake(function() {
scheduler.removeFunctionWithId(timeoutKey);
}, 2 * fnDelay);
});
expect(fn).not.toHaveBeenCalled();
scheduler.scheduleFunction(spyAndRemove, fnDelay);
scheduler.tick(3 * fnDelay);
timeoutKey = scheduler.scheduleFunction(spy, fnDelay, [], true);
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(2);
scheduler.tick(2 * fnDelay);
expect(spy).not.toHaveBeenCalled();
expect(spyAndRemove).toHaveBeenCalled();
});
it("removes functions during the first tick that runs the function", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
@@ -251,5 +253,34 @@ describe("DelayedFunctionScheduler", function() {
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(1);
});
it("does not remove a function that hasn't been added yet", function() {
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
scheduler.removeFunctionWithId('foo');
scheduler.scheduleFunction(fn, fnDelay, [], false, 'foo');
expect(fn).not.toHaveBeenCalled();
scheduler.tick(fnDelay + 1);
expect(fn).toHaveBeenCalled();
});
it("updates the mockDate per scheduled time", function () {
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
tickDate = jasmine.createSpy('tickDate');
scheduler.scheduleFunction(function() {});
scheduler.scheduleFunction(function() {}, 1);
scheduler.tick(1, tickDate);
expect(tickDate).toHaveBeenCalledWith(0);
expect(tickDate).toHaveBeenCalledWith(1);
})
});

View File

@@ -2,20 +2,20 @@
describe("Env", function() {
var env;
beforeEach(function() {
env = new j$.Env();
env = new jasmineUnderTest.Env();
});
describe("#pending", function() {
it("throws the Pending Spec exception", function() {
expect(function() {
env.pending();
}).toThrow(j$.Spec.pendingSpecExceptionMessage);
}).toThrow(jasmineUnderTest.Spec.pendingSpecExceptionMessage);
});
it("throws the Pending Spec exception with a custom message", function() {
expect(function() {
env.pending('custom message');
}).toThrow(j$.Spec.pendingSpecExceptionMessage + 'custom message');
}).toThrow(jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'custom message');
});
});
@@ -29,9 +29,9 @@ describe("Env", function() {
it('can configure specs to throw errors on expectation failures', function() {
env.throwOnExpectationFailure(true);
spyOn(j$, 'Spec');
spyOn(jasmineUnderTest, 'Spec');
env.it('foo', function() {});
expect(j$.Spec).toHaveBeenCalledWith(jasmine.objectContaining({
expect(jasmineUnderTest.Spec).toHaveBeenCalledWith(jasmine.objectContaining({
throwOnExpectationFailure: true
}));
});
@@ -39,10 +39,162 @@ describe("Env", function() {
it('can configure suites to throw errors on expectation failures', function() {
env.throwOnExpectationFailure(true);
spyOn(j$, 'Suite');
spyOn(jasmineUnderTest, 'Suite');
env.describe('foo', function() {});
expect(j$.Suite).toHaveBeenCalledWith(jasmine.objectContaining({
expect(jasmineUnderTest.Suite).toHaveBeenCalledWith(jasmine.objectContaining({
throwOnExpectationFailure: true
}));
});
describe('#describe', function () {
it("throws an error when given arguments", function() {
expect(function() {
env.describe('done method', function(done) {});
}).toThrowError('describe does not expect any arguments');
});
it('throws an error when it receives a non-fn argument', function() {
// Some versions of PhantomJS return [object DOMWindow] when
// Object.prototype.toString.apply is called with `undefined` or `null`.
// In a similar fashion, IE8 gives [object Object] for both `undefined`
// and `null`. We mostly just want these tests to check that using
// anything other than a function throws an error.
expect(function() {
env.describe('undefined arg', undefined);
}).toThrowError(/describe expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
expect(function() {
env.describe('null arg', null);
}).toThrowError(/describe expects a function argument; received \[object (Null|DOMWindow|Object)\]/);
expect(function() {
env.describe('array arg', []);
}).toThrowError('describe expects a function argument; received [object Array]');
expect(function() {
env.describe('object arg', {});
}).toThrowError('describe expects a function argument; received [object Object]');
expect(function() {
env.describe('fn arg', function() {});
}).not.toThrowError('describe expects a function argument; received [object Function]');
});
});
describe('#it', function () {
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.it('undefined arg', null);
}).toThrowError(/it expects a function argument; received \[object (Null|DOMWindow|Object)\]/);
});
it('does not throw when it is not given a fn argument', function() {
expect(function() {
env.it('pending spec');
}).not.toThrow();
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.it('async', jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
});
describe('#xit', function() {
it('calls spec.pend with "Temporarily disabled with xit"', function() {
var pendSpy = jasmine.createSpy();
spyOn(env, 'it').and.returnValue({
pend: pendSpy
});
env.xit('foo', function() {});
expect(pendSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
});
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.xit('undefined arg', null);
}).toThrowError(/xit expects a function argument; received \[object (Null|DOMWindow|Object)\]/);
});
it('does not throw when it is not given a fn argument', function() {
expect(function() {
env.xit('pending spec');
}).not.toThrow();
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.xit('async', jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
});
describe('#fit', function () {
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.fit('undefined arg', undefined);
}).toThrowError(/fit expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
});
});
describe('#beforeEach', function () {
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.beforeEach(undefined);
}).toThrowError(/beforeEach expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.beforeEach(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
});
describe('#beforeAll', function () {
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.beforeAll(undefined);
}).toThrowError(/beforeAll expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.beforeAll(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
});
describe('#afterEach', function () {
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.afterEach(undefined);
}).toThrowError(/afterEach expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.afterEach(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
});
describe('#afterAll', function () {
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.afterAll(undefined);
}).toThrowError(/afterAll expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.afterAll(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
});
});

View File

@@ -7,7 +7,7 @@ describe("ExceptionFormatter", function() {
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
},
exceptionFormatter = new j$.ExceptionFormatter(),
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
message = exceptionFormatter.message(sampleFirefoxException);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
@@ -20,7 +20,7 @@ describe("ExceptionFormatter", function() {
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
},
exceptionFormatter = new j$.ExceptionFormatter(),
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
message = exceptionFormatter.message(sampleWebkitException);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
@@ -31,7 +31,7 @@ describe("ExceptionFormatter", function() {
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
},
exceptionFormatter = new j$.ExceptionFormatter(),
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
message = exceptionFormatter.message(sampleV8);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar');
@@ -39,7 +39,7 @@ describe("ExceptionFormatter", function() {
it("formats thrown exceptions that aren't errors", function() {
var thrown = "crazy error",
exceptionFormatter = new j$.ExceptionFormatter(),
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
message = exceptionFormatter.message(thrown);
expect(message).toEqual("crazy error thrown");
@@ -47,17 +47,74 @@ describe("ExceptionFormatter", function() {
});
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; }
it("formats stack traces", function() {
var error;
try { throw new Error("an error") } catch(e) { error = e; }
expect(new j$.ExceptionFormatter().stack(error)).toMatch(/ExceptionFormatterSpec\.js.*\d+/)
expect(new jasmineUnderTest.ExceptionFormatter().stack(error)).toMatch(/ExceptionFormatterSpec\.js.*\d+/)
});
it("filters Jasmine stack frames from V8 style traces", function() {
var error = {
stack: 'Error: nope\n' +
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' at fn2 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
' at fn3 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)\n'
};
var subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
});
var result = subject.stack(error);
expect(result).toEqual('Error: nope\n' +
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' at <Jasmine>\n' +
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)'
);
});
it("filters Jamine stack frames from Webkit style traces", function() {
var error = {
stack: 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
'fn1@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
'fn2@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
};
var subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
});
var result = subject.stack(error);
expect(result).toEqual(
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
'<Jasmine>\n' +
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
);
});
it("filters Jasmine stack frames in this environment", function() {
var error, i;
try { throw new Error("an error"); } catch(e) { error = e; }
var subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: jasmine.util.jasmineFile()
});
var result = subject.stack(error);
var lines = result.split('\n');
if (lines[0].match(/an error/)) {
lines.shift();
}
expect(lines[0]).toMatch(/ExceptionFormatterSpec.js/);
expect(lines[1]).toMatch(/<Jasmine>/);
// Node has some number of additional frames below Jasmine.
for (i = 2; i < lines.length; i++) {
expect(lines[i]).not.toMatch(/jasmine.js/);
}
});
it("returns null if no Error provided", function() {
expect(new j$.ExceptionFormatter().stack()).toBeNull();
expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull();
});
});
});

View File

@@ -2,67 +2,45 @@ describe('Exceptions:', function() {
var env;
beforeEach(function() {
env = new j$.Env();
env = new jasmineUnderTest.Env();
});
describe('with break on exception', function() {
it('should not catch the exception', function() {
env.catchExceptions(false);
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!');
});
it('should handle exceptions thrown, but continue', function(done) {
var secondTest = jasmine.createSpy('second test');
env.describe('Suite for handles exceptions', function () {
env.it('should be a test that fails because it throws an exception', function() {
throw new Error();
});
var spy = jasmine.createSpy('spy');
try {
env.execute();
spy();
}
catch (e) {}
expect(spy).not.toHaveBeenCalled();
env.it('should be a passing test that runs after exceptions are thrown from a async test', secondTest);
});
var expectations = function() {
expect(secondTest).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
});
describe("with catch on exception", function() {
it('should handle exceptions thrown, but continue', function(done) {
var secondTest = jasmine.createSpy('second test');
env.describe('Suite for handles exceptions', function () {
env.it('should be a test that fails because it throws an exception', function() {
throw new Error();
});
env.it('should be a passing test that runs after exceptions are thrown from a async test', secondTest);
it("should handle exceptions thrown directly in top-level describe blocks and continue", function(done) {
var secondDescribe = jasmine.createSpy("second describe");
env.describe("a suite that throws an exception", function () {
env.it("is a test that should pass", function () {
this.expect(true).toEqual(true);
});
var expectations = function() {
expect(secondTest).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
throw new Error("top level error");
});
env.describe("a suite that doesn't throw an exception", secondDescribe);
it("should handle exceptions thrown directly in top-level describe blocks and continue", function(done) {
var secondDescribe = jasmine.createSpy("second describe");
env.describe("a suite that throws an exception", function () {
env.it("is a test that should pass", function () {
this.expect(true).toEqual(true);
});
var expectations = function() {
expect(secondDescribe).toHaveBeenCalled();
done();
};
throw new Error("top level error");
});
env.describe("a suite that doesn't throw an exception", secondDescribe);
var expectations = function() {
expect(secondDescribe).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
});
env.addReporter({ jasmineDone: expectations });
env.execute();
});
});

View File

@@ -1,16 +1,16 @@
describe("buildExpectationResult", function() {
it("defaults to passed", function() {
var result = j$.buildExpectationResult({passed: 'some-value'});
var result = jasmineUnderTest.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'});
var result = jasmineUnderTest.buildExpectationResult({passed: true, message: 'some-value'});
expect(result.message).toBe('Passed.');
});
it("message returns the message for failing expectations", function() {
var result = j$.buildExpectationResult({passed: false, message: 'some-value'});
var result = jasmineUnderTest.buildExpectationResult({passed: false, message: 'some-value'});
expect(result.message).toBe('some-value');
});
@@ -18,7 +18,7 @@ describe("buildExpectationResult", function() {
var fakeError = {message: 'foo'},
messageFormatter = jasmine.createSpy("exception message formatter").and.returnValue(fakeError.message);
var result = j$.buildExpectationResult(
var result = jasmineUnderTest.buildExpectationResult(
{
passed: false,
error: fakeError,
@@ -33,7 +33,7 @@ describe("buildExpectationResult", function() {
var fakeError = {stack: 'foo'},
stackFormatter = jasmine.createSpy("stack formatter").and.returnValue(fakeError.stack);
var result = j$.buildExpectationResult(
var result = jasmineUnderTest.buildExpectationResult(
{
passed: false,
error: fakeError,
@@ -45,17 +45,17 @@ describe("buildExpectationResult", function() {
});
it("matcherName returns passed matcherName", function() {
var result = j$.buildExpectationResult({matcherName: 'some-value'});
var result = jasmineUnderTest.buildExpectationResult({matcherName: 'some-value'});
expect(result.matcherName).toBe('some-value');
});
it("expected returns passed expected", function() {
var result = j$.buildExpectationResult({expected: 'some-value'});
var result = jasmineUnderTest.buildExpectationResult({expected: 'some-value'});
expect(result.expected).toBe('some-value');
});
it("actual returns passed actual", function() {
var result = j$.buildExpectationResult({actual: 'some-value'});
var result = jasmineUnderTest.buildExpectationResult({actual: 'some-value'});
expect(result.actual).toBe('some-value');
});
});

View File

@@ -6,7 +6,7 @@ describe("Expectation", function() {
},
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers
});
@@ -20,18 +20,18 @@ describe("Expectation", function() {
},
expectation;
j$.Expectation.addCoreMatchers(coreMatchers);
jasmineUnderTest.Expectation.addCoreMatchers(coreMatchers);
expectation = new j$.Expectation({});
expectation = new jasmineUnderTest.Expectation({});
expect(expectation.toQuux).toBeDefined();
});
it("Factory builds an expectation/negative expectation", function() {
var builtExpectation = j$.Expectation.Factory();
var builtExpectation = jasmineUnderTest.Expectation.Factory();
expect(builtExpectation instanceof j$.Expectation).toBe(true);
expect(builtExpectation.not instanceof j$.Expectation).toBe(true);
expect(builtExpectation instanceof jasmineUnderTest.Expectation).toBe(true);
expect(builtExpectation.not instanceof jasmineUnderTest.Expectation).toBe(true);
expect(builtExpectation.not.isNot).toBe(true);
});
@@ -46,7 +46,7 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
util: util,
customMatchers: matchers,
customEqualityTesters: customEqualityTesters,
@@ -74,7 +74,7 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
util: util,
customMatchers: matchers,
actual: "an actual",
@@ -100,7 +100,7 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
util: util,
actual: "an actual",
@@ -113,6 +113,7 @@ describe("Expectation", function() {
matcherName: "toFoo",
passed: true,
message: "",
error: undefined,
expected: "hello",
actual: "an actual"
});
@@ -132,7 +133,7 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
util: util,
actual: "an actual",
@@ -146,7 +147,8 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: "an actual",
message: ""
message: "",
error: undefined
});
});
@@ -166,7 +168,7 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
actual: "an actual",
customMatchers: matchers,
addExpectationResult: addExpectationResult
@@ -179,7 +181,8 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: "an actual",
message: "I am a custom message"
message: "I am a custom message",
error: undefined
});
});
@@ -199,7 +202,7 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -212,7 +215,8 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: "an actual",
message: "I am a custom message"
message: "I am a custom message",
error: undefined
});
});
@@ -231,7 +235,7 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
@@ -244,6 +248,7 @@ describe("Expectation", function() {
matcherName: "toFoo",
passed: true,
message: "",
error: undefined,
expected: "hello",
actual: actual
});
@@ -264,7 +269,7 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
actual: "an actual",
util: util,
@@ -279,7 +284,8 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: actual,
message: "default message"
message: "default message",
error: undefined
});
});
@@ -300,7 +306,7 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
@@ -314,7 +320,8 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: actual,
message: "I am a custom message"
message: "I am a custom message",
error: undefined
});
});
@@ -331,7 +338,7 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
@@ -345,7 +352,8 @@ describe("Expectation", function() {
passed: true,
expected: "hello",
actual: actual,
message: ""
message: "",
error: undefined
});
});
@@ -367,7 +375,7 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
expectation = new j$.Expectation({
expectation = new jasmineUnderTest.Expectation({
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
@@ -381,7 +389,44 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: actual,
message: "I'm a custom message"
message: "I'm a custom message",
error: undefined
});
});
it("reports a custom error message to the spec", function() {
var customError = new Error("I am a custom error");
var matchers = {
toFoo: function() {
return {
compare: function() {
return {
pass: false,
message: "I am a custom message",
error: customError
};
}
};
}
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new jasmineUnderTest.Expectation({
actual: "an actual",
customMatchers: matchers,
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(false, {
matcherName: "toFoo",
passed: false,
expected: "hello",
actual: "an actual",
message: "I am a custom message",
error: customError
});
});

View File

@@ -0,0 +1,110 @@
describe("GlobalErrors", function() {
it("calls the added handler on error", function() {
var fakeGlobal = { onerror: null },
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
fakeGlobal.onerror('foo');
expect(handler).toHaveBeenCalledWith('foo');
});
it("only calls the most recent handler", function() {
var fakeGlobal = { onerror: null },
handler1 = jasmine.createSpy('errorHandler1'),
handler2 = jasmine.createSpy('errorHandler2'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler1);
errors.pushListener(handler2);
fakeGlobal.onerror('foo');
expect(handler1).not.toHaveBeenCalled();
expect(handler2).toHaveBeenCalledWith('foo');
});
it("calls previous handlers when one is removed", function() {
var fakeGlobal = { onerror: null },
handler1 = jasmine.createSpy('errorHandler1'),
handler2 = jasmine.createSpy('errorHandler2'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler1);
errors.pushListener(handler2);
errors.popListener();
fakeGlobal.onerror('foo');
expect(handler1).toHaveBeenCalledWith('foo');
expect(handler2).not.toHaveBeenCalled();
});
it("uninstalls itself, putting back a previous callback", function() {
var originalCallback = jasmine.createSpy('error'),
fakeGlobal = { onerror: originalCallback },
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
expect(fakeGlobal.onerror).toBe(originalCallback);
errors.install();
expect(fakeGlobal.onerror).not.toBe(originalCallback);
errors.uninstall();
expect(fakeGlobal.onerror).toBe(originalCallback);
});
it("rethrows the original error when there is no handler", function() {
var fakeGlobal = { },
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal),
originalError = new Error('nope');
errors.install();
try {
fakeGlobal.onerror(originalError);
} catch (e) {
expect(e).toBe(originalError);
}
errors.uninstall();
});
it("works in node.js", function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
removeListener: jasmine.createSpy('process.removeListener'),
listeners: jasmine.createSpy('process.listeners').and.returnValue(['foo']),
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
expect(fakeGlobal.process.on).toHaveBeenCalledWith('uncaughtException', jasmine.any(Function));
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith('uncaughtException');
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith('uncaughtException');
errors.pushListener(handler);
var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1];
addedListener(new Error('bar'));
expect(handler).toHaveBeenCalledWith(new Error('bar'));
errors.uninstall();
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith('uncaughtException', addedListener);
expect(fakeGlobal.process.on).toHaveBeenCalledWith('uncaughtException', 'foo');
});
});

View File

@@ -5,7 +5,7 @@ xdescribe('JsApiReporter (integration specs)', function() {
var suite, nestedSuite, nestedSpec;
beforeEach(function() {
env = new j$.Env();
env = new jasmineUnderTest.Env();
suite = env.describe("top-level suite", function() {
spec1 = env.it("spec 1", function() {
@@ -25,7 +25,7 @@ xdescribe('JsApiReporter (integration specs)', function() {
});
reporter = new j$.JsApiReporter({});
reporter = new jasmineUnderTest.JsApiReporter({});
env.addReporter(reporter);
env.execute();
@@ -82,7 +82,7 @@ xdescribe('JsApiReporter (integration specs)', function() {
describe("JsApiReporter", function() {
it("knows when a full environment is started", function() {
var reporter = new j$.JsApiReporter({});
var reporter = new jasmineUnderTest.JsApiReporter({});
expect(reporter.started).toBe(false);
expect(reporter.finished).toBe(false);
@@ -94,7 +94,7 @@ describe("JsApiReporter", function() {
});
it("knows when a full environment is done", function() {
var reporter = new j$.JsApiReporter({});
var reporter = new jasmineUnderTest.JsApiReporter({});
expect(reporter.started).toBe(false);
expect(reporter.finished).toBe(false);
@@ -106,13 +106,13 @@ describe("JsApiReporter", function() {
});
it("defaults to 'loaded' status", function() {
var reporter = new j$.JsApiReporter({});
var reporter = new jasmineUnderTest.JsApiReporter({});
expect(reporter.status()).toEqual('loaded');
});
it("reports 'started' when Jasmine has started", function() {
var reporter = new j$.JsApiReporter({});
var reporter = new jasmineUnderTest.JsApiReporter({});
reporter.jasmineStarted();
@@ -120,7 +120,7 @@ describe("JsApiReporter", function() {
});
it("reports 'done' when Jasmine is done", function() {
var reporter = new j$.JsApiReporter({});
var reporter = new jasmineUnderTest.JsApiReporter({});
reporter.jasmineDone({});
@@ -128,7 +128,7 @@ describe("JsApiReporter", function() {
});
it("tracks a suite", function() {
var reporter = new j$.JsApiReporter({});
var reporter = new jasmineUnderTest.JsApiReporter({});
reporter.suiteStarted({
id: 123,
@@ -151,7 +151,7 @@ describe("JsApiReporter", function() {
describe("#specResults", function() {
var reporter, specResult1, specResult2;
beforeEach(function() {
reporter = new j$.JsApiReporter({});
reporter = new jasmineUnderTest.JsApiReporter({});
specResult1 = {
id: 1,
description: "A spec"
@@ -181,7 +181,7 @@ describe("JsApiReporter", function() {
describe("#suiteResults", function(){
var reporter, suiteResult1, suiteResult2;
beforeEach(function() {
reporter = new j$.JsApiReporter({});
reporter = new jasmineUnderTest.JsApiReporter({});
suiteStarted1 = {
id: 1
};
@@ -192,7 +192,7 @@ describe("JsApiReporter", function() {
};
suiteResult2 = {
id: 2,
status: 'finished'
status: 'passed'
};
reporter.suiteStarted(suiteStarted1);
@@ -218,7 +218,7 @@ describe("JsApiReporter", function() {
describe("#executionTime", function() {
it("should start the timer when jasmine starts", function() {
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
reporter = new j$.JsApiReporter({
reporter = new jasmineUnderTest.JsApiReporter({
timer: timerSpy
});
@@ -228,7 +228,7 @@ describe("JsApiReporter", function() {
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({
reporter = new jasmineUnderTest.JsApiReporter({
timer: timerSpy
});
@@ -240,7 +240,7 @@ describe("JsApiReporter", function() {
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({
reporter = new jasmineUnderTest.JsApiReporter({
timer: timerSpy
});
@@ -248,4 +248,12 @@ describe("JsApiReporter", function() {
});
});
});
describe('#runDetails', function() {
it('should have details about the run', function() {
var reporter = new jasmineUnderTest.JsApiReporter({});
reporter.jasmineDone({some: {run: 'details'}});
expect(reporter.runDetails).toEqual({some: {run: 'details'}});
});
});
});

View File

@@ -1,7 +1,7 @@
describe("FakeDate", function() {
it("does not fail if no global date is found", function() {
var fakeGlobal = {},
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
expect(function() {
mockDate.install();
@@ -17,7 +17,7 @@ describe("FakeDate", function() {
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
expect(fakeGlobal.Date).toEqual(globalDate);
mockDate.install();
@@ -32,7 +32,7 @@ describe("FakeDate", function() {
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
mockDate.uninstall();
@@ -49,7 +49,7 @@ describe("FakeDate", function() {
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -60,7 +60,7 @@ describe("FakeDate", function() {
it("can accept a date as time base when installing", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal),
mockDate = new jasmineUnderTest.MockDate(fakeGlobal),
baseDate = new Date();
spyOn(baseDate, 'getTime').and.returnValue(123);
@@ -71,7 +71,7 @@ describe("FakeDate", function() {
it("makes real dates", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
expect(new fakeGlobal.Date()).toEqual(jasmine.any(Date));
@@ -89,7 +89,7 @@ describe("FakeDate", function() {
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
var mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -105,7 +105,7 @@ describe("FakeDate", function() {
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -123,7 +123,7 @@ describe("FakeDate", function() {
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
var mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -147,7 +147,7 @@ describe("FakeDate", function() {
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
var mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -160,7 +160,7 @@ describe("FakeDate", function() {
it("allows creation of a Date in a different time than the mocked time", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -170,7 +170,7 @@ describe("FakeDate", function() {
it("allows creation of a Date that isn't fully specified", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();
@@ -180,7 +180,7 @@ describe("FakeDate", function() {
it('allows creation of a Date with millis', function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal),
mockDate = new jasmineUnderTest.MockDate(fakeGlobal),
now = new Date(2014, 3, 15).getTime();
mockDate.install();
@@ -191,7 +191,7 @@ describe("FakeDate", function() {
it("copies all Date properties to the mocked date", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
mockDate.install();

View File

@@ -1,34 +1,86 @@
describe("j$.pp", function () {
describe("jasmineUnderTest.pp", function () {
it("should wrap strings in single quotes", function() {
expect(j$.pp("some string")).toEqual("'some string'");
expect(j$.pp("som' string")).toEqual("'som' string'");
expect(jasmineUnderTest.pp("some string")).toEqual("'some string'");
expect(jasmineUnderTest.pp("som' string")).toEqual("'som' string'");
});
it("should stringify primitives properly", function() {
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");
expect(j$.pp(-0)).toEqual("-0");
expect(jasmineUnderTest.pp(true)).toEqual("true");
expect(jasmineUnderTest.pp(false)).toEqual("false");
expect(jasmineUnderTest.pp(null)).toEqual("null");
expect(jasmineUnderTest.pp(jasmine.undefined)).toEqual("undefined");
expect(jasmineUnderTest.pp(3)).toEqual("3");
expect(jasmineUnderTest.pp(-3.14)).toEqual("-3.14");
expect(jasmineUnderTest.pp(-0)).toEqual("-0");
});
describe('stringify sets', function() {
it("should stringify sets properly", function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set();
set.add(1);
set.add(2);
expect(jasmineUnderTest.pp(set)).toEqual("Set( 1, 2 )");
});
it("should truncate sets with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
jasmine.getEnv().requireFunctioningSets();
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
var set = new Set();
set.add('a');
set.add('b');
set.add('c');
expect(jasmineUnderTest.pp(set)).toEqual("Set( 'a', 'b', ... )");
} finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
}
})
});
describe('stringify maps', function() {
it("should stringify maps properly", function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map();
map.set(1,2);
expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 1, 2 ] )");
});
it("should truncate maps with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
jasmine.getEnv().requireFunctioningMaps();
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
var map = new Map();
map.set("a",1);
map.set("b",2);
map.set("c",3);
expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )");
} finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
}
})
});
describe('stringify arrays', function() {
it("should stringify arrays properly", function() {
expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', Object({ }), undefined, null ]");
expect(jasmineUnderTest.pp([1, 2])).toEqual("[ 1, 2 ]");
expect(jasmineUnderTest.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', Object({ }), undefined, null ]");
});
it("should truncate arrays that are longer than j$.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
it("should truncate arrays that are longer than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var array = [1, 2, 3];
try {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(j$.pp(array)).toEqual("[ 1, 2, ... ]");
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(jasmineUnderTest.pp(array)).toEqual("[ 1, 2, ... ]");
} finally {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
}
});
@@ -36,27 +88,27 @@ describe("j$.pp", function () {
var arr = [1, 2];
arr.foo = 'bar';
arr.baz = {};
expect(j$.pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
expect(jasmineUnderTest.pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
});
it("should stringify empty arrays with properties properly", function() {
var empty = [];
empty.foo = 'bar';
empty.baz = {};
expect(j$.pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
expect(jasmineUnderTest.pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
});
it("should stringify long arrays with properties properly", function() {
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var long = [1,2,3];
long.foo = 'bar';
long.baz = {};
try {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(j$.pp(long)).toEqual("[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]");
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(jasmineUnderTest.pp(long)).toEqual("[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]");
} finally {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
}
});
@@ -64,49 +116,101 @@ describe("j$.pp", function () {
var array1 = [1, 2];
var array2 = [array1];
array1.push(array2);
expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
expect(jasmineUnderTest.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
});
it("should not indicate circular references incorrectly", function() {
var array = [ [1] ];
expect(j$.pp(array)).toEqual("[ [ 1 ] ]");
expect(jasmineUnderTest.pp(array)).toEqual("[ [ 1 ] ]");
});
});
it("should stringify objects properly", function() {
expect(j$.pp({foo: 'bar'})).toEqual("Object({ foo: 'bar' })");
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })");
expect(j$.pp({foo: function () {
expect(jasmineUnderTest.pp({foo: 'bar'})).toEqual("Object({ foo: 'bar' })");
expect(jasmineUnderTest.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })");
expect(jasmineUnderTest.pp({foo: function () {
}, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
});
it("should truncate objects with too many keys", function () {
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var long = {a: 1, b: 2, c: 3};
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(jasmineUnderTest.pp(long)).toEqual("Object({ a: 1, b: 2, ... })");
} finally {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
}
});
function withMaxChars(maxChars, fn) {
var originalMaxChars = jasmineUnderTest.MAX_PRETTY_PRINT_CHARS;
try {
jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = maxChars;
fn();
} finally {
jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = originalMaxChars;
}
}
it("should truncate outputs that are too long", function() {
var big = [
{ a: 1, b: "a long string" },
{}
];
withMaxChars(34, function() {
expect(jasmineUnderTest.pp(big)).toEqual("[ Object({ a: 1, b: 'a long st ...");
});
});
it("should not serialize more objects after hitting MAX_PRETTY_PRINT_CHARS", function() {
var a = { jasmineToString: function() { return 'object a'; } },
b = { jasmineToString: function() { return 'object b'; } },
c = { jasmineToString: jasmine.createSpy('c jasmineToString').and.returnValue('') },
d = { jasmineToString: jasmine.createSpy('d jasmineToString').and.returnValue('') };
withMaxChars(30, function() {
jasmineUnderTest.pp([{a: a, b: b, c: c}, d]);
expect(c.jasmineToString).not.toHaveBeenCalled();
expect(d.jasmineToString).not.toHaveBeenCalled();
});
});
it("should print 'null' as the constructor of an object with its own constructor property", function() {
expect(jasmineUnderTest.pp({constructor: function() {}})).toContain("null({");
expect(jasmineUnderTest.pp({constructor: 'foo'})).toContain("null({");
});
it("should not include inherited properties when stringifying an object", function() {
var SomeClass = function SomeClass() {};
SomeClass.prototype.foo = "inherited foo";
var instance = new SomeClass();
instance.bar = "my own bar";
expect(j$.pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
expect(jasmineUnderTest.pp(instance)).toEqual("SomeClass({ 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;
it("should not recurse objects and arrays more deeply than jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH", function() {
var originalMaxDepth = jasmineUnderTest.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("Object({ level1: Object({ level2: Object }) })");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 2;
expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object }) })");
expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
j$.MAX_PRETTY_PRINT_DEPTH = 3;
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object }) }) })");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 3;
expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object }) }) })");
expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
j$.MAX_PRETTY_PRINT_DEPTH = 4;
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 4;
expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })");
expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
} finally {
j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
}
});
@@ -115,18 +219,18 @@ describe("j$.pp", function () {
var frozenObject = {foo: {bar: 'baz'}};
frozenObject.circular = frozenObject;
frozenObject = Object.freeze(frozenObject);
expect(j$.pp(frozenObject)).toEqual("Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })");
expect(jasmineUnderTest.pp(frozenObject)).toEqual("Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })");
}
});
it("should stringify RegExp objects properly", function() {
expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
expect(jasmineUnderTest.pp(/x|y|z/)).toEqual("/x|y|z/");
});
it("should indicate circular object references", function() {
var sampleValue = {foo: 'hello'};
sampleValue.nested = sampleValue;
expect(j$.pp(sampleValue)).toEqual("Object({ foo: 'hello', nested: <circular reference: Object> })");
expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ foo: 'hello', nested: <circular reference: Object> })");
});
it("should indicate getters on objects as such", function() {
@@ -138,39 +242,43 @@ describe("j$.pp", function () {
});
}
if (sampleValue.__defineGetter__) {
expect(j$.pp(sampleValue)).toEqual("Object({ id: 1, calculatedValue: <getter> })");
expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ id: 1, calculatedValue: <getter> })");
}
else {
expect(j$.pp(sampleValue)).toEqual("Object({ id: 1 })");
expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ id: 1 })");
}
});
it('should not do HTML escaping of strings', function() {
expect(j$.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
expect(jasmineUnderTest.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
});
it("should abbreviate the global (usually window) object", function() {
expect(j$.pp(jasmine.getGlobal())).toEqual("<global>");
expect(jasmineUnderTest.pp(jasmine.getGlobal())).toEqual("<global>");
});
it("should stringify Date objects properly", function() {
var now = new Date();
expect(j$.pp(now)).toEqual("Date(" + now.toString() + ")");
expect(jasmineUnderTest.pp(now)).toEqual("Date(" + now.toString() + ")");
});
it("should stringify spy objects properly", function() {
var TestObject = {
someFunction: function() {}
},
env = new j$.Env();
someFunction: function() {}
},
env = new jasmineUnderTest.Env();
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {return [];}});
var spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() {return [];},
createSpy: function(name, originalFn) {
return jasmineUnderTest.Spy(name, originalFn);
}
});
spyRegistry.spyOn(TestObject, 'someFunction');
expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
expect(jasmineUnderTest.pp(TestObject.someFunction)).toEqual("spy on someFunction");
expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
expect(jasmineUnderTest.pp(env.createSpy("something"))).toEqual("spy on something");
});
it("should stringify objects that implement jasmineToString", function () {
@@ -178,15 +286,47 @@ describe("j$.pp", function () {
jasmineToString: function () { return "strung"; }
};
expect(j$.pp(obj)).toEqual("strung");
expect(jasmineUnderTest.pp(obj)).toEqual("strung");
});
it("should stringify objects that implement custom toString", function () {
var obj = {
toString: function () { return "my toString"; }
};
expect(jasmineUnderTest.pp(obj)).toEqual("my toString");
// Simulate object from another global context (e.g. an iframe or Web Worker) that does not actually have a custom
// toString despite obj.toString !== Object.prototype.toString
var objFromOtherContext = {
foo: 'bar',
toString: function () { return Object.prototype.toString.call(this); }
};
expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar', toString: Function })");
});
it("should stringify objects have have a toString that isn't a function", function() {
var obj = {
toString: "foo"
};
expect(jasmineUnderTest.pp(obj)).toEqual("Object({ toString: 'foo' })");
});
it("should stringify objects from anonymous constructors with custom toString", function () {
var MyAnonymousConstructor = (function() { return function () {}; })();
MyAnonymousConstructor.toString = function () { return ''; };
var a = new MyAnonymousConstructor();
expect(jasmineUnderTest.pp(a)).toEqual("<anonymous>({ })");
});
it("should handle objects with null prototype", function() {
if (jasmine.getEnv().ieVersion < 9) { return; }
var obj = Object.create(null);
obj.foo = 'bar';
expect(j$.pp(obj)).toEqual("null({ foo: 'bar' })");
expect(jasmineUnderTest.pp(obj)).toEqual("null({ foo: 'bar' })");
});
});

View File

@@ -4,7 +4,7 @@ describe("QueueRunner", function() {
var calls = [],
queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2]
});
queueableFn1.fn.and.callFake(function() {
@@ -19,11 +19,31 @@ describe("QueueRunner", function() {
expect(calls).toEqual(['fn1', 'fn2']);
});
it("runs cleanup functions after the others", function() {
var calls = [],
queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1],
cleanupFns: [queueableFn2]
});
queueableFn1.fn.and.callFake(function() {
calls.push('fn1');
});
queueableFn2.fn.and.callFake(function() {
calls.push('fn2');
});
queueRunner.execute();
expect(calls).toEqual(['fn1', 'fn2']);
});
it("calls each function with a consistent 'this'-- an empty object", function() {
var queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2, queueableFn3]
}),
asyncContext;
@@ -31,7 +51,7 @@ describe("QueueRunner", function() {
queueRunner.execute();
var context = queueableFn1.fn.calls.first().object;
expect(context).toEqual({});
expect(context).toEqual(new jasmineUnderTest.UserContext());
expect(queueableFn2.fn.calls.first().object).toBe(context);
expect(asyncContext).toBe(context);
});
@@ -65,7 +85,7 @@ describe("QueueRunner", function() {
afterCallback();
setTimeout(done, 100);
} },
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2, queueableFn3],
onComplete: onComplete
});
@@ -99,7 +119,7 @@ describe("QueueRunner", function() {
} },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
fail: failFn
});
@@ -115,13 +135,59 @@ describe("QueueRunner", function() {
expect(queueableFn2.fn).toHaveBeenCalled();
});
it("explicitly fails an async function when next is called with an Error and moves to the next function", function() {
var err = new Error('foo'),
queueableFn1 = { fn: function(done) {
setTimeout(function() { done(err); }, 100);
} },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
fail: failFn
});
queueRunner.execute();
expect(failFn).not.toHaveBeenCalled();
expect(queueableFn2.fn).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(failFn).toHaveBeenCalledWith(err);
expect(queueableFn2.fn).toHaveBeenCalled();
});
it("does not cause an explicit fail if execution is being stopped", function() {
var err = new jasmineUnderTest.StopExecutionError('foo'),
queueableFn1 = { fn: function(done) {
setTimeout(function() { done(err); }, 100);
} },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
fail: failFn
});
queueRunner.execute();
expect(failFn).not.toHaveBeenCalled();
expect(queueableFn2.fn).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(failFn).not.toHaveBeenCalled();
expect(queueableFn2.fn).toHaveBeenCalled();
});
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
var timeout = 3,
beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [beforeFn, queueableFn],
onComplete: onComplete,
onException: onException
@@ -142,7 +208,7 @@ describe("QueueRunner", function() {
queueableFn = { fn: jasmine.createSpy('fn') },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [beforeFn, queueableFn],
onComplete: onComplete,
onException: onException,
@@ -151,7 +217,7 @@ describe("QueueRunner", function() {
queueRunner.execute();
expect(queueableFn.fn).not.toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
expect(onException).not.toHaveBeenCalled();
expect(queueableFn.fn).not.toHaveBeenCalled();
@@ -162,7 +228,7 @@ describe("QueueRunner", function() {
var queueableFn = { fn: function(done) { throw new Error("error!"); } },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
onComplete: onComplete,
onException: onException
@@ -173,7 +239,7 @@ describe("QueueRunner", function() {
expect(onComplete).toHaveBeenCalled();
expect(onException).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
expect(onException.calls.count()).toEqual(1);
});
@@ -181,7 +247,7 @@ describe("QueueRunner", function() {
var queueableFn = { fn: function(done) { done(); } },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
onComplete: onComplete,
onException: onException
@@ -189,20 +255,22 @@ describe("QueueRunner", function() {
queueRunner.execute();
jasmine.clock().tick(1);
expect(onComplete).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
expect(onException).not.toHaveBeenCalled();
});
it("only moves to the next spec the first time you call done", function() {
var queueableFn = { fn: function(done) {done(); done();} },
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
queueRunner.execute();
jasmine.clock().tick(1);
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
});
@@ -211,15 +279,174 @@ describe("QueueRunner", function() {
setTimeout(done, 1);
throw new Error('error!');
} },
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
queueRunner.execute();
jasmine.clock().tick(1);
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
});
it("should return a null when you call done", function () {
// Some promises want handlers to return anything but undefined to help catch "forgotten returns".
var doneReturn,
queueableFn = { fn: function(done) {
doneReturn = done();
} },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn]
});
queueRunner.execute();
expect(doneReturn).toBe(null);
});
it("continues running functions when an exception is thrown in async code without timing out", function() {
var queueableFn = { fn: function(done) { throwAsync(); }, timeout: function() { return 1; } },
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
onException = jasmine.createSpy('onException'),
globalErrors = { pushListener: jasmine.createSpy('pushListener'), popListener: jasmine.createSpy('popListener') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
onException: onException,
globalErrors: globalErrors
}),
throwAsync = function() {
globalErrors.pushListener.calls.mostRecent().args[0](new Error('foo'));
jasmine.clock().tick(2);
};
nextQueueableFn.fn.and.callFake(function() {
// should remove the same function that was added
expect(globalErrors.popListener).toHaveBeenCalledWith(globalErrors.pushListener.calls.argsFor(1)[0]);
});
queueRunner.execute();
function errorWithMessage(message) {
return {
asymmetricMatch: function(other) {
return new RegExp(message).test(other.message);
},
toString: function() {
return '<Error with message like "' + message + '">';
}
};
}
expect(onException).not.toHaveBeenCalledWith(errorWithMessage(/DEFAULT_TIMEOUT_INTERVAL/));
expect(onException).toHaveBeenCalledWith(errorWithMessage(/^foo$/));
expect(nextQueueableFn.fn).toHaveBeenCalled();
});
it("handles exceptions thrown while waiting for the stack to clear", function() {
var queueableFn = { fn: function(done) { done() } },
global = {},
errorListeners = [],
globalErrors = {
pushListener: function(f) { errorListeners.push(f); },
popListener: function() { errorListeners.pop(); }
},
clearStack = jasmine.createSpy('clearStack'),
onException = jasmine.createSpy('onException'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
globalErrors: globalErrors,
clearStack: clearStack,
onException: onException
}),
error = new Error('nope');
queueRunner.execute();
jasmine.clock().tick();
expect(clearStack).toHaveBeenCalled();
expect(errorListeners.length).toEqual(1);
errorListeners[0](error);
clearStack.calls.argsFor(0)[0]();
expect(onException).toHaveBeenCalledWith(error);
});
});
describe("with a function that returns a promise", function() {
function StubPromise() {}
StubPromise.prototype.then = function(resolve, reject) {
this.resolveHandler = resolve;
this.rejectHandler = reject;
};
beforeEach(function() {
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
it("runs the function asynchronously, advancing once the promise is settled", function() {
var onComplete = jasmine.createSpy('onComplete'),
fnCallback = jasmine.createSpy('fnCallback'),
p1 = new StubPromise(),
p2 = new StubPromise(),
queueableFn1 = { fn: function() {
setTimeout(function() {
p1.resolveHandler();
}, 100);
return p1;
} };
queueableFn2 = { fn: function() {
fnCallback();
setTimeout(function() {
p2.resolveHandler();
}, 100);
return p2;
} },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
onComplete: onComplete
});
queueRunner.execute();
expect(fnCallback).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(fnCallback).toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(onComplete).toHaveBeenCalled();
});
it("handles a rejected promise like an unhandled exception", function() {
var promise = new StubPromise(),
queueableFn1 = { fn: function() {
setTimeout(function() {
promise.rejectHandler('foo')
}, 100);
return promise;
} },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
onExceptionCallback = jasmine.createSpy('on exception callback'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
onException: onExceptionCallback
});
queueRunner.execute();
expect(onExceptionCallback).not.toHaveBeenCalled();
expect(queueableFn2.fn).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(onExceptionCallback).toHaveBeenCalledWith('foo');
expect(queueableFn2.fn).toHaveBeenCalled();
});
});
it("calls exception handlers when an exception is thrown in a fn", function() {
@@ -228,7 +455,7 @@ describe("QueueRunner", function() {
throw new Error('fake error');
} },
onExceptionCallback = jasmine.createSpy('on exception callback'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
onException: onExceptionCallback
});
@@ -238,24 +465,10 @@ describe("QueueRunner", function() {
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
});
it("rethrows an exception if told to", function() {
var queueableFn = { fn: function() {
throw new Error('fake error');
} },
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn],
catchException: function(e) { return false; }
});
expect(function() {
queueRunner.execute();
}).toThrowError('fake error');
});
it("continues running the functions even after an exception is thrown in an async spec", function() {
var queueableFn = { fn: function(done) { throw new Error("error"); } },
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
@@ -263,10 +476,109 @@ describe("QueueRunner", function() {
expect(nextQueueableFn.fn).toHaveBeenCalled();
});
describe("When configured to complete on first error", function() {
it("skips to cleanup functions on the first exception", function() {
var queueableFn = { fn: function() { throw new Error("error"); } },
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
cleanupFn = { fn: jasmine.createSpy("cleanup") },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true
});
queueRunner.execute();
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
expect(cleanupFn.fn).toHaveBeenCalled();
});
it("does not skip when a cleanup function throws", function() {
var queueableFn = { fn: function() { } },
cleanupFn1 = { fn: function() { throw new Error("error"); } },
cleanupFn2 = { fn: jasmine.createSpy("cleanupFn2") },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
cleanupFns: [cleanupFn1, cleanupFn2],
completeOnFirstError: true
});
queueRunner.execute();
expect(cleanupFn2.fn).toHaveBeenCalled();
});
describe("with an asynchronous function", function() {
beforeEach(function() {
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
it("skips to cleanup functions on the first exception", function() {
var errorListeners = [],
queueableFn = { fn: function(done) {} },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
queueRunner = new jasmineUnderTest.QueueRunner({
globalErrors: {
pushListener: function(f) { errorListeners.push(f); },
popListener: function() { errorListeners.pop(); },
},
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true,
});
queueRunner.execute();
errorListeners[errorListeners.length - 1](new Error('error'));
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
expect(cleanupFn.fn).toHaveBeenCalled();
});
it("skips to cleanup functions when next.fail is called", function() {
var queueableFn = { fn: function(done) {
done.fail('nope');
} },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true,
});
queueRunner.execute();
jasmine.clock().tick();
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
expect(cleanupFn.fn).toHaveBeenCalled();
});
it("skips to cleanup functions when next is called with an Error", function() {
var queueableFn = { fn: function(done) {
done(new Error('nope'));
} },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true,
});
queueRunner.execute();
jasmine.clock().tick();
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
expect(cleanupFn.fn).toHaveBeenCalled();
});
});
});
it("calls a provided complete callback when done", function() {
var queueableFn = { fn: jasmine.createSpy('fn') },
completeCallback = jasmine.createSpy('completeCallback'),
queueRunner = new j$.QueueRunner({
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
onComplete: completeCallback
});
@@ -276,21 +588,83 @@ describe("QueueRunner", function() {
expect(completeCallback).toHaveBeenCalled();
});
it("calls a provided stack clearing function when done", function() {
var asyncFn = { fn: function(done) { done() } },
afterFn = { fn: jasmine.createSpy('afterFn') },
completeCallback = jasmine.createSpy('completeCallback'),
clearStack = jasmine.createSpy('clearStack'),
queueRunner = new j$.QueueRunner({
queueableFns: [asyncFn, afterFn],
clearStack: clearStack,
onComplete: completeCallback
});
describe("clearing the stack", function() {
beforeEach(function() {
jasmine.clock().install();
});
clearStack.and.callFake(function(fn) { fn(); });
afterEach(function() {
jasmine.clock().uninstall();
});
queueRunner.execute();
expect(afterFn.fn).toHaveBeenCalled();
expect(clearStack).toHaveBeenCalledWith(completeCallback);
it("calls a provided stack clearing function when done", function() {
var asyncFn = { fn: function(done) { done() } },
afterFn = { fn: jasmine.createSpy('afterFn') },
completeCallback = jasmine.createSpy('completeCallback'),
clearStack = jasmine.createSpy('clearStack'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [asyncFn, afterFn],
clearStack: clearStack,
onComplete: completeCallback
});
clearStack.and.callFake(function(fn) { fn(); });
queueRunner.execute();
jasmine.clock().tick();
expect(afterFn.fn).toHaveBeenCalled();
expect(clearStack).toHaveBeenCalled();
clearStack.calls.argsFor(0)[0]();
expect(completeCallback).toHaveBeenCalled();
});
});
describe('when user context has not been defined', function() {
beforeEach(function() {
var fn;
this.fn = fn = jasmine.createSpy('fn1');
this.queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [{ fn: fn }]
});
});
it('runs the functions on the scope of a UserContext', function() {
var calls = [],
context;
this.fn.and.callFake(function() {
context = this;
});
this.queueRunner.execute();
expect(context.constructor).toBe(jasmineUnderTest.UserContext);
});
});
describe('when user context has been defined', function() {
beforeEach(function() {
var fn, context;
this.fn = fn = jasmine.createSpy('fn1');
this.context = context = new jasmineUnderTest.UserContext();
this.queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [{ fn: fn }],
userContext: context
});
});
it('runs the functions on the scope of a UserContext', function() {
var calls = [],
context;
this.fn.and.callFake(function() {
context = this;
});
this.queueRunner.execute();
expect(context).toBe(this.context);
});
});
});

View File

@@ -1,7 +1,7 @@
describe("ReportDispatcher", function() {
it("builds an interface of requested methods", function() {
var dispatcher = new j$.ReportDispatcher(['foo', 'bar', 'baz']);
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar', 'baz']);
expect(dispatcher.foo).toBeDefined();
expect(dispatcher.bar).toBeDefined();
@@ -9,32 +9,132 @@ describe("ReportDispatcher", function() {
});
it("dispatches requested methods to added reporters", function() {
var dispatcher = new j$.ReportDispatcher(['foo', 'bar']),
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
completeCallback = jasmine.createSpy('complete');
dispatcher.addReporter(reporter);
dispatcher.addReporter(anotherReporter);
dispatcher.foo(123, 456);
dispatcher.foo(123, 456, completeCallback);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: [{fn: jasmine.any(Function)}, {fn: jasmine.any(Function)}],
isReporter: true
}));
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
fns[0].fn();
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
expect(reporter.foo.calls.mostRecent().object).toBe(reporter);
fns[1].fn();
expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
expect(anotherReporter.foo.calls.mostRecent().object).toBe(anotherReporter);
dispatcher.bar('a', 'b');
queueRunnerFactory.calls.reset();
dispatcher.bar('a', 'b', completeCallback);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: [{fn: jasmine.any(Function)}, {fn: jasmine.any(Function)}],
isReporter: true
}));
fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
fns[0].fn();
expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
fns[1].fn();
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']),
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo'], queueRunnerFactory),
reporter = jasmine.createSpyObj('reporter', ['baz']);
dispatcher.addReporter(reporter);
expect(function() {
dispatcher.foo(123, 456);
}).not.toThrow();
dispatcher.foo(123, 456);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: []
}));
});
it("allows providing a fallback reporter in case there's no other reporter", function() {
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
completeCallback = jasmine.createSpy('complete');
dispatcher.provideFallbackReporter(reporter);
dispatcher.foo(123, 456, completeCallback);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: [{fn: jasmine.any(Function)}],
isReporter: true
}));
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
fns[0].fn();
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
});
it("does not call fallback reporting methods when another reporter is provided", function() {
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']),
completeCallback = jasmine.createSpy('complete');
dispatcher.provideFallbackReporter(fallbackReporter);
dispatcher.addReporter(reporter);
dispatcher.foo(123, 456, completeCallback);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: [{fn: jasmine.any(Function)}],
isReporter: true
}));
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
fns[0].fn();
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
expect(fallbackReporter.foo).not.toHaveBeenCalledWith(123, 456);
});
it("allows registered reporters to be cleared", function() {
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar'], queueRunnerFactory),
reporter1 = jasmine.createSpyObj('reporter1', ['foo', 'bar']),
reporter2 = jasmine.createSpyObj('reporter2', ['foo', 'bar']),
completeCallback = jasmine.createSpy('complete');
dispatcher.addReporter(reporter1);
dispatcher.foo(123, completeCallback);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: [{fn: jasmine.any(Function)}],
isReporter: true
}));
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
fns[0].fn();
expect(reporter1.foo).toHaveBeenCalledWith(123);
dispatcher.clearReporters();
dispatcher.addReporter(reporter2);
dispatcher.bar(456, completeCallback);
expect(queueRunnerFactory).toHaveBeenCalledWith(jasmine.objectContaining({
queueableFns: [{fn: jasmine.any(Function)}],
isReporter: true
}));
fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
fns[0].fn();
expect(reporter1.bar).not.toHaveBeenCalled();
expect(reporter2.bar).toHaveBeenCalledWith(456);
});
});

View File

@@ -1,36 +1,36 @@
describe("Spec", function() {
it("#isPendingSpecException returns true for a pending spec exception", function() {
var e = new Error(j$.Spec.pendingSpecExceptionMessage);
var e = new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage);
expect(j$.Spec.isPendingSpecException(e)).toBe(true);
expect(jasmineUnderTest.Spec.isPendingSpecException(e)).toBe(true);
});
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; }
toString: function() { return "Error: " + jasmineUnderTest.Spec.pendingSpecExceptionMessage; }
};
expect(j$.Spec.isPendingSpecException(fakeError)).toBe(true);
expect(jasmineUnderTest.Spec.isPendingSpecException(fakeError)).toBe(true);
});
it("#isPendingSpecException returns true for a pending spec exception with a custom message", function() {
expect(j$.Spec.isPendingSpecException(j$.Spec.pendingSpecExceptionMessage + 'foo')).toBe(true);
expect(jasmineUnderTest.Spec.isPendingSpecException(jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'foo')).toBe(true);
});
it("#isPendingSpecException returns false for not a pending spec exception", function() {
var e = new Error("foo");
expect(j$.Spec.isPendingSpecException(e)).toBe(false);
expect(jasmineUnderTest.Spec.isPendingSpecException(e)).toBe(false);
});
it("#isPendingSpecException returns false for thrown values that don't have toString", function() {
expect(j$.Spec.isPendingSpecException(void 0)).toBe(false);
expect(jasmineUnderTest.Spec.isPendingSpecException(void 0)).toBe(false);
});
it("delegates execution to a QueueRunner", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
description: 'my test',
id: 'some-id',
queueableFn: { fn: function() {} },
@@ -45,7 +45,7 @@ describe("Spec", function() {
it("should call the start callback on execution", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = jasmine.createSpy('startCallback'),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
id: 123,
description: 'foo bar',
queueableFn: { fn: function() {} },
@@ -55,6 +55,7 @@ describe("Spec", function() {
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
// TODO: due to some issue with the Pretty Printer, this line fails, but the other two pass.
// This means toHaveBeenCalledWith on IE8 will always be broken.
@@ -69,7 +70,7 @@ describe("Spec", function() {
startCallback = jasmine.createSpy('start-callback').and.callFake(function() {
expect(beforesWereCalled).toBe(false);
}),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
beforeFns: function() {
return [function() {
@@ -82,6 +83,7 @@ describe("Spec", function() {
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled();
});
@@ -93,7 +95,7 @@ describe("Spec", function() {
expect(before).toHaveBeenCalled();
expect(after).not.toHaveBeenCalled();
}) },
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
queueableFn: queueableFn,
beforeAndAfterFns: function() {
return {befores: [before], afters: [after]}
@@ -103,8 +105,26 @@ describe("Spec", function() {
spec.execute();
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
expect(allSpecFns).toEqual([before, queueableFn, after]);
var options = fakeQueueRunner.calls.mostRecent().args[0];
expect(options.queueableFns).toEqual([{fn: jasmine.any(Function)}, before, queueableFn]);
expect(options.cleanupFns).toEqual([after, {fn: jasmine.any(Function)}]);
});
it("tells the queue runner that it's a leaf node", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
beforeAndAfterFns: function() {
return {befores: [], afters: []}
},
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
expect(fakeQueueRunner).toHaveBeenCalledWith(jasmine.objectContaining({
isLeaf: true
}));
});
it("is marked pending if created without a function body", function() {
@@ -112,7 +132,7 @@ describe("Spec", function() {
startCallback = jasmine.createSpy('startCallback'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
onStart: startCallback,
queueableFn: { fn: null },
resultCallback: resultCallback,
@@ -122,59 +142,41 @@ describe("Spec", function() {
expect(spec.status()).toBe('pending');
});
it("can be disabled, but still calls callbacks", function() {
it("can be excluded at execution time by a parent", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = jasmine.createSpy('startCallback'),
specBody = jasmine.createSpy('specBody'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
onStart:startCallback,
queueableFn: { fn: specBody },
resultCallback: resultCallback,
queueRunnerFactory: fakeQueueRunner
});
spec.disable();
spec.execute('cally-back', true);
expect(spec.status()).toBe('disabled');
spec.execute();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(fakeQueueRunner).toHaveBeenCalledWith(jasmine.objectContaining({
onComplete: jasmine.any(Function),
queueableFns: [{fn: jasmine.any(Function)}],
cleanupFns: [{fn: jasmine.any(Function)}]
}));
expect(specBody).not.toHaveBeenCalled();
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled();
args.cleanupFns[0].fn();
expect(resultCallback).toHaveBeenCalled();
});
it("can be disabled at execution time by a parent", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = jasmine.createSpy('startCallback'),
specBody = jasmine.createSpy('specBody'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
onStart:startCallback,
queueableFn: { fn: specBody },
resultCallback: resultCallback,
queueRunnerFactory: fakeQueueRunner
});
spec.execute(undefined, false);
expect(spec.result.status).toBe('disabled');
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(startCallback).toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalled();
expect(spec.result.status).toBe('excluded');
});
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({
spec = new jasmineUnderTest.Spec({
onStart: startCallback,
resultCallback: resultCallback,
description: "with a spec",
@@ -191,9 +193,12 @@ describe("Spec", function() {
spec.execute();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(fakeQueueRunner).toHaveBeenCalled();
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled();
args.cleanupFns[0].fn('things');
expect(resultCallback).toHaveBeenCalledWith({
id: spec.id,
status: 'pending',
@@ -201,13 +206,14 @@ describe("Spec", function() {
fullName: 'a suite with a spec',
failedExpectations: [],
passedExpectations: [],
deprecationWarnings: [],
pendingReason: ''
});
}, 'things');
});
it("should call the done callback on execution complete", function() {
var done = jasmine.createSpy('done callback'),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
catchExceptions: function() { return false; },
resultCallback: function() {},
@@ -219,30 +225,48 @@ describe("Spec", function() {
expect(done).toHaveBeenCalled();
});
it("should call the done callback with an error if the spec is failed", function() {
var done = jasmine.createSpy('done callback'),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
catchExceptions: function() { return false; },
resultCallback: function() {},
queueRunnerFactory: function(attrs) {
spec.result.status = 'failed';
attrs.onComplete();
}
});
spec.execute(done);
expect(done).toHaveBeenCalledWith(jasmine.any(jasmineUnderTest.StopExecutionError));
});
it("#status returns passing by default", function() {
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
expect(spec.status()).toBe('passed');
});
it("#status returns passed if all expectations in the spec have passed", function() {
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
spec.addExpectationResult(true);
expect(spec.status()).toBe('passed');
});
it("#status returns failed if any expectations in the spec have failed", function() {
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body") } });
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body") } });
spec.addExpectationResult(true);
spec.addExpectationResult(false);
expect(spec.status()).toBe('failed');
});
it("keeps track of passed and failed expectations", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: jasmine.createSpy("spec body") },
expectationResultFactory: function (data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
queueRunnerFactory: fakeQueueRunner,
resultCallback: resultCallback
});
spec.addExpectationResult(true, 'expectation1');
@@ -250,34 +274,37 @@ describe("Spec", function() {
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['expectation1']);
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['expectation2']);
});
it("throws an ExpectationFailed error upon receiving a failed expectation when 'throwOnExpectationFailure' is set", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
resultCallback: resultCallback,
throwOnExpectationFailure: true
});
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: fakeQueueRunner,
resultCallback: resultCallback,
throwOnExpectationFailure: true
});
spec.addExpectationResult(true, 'passed');
expect(function() {
spec.addExpectationResult(false, 'failed')
}).toThrowError(j$.errors.ExpectationFailed);
}).toThrowError(jasmineUnderTest.errors.ExpectationFailed);
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['passed']);
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['failed']);
});
it("does not throw an ExpectationFailed error when handling an error", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
@@ -291,7 +318,7 @@ describe("Spec", function() {
it("can return its full name", function() {
var specNameSpy = jasmine.createSpy('specNameSpy').and.returnValue('expected val');
var spec = new j$.Spec({
var spec = new jasmineUnderTest.Spec({
getSpecName: specNameSpy,
queueableFn: { fn: null }
});
@@ -303,9 +330,9 @@ describe("Spec", function() {
describe("when a spec is marked pending during execution", function() {
it("should mark the spec as pending", function() {
var fakeQueueRunner = function(opts) {
opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage));
opts.onException(new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage));
},
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
description: 'my test',
id: 'some-id',
queueableFn: { fn: function() { } },
@@ -320,9 +347,9 @@ describe("Spec", function() {
it("should set the pendingReason", function() {
var fakeQueueRunner = function(opts) {
opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage + 'custom message'));
opts.onException(new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'custom message'));
},
spec = new j$.Spec({
spec = new jasmineUnderTest.Spec({
description: 'my test',
id: 'some-id',
queueableFn: { fn: function() { } },
@@ -337,17 +364,20 @@ describe("Spec", function() {
});
it("should log a failure when handling an exception", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
queueRunnerFactory: fakeQueueRunner,
resultCallback: resultCallback
});
spec.onException('foo');
spec.execute();
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.cleanupFns[0].fn();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([{
error: 'foo',
matcherName: '',
@@ -358,63 +388,20 @@ describe("Spec", function() {
});
it("should not log an additional failure when handling an ExpectationFailed error", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
queueRunnerFactory: fakeQueueRunner,
resultCallback: resultCallback
});
spec.onException(new j$.errors.ExpectationFailed());
spec.onException(new jasmineUnderTest.errors.ExpectationFailed());
spec.execute();
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.cleanupFns[0].fn();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
});
it("retrieves a result with updated status", function() {
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
expect(spec.getResult().status).toBe('passed');
});
it("retrives a result with disabled status", function() {
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
spec.disable();
expect(spec.getResult().status).toBe('disabled');
});
it("retrives a result with pending status", function() {
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
spec.pend();
expect(spec.getResult().status).toBe('pending');
});
it("should not be executable when disabled", function() {
var spec = new j$.Spec({
queueableFn: { fn: function() {} }
});
spec.disable();
expect(spec.isExecutable()).toBe(false);
});
it("should be executable when pending", function() {
var spec = new j$.Spec({
queueableFn: { fn: function() {} }
});
spec.pend();
expect(spec.isExecutable()).toBe(true);
});
it("should be executable when not disabled or pending", function() {
var spec = new j$.Spec({
queueableFn: { fn: function() {} }
});
expect(spec.isExecutable()).toBe(true);
});
});

View File

@@ -1,14 +1,18 @@
describe("SpyRegistry", function() {
function createSpy(name, originalFn) {
return jasmineUnderTest.Spy(name, originalFn);
}
describe("#spyOn", function() {
it("checks for the existence of the object", function() {
var spyRegistry = new j$.SpyRegistry();
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy});
expect(function() {
spyRegistry.spyOn(void 0, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks that a method name was passed", function() {
var spyRegistry = new j$.SpyRegistry(),
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
subject = {};
expect(function() {
@@ -16,8 +20,24 @@ describe("SpyRegistry", function() {
}).toThrowError(/No method name supplied/);
});
it("checks that the object is not `null`", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry();
expect(function() {
spyRegistry.spyOn(null, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks that the method name is not `null`", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
subject = {};
expect(function() {
spyRegistry.spyOn(subject, null);
}).toThrowError(/No method name supplied/);
});
it("checks for the existence of the method", function() {
var spyRegistry = new j$.SpyRegistry(),
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
subject = {};
expect(function() {
@@ -27,7 +47,10 @@ describe("SpyRegistry", function() {
it("checks if it has already been spied upon", function() {
var spies = [],
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
subject = { spiedFunc: function() {} };
spyRegistry.spyOn(subject, 'spiedFunc');
@@ -37,9 +60,35 @@ describe("SpyRegistry", function() {
}).toThrowError(/has already been spied upon/);
});
it("checks if it can be spied upon", function() {
var scope = {};
function myFunc() {
return 1;
}
Object.defineProperty(scope, 'myFunc', {
get: function() {
return myFunc;
}
});
var spies = [],
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
subject = { spiedFunc: scope.myFunc };
expect(function() {
spyRegistry.spyOn(scope, 'myFunc');
}).toThrowError(/is not declared writable or has no setter/);
expect(function() {
spyRegistry.spyOn(subject, 'spiedFunc');
}).not.toThrowError(/is not declared writable or has no setter/);
});
it("overrides the method on the object and returns the spy", function() {
var originalFunctionWasCalled = false,
spyRegistry = new j$.SpyRegistry(),
spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
@@ -48,10 +97,130 @@ describe("SpyRegistry", function() {
});
});
describe("#spyOnProperty", function() {
it("checks for the existence of the object", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry();
expect(function() {
spyRegistry.spyOnProperty(void 0, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks that a property name was passed", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
subject = {};
expect(function() {
spyRegistry.spyOnProperty(subject);
}).toThrowError(/No property name supplied/);
});
it("checks for the existence of the method", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
subject = {};
expect(function() {
spyRegistry.spyOnProperty(subject, 'pants');
}).toThrowError(/property does not exist/);
});
it("checks for the existence of access type", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
subject = {};
Object.defineProperty(subject, 'pants', {
get: function() { return 1; },
configurable: true
});
expect(function() {
spyRegistry.spyOnProperty(subject, 'pants', 'set');
}).toThrowError(/does not have access type/);
});
it("checks if it has already been spied upon", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
subject = {};
Object.defineProperty(subject, 'spiedProp', {
get: function() { return 1; },
configurable: true
});
spyRegistry.spyOnProperty(subject, 'spiedProp');
expect(function() {
spyRegistry.spyOnProperty(subject, 'spiedProp');
}).toThrowError(/has already been spied upon/);
});
it("checks if it can be spied upon", function() {
var subject = {};
Object.defineProperty(subject, 'myProp', {
get: function() {}
});
Object.defineProperty(subject, 'spiedProp', {
get: function() {},
configurable: true
});
var spyRegistry = new jasmineUnderTest.SpyRegistry();
expect(function() {
spyRegistry.spyOnProperty(subject, 'myProp');
}).toThrowError(/is not declared configurable/);
expect(function() {
spyRegistry.spyOnProperty(subject, 'spiedProp');
}).not.toThrowError(/is not declared configurable/);
});
it("overrides the property getter on the object and returns the spy", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
subject = {},
returnValue = 1;
Object.defineProperty(subject, 'spiedProperty', {
get: function() { return returnValue; },
configurable: true
});
expect(subject.spiedProperty).toEqual(returnValue);
var spy = spyRegistry.spyOnProperty(subject, 'spiedProperty');
var getter = Object.getOwnPropertyDescriptor(subject, 'spiedProperty').get;
expect(getter).toEqual(spy);
expect(subject.spiedProperty).toBeUndefined();
});
it("overrides the property setter on the object and returns the spy", function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: createSpy}),
subject = {},
returnValue = 1;
Object.defineProperty(subject, 'spiedProperty', {
get: function() { return returnValue; },
set: function() {},
configurable: true
});
var spy = spyRegistry.spyOnProperty(subject, 'spiedProperty', 'set');
var setter = Object.getOwnPropertyDescriptor(subject, 'spiedProperty').set;
expect(subject.spiedProperty).toEqual(returnValue);
expect(setter).toEqual(spy);
});
});
describe("#clearSpies", function() {
it("restores the original functions on the spied-upon objects", function() {
var spies = [],
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
originalFunction = function() {},
subject = { spiedFunc: originalFunction };
@@ -60,5 +229,136 @@ describe("SpyRegistry", function() {
expect(subject.spiedFunc).toBe(originalFunction);
});
it("restores the original functions, even when that spy has been replace and re-spied upon", function() {
var spies = [],
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
originalFunction = function() {},
subject = { spiedFunc: originalFunction };
spyRegistry.spyOn(subject, 'spiedFunc');
// replace the original spy with some other function
subject.spiedFunc = function() {};
// spy on the function in that location again
spyRegistry.spyOn(subject, 'spiedFunc');
spyRegistry.clearSpies();
expect(subject.spiedFunc).toBe(originalFunction);
});
it("does not add a property that the spied-upon object didn't originally have", function() {
var spies = [],
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
originalFunction = function() {},
subjectParent = {spiedFunc: originalFunction};
var subject = Object.create(subjectParent);
expect(subject.hasOwnProperty('spiedFunc')).toBe(false);
spyRegistry.spyOn(subject, 'spiedFunc');
spyRegistry.clearSpies();
expect(subject.hasOwnProperty('spiedFunc')).toBe(false);
expect(subject.spiedFunc).toBe(originalFunction);
});
it("restores the original function when it\'s inherited and cannot be deleted", function() {
var spies = [],
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
originalFunction = function() {},
subjectParent = {spiedFunc: originalFunction};
var subject = Object.create(subjectParent);
spyRegistry.spyOn(subject, 'spiedFunc');
// simulate a spy that cannot be deleted
Object.defineProperty(subject, 'spiedFunc', {
configurable: false
});
spyRegistry.clearSpies();
expect(jasmineUnderTest.isSpy(subject.spiedFunc)).toBe(false);
});
it("restores window.onerror by overwriting, not deleting", function() {
function FakeWindow() {
}
FakeWindow.prototype.onerror = function() {};
var spies = [],
global = new FakeWindow(),
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy,
global: global
});
spyRegistry.spyOn(global, 'onerror');
spyRegistry.clearSpies();
expect(global.onerror).toBe(FakeWindow.prototype.onerror);
expect(global.hasOwnProperty('onerror')).toBe(true);
});
});
describe('spying on properties', function() {
it("restores the original properties on the spied-upon objects", function() {
var spies = [],
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
originalReturn = 1,
subject = {};
Object.defineProperty(subject, 'spiedProp', {
get: function() { return originalReturn; },
configurable: true
});
spyRegistry.spyOnProperty(subject, 'spiedProp');
spyRegistry.clearSpies();
expect(subject.spiedProp).toBe(originalReturn);
});
it("does not add a property that the spied-upon object didn't originally have", function() {
var spies = [],
spyRegistry = new jasmineUnderTest.SpyRegistry({
currentSpies: function() { return spies; },
createSpy: createSpy
}),
originalReturn = 1,
subjectParent = {};
Object.defineProperty(subjectParent, 'spiedProp', {
get: function() { return originalReturn; },
configurable: true
});
var subject = Object.create(subjectParent);
expect(subject.hasOwnProperty('spiedProp')).toBe(false);
spyRegistry.spyOnProperty(subject, 'spiedProp');
spyRegistry.clearSpies();
expect(subject.hasOwnProperty('spiedProp')).toBe(false);
expect(subject.spiedProp).toBe(originalReturn);
});
});
});

View File

@@ -1,4 +1,10 @@
describe('Spies', function () {
var env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
});
describe("createSpy", function() {
var TestClass;
@@ -9,7 +15,7 @@ describe('Spies', function () {
});
it("preserves the properties of the spied function", function() {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
expect(spy.bob).toEqual("test");
});
@@ -18,19 +24,19 @@ describe('Spies', function () {
TestClass.prototype.someFunction.and = "turkey";
expect(function() {
j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
}).toThrowError("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon");
});
it("adds a spyStrategy and callTracker to the spy", function() {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
expect(spy.and).toEqual(jasmine.any(j$.SpyStrategy));
expect(spy.calls).toEqual(jasmine.any(j$.CallTracker));
expect(spy.and).toEqual(jasmine.any(jasmineUnderTest.SpyStrategy));
expect(spy.calls).toEqual(jasmine.any(jasmineUnderTest.CallTracker));
});
it("tracks the argument of calls", function () {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var trackSpy = spyOn(spy.calls, "track");
spy("arg");
@@ -39,7 +45,7 @@ describe('Spies', function () {
});
it("tracks the context of calls", function () {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var trackSpy = spyOn(spy.calls, "track");
var contextObject = { spyMethod: spy };
@@ -49,7 +55,7 @@ describe('Spies', function () {
});
it("tracks the return value of calls", function () {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var spy = env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var trackSpy = spyOn(spy.calls, "track");
spy.and.returnValue("return value");
@@ -57,29 +63,115 @@ describe('Spies', function () {
expect(trackSpy.calls.mostRecent().args[0].returnValue).toEqual("return value");
});
it("preserves arity of original function", function () {
var functions = [
function nullary () {},
function unary (arg) {},
function binary (arg1, arg2) {},
function ternary (arg1, arg2, arg3) {},
function quaternary (arg1, arg2, arg3, arg4) {},
function quinary (arg1, arg2, arg3, arg4, arg5) {},
function senary (arg1, arg2, arg3, arg4, arg5, arg6) {}
];
for (var arity = 0; arity < functions.length; arity++) {
var someFunction = functions[arity],
spy = env.createSpy(someFunction.name, someFunction);
expect(spy.length).toEqual(arity);
}
});
});
describe("createSpyObj", function() {
it("should create an object with spy methods and corresponding return values when you call jasmine.createSpyObj() with an object", function () {
var spyObj = env.createSpyObj('BaseName', {'method1': 42, 'method2': 'special sauce' });
expect(spyObj.method1()).toEqual(42);
expect(spyObj.method1.and.identity).toEqual('BaseName.method1');
expect(spyObj.method2()).toEqual('special sauce');
expect(spyObj.method2.and.identity).toEqual('BaseName.method2');
});
it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
var spyObj = j$.createSpyObj('BaseName', ['method1', 'method2']);
var spyObj = env.createSpyObj('BaseName', ['method1', 'method2']);
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
expect(spyObj.method1.and.identity()).toEqual('BaseName.method1');
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
expect(spyObj.method1.and.identity).toEqual('BaseName.method1');
expect(spyObj.method2.and.identity).toEqual('BaseName.method2');
});
it("should allow you to omit the baseName", function() {
var spyObj = j$.createSpyObj(['method1', 'method2']);
var spyObj = env.createSpyObj(['method1', 'method2']);
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
expect(spyObj.method1.and.identity()).toEqual('unknown.method1');
expect(spyObj.method2.and.identity()).toEqual('unknown.method2');
expect(spyObj.method1.and.identity).toEqual('unknown.method1');
expect(spyObj.method2.and.identity).toEqual('unknown.method2');
});
it("should throw if you do not pass an array argument", function() {
it("should throw if you do not pass an array or object argument", function() {
expect(function() {
j$.createSpyObj('BaseName');
}).toThrow("createSpyObj requires a non-empty array of method names to create spies for");
env.createSpyObj('BaseName');
}).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
});
it("should throw if you pass an empty array argument", function() {
expect(function() {
env.createSpyObj('BaseName', []);
}).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
});
it("should throw if you pass an empty object argument", function() {
expect(function() {
env.createSpyObj('BaseName', {});
}).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
});
});
it("can use different strategies for different arguments", function() {
var spy = env.createSpy('foo');
spy.and.returnValue(42);
spy.withArgs('baz', 'grault').and.returnValue(-1);
spy.withArgs('thud').and.returnValue('bob');
expect(spy('foo')).toEqual(42);
expect(spy('baz', 'grault')).toEqual(-1);
expect(spy('thud')).toEqual('bob');
expect(spy('baz', 'grault', 'waldo')).toEqual(42);
});
it("uses custom equality testers when selecting a strategy", function() {
var spy = env.createSpy('foo');
spy.and.returnValue(42);
spy.withArgs(jasmineUnderTest.any(String)).and.returnValue(-1);
expect(spy('foo')).toEqual(-1);
expect(spy({})).toEqual(42);
});
it("can reconfigure an argument-specific strategy", function() {
var spy = env.createSpy('foo');
spy.withArgs('foo').and.returnValue(42);
spy.withArgs('foo').and.returnValue(17);
expect(spy('foo')).toEqual(17);
});
describe("When withArgs is used without a base strategy", function() {
it("uses the matching strategy", function() {
var spy = env.createSpy('foo');
spy.withArgs('baz').and.returnValue(-1);
expect(spy('baz')).toEqual(-1);
});
it("throws if the args don't match", function() {
var spy = env.createSpy('foo');
spy.withArgs('bar').and.returnValue(-1);
expect(function() { spy('baz', {qux: 42}); }).toThrowError('Spy \'foo\' receieved a call with arguments [ \'baz\', Object({ qux: 42 }) ] but all configured strategies specify other arguments.');
});
});
});

View File

@@ -1,20 +1,20 @@
describe("SpyStrategy", function() {
it("defaults its name to unknown", function() {
var spyStrategy = new j$.SpyStrategy();
var spyStrategy = new jasmineUnderTest.SpyStrategy();
expect(spyStrategy.identity()).toEqual("unknown");
expect(spyStrategy.identity).toEqual("unknown");
});
it("takes a name", function() {
var spyStrategy = new j$.SpyStrategy({name: "foo"});
var spyStrategy = new jasmineUnderTest.SpyStrategy({name: "foo"});
expect(spyStrategy.identity()).toEqual("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 = new jasmineUnderTest.SpyStrategy({fn: originalFn});
spyStrategy.exec();
@@ -23,11 +23,11 @@ describe("SpyStrategy", function() {
it("allows an original function to be called, passed through the params and returns it's value", function() {
var originalFn = jasmine.createSpy("original").and.returnValue(42),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
returnValue;
spyStrategy.callThrough();
returnValue = spyStrategy.exec("foo");
returnValue = spyStrategy.exec(null, ["foo"]);
expect(originalFn).toHaveBeenCalled();
expect(originalFn.calls.mostRecent().args).toEqual(["foo"]);
@@ -36,7 +36,7 @@ describe("SpyStrategy", function() {
it("can return a specified value when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
returnValue;
spyStrategy.returnValue(17);
@@ -48,7 +48,7 @@ describe("SpyStrategy", function() {
it("can return specified values in order specified when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn});
spyStrategy.returnValues('value1', 'value2', 'value3');
@@ -61,7 +61,7 @@ describe("SpyStrategy", function() {
it("allows an exception to be thrown when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn});
spyStrategy.throwError(new TypeError("bar"));
@@ -71,7 +71,7 @@ describe("SpyStrategy", function() {
it("allows a non-Error to be thrown, wrapping it into an exception when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn});
spyStrategy.throwError("bar");
@@ -82,7 +82,7 @@ describe("SpyStrategy", function() {
it("allows a fake function to be called instead", function() {
var originalFn = jasmine.createSpy("original"),
fakeFn = jasmine.createSpy("fake").and.returnValue(67),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
returnValue;
spyStrategy.callFake(fakeFn);
@@ -92,10 +92,88 @@ describe("SpyStrategy", function() {
expect(returnValue).toEqual(67);
});
it("allows a fake async function to be called instead", function(done) {
jasmine.getEnv().requireAsyncAwait();
var originalFn = jasmine.createSpy("original"),
fakeFn = jasmine.createSpy("fake").and.callFake(eval("async () => { return 67; }")),
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
returnValue;
spyStrategy.callFake(fakeFn);
spyStrategy.exec().then(function (returnValue) {
expect(originalFn).not.toHaveBeenCalled();
expect(fakeFn).toHaveBeenCalled();
expect(returnValue).toEqual(67);
done();
}).catch(function (err) {
done.fail(err);
})
});
it("allows a custom strategy to be used", function() {
var plan = jasmine.createSpy('custom strategy')
.and.returnValue('custom strategy result'),
customStrategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan),
originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
customStrategies: {
doSomething: customStrategy
}
});
spyStrategy.doSomething(1, 2, 3);
expect(customStrategy).toHaveBeenCalledWith(1, 2, 3);
expect(spyStrategy.exec(null, ['some', 'args']))
.toEqual('custom strategy result');
expect(plan).toHaveBeenCalledWith('some', 'args');
});
it("throws an error if a custom strategy doesn't return a function", function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
customStrategies: {
doSomething: function() { return 'not a function' }
}
});
expect(function() { spyStrategy.doSomething(1, 2, 3) }).toThrowError('Spy strategy must return a function');
});
it("does not allow custom strategies to overwrite existing methods", function() {
var spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: function() {},
customStrategies: {
exec: function() {}
}
});
expect(spyStrategy.exec).toBe(jasmineUnderTest.SpyStrategy.prototype.exec);
});
it('throws an error when a non-function is passed to callFake strategy', function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
invalidFakes = [5, 'foo', {}, true, false, null, void 0, new Date(), /.*/];
spyOn(jasmineUnderTest, 'isFunction_').and.returnValue(false);
spyOn(jasmineUnderTest, 'isAsyncFunction_').and.returnValue(false);
expect(function () {
spyStrategy.callFake(function() {});
}).toThrowError(/^Argument passed to callFake should be a function, got/);
expect(function () {
spyStrategy.callFake(function() {});
}).toThrowError(/^Argument passed to callFake should be a function, got/);
});
it("allows a return to plan stubbing after another strategy", function() {
var originalFn = jasmine.createSpy("original"),
fakeFn = jasmine.createSpy("fake").and.returnValue(67),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
returnValue;
spyStrategy.callFake(fakeFn);
@@ -103,7 +181,7 @@ describe("SpyStrategy", function() {
expect(originalFn).not.toHaveBeenCalled();
expect(returnValue).toEqual(67);
spyStrategy.stub();
returnValue = spyStrategy.exec();
@@ -113,12 +191,12 @@ describe("SpyStrategy", function() {
it("returns the spy after changing the strategy", function(){
var spy = {},
spyFn = jasmine.createSpy('spyFn').and.returnValue(spy),
spyStrategy = new j$.SpyStrategy({getSpy: spyFn});
spyStrategy = new jasmineUnderTest.SpyStrategy({getSpy: spyFn});
expect(spyStrategy.callThrough()).toBe(spy);
expect(spyStrategy.returnValue()).toBe(spy);
expect(spyStrategy.throwError()).toBe(spy);
expect(spyStrategy.callFake()).toBe(spy);
expect(spyStrategy.callFake(function() {})).toBe(spy);
expect(spyStrategy.stub()).toBe(spy);
});
});

166
spec/core/StackTraceSpec.js Normal file
View File

@@ -0,0 +1,166 @@
describe("StackTrace", function() {
it("understands Chrome/IE/Edge style traces", function() {
var raw =
'Error: nope\n' +
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.message).toEqual('Error: nope');
expect(result.style).toEqual('v8');
expect(result.frames).toEqual([
{
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
func: 'UserContext.<anonymous>',
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
line: 115
},
{
raw: ' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)',
func: 'QueueRunner.run',
file: 'http://localhost:8888/__jasmine__/jasmine.js',
line: 4320
}
]);
});
it("understands Node style traces", function() {
var raw = 'Error\n' +
' at /somewhere/jasmine/lib/jasmine-core/jasmine.js:4255:9\n' +
' at QueueRunner.complete [as onComplete] (/somewhere/jasmine/lib/jasmine-core/jasmine.js:579:9)\n' +
' at Immediate.<anonymous> (/somewhere/jasmine/lib/jasmine-core/jasmine.js:4314:12)\n' +
' at runCallback (timers.js:672:20)';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.message).toEqual('Error');
expect(result.style).toEqual('v8');
expect(result.frames).toEqual([
{
raw: ' at /somewhere/jasmine/lib/jasmine-core/jasmine.js:4255:9',
func: undefined,
file: '/somewhere/jasmine/lib/jasmine-core/jasmine.js',
line: 4255
},
{
raw: ' at QueueRunner.complete [as onComplete] (/somewhere/jasmine/lib/jasmine-core/jasmine.js:579:9)',
func: 'QueueRunner.complete [as onComplete]',
file: '/somewhere/jasmine/lib/jasmine-core/jasmine.js',
line: 579
},
{
raw: ' at Immediate.<anonymous> (/somewhere/jasmine/lib/jasmine-core/jasmine.js:4314:12)',
func: 'Immediate.<anonymous>',
file: '/somewhere/jasmine/lib/jasmine-core/jasmine.js',
line: 4314
},
{
raw: ' at runCallback (timers.js:672:20)',
func: 'runCallback',
file: 'timers.js',
line: 672
}
]);
});
it("understands Safari/Firefox/Phantom-OS X style traces", function() {
var raw =
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
'run@http://localhost:8888/__jasmine__/jasmine.js:4320:27';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.message).toBeFalsy();
expect(result.style).toEqual('webkit');
expect(result.frames).toEqual([
{
raw: 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28',
func: undefined,
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
line: 115
},
{
raw: 'run@http://localhost:8888/__jasmine__/jasmine.js:4320:27',
func: 'run',
file: 'http://localhost:8888/__jasmine__/jasmine.js',
line: 4320
}
]);
});
it("does not mistake gibberish for Safari/Firefox/Phantom-OS X style traces", function() {
var raw = 'randomcharsnotincludingwhitespace';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.style).toBeNull();
expect(result.frames).toEqual([
{ raw: raw }
]);
});
it("understands Phantom-Linux style traces", function() {
var raw =
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.message).toBeFalsy();
expect(result.style).toEqual('v8');
expect(result.frames).toEqual([
{
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
func: 'UserContext.<anonymous>',
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
line: 115
},
{
raw: ' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)',
func: 'QueueRunner.run',
file: 'http://localhost:8888/__jasmine__/jasmine.js',
line: 4320
}
]);
});
it("ignores blank lines", function() {
var raw =
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.frames).toEqual([
{
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
func: 'UserContext.<anonymous>',
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
line: 115
}
]);
});
it("omits properties except 'raw' for frames that are not understood", function() {
var raw =
' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' but this is quite unexpected\n' +
' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)';
var result = new jasmineUnderTest.StackTrace(raw);
expect(result.style).toEqual('v8');
expect(result.frames).toEqual([
{
raw: ' at UserContext.<anonymous> (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)',
func: 'UserContext.<anonymous>',
file: 'http://localhost:8888/__spec__/core/UtilSpec.js',
line: 115
},
{
raw: ' but this is quite unexpected'
},
{
raw: ' at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)',
func: 'QueueRunner.run',
file: 'http://localhost:8888/__jasmine__/jasmine.js',
line: 4320
}
]);
});
});

View File

@@ -1,8 +1,8 @@
describe("Suite", function() {
it("keeps its id", function() {
var env = new j$.Env(),
suite = new j$.Suite({
var env = new jasmineUnderTest.Env(),
suite = new jasmineUnderTest.Suite({
env: env,
id: 456,
description: "I am a suite"
@@ -11,24 +11,24 @@ describe("Suite", function() {
expect(suite.id).toEqual(456);
});
it("returns its full name", function() {
var env = new j$.Env(),
suite = new j$.Suite({
it("returns blank full name for top level suite", function() {
var env = new jasmineUnderTest.Env(),
suite = new jasmineUnderTest.Suite({
env: env,
description: "I am a suite"
});
expect(suite.getFullName()).toEqual("I am a suite");
expect(suite.getFullName()).toEqual("");
});
it("returns its full name when it has parent suites", function() {
var env = new j$.Env(),
parentSuite = new j$.Suite({
var env = new jasmineUnderTest.Env(),
parentSuite = new jasmineUnderTest.Suite({
env: env,
description: "I am a parent suite",
parentSuite: jasmine.createSpy('pretend top level suite')
}),
suite = new j$.Suite({
suite = new jasmineUnderTest.Suite({
env: env,
description: "I am a suite",
parentSuite: parentSuite
@@ -38,8 +38,8 @@ describe("Suite", function() {
});
it("adds before functions in order of needed execution", function() {
var env = new j$.Env(),
suite = new j$.Suite({
var env = new jasmineUnderTest.Env(),
suite = new jasmineUnderTest.Suite({
env: env,
description: "I am a suite"
}),
@@ -53,8 +53,8 @@ describe("Suite", function() {
});
it("adds after functions in order of needed execution", function() {
var env = new j$.Env(),
suite = new j$.Suite({
var env = new jasmineUnderTest.Env(),
suite = new jasmineUnderTest.Suite({
env: env,
description: "I am a suite"
}),
@@ -67,79 +67,57 @@ describe("Suite", function() {
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
});
it('has a status of failed if any afterAll expectations have failed', function() {
var suite = new j$.Suite({
it('has a status of failed if any expectations have failed', function() {
var suite = new jasmineUnderTest.Suite({
expectationResultFactory: function() { return 'hi'; }
});
suite.addChild({ result: { status: 'done' } });
suite.addExpectationResult(false);
expect(suite.status()).toBe('failed');
});
it("retrieves a result with updated status", function() {
var suite = new j$.Suite({});
var suite = new jasmineUnderTest.Suite({});
expect(suite.getResult().status).toBe('finished');
expect(suite.getResult().status).toBe('passed');
});
it("retrieves a result with disabled status", function() {
var suite = new j$.Suite({});
suite.disable();
it("retrieves a result with pending status", function() {
var suite = new jasmineUnderTest.Suite({});
suite.pend();
expect(suite.getResult().status).toBe('disabled');
expect(suite.getResult().status).toBe('pending');
});
it("is executable if not disabled", function() {
var suite = new j$.Suite({});
expect(suite.isExecutable()).toBe(true);
});
it("is not executable if disabled", function() {
var suite = new j$.Suite({});
suite.disable();
expect(suite.isExecutable()).toBe(false);
});
it("tells all children about expectation failures, even if one throws", function() {
var suite = new j$.Suite({}),
child1 = { addExpectationResult: jasmine.createSpy('child1#expectationResult'), result: {} },
child2 = { addExpectationResult: jasmine.createSpy('child2#expectationResult'), result: {} };
suite.addChild(child1);
suite.addChild(child2);
child1.addExpectationResult.and.throwError('foo');
suite.addExpectationResult('stuff');
expect(child1.addExpectationResult).toHaveBeenCalledWith('stuff');
expect(child2.addExpectationResult).toHaveBeenCalledWith('stuff');
});
it("throws an ExpectationFailed when receiving a failed expectation in an afterAll when throwOnExpectationFailure is set", function() {
var suite = new j$.Suite({
it("throws an ExpectationFailed when receiving a failed expectation when throwOnExpectationFailure is set", function() {
var suite = new jasmineUnderTest.Suite({
expectationResultFactory: function(data) { return data; },
throwOnExpectationFailure: true
});
suite.addChild({ result: { status: 'done' } });
expect(function() {
suite.addExpectationResult(false, 'failed');
}).toThrowError(j$.errors.ExpectationFailed);
}).toThrowError(jasmineUnderTest.errors.ExpectationFailed);
expect(suite.status()).toBe('failed');
expect(suite.result.failedExpectations).toEqual(['failed']);
});
it("does not add an additional failure when an expectation fails in an afterAll", function(){
var suite = new j$.Suite({});
suite.addChild({ result: { status: 'done' } });
it("does not add an additional failure when an expectation fails", function(){
var suite = new jasmineUnderTest.Suite({});
suite.onException(new j$.errors.ExpectationFailed());
suite.onException(new jasmineUnderTest.errors.ExpectationFailed());
expect(suite.getResult().failedExpectations).toEqual([]);
})
});
describe('#sharedUserContext', function() {
beforeEach(function() {
this.suite = new jasmineUnderTest.Suite({});
});
it('returns a UserContext', function() {
expect(this.suite.sharedUserContext().constructor).toBe(jasmineUnderTest.UserContext);
});
});
});

View File

@@ -1,7 +1,7 @@
describe("Timer", function() {
it("reports the time elapsed", function() {
var fakeNow = jasmine.createSpy('fake Date.now'),
timer = new j$.Timer({now: fakeNow});
timer = new jasmineUnderTest.Timer({now: fakeNow});
fakeNow.and.returnValue(100);
timer.start();
@@ -22,7 +22,7 @@ describe("Timer", function() {
});
it("does not throw even though Date was taken away", function() {
var timer = new j$.Timer();
var timer = new jasmineUnderTest.Timer();
expect(timer.start).not.toThrow();
expect(timer.elapsed()).toEqual(jasmine.any(Number));

View File

@@ -8,61 +8,79 @@ describe("TreeProcessor", function() {
this.canBeReentered = function() {
return !attrs.noReenter;
};
this.isExecutable = function() {
return attrs.executable !== false;
};
this.markedPending = attrs.markedPending || false;
this.sharedUserContext = function() {
return attrs.userContext || {};
};
this.getResult = jasmine.createSpy(this.id + '#execute');
this.beforeAllFns = attrs.beforeAllFns || [];
this.afterAllFns = attrs.afterAllFns || [];
this.cleanupBeforeAfter = function() { };
}
function Leaf(attrs) {
attrs = attrs || {};
this.id = 'leaf' + leafNumber++;
this.isExecutable = function() {
return attrs.executable !== false;
};
this.markedPending = attrs.markedPending || false;
this.execute = jasmine.createSpy(this.id + '#execute');
}
it("processes a single executable leaf", function() {
it("processes a single leaf", function() {
var leaf = new Leaf(),
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
executable: true,
excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
});
it("processes a single non-executable leaf", function() {
var leaf = new Leaf({ executable: false }),
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
it("processes a single pending leaf", function() {
var leaf = new Leaf({ markedPending: true }),
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
executable: false,
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
});
it("processes a single non-specified leaf", function() {
var leaf = new Leaf(),
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: leaf, runnableIds: [] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
executable: false,
excluded: true,
willExecute: false,
segments: jasmine.any(Array)
});
});
it("processes a single excluded leaf", function() {
var leaf = new Leaf(),
processor = new jasmineUnderTest.TreeProcessor({
tree: leaf,
runnableIds: [leaf.id],
excludeNode: function(node) { return true; }
}),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
excluded: true,
willExecute: false,
segments: jasmine.any(Array)
});
});
@@ -70,86 +88,104 @@ describe("TreeProcessor", function() {
it("processes a tree with a single leaf with the root specified", function() {
var leaf = new Leaf(),
parent = new Node({ children: [leaf] }),
processor = new j$.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[parent.id]).toEqual({
executable: true,
excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
expect(result[leaf.id]).toEqual({
executable: true,
excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
});
it("processes a tree with a single non-executable leaf, with the root specified", function() {
var leaf = new Leaf({ executable: false }),
it("processes a tree with a single pending leaf, with the root specified", function() {
var leaf = new Leaf({ markedPending: true }),
parent = new Node({ children: [leaf] }),
processor = new j$.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[parent.id]).toEqual({
executable: false,
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
expect(result[leaf.id]).toEqual({
executable: false,
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
});
it("processes a complicated tree with the root specified", function() {
var nonExecutable = new Leaf({ executable: false }),
executable = new Leaf({ executable: true }),
parent = new Node({ children: [nonExecutable, executable] }),
var pendingLeaf = new Leaf({ markedPending: true }),
executableLeaf = new Leaf({ markedPending: false }),
parent = new Node({ children: [pendingLeaf, executableLeaf] }),
childless = new Node(),
childOfDisabled = new Leaf({ executable: true }),
disabledNode = new Node({ executable: false, children: [childOfDisabled] }),
root = new Node({ children: [parent, childless, disabledNode] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [root.id] }),
childOfPending = new Leaf({ markedPending: true }),
pendingNode = new Node({ markedPending: true, children: [childOfPending] }),
parentOfPendings = new Node({ markedPending: false, children: [childless, pendingNode] }),
root = new Node({ children: [parent, parentOfPendings] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [root.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[root.id]).toEqual({
executable: true,
excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
expect(result[parentOfPendings.id]).toEqual({
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
expect(result[childless.id]).toEqual({
executable: false,
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
expect(result[nonExecutable.id]).toEqual({
executable: false,
expect(result[pendingLeaf.id]).toEqual({
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
expect(result[executable.id]).toEqual({
executable: true,
expect(result[executableLeaf.id]).toEqual({
excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
expect(result[parent.id]).toEqual({
executable: true,
excluded: false,
willExecute: true,
segments: jasmine.any(Array)
});
expect(result[disabledNode.id]).toEqual({
executable: false,
expect(result[pendingNode.id]).toEqual({
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
expect(result[childOfDisabled.id]).toEqual({
executable: false,
expect(result[childOfPending.id]).toEqual({
excluded: false,
willExecute: false,
segments: jasmine.any(Array)
});
});
@@ -160,7 +196,7 @@ describe("TreeProcessor", function() {
leaf3 = new Leaf(),
reentered = new Node({ noReenter: true, children: [leaf1, leaf2] }),
root = new Node({ children: [reentered, leaf3] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
result = processor.processTree();
expect(result).toEqual({ valid: false });
@@ -172,7 +208,7 @@ describe("TreeProcessor", function() {
leaf3 = new Leaf(),
reentered = new Node({ children: [leaf1, leaf2] }),
root = new Node({ children: [reentered, leaf3] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
@@ -184,7 +220,7 @@ describe("TreeProcessor", function() {
leaf3 = new Leaf(),
noReentry = new Node({ noReenter: true }),
root = new Node({ children: [noReentry] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf2.id, leaf1.id, leaf3.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [leaf2.id, leaf1.id, leaf3.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
@@ -194,7 +230,7 @@ describe("TreeProcessor", function() {
var leaf1 = new Leaf(),
noReentry = new Node({ noReenter: true }),
root = new Node({ children: [noReentry] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [root.id] }),
processor = new jasmineUnderTest.TreeProcessor({ tree: root, runnableIds: [root.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
@@ -202,9 +238,9 @@ describe("TreeProcessor", function() {
it("runs a single leaf", function() {
var leaf = new Leaf(),
node = new Node({ children: [leaf] }),
node = new Node({ children: [leaf], userContext: { root: 'context' } }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({ tree: node, runnableIds: [leaf.id], queueRunnerFactory: queueRunner }),
processor = new jasmineUnderTest.TreeProcessor({ tree: node, runnableIds: [leaf.id], queueRunnerFactory: queueRunner }),
treeComplete = jasmine.createSpy('treeComplete');
processor.execute(treeComplete);
@@ -212,21 +248,22 @@ describe("TreeProcessor", function() {
expect(queueRunner).toHaveBeenCalledWith({
onComplete: treeComplete,
onException: jasmine.any(Function),
userContext: { root: 'context' },
queueableFns: [{ fn: jasmine.any(Function) }]
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
expect(leaf.execute).toHaveBeenCalledWith('foo', true);
expect(leaf.execute).toHaveBeenCalledWith('foo', false);
});
it("runs a node with no children", function() {
var node = new Node({ userContext: { node: 'context' } }),
root = new Node({ children: [node] }),
root = new Node({ children: [node], userContext: { root: 'context' } }),
nodeStart = jasmine.createSpy('nodeStart'),
nodeComplete = jasmine.createSpy('nodeComplete'),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
nodeStart: nodeStart,
@@ -241,24 +278,26 @@ describe("TreeProcessor", function() {
expect(queueRunner).toHaveBeenCalledWith({
onComplete: treeComplete,
onException: jasmine.any(Function),
userContext: { root: 'context' },
queueableFns: [{ fn: jasmine.any(Function) }]
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn(nodeDone);
expect(nodeStart).toHaveBeenCalledWith(node);
expect(queueRunner).toHaveBeenCalledWith({
onComplete: jasmine.any(Function),
queueableFns: [],
queueableFns: [{ fn: jasmine.any(Function) }],
userContext: { node: 'context' },
onException: jasmine.any(Function)
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
expect(nodeStart).toHaveBeenCalledWith(node, 'foo');
node.getResult.and.returnValue({ my: 'result' });
queueRunner.calls.mostRecent().args[0].onComplete();
expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' });
expect(nodeDone).toHaveBeenCalled();
expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' }, nodeDone);
});
it("runs a node with children", function() {
@@ -267,7 +306,7 @@ describe("TreeProcessor", function() {
node = new Node({ children: [leaf1, leaf2] }),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
@@ -280,25 +319,25 @@ describe("TreeProcessor", function() {
queueableFns[0].fn(nodeDone);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(2);
expect(queueableFns.length).toBe(3);
queueableFns[0].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
queueableFns[1].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
queueableFns[1].fn('bar');
expect(leaf2.execute).toHaveBeenCalledWith('bar', true);
queueableFns[2].fn('bar');
expect(leaf2.execute).toHaveBeenCalledWith('bar', false);
});
it("runs a disabled node", function() {
it("runs an excluded node with leaf", function() {
var leaf1 = new Leaf(),
node = new Node({ children: [leaf1], executable: false }),
node = new Node({ children: [leaf1] }),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
nodeStart = jasmine.createSpy('nodeStart'),
nodeComplete = jasmine.createSpy('nodeComplete'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
runnableIds: [],
queueRunnerFactory: queueRunner,
nodeStart: nodeStart,
nodeComplete: nodeComplete
@@ -310,18 +349,19 @@ describe("TreeProcessor", function() {
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
expect(nodeStart).toHaveBeenCalledWith(node);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(1);
expect(queueableFns.length).toBe(2);
queueableFns[0].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
queueableFns[0].fn('bar');
expect(nodeStart).toHaveBeenCalledWith(node, 'bar');
queueableFns[1].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
node.getResult.and.returnValue({ im: 'disabled' });
queueRunner.calls.mostRecent().args[0].onComplete();
expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' });
expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' }, nodeDone);
});
it("runs beforeAlls for a node with children", function() {
@@ -332,7 +372,7 @@ describe("TreeProcessor", function() {
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
@@ -346,7 +386,7 @@ describe("TreeProcessor", function() {
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual(['beforeAll1', 'beforeAll2', { fn: jasmine.any(Function) }]);
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, 'beforeAll1', 'beforeAll2', { fn: jasmine.any(Function) }]);
});
it("runs afterAlls for a node with children", function() {
@@ -357,7 +397,7 @@ describe("TreeProcessor", function() {
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
@@ -371,7 +411,7 @@ describe("TreeProcessor", function() {
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, 'afterAll1', 'afterAll2']);
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) }, 'afterAll1', 'afterAll2']);
});
it("does not run beforeAlls or afterAlls for a node with no children", function() {
@@ -381,7 +421,7 @@ describe("TreeProcessor", function() {
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
@@ -395,20 +435,20 @@ describe("TreeProcessor", function() {
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual([]);
expect(queueableFns).toEqual([{fn: jasmine.any(Function)}]);
});
it("does not run beforeAlls or afterAlls for a disabled node", function() {
var leaf = new Leaf(),
it("does not run beforeAlls or afterAlls for a node with only pending children", function() {
var leaf = new Leaf({ markedPending: true }),
node = new Node({
children: [leaf],
beforeAllFns: ['before'],
afterAllFns: ['after'],
executable: false
markedPending: false
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
@@ -422,7 +462,7 @@ describe("TreeProcessor", function() {
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }]);
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) }]);
});
it("runs leaves in the order specified", function() {
@@ -430,7 +470,7 @@ describe("TreeProcessor", function() {
leaf2 = new Leaf(),
root = new Node({ children: [leaf1, leaf2] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [leaf2.id, leaf1.id],
queueRunnerFactory: queueRunner
@@ -449,12 +489,12 @@ describe("TreeProcessor", function() {
expect(leaf1.execute).toHaveBeenCalled();
});
it("runs specified leaves before non-specified leaves", function() {
it("runs specified leaves before non-specified leaves within a parent node", function() {
var specified = new Leaf(),
nonSpecified = new Leaf(),
root = new Node({ children: [nonSpecified, specified] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [specified.id],
queueRunnerFactory: queueRunner
@@ -466,11 +506,11 @@ describe("TreeProcessor", function() {
queueableFns[0].fn();
expect(nonSpecified.execute).not.toHaveBeenCalled();
expect(specified.execute).toHaveBeenCalledWith(undefined, true);
expect(specified.execute).toHaveBeenCalledWith(undefined, false);
queueableFns[1].fn();
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, false);
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, true);
});
it("runs nodes and leaves with a specified order", function() {
@@ -479,7 +519,7 @@ describe("TreeProcessor", function() {
specifiedNode = new Node({ children: [childLeaf] }),
root = new Node({ children: [specifiedLeaf, specifiedNode] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [specifiedNode.id, specifiedLeaf.id],
queueRunnerFactory: queueRunner
@@ -491,7 +531,7 @@ describe("TreeProcessor", function() {
expect(specifiedLeaf.execute).not.toHaveBeenCalled();
var nodeQueueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
nodeQueueableFns[0].fn();
nodeQueueableFns[1].fn();
expect(childLeaf.execute).toHaveBeenCalled();
@@ -509,7 +549,7 @@ describe("TreeProcessor", function() {
reentered = new Node({ children: [leaf1, leaf2, leaf3] }),
root = new Node({ children: [reentered, leaf4, leaf5] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [leaf1.id, leaf4.id, leaf2.id, leaf5.id, leaf3.id],
queueRunnerFactory: queueRunner
@@ -520,8 +560,8 @@ describe("TreeProcessor", function() {
expect(queueableFns.length).toBe(5);
queueableFns[0].fn();
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(leaf1.execute).toHaveBeenCalled();
queueableFns[1].fn();
@@ -529,8 +569,8 @@ describe("TreeProcessor", function() {
queueableFns[2].fn();
expect(queueRunner.calls.count()).toBe(3);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[3].fn();
@@ -538,8 +578,8 @@ describe("TreeProcessor", function() {
queueableFns[4].fn();
expect(queueRunner.calls.count()).toBe(4);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(leaf3.execute).toHaveBeenCalled();
});
@@ -553,7 +593,7 @@ describe("TreeProcessor", function() {
grandparent = new Node({ children: [parent] }),
root = new Node({ children: [grandparent, leaf4, leaf5] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [leaf1.id, leaf4.id, leaf2.id, leaf5.id, leaf3.id],
queueRunnerFactory: queueRunner
@@ -565,12 +605,12 @@ describe("TreeProcessor", function() {
queueableFns[0].fn();
expect(queueRunner.calls.count()).toBe(2);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(queueRunner.calls.count()).toBe(3);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(leaf1.execute).toHaveBeenCalled();
queueableFns[1].fn();
@@ -578,12 +618,12 @@ describe("TreeProcessor", function() {
queueableFns[2].fn();
expect(queueRunner.calls.count()).toBe(4);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(queueRunner.calls.count()).toBe(5);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[3].fn();
@@ -591,12 +631,12 @@ describe("TreeProcessor", function() {
queueableFns[4].fn();
expect(queueRunner.calls.count()).toBe(6);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(2);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(queueRunner.calls.count()).toBe(7);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
queueRunner.calls.mostRecent().args[0].queueableFns[1].fn();
expect(leaf3.execute).toHaveBeenCalled();
});
@@ -607,7 +647,7 @@ describe("TreeProcessor", function() {
parent = new Node({ children: [leaf2, leaf3] }),
root = new Node({ children: [leaf1, parent] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [root.id],
queueRunnerFactory: queueRunner
@@ -623,11 +663,132 @@ describe("TreeProcessor", function() {
queueableFns[1].fn();
var childFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(childFns.length).toBe(2);
childFns[0].fn();
expect(childFns.length).toBe(3);
childFns[1].fn();
expect(leaf2.execute).toHaveBeenCalled();
childFns[1].fn();
childFns[2].fn();
expect(leaf3.execute).toHaveBeenCalled();
});
it("runs large segments of nodes in the order they were declared", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
leaf4 = new Leaf(),
leaf5 = new Leaf(),
leaf6 = new Leaf(),
leaf7 = new Leaf(),
leaf8 = new Leaf(),
leaf9 = new Leaf(),
leaf10 = new Leaf(),
leaf11 = new Leaf(),
root = new Node({ children: [leaf1, leaf2, leaf3, leaf4, leaf5, leaf6, leaf7, leaf8, leaf9, leaf10, leaf11] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [root.id],
queueRunnerFactory: queueRunner
});
processor.execute();
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(11);
queueableFns[0].fn();
expect(leaf1.execute).toHaveBeenCalled();
queueableFns[1].fn();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[2].fn();
expect(leaf3.execute).toHaveBeenCalled();
queueableFns[3].fn();
expect(leaf4.execute).toHaveBeenCalled();
queueableFns[4].fn();
expect(leaf5.execute).toHaveBeenCalled();
queueableFns[5].fn();
expect(leaf6.execute).toHaveBeenCalled();
queueableFns[6].fn();
expect(leaf7.execute).toHaveBeenCalled();
queueableFns[7].fn();
expect(leaf8.execute).toHaveBeenCalled();
queueableFns[8].fn();
expect(leaf9.execute).toHaveBeenCalled();
queueableFns[9].fn();
expect(leaf10.execute).toHaveBeenCalled();
queueableFns[10].fn();
expect(leaf11.execute).toHaveBeenCalled();
});
it("runs nodes in a custom order when orderChildren is overridden", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
leaf4 = new Leaf(),
leaf5 = new Leaf(),
leaf6 = new Leaf(),
leaf7 = new Leaf(),
leaf8 = new Leaf(),
leaf9 = new Leaf(),
leaf10 = new Leaf(),
leaf11 = new Leaf(),
root = new Node({ children: [leaf1, leaf2, leaf3, leaf4, leaf5, leaf6, leaf7, leaf8, leaf9, leaf10, leaf11] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [root.id],
queueRunnerFactory: queueRunner,
orderChildren: function(node) {
var children = node.children.slice();
return children.reverse();
}
});
processor.execute();
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(11);
queueableFns[0].fn();
expect(leaf11.execute).toHaveBeenCalled();
queueableFns[1].fn();
expect(leaf10.execute).toHaveBeenCalled();
queueableFns[2].fn();
expect(leaf9.execute).toHaveBeenCalled();
queueableFns[3].fn();
expect(leaf8.execute).toHaveBeenCalled();
queueableFns[4].fn();
expect(leaf7.execute).toHaveBeenCalled();
queueableFns[5].fn();
expect(leaf6.execute).toHaveBeenCalled();
queueableFns[6].fn();
expect(leaf5.execute).toHaveBeenCalled();
queueableFns[7].fn();
expect(leaf4.execute).toHaveBeenCalled();
queueableFns[8].fn();
expect(leaf3.execute).toHaveBeenCalled();
queueableFns[9].fn();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[10].fn();
expect(leaf1.execute).toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,54 @@
describe("UserContext", function() {
it("Behaves just like an plain object", function() {
var context = new jasmineUnderTest.UserContext(),
properties = [];
for (var prop in context) {
if (obj.hasOwnProperty(prop)) {
properties.push(prop);
}
}
expect(properties).toEqual([]);
});
describe('.fromExisting', function() {
describe('when using an already built context as model', function() {
beforeEach(function() {
this.context = new jasmineUnderTest.UserContext();
this.context.key = 'value';
this.cloned = jasmineUnderTest.UserContext.fromExisting(this.context);
});
it('returns a cloned object', function() {
expect(this.cloned).toEqual(this.context);
});
it('does not return the same object', function() {
expect(this.cloned).not.toBe(this.context);
});
});
describe('when using a regular object as parameter', function() {
beforeEach(function() {
this.context = {};
this.value = 'value'
this.context.key = this.value;
this.cloned = jasmineUnderTest.UserContext.fromExisting(this.context);
});
it('returns an object with the same attributes', function() {
expect(this.cloned.key).toEqual(this.value);
});
it('does not return the same object', function() {
expect(this.cloned).not.toBe(this.context);
});
it('returns an UserContext', function() {
expect(this.cloned.constructor).toBe(jasmineUnderTest.UserContext);
});
});
});
});

View File

@@ -1,28 +1,105 @@
describe("j$.util", function() {
describe("jasmineUnderTest.util", function() {
describe("isArray_", function() {
it("should return true if the argument is an array", function() {
expect(j$.isArray_([])).toBe(true);
expect(j$.isArray_(['a'])).toBe(true);
expect(jasmineUnderTest.isArray_([])).toBe(true);
expect(jasmineUnderTest.isArray_(['a'])).toBe(true);
});
it("should return false if the argument is not an array", function() {
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);
expect(jasmineUnderTest.isArray_(undefined)).toBe(false);
expect(jasmineUnderTest.isArray_({})).toBe(false);
expect(jasmineUnderTest.isArray_(function() {})).toBe(false);
expect(jasmineUnderTest.isArray_('foo')).toBe(false);
expect(jasmineUnderTest.isArray_(5)).toBe(false);
expect(jasmineUnderTest.isArray_(null)).toBe(false);
});
});
describe("isObject_", function() {
it("should return true if the argument is an object", function() {
expect(jasmineUnderTest.isObject_({})).toBe(true);
expect(jasmineUnderTest.isObject_({an: "object"})).toBe(true);
});
it("should return false if the argument is not an object", function() {
expect(jasmineUnderTest.isObject_(undefined)).toBe(false);
expect(jasmineUnderTest.isObject_([])).toBe(false);
expect(jasmineUnderTest.isObject_(function() {})).toBe(false);
expect(jasmineUnderTest.isObject_('foo')).toBe(false);
expect(jasmineUnderTest.isObject_(5)).toBe(false);
expect(jasmineUnderTest.isObject_(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);
expect(jasmineUnderTest.util.isUndefined(a)).toBe(true);
expect(jasmineUnderTest.util.isUndefined(undefined)).toBe(true);
var undefined = "diz be undefined yo";
expect(j$.util.isUndefined(undefined)).toBe(false);
expect(jasmineUnderTest.util.isUndefined(undefined)).toBe(false);
});
});
describe("getPropertyDescriptor", function() {
it("get property descriptor from object", function() {
var obj = {prop: 1},
actual = jasmineUnderTest.util.getPropertyDescriptor(obj, 'prop'),
expected = Object.getOwnPropertyDescriptor(obj, 'prop');
expect(actual).toEqual(expected);
});
it("get property descriptor from object property", function() {
var proto = {prop: 1},
obj = Object.create(proto),
actual = jasmineUnderTest.util.getPropertyDescriptor(proto, 'prop'),
expected = Object.getOwnPropertyDescriptor(proto, 'prop');
expect(actual).toEqual(expected);
});
});
describe("objectDifference", function() {
it("given two objects A and B, returns the properties in A not present in B", function() {
var a = {
foo: 3,
bar: 4,
baz: 5
};
var b = {
bar: 6,
quux: 7
};
expect(jasmineUnderTest.util.objectDifference(a, b)).toEqual({foo: 3, baz: 5})
});
it("only looks at own properties of both objects", function() {
function Foo() {}
Foo.prototype.x = 1;
Foo.prototype.y = 2;
var a = new Foo();
a.x = 1;
var b = new Foo();
b.y = 2;
expect(jasmineUnderTest.util.objectDifference(a, b)).toEqual({x: 1});
expect(jasmineUnderTest.util.objectDifference(b, a)).toEqual({y: 2});
});
});
describe("jasmineFile", function() {
it("returns the file containing jasmine.util", function() {
// Chrome sometimes reports foo.js as foo.js/, so tolerate
// a trailing slash if present.
expect(jasmineUnderTest.util.jasmineFile()).toMatch(/util.js\/?$/);
expect(jasmine.util.jasmineFile()).toMatch(/jasmine.js\/?$/);
});
});
});

View File

@@ -1,45 +1,91 @@
describe("Any", function() {
it("matches a string", function() {
var any = new j$.Any(String);
var any = new jasmineUnderTest.Any(String);
expect(any.asymmetricMatch("foo")).toBe(true);
});
it("matches a number", function() {
var any = new j$.Any(Number);
var any = new jasmineUnderTest.Any(Number);
expect(any.asymmetricMatch(1)).toBe(true);
});
it("matches a function", function() {
var any = new j$.Any(Function);
var any = new jasmineUnderTest.Any(Function);
expect(any.asymmetricMatch(function(){})).toBe(true);
});
it("matches an Object", function() {
var any = new j$.Any(Object);
var any = new jasmineUnderTest.Any(Object);
expect(any.asymmetricMatch({})).toBe(true);
});
it("matches a Boolean", function() {
var any = new j$.Any(Boolean);
var any = new jasmineUnderTest.Any(Boolean);
expect(any.asymmetricMatch(true)).toBe(true);
});
it("matches a Map", function() {
jasmine.getEnv().requireFunctioningMaps();
var any = new jasmineUnderTest.Any(Map);
expect(any.asymmetricMatch(new Map())).toBe(true);
});
it("matches a Set", function() {
jasmine.getEnv().requireFunctioningSets();
var any = new jasmineUnderTest.Any(Set);
expect(any.asymmetricMatch(new Set())).toBe(true);
});
it("matches a TypedArray", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
var any = new jasmineUnderTest.Any(Uint32Array);
expect(any.asymmetricMatch(new Uint32Array([]))).toBe(true);
});
it("matches a Symbol", function() {
jasmine.getEnv().requireFunctioningSymbols();
var any = new jasmineUnderTest.Any(Symbol);
expect(any.asymmetricMatch(Symbol())).toBe(true);
});
it("matches another constructed object", function() {
var Thing = function() {},
any = new j$.Any(Thing);
any = new jasmineUnderTest.Any(Thing);
expect(any.asymmetricMatch(new Thing())).toBe(true);
});
it("jasmineToString's itself", function() {
var any = new j$.Any(Number);
it("does not treat null as an Object", function() {
var any = new jasmineUnderTest.Any(Object);
expect(any.asymmetricMatch(null)).toBe(false);
});
it("jasmineToString's itself", function() {
var any = new jasmineUnderTest.Any(Number);
expect(any.jasmineToString()).toEqual('<jasmine.any(Number)>');
expect(any.jasmineToString()).toEqual('<jasmine.any(Number)>');
});
describe("when called without an argument", function() {
it("tells the user to pass a constructor or use jasmine.anything()", function() {
expect(function() {
new jasmineUnderTest.Any();
}).toThrowError(TypeError, /constructor.*anything/);
});
});
});

View File

@@ -1,43 +1,75 @@
describe("Anything", function() {
it("matches a string", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch('foo')).toBe(true);
});
it("matches a number", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(42)).toBe(true);
});
it("matches an object", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch({ foo: 'bar' })).toBe(true);
});
it("matches an array", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch([1,2,3])).toBe(true);
});
it("matches a Map", function() {
jasmine.getEnv().requireFunctioningMaps();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Map())).toBe(true);
});
it("matches a Set", function() {
jasmine.getEnv().requireFunctioningSets();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Set())).toBe(true);
});
it("matches a TypedArray", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true);
});
it("matches a Symbol", function() {
jasmine.getEnv().requireFunctioningSymbols();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(Symbol())).toBe(true);
});
it("doesn't match undefined", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch()).toBe(false);
expect(anything.asymmetricMatch(undefined)).toBe(false);
});
it("doesn't match null", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(null)).toBe(false);
});
it("jasmineToString's itself", function() {
var anything = new j$.Anything();
var anything = new jasmineUnderTest.Anything();
expect(anything.jasmineToString()).toEqual("<jasmine.anything>");
});

View File

@@ -1,12 +1,12 @@
describe("ArrayContaining", function() {
it("matches any actual to an empty array", function() {
var containing = new j$.ArrayContaining([]);
var containing = new jasmineUnderTest.ArrayContaining([]);
expect(containing.asymmetricMatch("foo")).toBe(true);
});
it("does not work when not passed an array", function() {
var containing = new j$.ArrayContaining("foo");
var containing = new jasmineUnderTest.ArrayContaining("foo");
expect(function() {
containing.asymmetricMatch([]);
@@ -14,26 +14,39 @@ describe("ArrayContaining", function() {
});
it("matches when the item is in the actual", function() {
var containing = new j$.ArrayContaining(["foo"]);
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
expect(containing.asymmetricMatch(["foo"])).toBe(true);
});
it("matches when additional items are in the actual", function() {
var containing = new j$.ArrayContaining(["foo"]);
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
expect(containing.asymmetricMatch(["foo", "bar"])).toBe(true);
});
it("does not match when the item is not in the actual", function() {
var containing = new j$.ArrayContaining(["foo"]);
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
expect(containing.asymmetricMatch(["bar"])).toBe(false);
});
it("jasmineToStrings itself", function() {
var containing = new j$.ArrayContaining([]);
var containing = new jasmineUnderTest.ArrayContaining([]);
expect(containing.jasmineToString()).toMatch("<jasmine.arrayContaining");
});
it("uses custom equality testers", function() {
var tester = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
return true;
}
};
var containing = new jasmineUnderTest.ArrayContaining(["fooVal"]);
expect(containing.asymmetricMatch(["fooBar"], [tester])).toBe(true);
});
});

View File

@@ -0,0 +1,47 @@
describe("ArrayWithExactContents", function() {
it("matches an array with the same items in a different order", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]);
expect(matcher.asymmetricMatch([2, 'a', /a/])).toBe(true);
});
it("does not work when not passed an array", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents("foo");
expect(function() {
matcher.asymmetricMatch([]);
}).toThrowError(/not 'foo'/);
});
it("does not match when an item is missing", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]);
expect(matcher.asymmetricMatch(['a', 2])).toBe(false);
expect(matcher.asymmetricMatch(['a', 2, undefined])).toBe(false);
});
it("does not match when there is an extra item", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a']);
expect(matcher.asymmetricMatch(['a', 2])).toBe(false);
});
it("jasmineToStrings itself", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents([]);
expect(matcher.jasmineToString()).toMatch("<jasmine.arrayWithExactContents");
});
it("uses custom equality testers", function() {
var tester = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
return true;
}
};
var matcher = new jasmineUnderTest.ArrayWithExactContents(["fooVal"]);
expect(matcher.asymmetricMatch(["fooBar"], [tester])).toBe(true);
});
});

View File

@@ -1,13 +1,13 @@
describe("ObjectContaining", function() {
it("matches any actual to an empty object", function() {
var containing = new j$.ObjectContaining({});
var containing = new jasmineUnderTest.ObjectContaining({});
expect(containing.asymmetricMatch("foo")).toBe(true);
});
it("does not match an empty object actual", function() {
var containing = new j$.ObjectContaining("foo");
var containing = new jasmineUnderTest.ObjectContaining("foo");
expect(function() {
containing.asymmetricMatch({})
@@ -15,52 +15,49 @@ describe("ObjectContaining", function() {
});
it("matches when the key/value pair is present in the actual", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(true);
});
it("does not match when the key/value pair is not present in the actual", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
expect(containing.asymmetricMatch({bar: "barVal", quux: "quuxVal"})).toBe(false);
});
it("does not match when the key is present but the value is different in the actual", function() {
var containing = new j$.ObjectContaining({foo: "other"});
var containing = new jasmineUnderTest.ObjectContaining({foo: "other"});
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(false);
});
it("jasmineToString's itself", function() {
var containing = new j$.ObjectContaining({});
var containing = new jasmineUnderTest.ObjectContaining({});
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
});
it("matches recursively", function() {
var containing = new j$.ObjectContaining({one: new j$.ObjectContaining({two: {}})});
var containing = new jasmineUnderTest.ObjectContaining({one: new jasmineUnderTest.ObjectContaining({two: {}})});
expect(containing.asymmetricMatch({one: {two: {}}})).toBe(true);
});
it("matches when key is present with undefined value", function() {
var containing = new j$.ObjectContaining({ one: undefined });
var containing = new jasmineUnderTest.ObjectContaining({ one: undefined });
expect(containing.asymmetricMatch({ one: undefined })).toBe(true);
});
it("does not match when key with undefined value is not present", function() {
var containing = new j$.ObjectContaining({ one: undefined });
var containing = new jasmineUnderTest.ObjectContaining({ one: undefined });
expect(containing.asymmetricMatch({})).toBe(false);
});
it("matches defined properties", function(){
// IE 8 doesn't support `definePropery` on non-DOM nodes
if (jasmine.getEnv().ieVersion < 9) { return; }
var containing = new j$.ObjectContaining({ foo: "fooVal" });
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
var definedPropertyObject = {};
Object.defineProperty(definedPropertyObject, "foo", {
@@ -70,7 +67,7 @@ describe("ObjectContaining", function() {
});
it("matches prototype properties", function(){
var containing = new j$.ObjectContaining({ foo: "fooVal" });
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
var prototypeObject = {foo: "fooVal"};
var obj;
@@ -86,4 +83,17 @@ describe("ObjectContaining", function() {
expect(containing.asymmetricMatch(obj)).toBe(true);
});
it("uses custom equality testers", function() {
var tester = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
return true;
}
};
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
expect(containing.asymmetricMatch({foo: "fooBar"}, [tester])).toBe(true);
});
});

View File

@@ -1,13 +1,13 @@
describe("StringMatching", function() {
it("matches a string against a provided regexp", function() {
var matcher = new j$.StringMatching(/foo/);
var matcher = new jasmineUnderTest.StringMatching(/foo/);
expect(matcher.asymmetricMatch('barfoobaz')).toBe(true);
expect(matcher.asymmetricMatch('barbaz')).toBe(false);
});
it("matches a string against provided string", function() {
var matcher = new j$.StringMatching('foo');
var matcher = new jasmineUnderTest.StringMatching('foo');
expect(matcher.asymmetricMatch('barfoobaz')).toBe(true);
expect(matcher.asymmetricMatch('barbaz')).toBe(false);
@@ -15,12 +15,12 @@ describe("StringMatching", function() {
it("raises an Error when the expected is not a String or RegExp", function() {
expect(function() {
new j$.StringMatching({});
new jasmineUnderTest.StringMatching({});
}).toThrowError(/not a String or a RegExp/);
});
it("jasmineToString's itself", function() {
var matching = new j$.StringMatching(/^foo/);
var matching = new jasmineUnderTest.StringMatching(/^foo/);
expect(matching.jasmineToString()).toEqual("<jasmine.stringMatching(/^foo/)>");
});

View File

@@ -0,0 +1,13 @@
describe('formatErrorMsg', function () {
it('should format an error with a domain', function() {
var formator = jasmineUnderTest.formatErrorMsg('api');
expect(formator('message')).toBe('api : message');
expect(formator('message2')).toBe('api : message2');
});
it('should format an error with a domain and usage', function() {
var formator = jasmineUnderTest.formatErrorMsg('api', 'with a param');
expect(formator('message')).toBe('api : message\nUsage: with a param');
expect(formator('message2')).toBe('api : message2\nUsage: with a param');
});
});

View File

@@ -3,7 +3,8 @@ describe("Custom Matchers (Integration)", function() {
var fakeTimer;
beforeEach(function() {
env = new j$.Env();
env = new jasmineUnderTest.Env();
env.randomizeTests(false);
});
it("allows adding more matchers local to a spec", function(done) {
@@ -56,6 +57,54 @@ describe("Custom Matchers (Integration)", function() {
env.execute();
});
it("passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers", function(done) {
env.it("spec using custom equality matcher", function() {
var customEqualityFn = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
return true;
}
};
env.addCustomEqualityTester(customEqualityFn);
env.expect({foo: 'fooValue'}).toEqual(jasmineUnderTest.objectContaining({foo: 'fooBar'}));
env.expect(['fooValue', 'things']).toEqual(jasmineUnderTest.arrayContaining(['fooBar']));
env.expect(['fooValue']).toEqual(jasmineUnderTest.arrayWithExactContents(['fooBar']));
});
var specExpectations = function(result) {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
it("displays an appropriate failure message if a custom equality matcher fails", function(done) {
env.it("spec using custom equality matcher", function() {
var customEqualityFn = function(a, b) {
// "foo" is not equal to anything
if (a === 'foo' || b === 'foo') {
return false;
}
};
env.addCustomEqualityTester(customEqualityFn);
env.expect({foo: 'foo'}).toEqual({foo: 'foo'});
});
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations[0].message).toEqual(
"Expected $.foo = 'foo' to equal 'foo'."
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
it("uses the negative compare function for a negative comparison, if provided", function(done) {
env.it("spec with custom negative comparison matcher", function() {
env.addMatchers({
@@ -142,7 +191,7 @@ describe("Custom Matchers (Integration)", function() {
});
var specExpectations = function() {
expect(argumentSpy).toHaveBeenCalledWith(j$.matchersUtil, [customEqualityFn]);
expect(argumentSpy).toHaveBeenCalledWith(jasmineUnderTest.matchersUtil, [customEqualityFn]);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });

View File

@@ -0,0 +1,138 @@
describe('Custom Spy Strategies (Integration)', function() {
var env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.randomizeTests(false);
});
it('allows adding more strategies local to a suite', function(done) {
var plan = jasmine.createSpy('custom strategy plan')
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
env.describe('suite defining a custom spy strategy', function() {
env.beforeEach(function() {
env.addSpyStrategy('frobnicate', strategy);
});
env.it('spec in the suite', function() {
var spy = env.createSpy('something').and.frobnicate(17);
expect(spy(1, 2, 3)).toEqual(42);
expect(strategy).toHaveBeenCalledWith(17);
expect(plan).toHaveBeenCalledWith(1, 2, 3);
});
});
env.it('spec without custom strategy defined', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
});
it('allows adding more strategies local to a spec', function(done) {
var plan = jasmine.createSpy('custom strategy plan')
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
env.it('spec defining a custom spy strategy', function() {
env.addSpyStrategy('frobnicate', strategy);
var spy = env.createSpy('something').and.frobnicate(17);
expect(spy(1, 2, 3)).toEqual(42);
expect(strategy).toHaveBeenCalledWith(17);
expect(plan).toHaveBeenCalledWith(1, 2, 3);
});
env.it('spec without custom strategy defined', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
});
it('allows using custom strategies on a per-argument basis', function(done) {
var plan = jasmine.createSpy('custom strategy plan')
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
env.it('spec defining a custom spy strategy', function() {
env.addSpyStrategy('frobnicate', strategy);
var spy = env.createSpy('something')
.and.returnValue('no args return')
.withArgs(1, 2, 3).and.frobnicate(17);
expect(spy()).toEqual('no args return');
expect(plan).not.toHaveBeenCalled();
expect(spy(1, 2, 3)).toEqual(42);
expect(plan).toHaveBeenCalledWith(1, 2, 3);
});
env.it('spec without custom strategy defined', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
});
it('allows multiple custom strategies to be used', function(done) {
var plan1 = jasmine.createSpy('plan 1').and.returnValue(42),
strategy1 = jasmine.createSpy('strat 1').and.returnValue(plan1),
plan2 = jasmine.createSpy('plan 2').and.returnValue(24),
strategy2 = jasmine.createSpy('strat 2').and.returnValue(plan2),
specDone = jasmine.createSpy('specDone');
env.beforeEach(function() {
env.addSpyStrategy('frobnicate', strategy1);
env.addSpyStrategy('jiggle', strategy2);
});
env.it('frobnicates', function() {
plan1.calls.reset();
plan2.calls.reset();
var spy = env.createSpy('spy').and.frobnicate();
expect(spy()).toEqual(42);
expect(plan1).toHaveBeenCalled();
expect(plan2).not.toHaveBeenCalled();
});
env.it('jiggles', function() {
plan1.calls.reset();
plan2.calls.reset();
var spy = env.createSpy('spy').and.jiggle();
expect(spy()).toEqual(24);
expect(plan1).not.toHaveBeenCalled();
expect(plan2).toHaveBeenCalled();
});
function jasmineDone(result) {
expect(result.overallStatus).toEqual('passed');
expect(specDone.calls.count()).toBe(2);
done();
}
env.addReporter({ jasmineDone: jasmineDone, specDone: specDone });
env.execute();
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,10 @@
describe("jasmine spec running", function () {
describe("spec running", function () {
var env;
beforeEach(function() {
env = new j$.Env();
jasmine.getEnv().registerIntegrationMatchers();
env = new jasmineUnderTest.Env();
env.randomizeTests(false);
});
it('should assign spec ids sequentially', function() {
@@ -169,9 +171,25 @@ describe("jasmine spec running", function () {
env.execute();
});
it("should run multiple befores and afters in the order they are declared", function(done) {
it("should run multiple befores and afters ordered so functions declared later are treated as more specific", function(done) {
var actions = [];
env.beforeAll(function() {
actions.push('runner beforeAll1');
});
env.afterAll(function() {
actions.push('runner afterAll1');
});
env.beforeAll(function() {
actions.push('runner beforeAll2');
});
env.afterAll(function() {
actions.push('runner afterAll2');
});
env.beforeEach(function () {
actions.push('runner beforeEach1');
});
@@ -212,6 +230,8 @@ describe("jasmine spec running", function () {
var assertions = function() {
var expected = [
"runner beforeAll1",
"runner beforeAll2",
"runner beforeEach1",
"runner beforeEach2",
"beforeEach1",
@@ -220,7 +240,9 @@ describe("jasmine spec running", function () {
"afterEach2",
"afterEach1",
"runner afterEach2",
"runner afterEach1"
"runner afterEach1",
"runner afterAll2",
"runner afterAll1"
];
expect(actions).toEqual(expected);
done();
@@ -475,7 +497,7 @@ describe("jasmine spec running", function () {
env.execute();
});
it('focused runnables unfocus ancestor focused suites', function() {
it('focused runnables unfocus ancestor focused suites', function(done) {
var actions = [];
env.fdescribe('focused suite', function() {
@@ -518,7 +540,29 @@ describe("jasmine spec running", function () {
env.execute();
});
it("should allow top level suites to be disabled", function() {
it("shouldn't run before/after functions in disabled suites", function(done) {
var shouldNotRun = jasmine.createSpy("shouldNotRun"),
suite = env.xdescribe('A disabled Suite', function() {
// None of the before/after functions should run.
env.beforeAll(shouldNotRun);
env.beforeEach(shouldNotRun);
env.afterEach(shouldNotRun);
env.afterAll(shouldNotRun);
env.it('spec inside a disabled suite', shouldNotRun);
});
var assertions = function() {
expect(shouldNotRun).not.toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("should allow top level suites to be disabled", function(done) {
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
otherSpec = jasmine.createSpy("otherSpec");
@@ -556,22 +600,29 @@ describe("jasmine spec running", function () {
env.execute();
});
// TODO: is this useful? It doesn't catch syntax errors
xit("should recover gracefully when there are errors in describe functions", function() {
var specs = [];
var superSimpleReporter = new j$.Reporter();
superSimpleReporter.reportSpecResults = function(result) {
specs.push("Spec: " + result.fullName);
};
it("should recover gracefully when there are errors in describe functions", function(done) {
var specs = [],
reporter = jasmine.createSpyObj(['specDone', 'suiteDone', 'jasmineDone']);
try {
reporter.specDone.and.callFake(function(result) {
specs.push(result.fullName);
});
reporter.jasmineDone.and.callFake(function() {
expect(specs).toEqual(['outer1 inner1 should thingy', 'outer1 inner2 should other thingy', 'outer2 should xxx']);
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1 inner1', [/inner error/]);
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('outer1', [/outer error/]);
done();
});
expect(function() {
env.describe("outer1", function() {
env.describe("inner1", function() {
env.it("should thingy", function() {
this.expect(true).toEqual(true);
});
throw new Error("fake error");
throw new Error("inner error");
});
env.describe("inner2", function() {
@@ -580,11 +631,10 @@ describe("jasmine spec running", function () {
});
});
throw new Error("fake error");
throw new Error("outer error");
});
} catch(e) {
}
}).not.toThrow();
env.describe("outer2", function() {
env.it("should xxx", function() {
@@ -592,17 +642,8 @@ describe("jasmine spec running", function () {
});
});
env.addReporter(superSimpleReporter);
env.addReporter(reporter);
env.execute();
expect(specs.join('')).toMatch(new RegExp(
'Spec: outer1 inner1 should thingy.' +
'Spec: outer1 inner1 encountered a declaration exception.' +
'Spec: outer1 inner2 should other thingy.' +
'Spec: outer1 encountered a declaration exception.' +
'Spec: outer2 should xxx.'
));
});
it("re-enters suites that have no *Alls", function(done) {
@@ -696,4 +737,240 @@ describe("jasmine spec running", function () {
env.execute([spec2.id, spec3.id, spec1.id]);
}).toThrowError(/afterAll/);
});
it("should run the tests in a consistent order when a seed is supplied", function(done) {
var actions = [];
env.seed('123456');
env.randomizeTests(true);
env.beforeEach(function () {
actions.push('topSuite beforeEach');
});
env.afterEach(function () {
actions.push('topSuite afterEach');
});
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('outer beforeEach');
});
env.afterEach(function() {
actions.push('outer afterEach');
});
env.it('does it 1', function() {
actions.push('outer it 1');
});
env.describe('Inner 1', function() {
env.beforeEach(function() {
actions.push('inner 1 beforeEach');
});
env.afterEach(function() {
actions.push('inner 1 afterEach');
});
env.it('does it 2', function() {
actions.push('inner 1 it');
});
});
env.it('does it 3', function() {
actions.push('outer it 2');
});
env.describe('Inner 2', function() {
env.beforeEach(function() {
actions.push('inner 2 beforeEach');
});
env.afterEach(function() {
actions.push('inner 2 afterEach');
});
env.it('does it 2', function() {
actions.push('inner 2 it');
});
});
});
var assertions = function() {
var expected = [
'topSuite beforeEach',
'outer beforeEach',
'outer it 2',
'outer afterEach',
'topSuite afterEach',
'topSuite beforeEach',
'outer beforeEach',
'inner 2 beforeEach',
'inner 2 it',
'inner 2 afterEach',
'outer afterEach',
'topSuite afterEach',
'topSuite beforeEach',
'outer beforeEach',
'inner 1 beforeEach',
'inner 1 it',
'inner 1 afterEach',
'outer afterEach',
'topSuite afterEach',
'topSuite beforeEach',
'outer beforeEach',
'outer it 1',
'outer afterEach',
'topSuite afterEach'
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
describe("When throwOnExpectationFailure is set", function() {
it("skips to cleanup functions after an error", function(done) {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('outer beforeEach');
throw new Error("error");
});
env.afterEach(function() {
actions.push('outer afterEach');
});
env.describe('Inner', function() {
env.beforeEach(function() {
actions.push('inner beforeEach');
});
env.afterEach(function() {
actions.push('inner afterEach');
});
env.it('does it' , function() {
actions.push('inner it');
});
});
});
env.throwOnExpectationFailure(true);
var assertions = function() {
expect(actions).toEqual([
'outer beforeEach',
'inner afterEach',
'outer afterEach'
]);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("skips to cleanup functions after done.fail is called", function(done) {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function(done) {
actions.push('beforeEach');
done.fail('error');
actions.push('after done.fail');
});
env.afterEach(function() {
actions.push('afterEach');
});
env.it('does it' , function() {
actions.push('it');
});
});
env.throwOnExpectationFailure(true);
var assertions = function() {
expect(actions).toEqual([
'beforeEach',
'afterEach'
]);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("skips to cleanup functions when an async function times out", function(done) {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function(innerDone) {
actions.push('beforeEach');
}, 1);
env.afterEach(function() {
actions.push('afterEach');
});
env.it('does it' , function() {
actions.push('it');
});
});
env.throwOnExpectationFailure(true);
var assertions = function() {
expect(actions).toEqual([
'beforeEach',
'afterEach'
]);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
describe("when stopOnSpecFailure is on", function() {
it("does not run further specs when one fails", function(done) {
var actions = [];
env.it('fails', function() {
actions.push('fails');
env.expect(1).toBe(2);
});
env.it('does not run', function() {
actions.push('does not run');
});
env.randomizeTests(false);
env.stopOnSpecFailure(true);
var assertions = function() {
expect(actions).toEqual(['fails']);
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
});
});

View File

@@ -0,0 +1,47 @@
describe("DiffBuilder", function() {
it("records the actual and expected objects", function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.record({x: 'actual'}, {x: 'expected'});
expect(diffBuilder.getMessage()).toEqual("Expected Object({ x: 'actual' }) to equal Object({ x: 'expected' }).");
});
it("prints the path at which the difference was found", function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.withPath('foo', function() {
diffBuilder.record({x: 'actual'}, {x: 'expected'});
});
expect(diffBuilder.getMessage()).toEqual("Expected $.foo = Object({ x: 'actual' }) to equal Object({ x: 'expected' }).");
});
it("prints multiple messages, separated by newlines", function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.withPath('foo', function() {
diffBuilder.record(1, 2);
});
var message =
"Expected $.foo = 1 to equal 2.\n" +
"Expected 3 to equal 4.";
diffBuilder.record(3, 4);
expect(diffBuilder.getMessage()).toEqual(message);
});
it("allows customization of the message", function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
function darthVaderFormatter(actual, expected, path) {
return "I find your lack of " + expected + " disturbing. (was " + actual + ", at " + path + ")"
}
diffBuilder.withPath('x', function() {
diffBuilder.record('bar', 'foo', darthVaderFormatter);
});
expect(diffBuilder.getMessage()).toEqual("I find your lack of foo disturbing. (was bar, at $.x)");
});
});

View File

@@ -0,0 +1,13 @@
describe('NullDiffBuilder', function() {
it('responds to withPath() by calling the passed function', function() {
var spy = jasmine.createSpy('callback');
jasmineUnderTest.NullDiffBuilder().withPath('does not matter', spy);
expect(spy).toHaveBeenCalled();
});
it('responds to record()', function() {
expect(function() {
jasmineUnderTest.NullDiffBuilder().record('does not matter');
}).not.toThrow();
})
});

View File

@@ -0,0 +1,43 @@
describe('ObjectPath', function() {
var ObjectPath = jasmineUnderTest.ObjectPath;
it('represents the path to a node in an object tree', function() {
expect(new ObjectPath(['foo', 'bar']).toString()).toEqual('$.foo.bar');
});
it('has a depth', function() {
expect(new ObjectPath().depth()).toEqual(0);
expect(new ObjectPath(['foo']).depth()).toEqual(1);
});
it('renders numbers as array access', function() {
expect(new ObjectPath(['foo', 0]).toString()).toEqual('$.foo[0]');
});
it('renders properties that are valid identifiers with dot notation', function() {
expect(new ObjectPath(['foo123']).toString()).toEqual('$.foo123');
expect(new ObjectPath(['x_y']).toString()).toEqual('$.x_y');
expect(new ObjectPath(['A$B']).toString()).toEqual('$.A$B');
});
it('renders properties with non-identifier-safe characters with square bracket notation', function() {
expect(new ObjectPath(['a b c']).toString()).toEqual("$['a b c']");
expect(new ObjectPath(['1hello']).toString()).toEqual("$['1hello']");
});
it('renders as the empty string when empty', function() {
expect(new ObjectPath().toString()).toEqual('');
});
it('stringifies properties that are not strings or numbers', function() {
expect(new ObjectPath([{}]).toString()).toEqual("$['[object Object]']");
});
it('can be created based on another path', function() {
var root = new ObjectPath();
var path = root.add('foo');
expect(path.toString()).toEqual('$.foo');
expect(root.toString()).toEqual('');
})
});

View File

@@ -1,105 +1,133 @@
describe("matchersUtil", function() {
describe("equals", function() {
it("passes for literals that are triple-equal", function() {
expect(j$.matchersUtil.equals(null, null)).toBe(true);
expect(j$.matchersUtil.equals(void 0, void 0)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(null, null)).toBe(true);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.equals({a: "foo"}, 1)).toBe(false);
});
it("passes for Strings that are equivalent", function() {
expect(j$.matchersUtil.equals("foo", "foo")).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals("foo", "foo")).toBe(true);
});
it("fails for Strings that are not equivalent", function() {
expect(j$.matchersUtil.equals("foo", "bar")).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals("foo", "bar")).toBe(false);
});
it("passes for Numbers that are equivalent", function() {
expect(j$.matchersUtil.equals(123, 123)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(123, 123)).toBe(true);
});
it("fails for Numbers that are not equivalent", function() {
expect(j$.matchersUtil.equals(123, 456)).toBe(false);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.equals(true, true)).toBe(true);
});
it("fails for Booleans that are not equivalent", function() {
expect(j$.matchersUtil.equals(true, false)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(true, false)).toBe(false);
});
it("passes for RegExps that are equivalent", function() {
expect(j$.matchersUtil.equals(/foo/, /foo/)).toBe(true);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.equals(/foo/, /bar/)).toBe(false);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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 Arrays that are equivalent, with elements added by changing length", function() {
var foo = [];
foo.length = 1;
expect(jasmineUnderTest.matchersUtil.equals(foo, [undefined])).toBe(true);
});
it("fails for Arrays that have different lengths", function() {
expect(jasmineUnderTest.matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
});
it("fails for Arrays that have different elements", function() {
expect(jasmineUnderTest.matchersUtil.equals([1, 2, 3], [1, 5, 3])).toBe(false);
});
it("fails for Arrays whose contents are equivalent, but have differing properties", function() {
var one = [1,2,3],
two = [1,2,3];
two = [1,2,3];
one.foo = 'bar';
two.foo = 'baz';
expect(j$.matchersUtil.equals(one, two)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(one, two)).toBe(false);
});
it("passes for Arrays with equivalent contents and properties", function() {
var one = [1,2,3],
two = [1,2,3];
one.foo = 'bar';
two.foo = 'bar';
expect(jasmineUnderTest.matchersUtil.equals(one, two)).toBe(true);
});
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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.equals(new Error("foo"), new Error("bar"))).toBe(false);
});
it("fails for objects with different constructors", function() {
function One() {}
function Two() {}
expect(jasmineUnderTest.matchersUtil.equals(new One(), new Two())).toBe(false);
});
it("passes for Objects that are equivalent (simple case)", function() {
expect(j$.matchersUtil.equals({a: "foo"}, {a: "foo"})).toBe(true);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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" };
expected = { a: "foo" };
actual.b = actual;
expected.b = actual;
expect(j$.matchersUtil.equals(actual, expected)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(true);
});
it("fails for Objects that are not equivalent (with cycles)", function() {
@@ -109,109 +137,146 @@ describe("matchersUtil", function() {
actual.b = actual;
expected.b = actual;
expect(j$.matchersUtil.equals(actual, expected)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(false);
});
it("fails for Objects that have the same number of keys, but different keys/values", function () {
var expected = { a: undefined },
actual = { b: 1 };
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.equals(emptyObject, emptyArray)).toBe(false);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true);
});
it("passes for equivalent Promises (GitHub issue #1314)", function() {
if (typeof Promise === 'undefined') { return; }
var p1 = new Promise(function () {}),
p2 = new Promise(function () {});
expect(jasmineUnderTest.matchersUtil.equals(p1, p1)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(p1, p2)).toBe(false);
});
it("passes for equivalent DOM nodes", function() {
if (typeof document === 'undefined') {
return;
describe("when running in a browser", function() {
function isNotRunningInBrowser() {
return typeof document === 'undefined'
}
var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value")
a.appendChild(document.createTextNode('test'));
var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value")
b.appendChild(document.createTextNode('test'));
it("passes for equivalent DOM nodes", function() {
if (isNotRunningInBrowser()) {
return;
}
var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value");
a.appendChild(document.createTextNode('test'));
expect(j$.matchersUtil.equals(a,b)).toBe(true);
var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value");
b.appendChild(document.createTextNode('test'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true);
});
it("passes for equivalent objects from different frames", function() {
if (isNotRunningInBrowser()) {
return;
}
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentWindow.eval('window.testObject = {}');
expect(jasmineUnderTest.matchersUtil.equals({}, iframe.contentWindow.testObject)).toBe(true);
document.body.removeChild(iframe);
});
it("fails for DOM nodes with different attributes or child nodes", function() {
if (isNotRunningInBrowser()) {
return;
}
var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value")
a.appendChild(document.createTextNode('test'));
var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value2")
b.appendChild(document.createTextNode('test'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(false);
b.setAttribute("test-attr", "attr-value");
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true);
b.appendChild(document.createTextNode('2'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(false);
a.appendChild(document.createTextNode('2'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(true);
});
});
it("fails for DOM nodes with different attributes or child nodes", function() {
if (typeof document === 'undefined') {
return;
}
var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value")
a.appendChild(document.createTextNode('test'));
var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value2")
b.appendChild(document.createTextNode('test'));
expect(j$.matchersUtil.equals(a,b)).toBe(false);
b.setAttribute("test-attr", "attr-value");
expect(j$.matchersUtil.equals(a,b)).toBe(true);
b.appendChild(document.createTextNode('2'));
expect(j$.matchersUtil.equals(a,b)).toBe(false);
a.appendChild(document.createTextNode('2'));
expect(j$.matchersUtil.equals(a,b)).toBe(true);
});
it("passes for equivalent objects from different vm contexts", function() {
if (typeof require !== 'function') {
return;
}
var vm = require('vm');
var sandbox = {
obj: null
};
vm.runInNewContext('obj = {a: 1, b: 2}', sandbox);
expect(j$.matchersUtil.equals(sandbox.obj, {a: 1, b: 2})).toBe(true);
});
it("passes for equivalent arrays from different vm contexts", function() {
if (typeof require !== 'function') {
return;
describe("when running in Node", function() {
function isNotRunningInNode() {
return typeof require !== 'function'
}
var vm = require('vm');
var sandbox = {
arr: null
};
vm.runInNewContext('arr = [1, 2]', sandbox);
it("passes for equivalent objects from different vm contexts", function() {
if (isNotRunningInNode()) {
return;
}
var vm = require('vm');
var sandbox = {
obj: null
};
vm.runInNewContext('obj = {a: 1, b: 2}', sandbox);
expect(j$.matchersUtil.equals(sandbox.arr, [1, 2])).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(sandbox.obj, {a: 1, b: 2})).toBe(true);
});
it("passes for equivalent arrays from different vm contexts", function() {
if (isNotRunningInNode()) {
return;
}
var vm = require('vm');
var sandbox = {
arr: null
};
vm.runInNewContext('arr = [1, 2]', sandbox);
expect(jasmineUnderTest.matchersUtil.equals(sandbox.arr, [1, 2])).toBe(true);
});
});
it("passes when Any is used", function() {
var number = 3,
anyNumber = new j$.Any(Number);
anyNumber = new jasmineUnderTest.Any(Number);
expect(j$.matchersUtil.equals(number, anyNumber)).toBe(true);
expect(j$.matchersUtil.equals(anyNumber, number)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(number, anyNumber)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(anyNumber, number)).toBe(true);
});
it("fails when Any is compared to something unexpected", function() {
var number = 3,
anyString = new j$.Any(String);
anyString = new jasmineUnderTest.Any(String);
expect(j$.matchersUtil.equals(number, anyString)).toBe(false);
expect(j$.matchersUtil.equals(anyString, number)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(number, anyString)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(anyString, number)).toBe(false);
});
it("passes when ObjectContaining is used", function() {
@@ -219,130 +284,325 @@ describe("matchersUtil", function() {
foo: 3,
bar: 7
},
containing = new j$.ObjectContaining({foo: 3});
containing = new jasmineUnderTest.ObjectContaining({foo: 3});
expect(j$.matchersUtil.equals(obj, containing)).toBe(true);
expect(j$.matchersUtil.equals(containing, obj)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(obj, containing)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(containing, obj)).toBe(true);
});
it("passes when an asymmetric equality tester returns true", function() {
var tester = { asymmetricMatch: function(other) { return true; } };
expect(j$.matchersUtil.equals(false, tester)).toBe(true);
expect(j$.matchersUtil.equals(tester, false)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(false, tester)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(tester, false)).toBe(true);
});
it("fails when an asymmetric equality tester returns false", function() {
var tester = { asymmetricMatch: function(other) { return false; } };
expect(j$.matchersUtil.equals(true, tester)).toBe(false);
expect(j$.matchersUtil.equals(tester, true)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(true, tester)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(tester, true)).toBe(false);
});
it("passes when ArrayContaining is used", function() {
var arr = ["foo", "bar"];
expect(j$.matchersUtil.equals(arr, new j$.ArrayContaining(["bar"]))).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(arr, new jasmineUnderTest.ArrayContaining(["bar"]))).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);
expect(jasmineUnderTest.matchersUtil.equals(1, 2, [tester])).toBe(true);
});
it("passes for two empty Objects", function () {
expect(j$.matchersUtil.equals({}, {})).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals({}, {})).toBe(true);
});
describe("when a custom equality matcher is installed that returns 'undefined'", function () {
var tester = function(a, b) { return jasmine.undefined; };
it("passes for two empty Objects", function () {
expect(j$.matchersUtil.equals({}, {}, [tester])).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals({}, {}, [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, 1, [tester])).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(1, 1, [tester])).toBe(false);
});
it("passes for an asymmetric equality tester that returns true when a custom equality tester return false", function() {
var asymmetricTester = { asymmetricMatch: function(other) { return true; } },
symmetricTester = function(a, b) { return false; };
symmetricTester = function(a, b) { return false; };
expect(j$.matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true);
expect(j$.matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true);
});
it("passes custom equality matchers to asymmetric equality testers", function() {
var tester = function(a, b) {};
var asymmetricTester = { asymmetricMatch: jasmine.createSpy('asymmetricMatch') };
asymmetricTester.asymmetricMatch.and.returnValue(true);
var other = {};
expect(jasmineUnderTest.matchersUtil.equals(asymmetricTester, other, [tester])).toBe(true);
expect(asymmetricTester.asymmetricMatch).toHaveBeenCalledWith(other, [tester]);
});
it("passes when an Any is compared to an Any that checks for the same type", function() {
var any1 = new j$.Any(Function),
any2 = new j$.Any(Function);
var any1 = new jasmineUnderTest.Any(Function),
any2 = new jasmineUnderTest.Any(Function);
expect(j$.matchersUtil.equals(any1, any2)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(any1, any2)).toBe(true);
});
it("passes for null prototype objects with same properties", function () {
if (jasmine.getEnv().ieVersion < 9) { return; }
var objA = Object.create(null),
objB = Object.create(null);
objB = Object.create(null);
objA.name = 'test';
objB.name = 'test';
expect(j$.matchersUtil.equals(objA, objB)).toBe(true);
expect(jasmineUnderTest.matchersUtil.equals(objA, objB)).toBe(true);
});
it("fails for null prototype objects with different properties", function () {
if (jasmine.getEnv().ieVersion < 9) { return; }
var objA = Object.create(null),
objB = Object.create(null);
objB = Object.create(null);
objA.name = 'test';
objB.test = 'name';
expect(j$.matchersUtil.equals(objA, objB)).toBe(false);
expect(jasmineUnderTest.matchersUtil.equals(objA, objB)).toBe(false);
});
it("passes when comparing two empty sets", function() {
jasmine.getEnv().requireFunctioningSets();
expect(jasmineUnderTest.matchersUtil.equals(new Set(), new Set())).toBe(true);
});
it("passes when comparing identical sets", function() {
jasmine.getEnv().requireFunctioningSets();
var setA = new Set();
setA.add(6);
setA.add(5);
var setB = new Set();
setB.add(6);
setB.add(5);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
});
it("passes when comparing identical sets with different insertion order and simple elements", function() {
jasmine.getEnv().requireFunctioningSets();
var setA = new Set();
setA.add(3);
setA.add(6);
var setB = new Set();
setB.add(6);
setB.add(3);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
});
it("passes when comparing identical sets with different insertion order and complex elements 1", function() {
jasmine.getEnv().requireFunctioningSets();
var setA1 = new Set();
setA1.add(['a',3]);
setA1.add([6,1]);
var setA2 = new Set();
setA1.add(['y',3]);
setA1.add([6,1]);
var setA = new Set();
setA.add(setA1);
setA.add(setA2);
var setB1 = new Set();
setB1.add([6,1]);
setB1.add(['a',3]);
var setB2 = new Set();
setB1.add([6,1]);
setB1.add(['y',3]);
var setB = new Set();
setB.add(setB1);
setB.add(setB2);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
});
it("passes when comparing identical sets with different insertion order and complex elements 2", function() {
jasmine.getEnv().requireFunctioningSets();
var setA = new Set();
setA.add([[1,2], [3,4]]);
setA.add([[5,6], [7,8]]);
var setB = new Set();
setB.add([[5,6], [7,8]]);
setB.add([[1,2], [3,4]]);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true);
});
it("fails for sets with different elements", function() {
jasmine.getEnv().requireFunctioningSets();
var setA = new Set();
setA.add(6);
setA.add(3);
setA.add(5);
var setB = new Set();
setB.add(6);
setB.add(4);
setB.add(5);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false);
});
it("fails for sets of different size", function() {
jasmine.getEnv().requireFunctioningSets();
var setA = new Set();
setA.add(6);
setA.add(3);
var setB = new Set();
setB.add(6);
setB.add(4);
setB.add(5);
expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false);
});
it("passes when comparing two empty maps", function() {
jasmine.getEnv().requireFunctioningMaps();
expect(jasmineUnderTest.matchersUtil.equals(new Map(), new Map())).toBe(true);
});
it("passes when comparing identical maps", function() {
jasmine.getEnv().requireFunctioningMaps();
var mapA = new Map();
mapA.set(6, 5);
var mapB = new Map();
mapB.set(6, 5);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true);
});
it("passes when comparing identical maps with different insertion order", function() {
jasmine.getEnv().requireFunctioningMaps();
var mapA = new Map();
mapA.set("a", 3);
mapA.set(6, 1);
var mapB = new Map();
mapB.set(6, 1);
mapB.set("a", 3);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true);
});
it("fails for maps with different elements", function() {
jasmine.getEnv().requireFunctioningMaps();
var mapA = new Map();
mapA.set(6, 3);
mapA.set(5, 1);
var mapB = new Map();
mapB.set(6, 4);
mapB.set(5, 1);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false);
});
it("fails for maps of different size", function() {
jasmine.getEnv().requireFunctioningMaps();
var mapA = new Map();
mapA.set(6, 3);
var mapB = new Map();
mapB.set(6, 4);
mapB.set(5, 1);
expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false);
});
describe("when running in an environment with array polyfills", function() {
var findIndexDescriptor = Object.getOwnPropertyDescriptor(Array.prototype, 'findIndex');
if (!findIndexDescriptor) {
return;
}
beforeEach(function() {
Object.defineProperty(Array.prototype, 'findIndex', {
enumerable: true,
value: function (predicate) {
if (this === null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
}
});
});
afterEach(function() {
Object.defineProperty(Array.prototype, 'findIndex', findIndexDescriptor);
});
it("passes when there's an array polyfill", function() {
expect(['foo']).toEqual(['foo']);
});
});
});
describe("contains", function() {
it("passes when expected is a substring of actual", function() {
expect(j$.matchersUtil.contains("ABC", "BC")).toBe(true);
expect(jasmineUnderTest.matchersUtil.contains("ABC", "BC")).toBe(true);
});
it("fails when expected is a not substring of actual", function() {
expect(j$.matchersUtil.contains("ABC", "X")).toBe(false);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.contains(["foo", {some: "bar"}], "foo")).toBe(true);
expect(jasmineUnderTest.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);
expect(jasmineUnderTest.matchersUtil.contains([1, 2], 2, [customTester])).toBe(true);
});
it("fails when actual is undefined", function() {
expect(j$.matchersUtil.contains(undefined, 'A')).toBe(false);
expect(jasmineUnderTest.matchersUtil.contains(undefined, 'A')).toBe(false);
});
it("fails when actual is null", function() {
expect(j$.matchersUtil.contains(null, 'A')).toBe(false);
expect(jasmineUnderTest.matchersUtil.contains(null, 'A')).toBe(false);
});
it("passes with array-like objects", function() {
@@ -351,7 +611,7 @@ describe("matchersUtil", function() {
capturedArgs = arguments;
}
testFunction('foo', 'bar');
expect(j$.matchersUtil.contains(capturedArgs, 'bar')).toBe(true);
expect(jasmineUnderTest.matchersUtil.contains(capturedArgs, 'bar')).toBe(true);
});
});
@@ -360,7 +620,7 @@ describe("matchersUtil", function() {
it("builds an English sentence for a failure case", function() {
var actual = "foo",
name = "toBar",
message = j$.matchersUtil.buildFailureMessage(name, false, actual);
message = jasmineUnderTest.matchersUtil.buildFailureMessage(name, false, actual);
expect(message).toEqual("Expected 'foo' to bar.");
});
@@ -369,7 +629,7 @@ describe("matchersUtil", function() {
var actual = "foo",
name = "toBar",
isNot = true,
message = message = j$.matchersUtil.buildFailureMessage(name, isNot, actual);
message = message = jasmineUnderTest.matchersUtil.buildFailureMessage(name, isNot, actual);
expect(message).toEqual("Expected 'foo' not to bar.");
});
@@ -377,7 +637,7 @@ describe("matchersUtil", function() {
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");
message = jasmineUnderTest.matchersUtil.buildFailureMessage(name, false, actual, "quux", "corge");
expect(message).toEqual("Expected 'foo' to bar 'quux', 'corge'.");
});

View File

@@ -0,0 +1,8 @@
describe('nothing', function() {
it('should pass', function() {
var matcher = jasmineUnderTest.matchers.nothing(),
result = matcher.compare();
expect(result.pass).toBe(true);
});
});

View File

@@ -1,6 +1,6 @@
describe("toBeCloseTo", function() {
it("passes when within two decimal places by default", function() {
var matcher = j$.matchers.toBeCloseTo(),
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
result = matcher.compare(0, 0);
@@ -8,29 +8,63 @@ describe("toBeCloseTo", function() {
result = matcher.compare(0, 0.001);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.005);
expect(result.pass).toBe(true);
});
it("fails when not within two decimal places by default", function() {
var matcher = j$.matchers.toBeCloseTo(),
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
result = matcher.compare(0, 0.01);
expect(result.pass).toBe(false);
result = matcher.compare(0, 0.05);
expect(result.pass).toBe(false);
});
it("accepts an optional precision argument", function() {
var matcher = j$.matchers.toBeCloseTo(),
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
result = matcher.compare(0, 0.1, 0);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.5, 0);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.0001, 3);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.0005, 3);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.00001, 4);
expect(result.pass).toBe(true);
result = matcher.compare(0, 0.00005, 4);
expect(result.pass).toBe(true);
});
it("fails when one of the arguments is null", function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo();
expect(function() {
matcher.compare(null, null);
}).toThrowError('Cannot use toBeCloseTo with null. Arguments evaluated to: expect(null).toBeCloseTo(null).');
expect(function() {
matcher.compare(0, null);
}).toThrowError('Cannot use toBeCloseTo with null. Arguments evaluated to: expect(0).toBeCloseTo(null).');
expect(function() {
matcher.compare(null, 0);
}).toThrowError('Cannot use toBeCloseTo with null. Arguments evaluated to: expect(null).toBeCloseTo(0).');
});
it("rounds expected values", function() {
var matcher = j$.matchers.toBeCloseTo(),
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
result = matcher.compare(1.23, 1.229);
@@ -42,7 +76,15 @@ describe("toBeCloseTo", function() {
result = matcher.compare(1.23, 1.225);
expect(result.pass).toBe(true);
result = matcher.compare(1.23, 1.235);
expect(result.pass).toBe(true);
// 1.2249999 will be rounded to 1.225
result = matcher.compare(1.23, 1.2249999);
expect(result.pass).toBe(true);
// 1.2249999 will be rounded to 1.224
result = matcher.compare(1.23, 1.2244999);
expect(result.pass).toBe(false);
result = matcher.compare(1.23, 1.234);

View File

@@ -1,6 +1,6 @@
describe("toBeDefined", function() {
it("matches for defined values", function() {
var matcher = j$.matchers.toBeDefined(),
var matcher = jasmineUnderTest.matchers.toBeDefined(),
result;
@@ -9,7 +9,7 @@ describe("toBeDefined", function() {
});
it("fails when matching undefined values", function() {
var matcher = j$.matchers.toBeDefined(),
var matcher = jasmineUnderTest.matchers.toBeDefined(),
result;
result = matcher.compare(void 0);

View File

@@ -1,6 +1,6 @@
describe("toBeFalsy", function() {
it("passes for 'falsy' values", function() {
var matcher = j$.matchers.toBeFalsy(),
var matcher = jasmineUnderTest.matchers.toBeFalsy(),
result;
result = matcher.compare(false);
@@ -20,7 +20,7 @@ describe("toBeFalsy", function() {
});
it("fails for 'truthy' values", function() {
var matcher = j$.matchers.toBeFalsy(),
var matcher = jasmineUnderTest.matchers.toBeFalsy(),
result;
result = matcher.compare(true);

View File

@@ -0,0 +1,29 @@
describe("toBeGreaterThanOrEqual", function() {
it("passes when actual >= expected", function() {
var matcher = jasmineUnderTest.matchers.toBeGreaterThanOrEqual(),
result;
result = matcher.compare(2, 1);
expect(result.pass).toBe(true);
result = matcher.compare(1, 1);
expect(result.pass).toBe(true);
result = matcher.compare(1.0000001, 1);
expect(result.pass).toBe(true);
result = matcher.compare(1.0, 1.0);
expect(result.pass).toBe(true);
})
it("fails when actual < expected", function() {
var matcher = jasmineUnderTest.matchers.toBeGreaterThanOrEqual(),
result;
result = matcher.compare(1, 2);
expect(result.pass).toBe(false);
result = matcher.compare(1, 1.0000001);
expect(result.pass).toBe(false);
})
});

View File

@@ -1,6 +1,6 @@
describe("toBeGreaterThan", function() {
it("passes when actual > expected", function() {
var matcher = j$.matchers.toBeGreaterThan(),
var matcher = jasmineUnderTest.matchers.toBeGreaterThan(),
result;
result = matcher.compare(2, 1);
@@ -8,7 +8,7 @@ describe("toBeGreaterThan", function() {
});
it("fails when actual <= expected", function() {
var matcher = j$.matchers.toBeGreaterThan(),
var matcher = jasmineUnderTest.matchers.toBeGreaterThan(),
result;
result = matcher.compare(1, 1);

View File

@@ -0,0 +1,29 @@
describe("toBeLessThanOrEqual", function() {
it("passes when actual <= expected", function() {
var matcher = jasmineUnderTest.matchers.toBeLessThanOrEqual(),
result;
result = matcher.compare(1, 2);
expect(result.pass).toBe(true);
result = matcher.compare(1, 1);
expect(result.pass).toBe(true);
result = matcher.compare(1, 1.0000001);
expect(result.pass).toBe(true);
result = matcher.compare(1.0, 1.0);
expect(result.pass).toBe(true);
});
it("fails when actual < expected", function() {
var matcher = jasmineUnderTest.matchers.toBeLessThanOrEqual(),
result;
result = matcher.compare(2, 1);
expect(result.pass).toBe(false);
result = matcher.compare(1.0000001, 1);
expect(result.pass).toBe(false);
});
});

View File

@@ -1,6 +1,6 @@
describe("toBeLessThan", function() {
it("passes when actual < expected", function() {
var matcher = j$.matchers.toBeLessThan(),
var matcher = jasmineUnderTest.matchers.toBeLessThan(),
result;
result = matcher.compare(1, 2);
@@ -8,7 +8,7 @@ describe("toBeLessThan", function() {
});
it("fails when actual <= expected", function() {
var matcher = j$.matchers.toBeLessThan(),
var matcher = jasmineUnderTest.matchers.toBeLessThan(),
result;
result = matcher.compare(1, 1);

View File

@@ -1,6 +1,6 @@
describe("toBeNaN", function() {
it("passes for NaN with a custom .not fail", function() {
var matcher = j$.matchers.toBeNaN(),
var matcher = jasmineUnderTest.matchers.toBeNaN(),
result;
result = matcher.compare(Number.NaN);
@@ -9,7 +9,7 @@ describe("toBeNaN", function() {
});
it("fails for anything not a NaN", function() {
var matcher = j$.matchers.toBeNaN(),
var matcher = jasmineUnderTest.matchers.toBeNaN(),
result;
result = matcher.compare(1);
@@ -29,7 +29,7 @@ describe("toBeNaN", function() {
});
it("has a custom message on failure", function() {
var matcher = j$.matchers.toBeNaN(),
var matcher = jasmineUnderTest.matchers.toBeNaN(),
result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 to be NaN.");

View File

@@ -0,0 +1,31 @@
describe("toBeNegativeInfinity", function() {
it("fails for anything that isn't -Infinity", function() {
var matcher = jasmineUnderTest.matchers.toBeNegativeInfinity(),
result;
result = matcher.compare(1);
expect(result.pass).toBe(false);
result = matcher.compare(Number.NaN);
expect(result.pass).toBe(false);
result = matcher.compare(null);
expect(result.pass).toBe(false);
});
it("has a custom message on failure", function() {
var matcher = jasmineUnderTest.matchers.toBeNegativeInfinity(),
result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 not to be -Infinity.")
});
it("succeeds for -Infinity", function() {
var matcher = jasmineUnderTest.matchers.toBeNegativeInfinity(),
result = matcher.compare(Number.NEGATIVE_INFINITY);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected actual to be -Infinity.")
});
});

View File

@@ -1,6 +1,6 @@
describe("toBeNull", function() {
it("passes for null", function() {
var matcher = j$.matchers.toBeNull(),
var matcher = jasmineUnderTest.matchers.toBeNull(),
result;
result = matcher.compare(null);
@@ -8,7 +8,7 @@ describe("toBeNull", function() {
});
it("fails for non-null", function() {
var matcher = j$.matchers.toBeNull(),
var matcher = jasmineUnderTest.matchers.toBeNull(),
result;
result = matcher.compare('foo');

View File

@@ -0,0 +1,31 @@
describe("toBePositiveInfinity", function() {
it("fails for anything that isn't Infinity", function() {
var matcher = jasmineUnderTest.matchers.toBePositiveInfinity(),
result;
result = matcher.compare(1);
expect(result.pass).toBe(false);
result = matcher.compare(Number.NaN);
expect(result.pass).toBe(false);
result = matcher.compare(null);
expect(result.pass).toBe(false);
});
it("has a custom message on failure", function() {
var matcher = jasmineUnderTest.matchers.toBePositiveInfinity(),
result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 not to be Infinity.")
});
it("succeeds for Infinity", function() {
var matcher = jasmineUnderTest.matchers.toBePositiveInfinity(),
result = matcher.compare(Number.POSITIVE_INFINITY);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected actual to be Infinity.")
});
});

View File

@@ -1,6 +1,6 @@
describe("toBe", function() {
it("passes when actual === expected", function() {
var matcher = j$.matchers.toBe(),
var matcher = jasmineUnderTest.matchers.toBe(),
result;
result = matcher.compare(1, 1);
@@ -8,7 +8,7 @@ describe("toBe", function() {
});
it("fails when actual !== expected", function() {
var matcher = j$.matchers.toBe(),
var matcher = jasmineUnderTest.matchers.toBe(),
result;
result = matcher.compare(1, 2);

Some files were not shown because too many files have changed in this diff Show More