Compare commits

...

391 Commits

Author SHA1 Message Date
Gregg Van Hove
426eebe1ce bump version to 2.3.2 2015-05-07 14:02:12 -07:00
Gregg Van Hove
add841a1e9 A spec without a function provided should be pending not disabled
Fixes #840
2015-05-07 13:46:52 -07:00
Gregg Van Hove
023c998660 use a link for the PR in release notes 2015-05-05 07:51:49 -07:00
Gregg Van Hove
3dde7d0c29 Bump version to 2.3.1 to create a new bower package 2015-05-05 07:48:49 -07:00
Gregg Van Hove
4e3f9a4d09 Merge pull request #843 from evoL/fix-bower-package
Make the Bower package use browser-friendly files.
2015-05-05 07:22:25 -07:00
Rafał Hirsz
b89fbc71a7 Point Bower's main field to jasmine.js, which is browser-friendly. 2015-05-05 15:36:24 +02:00
Gregg Van Hove
4c0e3b2aed remove dist zips from the repo. They should all be available on github releases 2015-04-28 13:43:21 -07:00
Gregg Van Hove
19f812c4f6 Fix cp command for release documentation 2015-04-28 11:27:03 -07:00
Gregg Van Hove
5ea24a8448 version bump to 2.3.0 2015-04-28 10:13:42 -07:00
Gregg Van Hove
4173a4089c Merge pull request #827 from davetron5000/patch-1
Explicitly state the main JS
2015-04-19 10:03:19 -07:00
David Copeland
f712b795d7 Explicitly state the main JS
# Problem

To bring this lib in using Sprockets, you must do this:

```javascript
//= require jasmine/lib/jasmine-core
```

Sprockets can read `bower.json` and, if `main` is explicitly stated in the file, you can do the much more future-proof and compact:


```javascript
//= require jasmine
```

# Solution

Explicitly specify it.

# Caveats

I am not super-versed in Bower or JS packaging, so this is proposed in the vein of "this fixes my problem and seems consistent with other JS libs I've looked at", but I'm open to other solutions.
2015-04-19 12:22:33 -04:00
Gregg Van Hove
ff029b37b5 Use instanceof when checking Error types in toThrowError
Fixes #819
2015-04-09 15:38:24 -07:00
Gregg Van Hove
7cd8c41d31 Merge pull request #818 from lpww/patch-1
Update formatting
2015-04-05 21:56:59 -07:00
Thomas Treffry
d7dd85c64f Update formatting
Remove periods from bullet points for consistency with rest of document
2015-04-05 20:19:29 -07:00
Davis W. Frank
2d5c071d28 Merge pull request #815 from jhamon/contributing-subjective-readability-improvements
Subjective readability improvements to CONTRIBUTING.md
2015-04-02 08:49:39 -07:00
Jen Hamon
76bc0a87db Use code fence syntax around git workflow for readability. 2015-04-01 13:25:32 -07:00
Jen Hamon
5cae401c98 Pull urls out of paragraph to improve readability 2015-04-01 13:06:58 -07:00
Gregg Van Hove
1d366772b7 Don't throw if we're already handling an exception
[finish #91407284]
2015-03-30 08:19:06 -07:00
Gregg Van Hove and Nikhil Gajwani
d137b83c1c Don't install the clock if the current timing functions aren't the originals
[finish #64116664] Fix #782
2015-03-27 10:14:03 -07:00
Gregg Van Hove
692c8716f0 Style disabled specs in the results list 2015-03-26 15:45:26 -07:00
Gregg Van Hove
965229bd03 Properly pass j$ to Any so it can use other jasmine stuff
Fixes #806
2015-03-18 13:12:40 -07:00
Gregg Van Hove
46044dd345 Merge branch 'sgravrock-clock-reset' 2015-03-15 13:23:56 -07:00
Steve Gravrock
2af9a45fb2 Correctly handle functions that are scheduled after the clock is uninstalled and reinstalled from within Clock#tick.
Fixes #790.
2015-03-14 17:40:27 -07:00
Gregg Van Hove
abc0c4a97e Update to ruby 2.x for travis builds
- sauce gem allowed cmdparse to upgrade a major version and 3.0 of
  cmdparse requires ruby >= 2.0.0
2015-03-14 15:26:46 -07:00
slackersoft
eb1d98338a Properly inject j$ into Suite 2015-03-06 11:43:57 -08:00
slackersoft
f0c480f456 Use onclick directly to better support older webkit 2015-03-06 10:09:08 -08:00
Gregg Van Hove and Molly Trombley-McCann
7693a4c959 Allow user to stop a specs execution when an expectation fails
[finish #1165916] #577
2015-03-05 15:28:00 -08:00
Gregg Van Hove
1a08d1e8c6 Don't use deprecated onComplete syntax for jasmine-npm 2015-03-04 17:44:05 -08:00
Gregg Van Hove
ce9600a3f6 Allow the clock to be installed for the duration of a single closure
[finish #67434180]
2015-03-04 17:41:49 -08:00
Gregg Van Hove and Molly Trombley-McCann
c58d83bbe3 Merge branch 'remove-unnecessary-conditional' of https://github.com/toddbranch/jasmine into toddbranch-remove-unnecessary-conditional 2015-03-04 12:00:07 -08:00
Gregg Van Hove and Molly Trombley-McCann
1c6f4ef0e6 Build distribution for previous changes 2015-03-04 11:58:47 -08:00
Gregg Van Hove
c77ff30263 Show the name of the constructor function when printing an any
- instead of a `toString` of the entire constructor

Fixes #796
2015-03-03 13:27:31 -08:00
Gregg Van Hove
dc652cfb05 Clean up some TreeProcessor stuff.
- Properly segment parents of segmented suites
2015-03-03 13:14:20 -08:00
Gregg Van Hove
22f58c0049 Merge pull request #789 from sgravrock/safe-temp-dir
Don't use hardcoded temporary directory paths
2015-03-02 13:59:26 -08:00
slackersoft
715de7aa38 Implement TreeProcessor to solve some issues with running the suite
- execute beforeAll/afterAll once per suite instead of once per child
  when running focused specs/suites Fixes #773
- refuse to execute an order if it would cause a suite with a beforeAll
  or afterAll to be re-entered after leaving once
- report children of an xdescribe similarly to how they would be
  reported if they were themselves x'd out Fixes #774
- only process the tree once instead of figuring it out again at each
  level

[finishes #87545620]
Fixes #776
2015-03-02 11:41:45 -08:00
slackersoft
0c68cc4afc Fix spec so it can be run in isolation
relates to #790
2015-02-27 16:57:23 -08:00
slackersoft
ce6ce4e2c7 Add safari 7 & 8 to browser matrix 2015-02-27 13:44:55 -08:00
Greg Cobb
10f87b3b90 Fixes issue where mock clock was being used by QueueRunner
- If the mock clock was installed in a beforeAll, the QueueRunner would use the mock clock for its own clock.  If the mock clock was ticked more than the default timeout, async specs would timeout.

[fixes #783 #792]
2015-02-24 21:56:52 -05:00
Steve Gravrock
0776146d3b Don't use hardcoded temporary directory paths 2015-02-22 16:03:20 -08:00
Todd Branchflower
bbac4bb23f remove unnecessary conditional 2015-02-20 14:04:08 -07:00
Gregg Van Hove
8c59875afe Merge pull request #775 from joscha/patch-1
add missing semicolon
2015-02-09 09:54:54 -08:00
Joscha Feth
cdee9c8853 add missing semicolon 2015-02-09 15:40:41 +01:00
Greg Cobb and Gregg Van Hove
69956bf8f6 ObjectContaining matches prototype properties
[#769]
2015-02-05 14:15:57 -08:00
Christopher Amavisca
e1249ac89a Remove unused standaloneBuilder var from Gruntfile 2015-02-04 17:06:56 -08:00
Christopher Amavisca
a84e0cd8ef Add test script to package.json
- Use `npm test` in travis-node-script
2015-02-04 16:55:07 -08:00
Christopher Amavisca
6177a4aeff Update bower.json keywords to match package.json keywords 2015-02-04 16:36:43 -08:00
Christopher Amavisca
471a241493 Add keywords to package.json 2015-02-04 16:36:31 -08:00
Greg Cobb and Gregg Van Hove
d5dfbc98c3 Updates pretty printer to include array properties
[fixes #766][finishes #87644044]
2015-02-04 11:05:03 -08:00
Gregg Van Hove
2ab2a83a3b Merge pull request #768 from danilovaz/master
Update year copyright
2015-02-04 09:58:40 -08:00
Greg Cobb and Gregg Van Hove
f22862fd80 Merge branch 'juliemr-arrayfix'
Fixes #765
2015-02-04 09:38:45 -08:00
Julie Ralph
53b0752ff0 Allow arrays from different frames or contexts to be equal 2015-02-04 09:28:04 -08:00
Danilo Vaz
7616e5a3fd Update year copyright 2015-02-04 08:42:18 -02:00
Greg Cobb and Gregg Van Hove
e173cd1c9d bump version to 2.2.1 for bower fix 2015-02-02 12:24:14 -08:00
Gregg Van Hove
234dc1a047 Merge pull request #763 from gabrielhpugliese/gabrielhpugliese-patch-bower-json
Fix missing comma on bower.json
2015-02-02 12:16:47 -08:00
Gabriel H Pugliese
d22a030b87 Fix missing comma on bower.json 2015-02-02 18:03:32 -02:00
Greg Cobb and Gregg Van Hove
4acb7448d8 Update release notes and bump version for 2.2.0 2015-02-02 11:27:14 -08:00
slackersoft
a26e85ff3a update 2.2.0 release notes now that I've pulled 2015-01-30 13:03:08 -08:00
slackersoft
39e175c05f Initial cut of release notes for 2.2.0 2015-01-30 13:02:01 -08:00
Christopher Amavisca
d129a6c0ee Restructure node examples folder structure to look more realistic.
- Updates PlayerSpec's require statement to match folder structure change
2015-01-27 14:39:59 -08:00
slackersoft
837101c025 Add a basic bower config
- Also ignore sauce_connect.log

Fix #719
2015-01-26 17:53:41 -08:00
slackersoft
8e3066db42 Allow pending to take a reason and show it in the HtmlReporter
[#78954014] Fix #671
2015-01-26 15:55:31 -08:00
slackersoft
a857f4c042 Merge branch 'ptomato-gjs-global-object' 2015-01-26 12:22:05 -08:00
slackersoft
dca543accb Merge branch 'gjs-global-object' of https://github.com/ptomato/jasmine into ptomato-gjs-global-object 2015-01-26 12:21:56 -08:00
slackersoft
5dbcf27f72 Merge branch 'ptomato-spidermonkey-compat' 2015-01-26 11:47:35 -08:00
slackersoft
b54de4a180 Merge branch 'spidermonkey-compat' of https://github.com/ptomato/jasmine into ptomato-spidermonkey-compat 2015-01-26 11:47:09 -08:00
slackersoft
46509f05a9 Add jshint to node run on travis
- To ensure that pull requests pass

[Finish #59588854]
2015-01-26 10:59:44 -08:00
Philip Chimento
ebaa2e7f24 Set jasmineGlobal correctly in GJS
In GJS, jasmineGlobal was not getting set to the global object; when
importing jasmine.js in GJS, "this" resolves to the jasmine.js module
object, not the global object. Solve this specifically for GJS by
assuming that `window.toString === '[object GjsGlobal]'` only in GJS; if
this is the case, assign "window" to "jasmineGlobal".

Adding a "var" to the declaration of "getJasmineRequireObj" is also
necessary, or else "getJasmineRequireObj" won't be exported in the
Jasmine module.

See #751
2015-01-24 23:50:40 -08:00
Philip Chimento
5eaf7152bf Fix some SpiderMonkey lint
SpiderMonkey complains about functions not always returning a value. In
most cases that is a conscious code style choice, so it is not fixed
here.

In one case (MockDate) the interpreter thought you could have fallen off
the end of a "switch" statement, although the number of arguments
prevented that. This was fixed by changing the last case to "default".

In another case (QueueRunner) the function really did return a value
sometimes and nothing other times, although as far as I could see, it
could only ever return "undefined". The function now explicitly only
returns no value.

See #751
2015-01-24 23:43:38 -08:00
Greg Cobb
ebbaab4cf9 Prevents *Alls from running when runnables are explicitly set
- This requires passing if runnables are set to the Suite. Hopefully in
  the future we will change how focused runnables and *Alls interact so
  this is no longer necessary.

[#732]
2015-01-23 17:27:13 -08:00
Greg Cobb
1936a36c79 Fix jslint issues 2015-01-23 17:23:07 -08:00
slackersoft
1dd4af3835 anything and stringMatching have custom pretty-print now. 2015-01-21 12:59:01 -08:00
slackersoft
6ae054c3e2 Update contribution guide to mention possible ffi dependencies for Ubuntu
Fixes #755
2015-01-21 12:55:07 -08:00
Gregg Van Hove
e5feba994f Merge pull request #746 from swirlycheetah/patch-1
Fix spelling mistake
2015-01-14 17:00:19 -08:00
Chris Wheatley
20faa883fb fix spelling mistake 2015-01-14 22:15:49 +00:00
Gregg Van Hove
3bba1eabd4 Merge pull request #745 from rohit/fix-repo-url
Use new jasmine github repo url
2015-01-14 10:26:39 -08:00
Rohit Arondekar
9ad3eac469 Use new jasmine github repo url 2015-01-14 20:47:09 +05:30
Gregg Van Hove
3140d5fb95 Allow createSpyObj to be called with just an array of method names
[Finish #50757607] #321
2015-01-12 15:16:50 -08:00
Gregg Van Hove
69a61547e7 Don't forget to buildDistribution
- Also fix jshint errors

[#59947350] #440
2015-01-12 14:10:50 -08:00
Gregg Van Hove
a999490de9 Merge branch 'arrayContaining' of https://github.com/slackersoft/jasmine into slackersoft-arrayContaining
Merge #440 [Finish #59947350]
2015-01-12 14:01:02 -08:00
Gregg Van Hove
c1479acd17 Fix fail specs for all browsers #734 2015-01-12 13:37:10 -08:00
Gregg Van Hove
3a93f845d6 Use the stack trace from the Error object if supplied
Fixes #734
2015-01-12 11:51:45 -08:00
Gregg Van Hove
6c58024321 Update readme with link to upgrading doc and mention browser support.
Fix #739
2015-01-12 11:06:59 -08:00
Gregg Van Hove
aeae141fd4 Merge branch 'moonmaster9000-patch-2' 2015-01-12 10:08:15 -08:00
Matt Parker
a951bbbb47 Link to the Jasmine NPM module
Also, put the jasmine-<language> links above the confusing "install jasmine on your local box" stuff (why would I want to do that?)
2015-01-12 10:08:04 -08:00
slackersoft
895c17e5c1 Merge branch 'rohit-equals-null-protoObjects' 2014-12-20 16:48:26 -08:00
Rohit Arondekar
a84eaf2cbe Allow null prototype obj to be compared for equals
Fixes #729
2014-12-20 08:35:27 +05:30
slackersoft
9f240c5b9e Build distribution to properly expose stringMatching
[#58120558]
2014-12-19 12:45:58 -08:00
slackersoft
dfa8a77dc3 Add asymmetric equality tester to match a string against a regexp
- Also move the asymmetric testers into their own dir for easier
  locating.

[#58120558] Fix #243
2014-12-19 12:39:24 -08:00
Gregg Van Hove
2472982fe9 Merge pull request #730 from rohit/patch-1
Fix URL's of Jasmine repositories on Github
2014-12-19 09:21:02 -08:00
Rohit Arondekar
c85500a924 Fix URL's of Jasmine repositories on Github 2014-12-19 07:36:03 +05:30
slackersoft
482f4d62fc Add anything matcher to match any value that is neither null or undefined
[finish #58117878] Fix #186
2014-12-17 12:58:47 -08:00
slackersoft
bfcd8b046d Allow asymmetric equality testers to preempt their symmetric brethren
- Also allow them to be compared to each other properly.

Fixes #540
2014-12-16 17:45:58 -08:00
slackersoft
2ab22951a1 Just check if either side implements asymmetricMatch
- Don't explicitly look for `Any` or `ObjectContaining`

[#82295210]
2014-12-16 17:29:18 -08:00
slackersoft
6c131beda7 Don't double escape focus spec links.
- QueryString already escapes parameter values, no need to escape when
  passing them in from HtmlReporter.

[finish #29578495]
2014-12-16 17:21:22 -08:00
slackersoft
ea88023553 Check for ObjectContaining on either side of equality.
- Also clean up `undefined` check.

Fixes #682
2014-12-16 17:07:35 -08:00
slackersoft
6bd98cb2ab Rename jasmineMatches to asymmetricMatch
- This should be more clear what it is for

[finish #82295210]
2014-12-16 16:47:31 -08:00
slackersoft
b4b3ac25a1 spyOn explicitly checks to see that a method name to spy on was passed.
[finish #27689237]
2014-12-16 13:21:48 -08:00
slackersoft
7570bc422b Display the name of the constructor when pretty printing objects
Fixes #598 [finishes #81228592]
2014-12-16 12:56:04 -08:00
slackersoft
eca8d8f009 Also test in IE 11 on travis 2014-12-16 11:57:48 -08:00
slackersoft
305252f5a8 toMatch requires the expected to be a String or RegExp
- Otherwise it was using the `toString` as the RegExp, which is almost
  definitely _not_ what you want.

Fixes #723
2014-12-16 11:50:45 -08:00
slackersoft
0fdb28c6ff Merge branch 'toEqualDomNodes' of https://github.com/alexeibs/jasmine into alexeibs-toEqualDomNodes 2014-12-16 11:25:14 -08:00
slackersoft
a84202a6f9 Also check custom properties on Arrays when computing equality
[Finishes #50616649]
2014-12-16 10:22:23 -08:00
slackersoft
503f4b7f49 Keep extra query params when focusing on a spec or suite
[finish #29578495]
2014-12-15 18:30:32 -08:00
slackersoft
fbe38018c9 Hide more things from the npm package
Fixes #726
2014-12-11 12:48:50 -08:00
slackersoft
8bb2f67fb3 Properly record finishing an xdescribe so further cleanup works
Fix #724
2014-12-09 12:40:00 -08:00
slackersoft
ba9c863de9 Add spec to verify custom query params are left alone
[#29578495]
2014-12-05 08:12:42 -08:00
slackersoft
02161b7d48 ObjectContaining no longer tries to track exact mismatches
- equals wasn't looking at it anyways, so just bail as soon as something
  is different.
2014-12-05 08:06:20 -08:00
slackersoft
4d5f27d359 Reschedule all functions for a tick before executing any
- This allows any function run during a tick to cancel any other in the
  same tick.

Fixes #708
2014-12-05 08:01:34 -08:00
slackersoft
a4faa80be4 pass through all args from external interface for befores, afters, its
Fix #483
2014-12-02 13:29:43 -08:00
slackersoft
b68ba90ad7 Just return the result directly from any and objectContaining
- They return false when they fail which means not equal.
2014-12-02 07:56:40 -08:00
slackersoft
dc7be9c55e change 2.1.3 release notes filename to match others 2014-12-01 12:49:40 -08:00
slackersoft
b56c2a69ac add standalone dist for 2.1.3 2014-12-01 12:46:52 -08:00
slackersoft
4b6789ccd9 version bump for 2.1.3 2014-12-01 12:43:52 -08:00
slackersoft
9f94e8e226 Top level suite no longer reports suiteStart and suiteDone
- jasmineStart and jasmineDone are reported separately

Fixes #716
2014-11-28 21:25:45 -08:00
slackersoft
55f32e2dc6 Don't keep the expected and actual for a passed expectation
- It causes memory problems in phantom and you probably don't need it
  anyways.

Fixes #640 Fixes #690
2014-11-22 15:03:27 -08:00
Gregg Van Hove
b30a85c8f1 Merge pull request #712 from joshk/patch-1
Use the new build env on Travis
2014-11-22 14:58:34 -08:00
Josh Kalderimis
20ce62d5f5 Use the new build env on Travis
better faster stronger

more ram, cpu, faster boot times, better network

docs coming soon
2014-11-22 14:21:03 -05:00
Christopher Amavisca
c3de57aaac Update travis badge 2014-11-22 11:16:07 -08:00
slackersoft
2517ddfe17 bump verion to 2.1.2 2014-11-16 14:56:27 -08:00
slackersoft
23a492cb65 Suites still run their children even if none are executable
- Continue skipping beforeAll and afterAll

Fixes #707
2014-11-16 14:43:44 -08:00
slackersoft
25c546a904 add release notes and standalone dist for 2.1.1 2014-11-14 18:44:28 -08:00
slackersoft
97ab0cb403 bump version to 2.1.1 2014-11-14 18:43:00 -08:00
slackersoft
42b1bda919 Top-level suite triggers suiteStarted and suiteEnd to be consistent
Fixes #706
2014-11-14 18:37:00 -08:00
slackersoft
216b40439f Attempt to use selenium runner from source, to fix dependency loop 2014-11-14 12:41:50 -08:00
slackersoft
590a9d9d41 bump version to 2.1.0 2014-11-14 07:54:19 -08:00
Davis W. Frank
66c8624022 Updating links in release notes 2014-11-11 09:46:38 -08:00
Davis W. Frank
75e5a5c308 Fix for wayward underscore and Anchorman bug 2014-11-10 17:24:06 -08:00
Davis W. Frank
9b5c20cc19 Adding first crack at 2.1 release notes 2014-11-10 17:15:57 -08:00
slackersoft
cc720e7f56 Add release notes for previous releases, so they can be removed from the wiki
[#54582902]
2014-11-06 08:21:31 -08:00
Gregg Van Hove
1426416666 Merge pull request #700 from tkrotoff/patch-1
Simplifies SpecRunner.html
2014-11-04 13:20:55 -08:00
Tanguy Krotoff
197cb13817 Simplifies SpecRunner.html
No need to specify type="text/javascript" for script tag
No need to specify type="text/css" for link tag with rel="stylesheet"
2014-11-04 10:30:11 +01:00
slackersoft
816b7d701f Merge branch 'charleshansen-to_contain_array_like_objects' 2014-11-03 13:10:13 -08:00
Charles Hansen
da6813ef0d toContain works with array-like objects (Arguments, HTMLCollections, etc)
Fixes #699

Don't rely on Array.prototype.indexOf for testing containment (not in IE8)
2014-11-03 13:09:57 -08:00
slackersoft
a4d134521a Revert "toContain works with array-like objects (Arguments, HTMLCollections, etc)"
IE 8 doesn't have Array.prototype.indexOf so this breaks there.
Reverting until we can figure out a better way to solve across all
supported browsers.

This reverts commit 663fbd0cdb.
2014-11-01 14:28:32 -07:00
slackersoft
d4fc787ea7 Merge branch 'charleshansen-to_contain_array_like_objects' 2014-10-30 13:08:45 -07:00
Charles Hansen
663fbd0cdb toContain works with array-like objects (Arguments, HTMLCollections, etc)
Fix #699
2014-10-30 13:08:16 -07:00
Matt Parker
cf83ae474c Added Sheel to the Maintainers Emeritus list 2014-10-25 08:07:15 -07:00
Matt Parker
325c5a2288 Name / Email / Org updates in README 2014-10-25 07:51:18 -07:00
Gregg Van Hove
3ca687a9ad Merge pull request #691 from ertrzyiks/fix-spec-title
Fixed isPendingSpecException test title
2014-10-22 09:52:10 -07:00
Mateusz Derks
3b557f85c7 Fixed isPendingSpecException test title 2014-10-17 15:36:24 +02:00
slackersoft
b67a19507f Add notes for releasing new versions of the docs 2014-10-11 22:13:26 -07:00
slackersoft
ecae3d47a7 Use the jasmine-npm tarball, since that works on travis
[#80505862]
2014-10-11 15:04:04 -07:00
slackersoft
a76d6d1cd4 Pass in the current distribution when running node specs
- npm package spec can use beforeAll/afterAll now
- also depend on github repo directly instead of the tarball

[finish #80505862]
2014-10-11 14:54:08 -07:00
slackersoft
916dc03d9c build distribution with deprecated console
[#80410002]
2014-10-11 14:28:51 -07:00
slackersoft
2151a13705 Let's just use the print function that's passed in for deprecation messaging
[#80410002]
2014-10-11 14:20:19 -07:00
slackersoft
6cc09e00d3 Oh right, IE doesn't have console by default
[#80410002]
2014-10-11 13:54:41 -07:00
slackersoft
6d6c31328b Deprecate console reporter
- jasmine-npm has its own version so it's no longer dependent on this
  one.

[finish #80410002]
2014-10-11 13:34:45 -07:00
Gerg
c8cd2eabe5 Fixes console check for IE8
- Was causing IE8 to hang for some reason
- Also reverts previous commit, not that issue was resolved

[#79533268][fixes #80356450]
2014-10-09 00:41:17 -07:00
Gerg
f77071254a Fixes additional odd IE8 failure
[#79533268]
2014-10-08 23:14:40 -07:00
Gerg
8880729250 JsApiReporter suiteResults only includes suite results
- It was including suite starts also

[#79533268]
2014-10-08 22:33:36 -07:00
slackersoft
9ad15eeaba Merge branch 'akoptsov-patch-1' 2014-10-08 12:52:40 -07:00
Alexander Koptsov
10ca5f0246 Fixed path to src files in node_example
There's no such folder as 'jasmine_examples'
2014-10-07 16:35:38 +04:00
Gerg
a5cd2731b4 Fixes CI for IE8
For some reason, when you put this spec in a describe block, it causes
specs to hang on IE8. I tried to debug this for a while, and I have no
idea what is happening.

[#79533268]
2014-10-05 14:33:40 -07:00
Gerg
b12974db2e Adds suiteResults method to JsApiReporter
- Behaves similarly to to specResults
- Since suites were stored in an object instead of an array and the
  current interface exposes this object, we now must keep track of suites
  twice in the reporter. We cannot just construct the object lazily,
  because then the object will not update with new suite results
  like it does currently (see JsApiReporterSpec:148).

[#79533268]
2014-10-04 18:36:38 -07:00
slackersoft
f4e5573ee3 Add explicit fail and move on for async functions
- `done` now has a `fail` property which will call the global `fail`
  then continue to the next function in the queue

[finish #73744618] Fix #567 Fix #568
2014-10-02 08:10:29 -07:00
slackersoft
0c77c6cfb5 Use the Gemfile from the docs repo 2014-10-01 13:10:11 -07:00
slackersoft
cfc64a6f5c bundle exec the docs rake tasks 2014-10-01 09:59:39 -07:00
slackersoft
6ab70923b3 Use rake tasks in the docs repo to test it 2014-10-01 08:15:35 -07:00
slackersoft
d9c0b10be4 Remove type from queueableFns since we're not using it to determine afterAll anymore. 2014-09-30 18:28:41 -07:00
slackersoft
a58fd20d82 Build distribution for suite failed status changes 2014-09-26 18:35:06 -07:00
slackersoft
eefa716530 set suite status to failed when afterAll has failures 2014-09-26 09:12:48 -07:00
slackersoft
66c364564e Fix custom timeout specs for firefox 2014-09-26 08:21:54 -07:00
slackersoft
68ba5b6d48 Allow custom timeout for beforeEach, afterEach, beforeAll, afterAll and it
Fix #483
2014-09-25 22:31:00 -07:00
slackersoft
15ae0379ec Add fit and fdescribe to the public interface
They got lost in the merge
2014-09-25 13:19:13 -07:00
slackersoft
1fb0d2eefa Merge branch 'master' of https://github.com/chernetsov/jasmine into chernetsov-master
Fix #678 Close #679
2014-09-25 12:59:10 -07:00
slackersoft
ba0982d89f Merge branch 'beforeAll' into master
Conflicts:
	lib/jasmine-core/boot.js
	lib/jasmine-core/boot/boot.js
	lib/jasmine-core/jasmine.css
	lib/jasmine-core/jasmine.js
	spec/core/SpecSpec.js
	spec/core/SuiteSpec.js
	spec/core/integration/EnvSpec.js
	spec/node_suite.js
	src/core/Env.js
	src/core/requireCore.js
	src/core/util.js
2014-09-24 20:20:39 -07:00
slackersoft
f703539942 build distribution for toThrowError refactor 2014-09-24 18:27:40 -07:00
Misha Chernetsov
62840f72a6 when jasmine clock is installed and date is mocked new Date() instanceof Date should equal true 2014-09-24 15:07:22 -07:00
slackersoft
6d10f97151 Merge branch 'toThrowError_refactor' 2014-09-24 13:23:50 -07:00
slackersoft
15f3d0e9d7 update doc comment for boot.js to match current documentation 2014-09-23 08:22:05 -07:00
slackersoft
b1344d5c73 Add explicit fail function.
- Adds an expectation failure to the current spec

[finishes #70975468] Fix #563
2014-09-23 08:00:46 -07:00
slackersoft
59aaac026c Merge branch 'paladox2015-patch-1' 2014-09-22 13:10:12 -07:00
slackersoft
21f62c697a Merge branch 'patch-1' of https://github.com/paladox2015/jasmine into paladox2015-patch-1 2014-09-22 13:09:07 -07:00
slackersoft
dc93c33af6 Merge branch 'pimterry-trackReturnValues' 2014-09-22 13:04:18 -07:00
slackersoft
4889583d5c Merge branch 'trackReturnValues' of https://github.com/pimterry/jasmine into pimterry-trackReturnValues 2014-09-22 13:04:01 -07:00
slackersoft
41df058171 update contributing doc to indicate use of jasmine-npm 2014-09-20 20:54:45 -07:00
slackersoft
fa837ae90a Don't depend on debugger gem, we don't really have any ruby code here. 2014-09-20 20:17:55 -07:00
slackersoft
c82c958e0d Build distribution for earlier fixes 2014-09-16 13:05:11 -07:00
slackersoft
752e831b30 Merge branch 'mkhanal-chain_spy_andReturn'
Fix #669 #660
2014-09-15 13:10:40 -07:00
slackersoft
bd30065d66 Merge branch 'chain_spy_andReturn' of https://github.com/mkhanal/jasmine into mkhanal-chain_spy_andReturn 2014-09-15 13:10:24 -07:00
slackersoft
84dff421ea Use === when checking for circular dependencies for pretty printing. 2014-09-13 18:58:02 -07:00
Mridul
709e032d1c Added returnValues functionality to spy strategy 2014-09-13 12:41:20 +10:00
Greg Cobb
1290d93b6a Suite result status added when suite is complete
- This makes it easier to detect afterAll failures, because we can
  rely only complete runnables having statuses

[#78306786 & #73741654]
2014-09-09 11:26:32 -07:00
slackersoft
345903220c Refactor toThrowError to be less one huge if/else if/else if block
- This should also improve it's code climate score as well.
- It's also about 20 lines shorter now too :)

[#59524164]
2014-09-07 16:02:42 -07:00
Greg Cobb
3332f93a24 Only run focused runnables inside focused suites
- Focused runnables now walk up the tree to unfocus the first focused
  ancestor. Because of the way the tree is constructed, this makes sure
  that each focused runnable has no focused ancestors.

[#78289686]
2014-09-05 12:25:28 -07:00
slackersoft
3b19d66268 Check for afterAll failures in a more browser independent way.
- Only look at the message, so browsers that don't provide a stack don't
  blow up.
2014-09-04 18:49:14 -07:00
slackersoft
137c1a39f6 Check afterAll failure messages with regexp, since some browsers add more info 2014-09-04 08:15:23 -07:00
slackersoft
9402d59859 Suites report errors in afterAlls in the suiteDone event
- remove `afterAllEvent` from reporters
2014-09-03 22:18:20 -07:00
slackersoft
e8178d061b Merge branch 'tgirardi-issue655'
Fix #655 #658
2014-09-02 13:20:18 -07:00
slackersoft
dd75394ea8 Merge branch 'issue655' of https://github.com/tgirardi/jasmine into tgirardi-issue655 2014-09-02 13:19:31 -07:00
Greg Cobb and Tim Jarratt
6b857d11ce Factor out some common logic between fdesc and desc 2014-08-29 09:25:41 -07:00
Tomás Girardi
eb48c83649 Add specs for intervals that "clear themselves"
Add specs to test if issue #655 is present: the handler of an interval
cannot successfully clear the same interval that generated it's
invocation.

The most direct test consist in setting an interval with a handler that
calls clearInterval over that same interval and make the clock tick for
double of it's period. If the issue is present the interval's handler
will be called twice. If the issue is not present, the first invocation
of the handler will avoid a second one (because of the clearInterval).

Another test is included in order to check if recurring scheduled
functions are rescheduled before being called. Doing this in the reverse
order is the exact cause of the issue.
2014-08-28 20:58:30 -04:00
Greg Cobb and Tim Jarratt
08a35d134d Ensure focused tests are only run once
Required duplicating some of the logic for constructing a suite from
describe so that we could mark a suite as focused in fdescribe, but
otherwise this prevents focused tests from being run more than once.

[#73742944]
2014-08-28 17:54:42 -07:00
Greg Cobb and Tim Jarratt
14824b5f9e Expose fit and fdescribe in boot.js
* adds done() callbacks to existing specs (because we forgot, whoops!)

[Finishes #73742944]
2014-08-28 16:37:37 -07:00
Greg Cobb and Tim Jarratt
9afae3d978 Add a test documenting fits in fdescribes
Yo, this probably isn't the best behavior. Rspec and Ginkgo definitely
do not exhibit this behavior when you nest focused runnables inside
other focused runnables. We thought fixing it, but it seems like a
nontrivial refactoring would be necessary to clean this up.

[#73742944]
2014-08-28 16:19:31 -07:00
Greg Cobb and Tim Jarratt
64a67ed320 Trim extraneous whitespace 2014-08-28 15:55:39 -07:00
Greg Cobb and Tim Jarratt
dee1066652 Focused runnables play nicely with beforeAll/afterAll
[#73742944]
2014-08-28 15:54:27 -07:00
Greg Cobb and Tim Jarratt
d7ab9083be Add focused describe
[#73742944]
2014-08-28 15:43:59 -07:00
Greg Cobb and Tim Jarratt
caee1508d1 Adds a fit function to Env
[#73742944]
2014-08-28 15:37:18 -07:00
slackersoft
3b8326f1e6 Detect global object properly when getting the jasmine require obj
- Pull global detection into requireCore and pass the global to base

Fix #569
[fix #73684570]
2014-08-28 13:31:04 -07:00
Greg Cobb and Tim Jarratt
980509cd7b Preserve relative order of "alls" w.r.t. "eachs"
[Finishes #73742528]
2014-08-28 11:54:58 -07:00
Greg Cobb and Tim Jarratt
b984ff2fa6 Run before,afterAlls as 'eachs' when specifying runnablesToRun
- Fix bug where beforeAlls were being mutated in Suite#execute
- When Env.execute() receives a list of runnables, beforeAlls and
  afterAlls are collected as beforeEachs and afterEachs. This allows
  runnables to be specified in any order, regardless of if any of them
  have before/afterAlls.
- Spec constructor takes a single function that returns both before and
  afters, instead of two functions. This breaks the current interface
  for constructing a Spec.

[#73742528]
2014-08-28 11:54:54 -07:00
Greg Cobb and Tim Jarratt
61bf9ac7d7 Improve quality of async timeout for afterAll spec
We found that this test was always passing and had strange interactions
with the ordering of other specs. Rewriting it to explicitly finish the
afterAll after a specified interval makes it fail correctly.

[#73742528]
2014-08-28 11:54:46 -07:00
Greg Cobb and Tim Jarratt
5b397ff33e Revert "Deprecate suite/spec ordering hook ."
This reverts commit 76fafa0388.

[#73742528]
2014-08-28 11:54:27 -07:00
Greg Cobb and Tim Jarratt
cd4d5c2445 ConsoleReporter exits 1 when afterAll events occur
[Finishes #67068790]
2014-08-27 14:45:59 -07:00
Greg Cobb and Tim Jarratt
5b6edff3fd Report AfterAll failures as they occur
There didn't seem to be a valid reason to wait until the very end to
report these.
2014-08-27 14:01:28 -07:00
Greg Cobb and Tim Jarratt
cc3678f033 Refactor suite to share reportExpectationFailure func
This was shared between our suite factory and the suite factory.
Sweet.
2014-08-27 13:50:56 -07:00
Greg Cobb and Tim Jarratt
35f52bcb24 Rewrite an incorrect suite spec 2014-08-27 12:27:11 -07:00
slackersoft
f8bccabf03 Move afterAll reporting into Suite since that's where they're being tracked 2014-08-27 08:13:17 -07:00
Greg Cobb and Tim Jarratt
97867b2bf5 Reports expectation failures in afterAlls
This makes the specs green and appears to work for most cases. I have a
number of concerns about the implementation and would appreciate
ideas/feedback.

- Suite#addExpecationResult infers if it is coming from an afterAll fn
  based on if the first child of the suite is finished. This assumes
  that the first child of the suite is a spec (this appears to be true
  as long as there is at least one spec in the suite)
  - Suites behave like unfinished specs. Because suites will propagate
    expectation failures to their children suites, the afterAll
    expectation reporting appears to work for suites without specs
    unless you have:
    1) An otherwise empty suite with an afterAll
    2) An afterAll'd suite whose first suite is empty (or whose first
    suite's first suite is empty (and so on))
- Changed afterAllError to afterAllEvent, so it can accommodate both
  errors and expectation failures. The reporter now receives a string
  instead of the actual error object. The loss of the object doesn't
  affect our reporters, but may be a nice-to-have for other reporters/
  the future.
- The gap between the expectations caught in Suite and QueueRunner (who
  triggers reporting via an injected callback) is an array injected into
  QR by the Suite. The array is then flushed at some point (currently
  after the attempt… functions). This works, but is a bit goofy.

[#73741654]
2014-08-26 18:04:12 -07:00
slackersoft
18eb6e2f36 Don't run npm package specs in browsers 2014-08-26 13:18:16 -07:00
Tomás Girardi
51462f369b Allow clearInterval to clear it's own interval
As described in issue #655, the handler of an interval cannot
successfully clear the same interval that generated it's invocation.

Solve this issue by changing the order in which interval's handlers are
called and then rescheduled to: first reschedule it and then call it.

The actual order (call first then reschedule) produces that, during the
execution of the interval's handler, the handler is not registered as
a function to run after a timeout or interval ("scheduledFunctions"),
because it was previously unregistered. Consequently, if the handler
calls clearInterval, that function wont be able to find the handler and
remove it completely.
2014-08-26 12:01:49 -04:00
slackersoft
ea57ad97cf Add some tests to make sure we're packaging up the npm properly 2014-08-26 08:08:04 -07:00
slackersoft
3132d98f23 Bump version to 2.0.4 now that I think npm files are sorted 2014-08-24 21:14:11 -07:00
slackersoft
b799f54bc9 Remove runtime dependency on 'glob' so we have no runtime deps
- Clean up .npmignore a bit more
2014-08-24 21:11:50 -07:00
Alexei Bykov
ac8ef2988d add better support of DOM nodes into equality matcher 2014-08-24 17:07:18 +04:00
slackersoft
3c051fc291 bump to 2.0.3 to fix npm dependencies 2014-08-22 22:50:46 -07:00
slackersoft
6b937da863 Fix npm dependencies 2014-08-22 22:47:43 -07:00
slackersoft
89232db2ee Version bump to 2.0.2 2014-08-22 22:20:38 -07:00
slackersoft
8b0d9c83bb keep the files for running in a webpage around in the npm package
[Fixes #656]
2014-08-21 12:56:04 -07:00
slackersoft
60533ca868 Expose files and paths necessary to embed jasmine in an html page for nodejs 2014-08-21 08:17:02 -07:00
slackersoft
048ab728ec Pull out the building of the jasmine interface so node and web both get the same one. 2014-08-15 08:14:59 -07:00
slackersoft
488df899fb Merge branch 'javenwang-suite-start' 2014-08-06 13:24:25 -07:00
slackersoft
753f4b44b4 Merge branch 'suite-start' of https://github.com/javenwang/jasmine into javenwang-suite-start 2014-08-06 13:24:01 -07:00
slackersoft
2c23d35b03 Merge branch 'javenwang-disabled-suite' 2014-08-06 13:14:00 -07:00
Javen Wang
2b0be0c74b a disabled suite should call resultCallback with status being disabled
close #574
2014-08-06 13:09:44 -07:00
slackersoft
b4f49db6bd Show a dot with color of pending spec when no expectations
[fix #76307802]
2014-08-04 12:48:35 -07:00
slackersoft
cee3cc56e6 fix casing for jshint 2014-07-31 13:42:09 -07:00
slackersoft
f2346d357f Allow mocked Date constructor to be called with a subset of full params
Fix #643 #624
2014-07-31 13:42:05 -07:00
Sheel Choksi
ee09301d8d Console reporter prints out failed expectation's message
Previously, was only printing out the stack while the html reporter
would print out the message as well as the stack. Now they should be
more consistent.

As noticed by @despairblue in #638
2014-07-27 18:31:47 -07:00
Davis W. Frank
760b50d969 Adding NPM instructions 2014-07-21 13:56:15 -07:00
Davis W. Frank
773b15e450 Fixed typo in 2.0.1.md 2014-07-21 13:24:10 -07:00
Davis W. Frank
227698f5fa Updating source and standalone distribution to 2.0.1 2014-07-21 12:36:24 -07:00
Davis W. Frank
ff1fa6a893 Updating version to 2.0.1 2014-07-21 12:35:34 -07:00
Davis W. Frank
ba1f8bc036 Merge branch 'master' of https://github.com/pivotal/jasmine 2014-07-21 12:33:42 -07:00
Davis W. Frank
a5be51f912 First cut at 2.0.1 release notes 2014-07-21 12:33:39 -07:00
Rajan Agaskar
d64ed6ebe9 Merge pull request #632 from kissrobber/bug_fix
Fixes incorrect use of signature args

- Not currently an issue, since always called with '2', but could break unexpectedly if argSlice is used without reading the body.
2014-07-21 06:46:05 -07:00
kissrobber
062dc6b15a fix a potential bug 2014-07-21 00:35:33 +09:00
slackersoft
33641578e6 update release doc to use github releases 2014-07-18 14:27:18 -07:00
slackersoft
a1c109ea17 Contains is explicitly false if actual is undefined or null
Fix #627
2014-07-18 13:18:22 -07:00
slackersoft
62212bbfa4 use released jasmine selenium runner 2014-07-18 13:07:11 -07:00
Rajan Agaskar
6a89d084f4 Merge pull request #621 from bengrunfeld/docs-installation
Add installation instructions to README
2014-07-07 12:56:32 -07:00
bengrunfeld
013c4f725f Add Ruby Gem and Python Egg to docs 2014-07-07 10:11:13 -06:00
bengrunfeld
c064488192 Add installation instructions to README 2014-07-07 09:37:44 -06:00
Sheel Choksi
f20df57607 Keeping jasmine_selenium_runner in Gemfile only for now 2014-06-28 18:09:41 -07:00
Sheel Choksi
48f7a5f17b Point to head of jasmine_selenium_runner
jasmine_selenium_runner on master now has a fix for printing circular
objects which is needed since Jasmine has some circular objects that are
included now that we return passedExpectations (but was a bug with
    failedExpectations anyways)
2014-06-28 17:59:29 -07:00
Sheel Choksi
f7ff47706c Remove 'empty' as an option as a spec result
- Having the 'empty' state for a spec result can be considered a
breaking change to the reporter interface
- Instead, we determine if a spec has no expectations using the added
key of 'passedExpectations' in combination of the 'failedExpectations'
to determine that there a spec is 'empty'

[fixes #73741032]
2014-06-27 23:50:28 -07:00
Alex Treppass
5f34be446c keeping track of passed expectations 2014-06-27 22:34:05 -07:00
Sheel Choksi
e1e49e8292 Bumping built distribution 2014-06-27 22:19:44 -07:00
paladox2015
ae94dd1bfa Update json2.js 2014-06-27 10:51:02 +01:00
Lee Penkman
eb1bd25445 namespace html-reporter -> jasmine_html-reporter 2014-06-22 21:47:46 -07:00
Lee Penkman
aac6968ed8 Stop Jasmine's CSS affecting the style of the body tag
[fixes #600]
2014-06-22 21:47:07 -07:00
slackersoft
1bad048c15 Extract afterAll checking from queueRunner 2014-06-20 08:16:42 -07:00
Sheel Choksi
7d93541c09 Throw a more specific error when 'expect' is used without a currentSpec
If an async test has timed-out, there could still be some expectations
that are scheduled to run after the fact in which case curerntSpec will
be null. Rather than the type error that would result, we now indicate
that 'expect' was used at an unexpected time.

This also helps cases where an 'expect' is being used at a top-level,
showing an error message in the console for this case as well.

[fixes #602]
2014-06-06 23:49:58 -07:00
Drew Freyling
29aad761d9 Smushed with PNG Gauntlet. 2014-06-06 23:09:08 -07:00
Sheel Choksi
7d3de92cef Merge pull request #594 from plukevdh/reporter-reset
HTML Reporter reset previous DOM when re-initialized
2014-06-06 22:59:52 -07:00
Sheel Choksi
13e0dd27c9 Narrow down raise exceptions query selector
Finding by any input tag is a little bit broad [#605]
2014-06-06 22:20:18 -07:00
slackersoft
f0892a55aa report when an async afterAll doesn't call in time 2014-06-06 18:41:06 -07:00
Sheel Choksi
fc6603e99f Merge pull request #580 from pablofiu/detailedGeneralWorkflow
added detailed steps on how to contribute coding
2014-06-02 23:04:35 -07:00
Luke van der Hoeven
07cce0b1d1 clear prior test results on multiple inits 2014-05-23 15:59:56 -04:00
Luke van der Hoeven
6750559211 failing spec for multiple inits 2014-05-23 15:58:09 -04:00
Pablo Alejandro Fiumara
0419780682 added detailed steps on how to contribute coding 2014-04-25 01:18:38 -03:00
Gregg Van Hove
6066c71966 Add failing specs for expectation failures in afterAll 2014-04-18 16:37:27 -07:00
Gregg Van Hove
0d4b04d37c rename afterAllException to afterAllError
It should also handle expectation failures
2014-04-18 16:00:02 -07:00
Javen Wang
7ad261837a disabled suite should still call onStart callback 2014-04-12 00:35:47 +08:00
Sheel Choksi
00c8e37257 Pass through custom equality testers in toHaveBeenCalledWith [fixes #536] 2014-03-26 22:19:03 -07:00
Christopher Amavisca and Davis W Frank
e53b487017 - Add a main entry point for the jasmine-core npm
- jasmine-core can now self test with the jasmine-npm
- Add node examples files
- Add node_boot.js for node environment
- Move jasmine-core npm packaging to .npmignore
- removing src_dir and src_files from jasmine.json b/c jasmine-npm does not support requiring source files automatically.
2014-03-21 17:21:52 -07:00
Sheel Choksi
ed5cd6ba2c Merge pull request #550 from slothmonster/fix-copyright-year
Fix outdated copyright year (update to 2014)

[skip ci]
2014-03-16 18:36:21 -07:00
Greg Cobb and Luan Santos
213a6023fd Add package.json to egg to get correct version number
[#67556148][#551]
2014-03-14 10:51:26 -07:00
Adam Deibert
7d220fcd1b Fix outdated copyright year (update to 2014) 2014-03-14 01:42:39 -07:00
Greg Cobb and Luan Santos
c1382c77b4 Enable bundler cache 2014-03-12 13:46:25 -07:00
Greg Cobb and Luan Santos
311263a3df Fix build in IE8 (IE8 doesn't support Object.freeze) 2014-03-12 13:45:46 -07:00
mikemoraned
33e4f5efbe Allow users to set the maximum length of array that the pretty-printer
will print out.

Currently, jasmine's pretty printer will iterate over an entire array,
formatting every element recursively. For very large arrays, this can
crash the page, or cause a 'slow script' warning.

This commit exposes a 'MAX_PRETTY_PRINT_ARRAY_LENGTH' option. If an
array larger than this is encountered, recursion will stop and the
array length will be printed instead e.g. "Array[20000000]".

The 'MAX_PRETTY_PRINT_ARRAY_LENGTH' option defaults to 100. This is
length of array will not kill your browser, but will allow you
to see big arrays, if you can stomach the output.
2014-03-12 12:16:01 -07:00
Greg Cobb and Luan Santos
367d3dcf66 Rebuild distribution 2014-03-12 11:51:49 -07:00
Greg Cobb and Luan Santos
21de44a204 Remove space between key and colon when pretty printing objects
[#4005255]
2014-03-12 11:47:47 -07:00
Greg Cobb and Luan Santos
c9e37a2a1c Refactor prettyPrinter to work with immutable objects
[#50766813][#266]
2014-03-12 11:41:18 -07:00
Davis W. Frank
9e927af56e Merge pull request #548 from pivotal/python
Create jasmine-core python egg
2014-03-11 14:05:45 -07:00
Greg Cobb
fc173e9a5e Add logo image to readme 2014-03-11 13:54:47 -07:00
Greg Cobb
62a7f64659 Update readme with correct code climate link 2014-03-11 13:49:51 -07:00
Greg Cobb and Luan Santos
3e739e4bc9 Create jasmine-core python egg 2014-03-11 13:40:28 -07:00
Greg Cobb and Luan Santos
ba6f99423f Add jasmine logo image to html runner
[#3984585]
2014-03-10 17:16:31 -07:00
Christopher Amavisca, Greg Cobb and Luan Santos
3a5672cd33 Show message if no specs are found in console reporter
[#12784235]
2014-03-10 12:00:49 -07:00
Christopher Amavisca, Greg Cobb and Luan Santos
af4cc76e2a Show message if no specs are found
[#12784235]
2014-03-10 11:23:27 -07:00
Christopher Amavisca, Greg Cobb and Luan Santos
1922514f2d Specs without expectations should be alerted to the user
- Add console.error to the HtmlReporter when there is a spec without any expectation
- Change the spec's link text and color to include a warning
- Create a status for specs to label them as "empty"
- console is not accessible to IE unless you have developer tools open,
  so protect against that by mocking console.

[#59424794]
2014-03-10 11:19:07 -07:00
Christopher Amavisca and Greg Cobb
668846147c Fix issues with displaying error messages for afterAll (browser compatibility)
- Switch from showing error stack to showing message/description since only chrome/ff support stack
- Fallback to error.description if error.message is undefined
- Made exceptionList variable name consistent between both reporters
2014-03-06 18:25:49 -08:00
Christopher Amavisca and Greg Cobb
76fafa0388 Deprecate suite/spec ordering hook .
- Remove parameter from env.execute()
- Remove deprecated test
- Set runnablesToRun to always start with the topSuite

[#66789174]
2014-03-06 16:54:53 -08:00
Christopher Amavisca and Greg Cobb
bed1c15ea4 HtmlReporter shows error alerts for afterAllExceptions
-Add list of exceptions in HtmlReporter to push to on error
-Create alerts for each exception in the list (with stack trace)

[#67055688]
2014-03-06 15:39:04 -08:00
Christopher Amavisca and Greg Cobb
6caf4c5de2 Print afterAllExceptions to the console.
- Add afterAllException function to ConsoleReporter
- Print the stack traces of the errors at the end of the console output

[#67055730]
2014-03-06 15:02:55 -08:00
Christopher Amavisca and Greg Cobb
97ae9a2d88 After all exceptions dispatch to reporter hook
- Add 'afterAllException' hook to reporter dispatch, we might want to make this more generic in the future
- Add afterAllException function to HtmlReporter

[#66789174]
2014-03-06 12:01:37 -08:00
slackersoft
71dbffeaef Merge branch 'recursive-containing' of https://github.com/cbandy/jasmine into cbandy-recursive-containing 2014-03-05 21:01:34 -08:00
Christopher Amavisca and Greg Cobb
a3c3505086 beforeAll can have expectations and passes expectation failures to its children
[#66789174]
2014-03-05 16:27:58 -08:00
Christopher Amavisca and Greg Cobb
a9e0112a9b Throw error if you add a custom matcher or equality outside of a runnable
[#66789174]
2014-03-05 14:37:17 -08:00
Christopher Amavisca and Greg Cobb
a2ac5ef3b6 Throw error if you define a spy outside of a runnable
[#66789174]
2014-03-05 14:27:19 -08:00
Christopher Amavisca and Greg Cobb
b200952195 Only clear resources if suite is not disabled
[#66789174]
2014-03-05 14:00:57 -08:00
Rajan Agaskar
9c6d03d3ac README.md: Add link to Jasmine 2.0 release notes
- To help people upgrading find a list of what they'll need to change.
2014-03-05 11:31:39 -08:00
Christopher Amavisca, Greg Cobb and Sheel Choksi
752a36d3ff Manage spys/matchers/custom equalities for beforeAll
- Refactor expectations to take list of matchers
- Add spyRegistry to manage runnables' spies
- Add clone util

[#66789174]
2014-03-05 10:28:37 -08:00
Gregg Van Hove and Sheel Choksi
52026fb0f7 beforeAll/afterAll can be timed out and errors are applied to all children specs 2014-03-03 16:13:59 -08:00
Gregg Van Hove and Sheel Choksi
e17a2cb1e0 share usercontext for full suite 2014-03-03 11:57:32 -08:00
Gregg Van Hove and Sheel Choksi
ec5695acc1 first (naive) pass at beforeAll/afterAll 2014-03-03 09:26:39 -08:00
Chris Bandy
47884032ad Fix ObjectContaining to match recursively
matchersUtil.equals() does not expect a matcher as its first argument,
so send the "actual" value first and the "expected" value second.
2014-03-02 11:42:37 -06:00
slackersoft
d7053612f5 Build distribution to include MockDate
- Forgot to do this when merging the pull request
- Also fix quotes for string to match jshint rules
2014-03-01 13:18:15 -08:00
Christopher Amavisca and Sheel Choksi
9d1e92f5e2 Clean up more remnants of dev_boot 2014-02-27 18:02:14 -08:00
Elana Koren and Gregg Van Hove
eebba2ecca Support browsers that don't supply a Date.now()
- install the mockDate by calling `mockDate` on `clock` instead of
  passing an argument to `clock.install()`

[Finishes #66606132] Closes #361
2014-02-27 11:55:25 -08:00
Elana Koren and Gregg Van Hove
627a262085 Merge branch 'mock-date' of https://github.com/jalopez/jasmine into jalopez-mock-date 2014-02-27 10:03:35 -08:00
Christopher Amavisca and Sheel Choksi
305bd73142 Instead of dev boot use a custom helper to defined j$ 2014-02-26 17:35:10 -08:00
Elana Koren and Gregg Van Hove
fb853ad5b5 Don't include jasmine_selenium_runner from github, now that it's
published to rubygems

[finish #66472672]
2014-02-26 15:30:17 -08:00
Greg Cobb and Sheel Choksi
640f94a1bd Don't allow calling the same done callback multiple times
[finishes #62585700][fixes #523]
2014-02-25 18:06:30 -08:00
Greg Cobb and Sheel Choksi
5aac3e3292 Refactor Spec and QueueRunner [#62585700]
- QueueRunner now responsible for timing out async specs instead of
   Spec
 - Make sure only spec functions are timeoutable and not suites (due to
   the refactor)
2014-02-25 18:06:30 -08:00
Charles Hansen and Gregg Van Hove
84160ff51d revert to old version of checking the docs 2014-02-25 11:28:02 -08:00
Charles Hansen and Gregg Van Hove
e972bac80d No longer try to push to github, we'll update jasmine in docs manually 2014-02-25 10:58:59 -08:00
Charles Hansen and Gregg Van Hove
455b6bade8 bundle install in docs repo 2014-02-25 10:56:41 -08:00
Charles Hansen and Gregg Van Hove
23c0e379e0 update edge docs when changes are made to jasmine 2014-02-25 10:42:59 -08:00
Robin Böhm
31d71ac22f add single quote check to jshint and fix src files for that
[fixes #522]
2014-02-24 16:28:16 -08:00
Greg Cobb and Sheel Choksi
095b02ad83 Follow redirects when trying to connect to sauce 2014-02-24 16:13:25 -08:00
Greg Cobb and Sheel Choksi
98c258a659 Bump built distribution [#503][finishes #66350898] 2014-02-24 15:47:34 -08:00
Michal Mocny
85fa148f18 Support running jasmine within CSP (remove eval)
[fixes #503]
2014-02-24 15:44:11 -08:00
Sheel Choksi
76ca5ef6d4 Allow matcher custom failure messages to be a function
By deferring the evaluation of these messages, we can avoid the
expensive creation of them when in the majority use case (tests are
    passing) they are not needed.

These failure messages were causing performance problems with larger
objects needed to be pretty printed as discussed in #520 and brought up
by @rdy.

[fixes #65925900][fixes #520]
2014-02-18 20:05:30 -08:00
Sheel Choksi
46d2c43da1 Revert "Use default failure message for toBeNaN"
Forgot that NaN has special casing that it needs a custom error message
for

This reverts commit b6c03a34e7.
2014-02-18 19:14:16 -08:00
Sheel Choksi
b6c03a34e7 Use default failure message for toBeNaN
It is providing the same functionality by default without a custom error message
2014-02-17 22:45:54 -08:00
Sheel Choksi
4ddf316388 Add in default rake task 2014-02-16 14:57:14 -08:00
Sheel Choksi
a8cbef3123 More color blind friendly CSS from @dleppik
Updating the passing and failing colors in HTML reporter to
help red/green color blind users using the colors suggested by @dleppik

Console reporter still likely needs similar changes but there's less
options there

[#463, #509, finishes #60613086]
2014-02-16 14:56:18 -08:00
Sheel Choksi
a937d8d74f Merge pull request #521 from robinboehm/load-grunt-tasks
use load-grunt-tasks
2014-02-16 14:53:07 -08:00
Robin Böhm
2fc2802809 use load-grunt-tasks 2014-02-16 22:13:53 +01:00
Sheel Choksi
7cf899a4ea Special case printing -0
Use the 1/x trick to determine if a value is -0 and special case the
printing of it.

[closes #496]
2014-02-09 14:14:33 -08:00
Sheel Choksi
83c0ea7f91 Fix error message in jasmine.any
The expected any 'class' was not being included in the error message
due to accessing the wrong property
2014-02-09 14:06:47 -08:00
Sheel Choksi
289c8313d1 Short spec to document why we close over Date and ensure cross-browser compatibility
[closes #506]
2014-02-09 12:20:03 -08:00
tcorral
b5775aec4f Allow stub or spy Date object safely using a closure to get a clean copy
[closes #506]
2014-02-09 12:20:03 -08:00
Davis W. Frank
21b01f4a5d Whitespace Markdown fix 2014-01-24 09:32:20 -08:00
Davis W. Frank
71faeea7b0 First attempt at publishing an npm 2014-01-24 09:31:38 -08:00
Sheel Choksi
de7d005b3d Break out quick start guide on newline
[skip ci]
2014-01-19 14:21:21 -08:00
Sheel Choksi
7acf5d4220 Add in link to quick start of Jasmine, closes #498
[skip ci]
2014-01-19 14:16:00 -08:00
slackersoft
2a8b5a30b6 Use \d7 instead of plain 'x' for more square appearance
[finishes #48434179]
2014-01-18 17:33:57 -10:00
Sheel Choksi
9c7ba43ebd Clean up a bunch of spec global variable leaks
Also some formatting changes to highlight when using one 'var' with comma operator
2014-01-18 14:17:14 -08:00
Sheel Choksi
8ca08ff999 Run Object.create(null) spec on all browsers not IE 8
IE 8 doesn't support Object.create so there shouldn't be a need to run this spec in IE 8
2014-01-18 13:12:07 -08:00
slackersoft
15aa3ecb5d Better support in pretty printer when an object has null prototype
- Fixes #500
2014-01-17 19:56:43 -10:00
Davis W. Frank
2670bb40a7 Get rid of freeze property for now - it's not adding value. 2014-01-10 10:23:14 -08:00
Sheel Choksi
c8ffa6000b Reproducing change made in #479 that was made to build distribution instead of src
It was lost when I rebuilt the distribution
2014-01-09 22:14:04 -08:00
Sheel Choksi
06a553503d Better failure message when something is thrown that's not an error
Change from 'undefined : undefined' to '<thing that was thrown> thrown'

Pointed out by @charleshansen
2014-01-09 22:10:40 -08:00
Sheel Choksi
aab4808410 Bump built distribution 2014-01-09 22:07:59 -08:00
Sheel Choksi
b525313cdb Make the check for pending spec exception work for values that don't have toString 2014-01-04 23:11:20 -08:00
Sheel Choksi
f576395620 Bump built distribution copyright's for 2014 2014-01-04 23:11:20 -08:00
Sheel Choksi
b161e9e3df Merge pull request #486 from nextmat/link_fix
Update link at top of README
2014-01-01 20:00:18 -08:00
Matt Sanders
94ecb998bb Update link at top of README
Allows access to Jasmine 2.0 docs
2013-12-27 00:29:35 -07:00
Davis W. Frank
38daa43c7e Merge pull request #479 from shprink/fix_jasmine_html
force query selector to seek within the html-reporter element
2013-12-19 09:42:15 -08:00
Davis W. Frank
9fb9c12066 Merge pull request #478 from shprink/adding_netbeans_to_gitignore
adding netbeans project folder to the gitignore list
2013-12-19 09:37:19 -08:00
shprink
de2fb225b0 adding netbeans project folder to the gitignore list 2013-12-19 10:20:49 +01:00
shprink
4f4ae086aa force query selector to seek within the html-reporter element 2013-12-19 10:19:02 +01:00
Sheel Choksi
8510bdd947 Update mailing list link
It seems that Github was interpreting it as a repository link. Made it an explicit mailto instead.
2013-12-17 18:37:10 -08:00
Sheel Choksi
66bd8c7825 Adding older standalone zips from downloads page to our dist folder 2013-12-17 12:19:53 -08:00
Christopher Jobst and Sheel Choksi
a736e664ea Remove the old RC standalone distributions. 2013-12-16 15:49:27 -08:00
Christopher Jobst and Sheel Choksi
812b14d000 Update README and remove rc release notes
RC release notes have been merged into release_notes/20.md
2013-12-16 12:42:17 -08:00
Christopher Jobst and Sheel Choksi
a2a8b5dde2 Create a 2.0 distribution 2013-12-16 12:33:34 -08:00
Christopher Jobst
78bed99ba3 Add in 2.0 release notes 2013-12-16 11:17:51 -08:00
pimterry
b1d4ab09af Add tests for call return value tracking 2013-12-08 13:40:25 +00:00
pimterry
3b52d015ea Track return values of spy functions 2013-12-08 13:40:24 +00:00
Sheel Choksi
f9191d7b0d Merge pull request #473 from pimterry/callTrackingTests
Refactored the createSpy tests, to add unit tests for its part of call tracking
2013-12-07 16:57:57 -08:00
pimterry
83a692d5a8 Use the correct Jasmine version in the spy integration tests 2013-12-07 22:16:24 +00:00
pimterry
14a8c2ca09 Move spy integration tests out of the unit test suite 2013-12-07 20:52:02 +00:00
pimterry
b2e8de7bcd Mock callTracker in spy tests for better test isolation 2013-12-07 20:43:38 +00:00
pimterry
1d98a23b14 Add tests for call tracking in createSpy 2013-12-07 20:27:08 +00:00
Sheel Choksi
16ffd3b3fb Fix up specs that failed when maximumSpecCallbackDepth is set to 1 2013-11-22 23:04:42 -08:00
Sheel Choksi
6bc87ad223 Merge pull request #466 from
maciej-filip-sz:DelayedFunctionScheduler-patch

Sets and executes timeouts set during a tick.
2013-11-17 17:17:31 -08:00
Maciej Filip Szkodziński
555d328cf2 Moved last currentTime assignment to tick. 2013-11-17 17:14:29 -08:00
Maciej Filip Szkodziński
c78fba4b13 Sets and executes timeouts set during a tick.
All timeouts and intervals set during a tick were being scheduled to run
at delay + end-of-tick, instead of delay + time-of-outer-timeout.

Scheduled run-at times were shifted because currentTime was being
incremented before executing scheduled functions.

Additionally, the execute loop was iterating over a functions-to-run
array, created from scheduledFunctions before starting. Any changes to
scheduledFunctions were being ignored during the tick, and the next tick
would ignore any functions which should have been executed in the past.

The commit is a rewrite of DelayedFunctionScheduler, preserving the
public interface. Execution of scheduled functions updates currentTime
on each iteration, and each time takes the functions with the lowest
runAtMillis from the schedule, if they aren't higher than endTime.
2013-11-17 17:14:29 -08:00
Sheel Choksi
8a6d7828c6 Make all async functions be subject to the timeout
[finishes #60798058]
2013-11-14 23:01:43 -08:00
Sheel Choksi
c888b0c1b8 Slight refactoring of clearing timeouts when an exception is thrown 2013-11-14 20:48:28 -08:00
Sheel Choksi
72e9851217 Bumping built distribution 2013-11-14 18:16:32 -08:00
Sheel Choksi
7ee5073921 Fix bad merge 2013-11-11 21:01:36 -08:00
Sheel Choksi
614a18453e Rename Spec's queueRunner to more accurately be a queueRunnerFactory 2013-11-11 20:53:13 -08:00
Rajan Agaskar
916f889c01 Merge pull request #462 from tidoust/clear-timeout-async
Clears timeout timer even when async spec throws an exception
2013-11-07 09:40:43 -08:00
François Daoust
4a7b79ad0d Regression spec added for timeout timer in an async spec
The spec ensures that the timeout timer is properly cleared out
even when the async spec throws an exception.
2013-11-07 16:08:41 +01:00
François Daoust
775e2ff0a9 Clears timeout timer even when async spec throws an exception
When an async spec throws a (sync) exception for some reason, the
exception was correctly caught and reported by Jasmine but the timeout
timer continued to run in the background.

For instance, running the (rather stupid) example below would report
the exception immediately but would also make the process loop for 5s
(and report the exception depending on the reported being used).

describe('exception', function () {
  it('is caught but timer continues to run', function (done) {
    throw new Error('Oh no!');
  });
});

This happened because the timout timer is set in Spec while the
"try... catch" block is in the queue runner. The "callDone" function
of "timeoutable" that resets the timer was thus not called.

The commit simply introduces a "try... catch" block within the
`timeoutable` function to ensure that "callDone" gets called even
when an exception is thrown.
2013-11-07 14:51:46 +01:00
Sheel Choksi
1b6725ec25 Updating Spec#getFullName spec to work in IE 8
Forgot that the pretty printer is not functional in IE 8, which
subsequently brings down toHaveBeenCalledWith
2013-11-04 21:59:06 -08:00
Sheel Choksi
952eb59707 Change test for how a spy gets its full name
- Removes another TODO
- A spec uses its full name as soon as it is created (for the result
    object) and so it needed to be tested differently
2013-11-04 21:38:01 -08:00
Sheel Choksi
de6a305b44 Move the various integration specs into their own folder
- There is now an integration folder inside of spec/core
- Killed the TODOs about moving around integration specs
2013-11-03 16:48:35 -08:00
Sheel Choksi
8513201fa3 Add in missing repository field to package.json
Removes the following warning when doing a `npm install`: 'npm WARN
package.json jasmine-core@2.0.0-rc5 No repository field.'
2013-11-02 18:28:53 -07:00
JR and Sheel Choksi
6e07dccb68 Make getGlobal() work in strict mode
Slight modifications to implementation in pull #437
2013-11-01 11:06:57 -07:00
JR and Sheel Choksi
fcc50cc6f4 Rename Release.markdown to be more consistently named 2013-10-31 14:27:30 -07:00
Sheel Choksi
9e8466ba2b Merge pull request #458 from jsoref/readme
Rename README for consistency
2013-10-31 14:24:43 -07:00
Kristóf Marussy
4350045d61 Replaced deprecated octal literal with hexadecimal
Octal literals are deprecated in JavaScript 1.5 and Gjs were generating
warnings because of them.
2013-10-31 14:03:06 -07:00
Rajan Agaskar
666e9c341e Merge pull request #460 from jsoref/releasenotes
Improving Release note text
2013-10-30 20:52:30 -07:00
Josh Soref
5830d9f86b Improving Release note text 2013-10-30 23:14:57 -04:00
August Toman-Yih and Sheel Choksi
ea888e4c03 Fix triple/tripple spelling error 2013-10-30 17:30:25 -07:00
Josh Soref
c7e3ca6c8a Spelling: Fix spelling errors
* equal
* existence
* expectation
* expected
* intend
* message
* report
* singular
2013-10-30 20:12:05 -04:00
Josh Soref
06db4a8583 Rename README for consistency 2013-10-30 10:31:15 -04:00
Rajan Agaskar and Sheel Choksi
a2debf60b6 Use jasmine.addMatchers instead of reaching through jasmine.Expectation [finishes #59518946] 2013-10-29 18:35:17 -07:00
Javier López Pardo
3186b24a66 add acceptance tests for mock clock with date 2013-10-25 14:59:07 +02:00
Javier López Pardo
81b822fea9 Add specs for mock date 2013-10-25 14:41:32 +02:00
Javier López Pardo
fb8bede8ea Add FakeDate object 2013-10-25 13:25:09 +02:00
slackersoft
b5b77b318a Argument matcher for an array containing at least the specified entries 2013-10-03 18:21:47 -07:00
Mike Stay
ffa6138d75 Make getGlobal() work in strict mode
An update of fb3e1acb09

ES5 strict mode does not promote an undefined 'this' to the global object.  The only way to get the global object in strict mode is to say 'this' while in the global scope.
2013-10-02 12:38:25 -06:00
162 changed files with 10688 additions and 3803 deletions

5
.gitignore vendored
View File

@@ -15,5 +15,10 @@ pkg/*
.sass-cache/*
src/html/.sass-cache/*
node_modules/
*.pyc
sauce_connect.log
*.swp
build/
*.egg-info/
dist
nbproject/

View File

@@ -1,9 +1,9 @@
{
"bitwise": true,
"curly": true,
"freeze": true,
"immed": true,
"newcap": true,
"trailing": true,
"loopfunc": true
"loopfunc": true,
"quotmark": "single"
}

28
.npmignore Normal file
View File

@@ -0,0 +1,28 @@
dist/
grunt/
node_modules
pkg/
release_notes/
spec/
src/
Gemfile
Gemfile.lock
Rakefile
jasmine-core.gemspec
.bundle/
.gitignore
.gitmodules
.idea
.jshintrc
.rspec
.sass-cache/
.travis.yml
*.sh
*.py
Gruntfile.js
lib/jasmine-core.rb
lib/jasmine-core/boot/
lib/jasmine-core/spec
lib/jasmine-core/version.rb
lib/jasmine-core/*.py
sauce_connect.log

View File

@@ -1,50 +1,67 @@
---
script: $TEST_COMMAND
language: ruby
rvm: 1.9.3
sudo: false
rvm: 2.2.0
script: $TEST_COMMAND
env:
global:
- USE_SAUCE=true
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
- TEST_COMMAND="bash travis-core-script.sh"
- JASMINE_BROWSER="firefox"
- SAUCE_OS="Linux"
- SAUCE_BROWSER_VERSION=''
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
matrix:
include:
- env:
- USE_SAUCE=false
- TEST_COMMAND="bash travis-node-script.sh"
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.8"
- SAUCE_BROWSER_VERSION=6
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.6"
- SAUCE_BROWSER_VERSION=5
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 8"
- SAUCE_BROWSER_VERSION=10
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=9
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=8
- env:
- JASMINE_BROWSER="chrome"
- USE_SAUCE=true
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
- TEST_COMMAND="bash travis-core-script.sh"
- JASMINE_BROWSER="firefox"
- SAUCE_OS="Linux"
- SAUCE_BROWSER_VERSION=''
- env:
- JASMINE_BROWSER="phantomjs"
- USE_SAUCE=false
- env:
- USE_SAUCE=false
- JASMINE_BROWSER="phantomjs"
- TEST_COMMAND="bash travis-docs-script.sh"
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
matrix:
include:
- env:
- USE_SAUCE=false
- TEST_COMMAND="bash travis-node-script.sh"
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.10"
- SAUCE_BROWSER_VERSION=8
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.9"
- SAUCE_BROWSER_VERSION=7
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.8"
- SAUCE_BROWSER_VERSION=6
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.6"
- SAUCE_BROWSER_VERSION=5
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 8.1"
- SAUCE_BROWSER_VERSION=11
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 8"
- SAUCE_BROWSER_VERSION=10
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=9
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=8
- env:
- JASMINE_BROWSER="chrome"
- SAUCE_OS="Linux"
- SAUCE_BROWSER_VERSION=''
- env:
- JASMINE_BROWSER="phantomjs"
- USE_SAUCE=false
- env:
- USE_SAUCE=false
- JASMINE_BROWSER="phantomjs"
- TEST_COMMAND="bash travis-docs-script.sh"

View File

@@ -1,18 +1,28 @@
# Developing for Jasmine Core
We welcome your contributions - Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists (the main group - [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) and the developer's list - [http://groups.google.com/group/jasmine-js-dev](http://groups.google.com/group/jasmine-js-dev)) before starting work - what you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
We welcome your contributions! Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
## Links
- [Jasmine Google Group](http://groups.google.com/group/jasmine-js)
- [Jasmine-dev Google Group](http://groups.google.com/group/jasmine-js-dev)
- [Jasmine on PivotalTracker](https://www.pivotaltracker.com/n/projects/10606)
## General Workflow
Please submit pull requests via feature branches using the semi-standard workflow of:
1. Fork it
1. Create your feature branch (`git checkout -b my-new-feature`)
1. Commit your changes (`git commit -am 'Add some feature'`)
1. Push to the branch (`git push origin my-new-feature`)
1. Create new Pull Request
```bash
git clone git@github.com:yourUserName/jasmine.git # Clone your fork
cd jasmine # Change directory
git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream'
git fetch upstream # Pull in changes not present in your local repository
git checkout -b my-new-feature # Create your feature branch
git commit -am 'Add some feature' # Commit your changes
git push origin my-new-feature # Push to the branch
```
We favor pull requests with very small, single commits with a single purpose.
Once you've pushed a feature branch to your forked repo, you're ready to open a pull request. We favor pull requests with very small, single commits with a single purpose.
## Background
@@ -62,7 +72,11 @@ To install the Ruby dependencies, you will need Ruby, Rubygems, and Bundler avai
$ bundle
...will install all of the Ruby dependencies.
...will install all of the Ruby dependencies. If the ffi gem fails to build its native extensions, you may need to manually install some system dependencies. On Ubuntu:
$ apt-get install gcc ruby ruby-dev libxml2 libxml2-dev libxslt1-dev
...should get you to the point that `bundle` can install everything.
To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http://gruntjs.com/), the [grunt-cli](https://github.com/gruntjs/grunt-cli) and ensure that `grunt` is on your path.
@@ -89,13 +103,13 @@ Follow these tips and your pull request, patch, or suggestion is much more likel
### Running Specs
Jasmine uses the [Jasmine Ruby gem](http://github.com/pivotal/jasmine-gem) to test itself in browser.
Jasmine uses the [Jasmine Ruby gem](http://github.com/jasmine/jasmine-gem) to test itself in browser.
$ rake jasmine
...and then visit `http://localhost:8888` to run specs.
Jasmine uses Node.js with a custom runner to test outside of a browser.
Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/jasmine-npm) to test itself in a Node.js/npm environment.
$ grunt execSpecsInNode
@@ -104,13 +118,13 @@ Jasmine uses Node.js with a custom runner to test outside of a browser.
## Before Committing or Submitting a Pull Request
1. Ensure all specs are green in browser *and* node
1. Ensure JSHint is green with `grunt jsHint`
1. Ensure JSHint is green with `grunt jshint`
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
## Submitting a Pull Request
1. Revert your changes to `jasmine.js` and `jasmine-html.js`
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches.
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master.
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master
Note that we use Travis for Continuous Integration. We only accept green pull requests.

11
Gemfile
View File

@@ -1,14 +1,9 @@
source 'https://rubygems.org'
gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git'
# gem "jasmine", path: "/Users/pivotal/workspace/jasmine-gem"
unless ENV["TRAVIS"]
group :debug do
gem 'debugger'
end
end
gem "jasmine", :git => 'https://github.com/jasmine/jasmine-gem.git'
# gem "jasmine", path: "../jasmine-gem"
gemspec
gem "jasmine_selenium_runner", :git => 'https://github.com/jasmine/jasmine_selenium_runner.git'
gem "jasmine_selenium_runner", :github => 'jasmine/jasmine_selenium_runner'
gem "anchorman"

View File

@@ -10,17 +10,13 @@ module.exports = function(grunt) {
compress: require('./grunt/config/compress.js')
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-compress');
require('load-grunt-tasks')(grunt);
grunt.loadTasks('grunt/tasks');
grunt.registerTask('default', ['jshint:all']);
var version = require('./grunt/tasks/version.js');
var standaloneBuilder = require('./grunt/tasks/build_standalone.js');
grunt.registerTask('build:copyVersionToGem',
"Propagates the version from package.json to version.rb",
@@ -37,12 +33,27 @@ module.exports = function(grunt) {
]
);
var spec = require('./grunt/tasks/spec.js');
grunt.registerTask("execSpecsInNode",
"Run Jasmine core specs in Node.js",
spec.execSpecsInNode
"Run Jasmine core specs in Node.js",
function() {
var done = this.async(),
Jasmine = require('jasmine'),
jasmineCore = require('./lib/jasmine-core.js'),
jasmine = new Jasmine({jasmineCore: jasmineCore});
jasmine.loadConfigFile('./spec/support/jasmine.json');
jasmine.onComplete(function(passed) {
done(passed);
});
jasmine.execute();
}
);
grunt.registerTask("execSpecsInNode:performance",
"Run Jasmine performance specs in Node.js",
function() {
require("shelljs").exec("node_modules/.bin/jasmine JASMINE_CONFIG_PATH=spec/support/jasmine-performance.json");
}
);
};

5
MANIFEST.in Normal file
View File

@@ -0,0 +1,5 @@
recursive-include . *.py
include lib/jasmine-core/*.js
include lib/jasmine-core/*.css
include images/*.png
include package.json

View File

@@ -1,4 +1,4 @@
Copyright (c) 2008-2011 Pivotal Labs
Copyright (c) 2008-2014 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,31 +0,0 @@
<a name="README">[Jasmine](http://pivotal.github.com/jasmine/)</a> [![Build Status](https://travis-ci.org/pivotal/jasmine.png?branch=master)](https://travis-ci.org/pivotal/jasmine) [![Code Climate](https://codeclimate.com/repos/5269970a13d6374b6c01d632/badges/8bc25526da64e02065f4/gpa.png)](https://codeclimate.com/repos/5269970a13d6374b6c01d632/feed)
=======
**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://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
## Contributing
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md)
## Support
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
* Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
## Maintainers
* [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
* [Sheel Choksi](mailto:schoksi@pivotallabs.com), Pivotal Labs
### Maintainers Emeritus
* [Christian Williams](mailto:antixian666@gmail.com), Square
Copyright (c) 2008-2013 Pivotal Labs. This software is licensed under the MIT License.

71
README.md Normal file
View File

@@ -0,0 +1,71 @@
<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)
=======
**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)
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)
## Installation
For the Jasmine NPM module:<br>
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm)
For the Jasmine Ruby Gem:<br>
[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem)
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:
* Clone Jasmine - `git clone https://github.com/jasmine/jasmine.git`
* 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`
* Change directory - `cd my-project/jasmine`
* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip`
Add the following to your HTML file:
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">
<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>
## Supported environments
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
## Support
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com)
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
## Maintainers
* [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
* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry
* Sheel Choksi
Copyright (c) 2008-2015 Pivotal Labs. This software is licensed under the MIT License.

View File

@@ -15,19 +15,16 @@ Please attempt to keep commits to `master` small, but cohesive. If a feature is
We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
The current version lives in the file `/package.json`. This file should be set to the version that is _currently_ under development. That is, if version 1.0.0 is the current release then version should be incremented say, to 1.1.0.
The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` and `bower.json` with the new version and `grunt build:copyVersionToGem` to update the gem version number.
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
Note that Jasmine should *not* use the "patch" version number. Let downstream projects rev their patch versions as needed, keeping their major and minor version numbers in sync with Jasmine core.
### Update the Github Pages (as needed)
Note that Jasmine should only use the "patch" version number in the following cases:
___Note: This is going to change right after 2.0___
* Changes related to packaging for a specific platform (npm, gem, or pip).
* Fixes for regressions.
Github pages have to exist in a branch called `gh-pages` in order for their app to serve them. This repo adds that branch as a submodule under the `pages` directory. This is a bit of a hack, but it allows us to work with the pages and the source at the same time and with one set of rake tasks.
If you want to submit changes to this repo and aren't a Pivotal Labs employee, you can fork and work in the `gh-pages` branch. You won't be able to edit the pages in the submodule off of master.
When jasmine-core revs its major or minor version, the binding libraries should also rev to that version.
## Release
@@ -36,14 +33,41 @@ When ready to release - specs are all green and the stories are done:
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly
1. Update the version in `package.json` to a release candidate
1. Update any links or top-level landing page for the Github Pages
### Build standalone distribution
1. Build the standalone distribution with `grunt buildStandaloneDist`
1. Make sure you add the new ZIP file to git
### Release the Python egg
1. `python setup.py register sdist upload` You will need pypi credentials to upload the egg.
### Release the Ruby gem
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile.
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release.
1. Push these changes to GitHub and verify that this SHA is green
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
1. Visit the [Releases page for Jasmine](https://github.com/pivotal/jasmine/releases), find the tag just pushed. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes. If it is a pre-release, mark it as such.
### Release the NPM
1. `npm adduser` to save your credentials locally
1. `npm publish .` to publish what's in `package.json`
### Release the docs
Probably only need to do this when releasing a minor version, and not a patch version.
1. `cp -R edge ${version}` to copy the current edge docs to the new version
1. Add a link to the new version in `index.html`
### Finally
1. Visit the [Releases page for Jasmine](https://github.com/jasmine/jasmine/releases), find the tag just pushed.
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
1. If it is a pre-release, mark it as such.
1. Attach the standalone zipfile
There should be a post to Pivotal Labs blog and a tweet to that link.

View File

@@ -15,3 +15,4 @@ end
task "jasmine:configure" => "jasmine:set_env"
task :default => "jasmine:ci"

41
bower.json Normal file
View File

@@ -0,0 +1,41 @@
{
"name": "jasmine-core",
"version": "2.3.2",
"homepage": "http://jasmine.github.io",
"authors": [
"slackersoft <gregg@slackersoft.net>"
],
"description": "Official packaging of Jasmine's core files",
"keywords": [
"test",
"jasmine",
"tdd",
"bdd"
],
"license": "MIT",
"moduleType": "globals",
"main": "lib/jasmine-core/jasmine.js",
"ignore": [
"**/.*",
"dist",
"grunt",
"node_modules",
"pkg",
"release_notes",
"spec",
"src",
"Gemfile",
"Gemfile.lock",
"Rakefile",
"jasmine-core.gemspec",
"*.sh",
"*.py",
"Gruntfile.js",
"lib/jasmine-core.rb",
"lib/jasmine-core/boot/",
"lib/jasmine-core/spec",
"lib/jasmine-core/version.rb",
"lib/jasmine-core/*.py",
"sauce_connect.log"
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -39,6 +39,10 @@ module.exports = {
src: ['lib/jasmine-core/boot/boot.js'],
dest: 'lib/jasmine-core/boot.js'
},
nodeBoot: {
src: ['lib/jasmine-core/boot/node_boot.js'],
dest: 'lib/jasmine-core/node_boot.js'
},
console: {
src: [
'src/console/requireConsole.js',

View File

@@ -1,11 +0,0 @@
var shell = require('shelljs');
var grunt = require('grunt');
module.exports = {
execSpecsInNode: function() {
var exit_code = shell.exec("node spec/node_suite.js --color=true").code;
if (exit_code !== 0) {
grunt.fail.fatal("Specs Failed", exit_code);
}
}
};

View File

@@ -1,23 +1,23 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Jasmine Spec Runner v<%= jasmineVersion %></title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-<%= jasmineVersion %>/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-<%= jasmineVersion %>/jasmine.css">
<link rel="stylesheet" href="lib/jasmine-<%= jasmineVersion %>/jasmine.css">
<script type="text/javascript" src="lib/jasmine-<%= jasmineVersion %>/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-<%= jasmineVersion %>/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-<%= jasmineVersion %>/boot.js"></script>
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine.js"></script>
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine-html.js"></script>
<script src="lib/jasmine-<%= jasmineVersion %>/boot.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="src/Player.js"></script>
<script type="text/javascript" src="src/Song.js"></script>
<script src="src/Player.js"></script>
<script src="src/Song.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="spec/SpecHelper.js"></script>
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
<script src="spec/SpecHelper.js"></script>
<script src="spec/PlayerSpec.js"></script>
</head>

0
images/__init__.py Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="681.96252"
height="187.5"
id="svg2"
xml:space="preserve"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"><path
d="M 0,1500 0,0 l 5455.74,0 0,1500 L 0,1500 z"
inkscape:connector-curvature="0"
id="path20" /></clipPath></defs><g
transform="matrix(1.25,0,0,-1.25,0,187.5)"
id="g10"><g
transform="scale(0.1,0.1)"
id="g12"><g
id="g14"><g
clip-path="url(#clipPath18)"
id="g16"><path
d="m 1544,599.434 c 0.92,-40.352 25.68,-81.602 71.53,-81.602 27.51,0 47.68,12.832 61.44,35.754 12.83,22.93 12.83,56.852 12.83,82.527 l 0,329.184 -71.52,0 0,104.543 266.83,0 0,-104.543 -70.6,0 0,-344.77 c 0,-58.691 -3.68,-104.531 -44.93,-152.218 -36.68,-42.18 -96.28,-66.02 -153.14,-66.02 -117.37,0 -207.24,77.941 -202.64,197.145 l 130.2,0"
inkscape:connector-curvature="0"
id="path22"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 2301.4,662.695 c 0,80.703 -66.94,145.813 -147.63,145.813 -83.44,0 -147.63,-68.781 -147.63,-151.301 0,-79.785 66.94,-145.801 145.8,-145.801 84.35,0 149.46,67.852 149.46,151.289 z m -1.83,-181.547 c -35.77,-54.097 -93.53,-78.859 -157.72,-78.859 -140.3,0 -251.24,116.449 -251.24,254.918 0,142.129 113.7,260.41 256.74,260.41 63.27,0 118.29,-29.336 152.22,-82.523 l 0,69.687 175.14,0 0,-104.527 -61.44,0 0,-280.598 61.44,0 0,-104.527 -175.14,0 0,66.019"
inkscape:connector-curvature="0"
id="path24"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 2622.33,557.258 c 3.67,-44.016 33.01,-73.348 78.86,-73.348 33.93,0 66.93,23.824 66.93,60.504 0,48.606 -45.84,56.856 -83.44,66.941 -85.28,22.004 -178.81,48.606 -178.81,155.879 0,93.536 78.86,147.633 165.98,147.633 44,0 83.43,-9.176 110.94,-44.008 l 0,33.922 82.53,0 0,-132.965 -108.21,0 c -1.83,34.856 -28.42,57.774 -63.26,57.774 -30.26,0 -62.35,-17.422 -62.35,-51.348 0,-45.847 44.93,-55.93 80.69,-64.18 88.02,-20.175 182.47,-47.695 182.47,-157.734 0,-99.027 -83.44,-154.039 -175.13,-154.039 -49.53,0 -94.46,15.582 -126.55,53.18 l 0,-40.34 -85.27,0 0,142.129 114.62,0"
inkscape:connector-curvature="0"
id="path26"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 2988.18,800.254 -63.26,0 0,104.527 165.05,0 0,-73.355 c 31.18,51.347 78.86,85.277 141.21,85.277 67.85,0 124.71,-41.258 152.21,-102.699 26.6,62.351 92.62,102.699 160.47,102.699 53.19,0 105.46,-22 141.21,-62.351 38.52,-44.938 38.52,-93.532 38.52,-149.457 l 0,-185.239 63.27,0 0,-104.527 -238.42,0 0,104.527 63.28,0 0,157.715 c 0,32.102 0,60.527 -14.67,88.957 -18.34,26.582 -48.61,40.344 -79.77,40.344 -30.26,0 -63.28,-12.844 -82.53,-36.672 -22.93,-29.355 -22.93,-56.863 -22.93,-92.629 l 0,-157.715 63.27,0 0,-104.527 -238.41,0 0,104.527 63.28,0 0,150.383 c 0,29.348 0,66.023 -14.67,91.699 -15.59,29.336 -47.69,44.934 -80.7,44.934 -31.18,0 -57.77,-11.008 -77.94,-35.774 -24.77,-30.253 -26.6,-62.343 -26.6,-99.941 l 0,-151.301 63.27,0 0,-104.527 -238.4,0 0,104.527 63.26,0 0,280.598"
inkscape:connector-curvature="0"
id="path28"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 3998.66,951.547 -111.87,0 0,118.293 111.87,0 0,-118.293 z m 0,-431.891 63.27,0 0,-104.527 -239.33,0 0,104.527 64.19,0 0,280.598 -63.27,0 0,104.527 175.14,0 0,-385.125"
inkscape:connector-curvature="0"
id="path30"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 4159.12,800.254 -63.27,0 0,104.527 175.14,0 0,-69.687 c 29.35,54.101 84.36,80.699 144.87,80.699 53.19,0 105.45,-22.016 141.22,-60.527 40.34,-44.934 41.26,-88.032 41.26,-143.957 l 0,-191.653 63.27,0 0,-104.527 -238.4,0 0,104.527 63.26,0 0,158.637 c 0,30.262 0,61.434 -19.26,88.035 -20.17,26.582 -53.18,39.414 -86.19,39.414 -33.93,0 -68.77,-13.75 -88.94,-41.25 -21.09,-27.5 -21.09,-69.687 -21.09,-102.707 l 0,-142.129 63.26,0 0,-104.527 -238.4,0 0,104.527 63.27,0 0,280.598"
inkscape:connector-curvature="0"
id="path32"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 5082.48,703.965 c -19.24,70.605 -81.6,115.547 -154.04,115.547 -66.04,0 -129.3,-51.348 -143.05,-115.547 l 297.09,0 z m 85.27,-144.883 c -38.51,-93.523 -129.27,-156.793 -231.05,-156.793 -143.07,0 -257.68,111.871 -257.68,255.836 0,144.883 109.12,261.328 254.91,261.328 67.87,0 135.72,-30.258 183.39,-78.863 48.62,-51.344 68.79,-113.695 68.79,-183.383 l -3.67,-39.434 -396.13,0 c 14.67,-67.863 77.03,-117.363 146.72,-117.363 48.59,0 90.76,18.328 118.28,58.672 l 116.44,0"
inkscape:connector-curvature="0"
id="path34"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 690.895,850.703 90.75,0 22.543,31.035 0,243.122 -135.829,0 0,-243.141 22.536,-31.016"
inkscape:connector-curvature="0"
id="path36"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 632.395,742.258 28.039,86.304 -22.551,31.04 -231.223,75.128 -41.976,-129.183 231.257,-75.137 36.454,11.848"
inkscape:connector-curvature="0"
id="path38"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 717.449,653.105 -73.41,53.36 -36.488,-11.875 -142.903,-196.692 109.883,-79.828 142.918,196.703 0,38.332"
inkscape:connector-curvature="0"
id="path40"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 828.52,706.465 -73.426,-53.34 0.011,-38.359 L 898.004,418.07 1007.9,497.898 864.973,694.609 828.52,706.465"
inkscape:connector-curvature="0"
id="path42"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 812.086,828.586 28.055,-86.32 36.484,-11.836 231.225,75.117 -41.97,129.183 -231.239,-75.14 -22.555,-31.004"
inkscape:connector-curvature="0"
id="path44"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 736.301,1335.88 c -323.047,0 -585.875,-262.78 -585.875,-585.782 0,-323.118 262.828,-585.977 585.875,-585.977 323.019,0 585.809,262.859 585.809,585.977 0,323.002 -262.79,585.782 -585.809,585.782 l 0,0 z m 0,-118.61 c 257.972,0 467.189,-209.13 467.189,-467.172 0,-258.129 -209.217,-467.348 -467.189,-467.348 -258.074,0 -467.254,209.219 -467.254,467.348 0,258.042 209.18,467.172 467.254,467.172"
inkscape:connector-curvature="0"
id="path46"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 1091.13,619.883 -175.771,57.121 11.629,35.808 175.762,-57.121 -11.62,-35.808"
inkscape:connector-curvature="0"
id="path48"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="M 866.957,902.074 836.5,924.199 945.121,1073.73 975.586,1051.61 866.957,902.074"
inkscape:connector-curvature="0"
id="path50"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="M 607.465,903.445 498.855,1052.97 529.32,1075.1 637.93,925.566 607.465,903.445"
inkscape:connector-curvature="0"
id="path52"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 380.688,622.129 -11.626,35.801 175.758,57.09 11.621,-35.801 -175.753,-57.09"
inkscape:connector-curvature="0"
id="path54"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 716.289,376.59 37.6406,0 0,184.816 -37.6406,0 0,-184.816 z"
inkscape:connector-curvature="0"
id="path56"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
s.name = "jasmine-core"
s.version = Jasmine::Core::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Christian Williams"]
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Gregg Van Hove"]
s.summary = %q{JavaScript BDD framework}
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
s.email = %q{jasmine-js@googlegroups.com}
s.homepage = "http://pivotal.github.com/jasmine"
s.homepage = "http://jasmine.github.io"
s.rubyforge_project = "jasmine-core"
s.license = "MIT"
@@ -18,6 +18,6 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.add_development_dependency "rake"
s.add_development_dependency "sauce-connect"
s.add_development_dependency "jasmine_selenium_runner"
s.add_development_dependency "compass"
s.add_development_dependency "jasmine_selenium_runner", ">= 0.2.0"
end

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2015 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -21,7 +21,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
function getJasmineRequireObj() {
if (typeof module !== "undefined" && module.exports) {
if (typeof module !== 'undefined' && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};
@@ -50,17 +50,20 @@ getJasmineRequireObj().ConsoleReporter = function() {
failedSpecs = [],
pendingCount,
ansi = {
green: '\033[32m',
red: '\033[31m',
yellow: '\033[33m',
none: '\033[0m'
};
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");
print('Started');
printNewline();
timer.start();
};
@@ -71,50 +74,65 @@ getJasmineRequireObj().ConsoleReporter = function() {
specFailureDetails(failedSpecs[i]);
}
printNewline();
var specCounts = specCount + " " + plural("spec", specCount) + ", " +
failureCount + " " + plural("failure", failureCount);
if(specCount > 0) {
printNewline();
if (pendingCount) {
specCounts += ", " + pendingCount + " pending " + plural("spec", pendingCount);
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');
}
print(specCounts);
printNewline();
var seconds = timer.elapsed() / 1000;
print("Finished in " + seconds + " " + plural("second", seconds));
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") {
if (result.status == 'pending') {
pendingCount++;
print(colored("yellow", "*"));
print(colored('yellow', '*'));
return;
}
if (result.status == "passed") {
print(colored("green", '.'));
if (result.status == 'passed') {
print(colored('green', '.'));
return;
}
if (result.status == "failed") {
if (result.status == 'failed') {
failureCount++;
failedSpecs.push(result);
print(colored("red", 'F'));
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");
print('\n');
}
function colored(color, str) {
@@ -122,7 +140,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
function plural(str, count) {
return count == 1 ? str : str + "s";
return count == 1 ? str : str + 's';
}
function repeat(thing, times) {
@@ -134,12 +152,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
function indent(str, spaces) {
var lines = (str || '').split("\n");
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(" ", spaces).join("") + lines[i]);
newArr.push(repeat(' ', spaces).join('') + lines[i]);
}
return newArr.join("\n");
return newArr.join('\n');
}
function specFailureDetails(result) {
@@ -149,11 +167,23 @@ getJasmineRequireObj().ConsoleReporter = function() {
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
printNewline();
print(indent(failedExpectation.message, 2));
print(indent(failedExpectation.stack, 2));
}
printNewline();
}
function suiteFailureDetails(result) {
for (var i = 0; i < result.failedExpectations.length; i++) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
printNewline();
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
}
printNewline();
}
}
return ConsoleReporter;

37
lib/jasmine-core.js Normal file
View File

@@ -0,0 +1,37 @@
module.exports = require("./jasmine-core/jasmine.js");
module.exports.boot = require('./jasmine-core/node_boot.js');
var path = require('path'),
fs = require('fs');
var rootPath = path.join(__dirname, "jasmine-core"),
bootFiles = ['boot.js'],
nodeBootFiles = ['node_boot.js'],
cssFiles = [],
jsFiles = [],
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles);
fs.readdirSync(rootPath).forEach(function(file) {
if(fs.statSync(path.join(rootPath, file)).isFile()) {
switch(path.extname(file)) {
case '.css':
cssFiles.push(file);
break;
case '.js':
if (jsFilesToSkip.indexOf(file) < 0) {
jsFiles.push(file);
}
break;
}
}
});
module.exports.files = {
path: rootPath,
bootDir: rootPath,
bootFiles: bootFiles,
nodeBootFiles: nodeBootFiles,
cssFiles: cssFiles,
jsFiles: ['jasmine.js'].concat(jsFiles),
imagesDir: path.join(__dirname, '../images')
};

View File

@@ -6,7 +6,7 @@ module Jasmine
end
def js_files
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - node_boot_files
end
SPEC_TYPES = ["core", "html", "node"]
@@ -27,8 +27,12 @@ module Jasmine
["boot.js"]
end
def node_boot_files
["node_boot.js"]
end
def boot_dir
File.join(path, 'boot')
path
end
def spec_files(type)

View File

@@ -0,0 +1 @@
from .core import Core

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2015 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -21,7 +21,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
@@ -54,77 +54,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
*/
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
pending: function() {
return env.pending();
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})
};
var jasmineInterface = jasmineRequire.interface(jasmine, env);
/**
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
*/
if (typeof window == "undefined" && typeof exports == "object") {
extend(exports, jasmineInterface);
} else {
extend(window, jasmineInterface);
}
/**
* Expose the interface for adding custom equality testers.
*/
jasmine.addCustomEqualityTester = function(tester) {
env.addCustomEqualityTester(tester);
};
/**
* Expose the interface for adding custom expectation matchers
*/
jasmine.addMatchers = function(matchers) {
return env.addMatchers(matchers);
};
/**
* Expose the mock interface for the JavaScript timeout functions
*/
jasmine.clock = function() {
return env.clock;
};
extend(window, jasmineInterface);
/**
* ## Runner Parameters
@@ -139,13 +74,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
var throwingExpectationFailures = queryString.getParam("throwFailures");
env.throwOnExpectationFailure(throwingExpectationFailures);
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },

View File

@@ -1,5 +1,5 @@
/**
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
@@ -32,77 +32,12 @@
*
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
*/
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
pending: function() {
return env.pending();
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})
};
var jasmineInterface = jasmineRequire.interface(jasmine, env);
/**
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
*/
if (typeof window == "undefined" && typeof exports == "object") {
extend(exports, jasmineInterface);
} else {
extend(window, jasmineInterface);
}
/**
* Expose the interface for adding custom equality testers.
*/
jasmine.addCustomEqualityTester = function(tester) {
env.addCustomEqualityTester(tester);
};
/**
* Expose the interface for adding custom expectation matchers
*/
jasmine.addMatchers = function(matchers) {
return env.addMatchers(matchers);
};
/**
* Expose the mock interface for the JavaScript timeout functions
*/
jasmine.clock = function() {
return env.clock;
};
extend(window, jasmineInterface);
/**
* ## Runner Parameters
@@ -117,13 +52,18 @@
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
var throwingExpectationFailures = queryString.getParam("throwFailures");
env.throwOnExpectationFailure(throwingExpectationFailures);
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },

View File

@@ -0,0 +1,19 @@
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);
extend(global, jasmineInterface);
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
return jasmine;
};

60
lib/jasmine-core/core.py Normal file
View File

@@ -0,0 +1,60 @@
import pkg_resources
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
class Core(object):
@classmethod
def js_package(cls):
return __package__
@classmethod
def css_package(cls):
return __package__
@classmethod
def image_package(cls):
return __package__ + ".images"
@classmethod
def js_files(cls):
js_files = sorted(list(filter(lambda x: '.js' in x, pkg_resources.resource_listdir(cls.js_package(), '.'))))
# jasmine.js needs to be first
js_files.insert(0, 'jasmine.js')
# boot needs to be last
js_files.remove('boot.js')
js_files.append('boot.js')
return cls._uniq(js_files)
@classmethod
def css_files(cls):
return cls._uniq(sorted(filter(lambda x: '.css' in x, pkg_resources.resource_listdir(cls.css_package(), '.'))))
@classmethod
def favicon(cls):
return 'jasmine_favicon.png'
@classmethod
def _uniq(self, items, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in items:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen:
continue
seen[marker] = 1
result.append(item)
return result

View File

@@ -0,0 +1,24 @@
function Player() {
}
Player.prototype.play = function(song) {
this.currentlyPlayingSong = song;
this.isPlaying = true;
};
Player.prototype.pause = function() {
this.isPlaying = false;
};
Player.prototype.resume = function() {
if (this.isPlaying) {
throw new Error("song is already playing");
}
this.isPlaying = true;
};
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
module.exports = Player;

View File

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

View File

@@ -0,0 +1,15 @@
beforeEach(function () {
jasmine.addMatchers({
toBePlaying: function () {
return {
compare: function (actual, expected) {
var player = actual;
return {
pass: player.currentlyPlayingSong === expected && player.isPlaying
}
}
};
}
});
});

View File

@@ -0,0 +1,60 @@
describe("Player", function() {
var Player = require('../../lib/jasmine_examples/Player');
var Song = require('../../lib/jasmine_examples/Song');
var player;
var song;
beforeEach(function() {
player = new Player();
song = new Song();
});
it("should be able to play a Song", function() {
player.play(song);
expect(player.currentlyPlayingSong).toEqual(song);
//demonstrates use of custom matcher
expect(player).toBePlaying(song);
});
describe("when song has been paused", function() {
beforeEach(function() {
player.play(song);
player.pause();
});
it("should indicate that the song is currently paused", function() {
expect(player.isPlaying).toBeFalsy();
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
it("should be possible to resume", function() {
player.resume();
expect(player.isPlaying).toBeTruthy();
expect(player.currentlyPlayingSong).toEqual(song);
});
});
// demonstrates use of spies to intercept and test method calls
it("tells the current song if the user has made it a favorite", function() {
spyOn(song, 'persistFavoriteStatus');
player.play(song);
player.makeFavorite();
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
});
//demonstrates use of expected exceptions
describe("#resume", function() {
it("should throw an exception if song is already playing", function() {
player.play(song);
expect(function() {
player.resume();
}).toThrowError("song is already playing");
});
});
});

View File

@@ -1,15 +1,15 @@
beforeEach(function () {
jasmine.Expectation.addMatchers({
toBePlaying: function () {
return {
compare: function (actual, expected) {
var player = actual;
jasmine.addMatchers({
toBePlaying: function () {
return {
compare: function (actual, expected) {
var player = actual;
return {
pass: player.currentlyPlayingSong === expected && player.isPlaying
}
}
};
return {
pass: player.currentlyPlayingSong === expected && player.isPlaying
};
}
});
};
}
});
});

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2015 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -40,29 +40,33 @@ jasmineRequire.HtmlReporter = function(j$) {
createElement = options.createElement,
createTextNode = options.createTextNode,
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
timer = options.timer || noopTimer,
results = [],
specsExecuted = 0,
failureCount = 0,
pendingSpecCount = 0,
htmlReporterMain,
symbols;
symbols,
failedSuites = [];
this.initialize = function() {
htmlReporterMain = createDom("div", {className: "html-reporter"},
createDom("div", {className: "banner"},
createDom("span", {className: "title"}, "Jasmine"),
createDom("span", {className: "version"}, j$.version)
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("ul", {className: "symbol-summary"}),
createDom("div", {className: "alert"}),
createDom("div", {className: "results"},
createDom("div", {className: "failures"})
createDom('ul', {className: 'symbol-summary'}),
createDom('div', {className: 'alert'}),
createDom('div', {className: 'results'},
createDom('div', {className: 'failures'})
)
);
getContainer().appendChild(htmlReporterMain);
symbols = find(".symbol-summary");
symbols = find('.symbol-summary');
};
var totalSpecsDefined;
@@ -71,17 +75,21 @@ jasmineRequire.HtmlReporter = function(j$) {
timer.start();
};
var summary = createDom("div", {className: "summary"});
var summary = createDom('div', {className: 'summary'});
var topResults = new j$.ResultsNode({}, "", null),
var topResults = new j$.ResultsNode({}, '', null),
currentParent = topResults;
this.suiteStarted = function(result) {
currentParent.addChild(result, "suite");
currentParent.addChild(result, 'suite');
currentParent = currentParent.last();
};
this.suiteDone = function(result) {
if (result.status == 'failed') {
failedSuites.push(result);
}
if (currentParent == topResults) {
return;
}
@@ -90,82 +98,132 @@ jasmineRequire.HtmlReporter = function(j$) {
};
this.specStarted = function(result) {
currentParent.addChild(result, "spec");
currentParent.addChild(result, 'spec');
};
var failures = [];
this.specDone = function(result) {
if (result.status != "disabled") {
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
console.error('Spec \'' + result.fullName + '\' has no expectations.');
}
if (result.status != 'disabled') {
specsExecuted++;
}
symbols.appendChild(createDom("li", {
className: result.status,
id: "spec_" + result.id,
symbols.appendChild(createDom('li', {
className: noExpectations(result) ? 'empty' : result.status,
id: 'spec_' + result.id,
title: result.fullName
}
));
if (result.status == "failed") {
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: 'spec-detail failed'},
createDom('div', {className: 'description'},
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
),
createDom("div", {className: "messages"})
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));
messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
}
failures.push(failure);
}
if (result.status == "pending") {
if (result.status == 'pending') {
pendingSpecCount++;
}
};
this.jasmineDone = function() {
var banner = find(".banner");
banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s"));
var banner = find('.banner');
var alert = find('.alert');
alert.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
var alert = find(".alert");
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'))
)
));
alert.appendChild(createDom("span", { className: "exceptions" },
createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
createDom("input", {
className: "raise",
id: "raise-exceptions",
type: "checkbox"
})
));
var checkbox = find("input");
var raiseCheckbox = find('#raise-exceptions');
checkbox.checked = !env.catchingExceptions();
checkbox.onclick = onRaiseExceptionsClick;
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";
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
alert.appendChild(
createDom("span", {className: "bar skipped"},
createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
createDom('span', {className: 'bar skipped'},
createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
)
);
}
var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
var statusBarMessage = '';
var statusBarClassName = 'bar ';
var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
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';
}
var results = find(".results");
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
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 results = find('.results');
results.appendChild(summary);
summaryList(topResults, summary);
@@ -174,27 +232,34 @@ jasmineRequire.HtmlReporter = function(j$) {
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)
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"});
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", {
createDom('li', {
className: resultNode.result.status,
id: "spec-" + resultNode.result.id
id: 'spec-' + resultNode.result.id
},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
createDom('a', {href: specHref(resultNode.result)}, specDescription)
)
);
}
@@ -203,24 +268,24 @@ jasmineRequire.HtmlReporter = function(j$) {
if (failures.length) {
alert.appendChild(
createDom('span', {className: "menu bar spec-list"},
createDom("span", {}, "Spec List | "),
createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
createDom('span', {className: 'menu bar spec-list'},
createDom('span', {}, 'Spec List | '),
createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
alert.appendChild(
createDom('span', {className: "menu bar failure-list"},
createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
createDom("span", {}, " | Failures ")));
createDom('span', {className: 'menu bar failure-list'},
createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
createDom('span', {}, ' | Failures ')));
find(".failures-menu").onclick = function() {
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
};
find(".spec-list-menu").onclick = function() {
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('failure-list');
var failureNode = find(".failures");
var failureNode = find('.failures');
for (var i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
@@ -230,7 +295,16 @@ jasmineRequire.HtmlReporter = function(j$) {
return this;
function find(selector) {
return getContainer().querySelector(selector);
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
}
function clearPrior() {
// return the reporter
var oldReporter = find('');
if(oldReporter) {
getContainer().removeChild(oldReporter);
}
}
function createDom(type, attrs, childrenVarArgs) {
@@ -249,7 +323,7 @@ jasmineRequire.HtmlReporter = function(j$) {
}
for (var attr in attrs) {
if (attr == "className") {
if (attr == 'className') {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
@@ -260,17 +334,26 @@ jasmineRequire.HtmlReporter = function(j$) {
}
function pluralize(singular, count) {
var word = (count == 1 ? singular : singular + "s");
var word = (count == 1 ? singular : singular + 's');
return "" + count + " " + word;
return '' + count + ' ' + word;
}
function specHref(result) {
return "?spec=" + encodeURIComponent(result.fullName);
return addToExistingQueryString('spec', result.fullName);
}
function defaultQueryString(key, value) {
return '?' + key + '=' + value;
}
function setMenuModeTo(mode) {
htmlReporterMain.setAttribute("class", "html-reporter " + mode);
htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
}
function noExpectations(result) {
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
result.status === 'passed';
}
}
@@ -279,7 +362,7 @@ jasmineRequire.HtmlReporter = function(j$) {
jasmineRequire.HtmlSpecFilter = function() {
function HtmlSpecFilter(options) {
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
var filterPattern = new RegExp(filterString);
this.matches = function(specName) {
@@ -313,10 +396,14 @@ jasmineRequire.ResultsNode = function() {
jasmineRequire.QueryString = function() {
function QueryString(options) {
this.setParam = function(key, value) {
this.navigateWithNewParam = function(key, value) {
options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
};
this.fullStringWithNewParam = function(key, value) {
var paramMap = queryStringToParamMap();
paramMap[key] = value;
options.getWindowLocation().search = toQueryString(paramMap);
return toQueryString(paramMap);
};
this.getParam = function(key) {
@@ -328,9 +415,9 @@ jasmineRequire.QueryString = function() {
function toQueryString(paramMap) {
var qStrPairs = [];
for (var prop in paramMap) {
qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
}
return "?" + qStrPairs.join('&');
return '?' + qStrPairs.join('&');
}
function queryStringToParamMap() {
@@ -343,7 +430,7 @@ jasmineRequire.QueryString = function() {
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
var value = decodeURIComponent(p[1]);
if (value === "true" || value === "false") {
if (value === 'true' || value === 'false') {
value = JSON.parse(value);
}
paramMap[decodeURIComponent(p[0])] = value;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
http://www.JSON.org/json2.js
2009-08-17
json2.js
2014-02-04
Public Domain.
@@ -8,6 +8,14 @@
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
@@ -136,15 +144,9 @@
This is a reference implementation. You are free to copy, modify, or
redistribute.
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
*/
/*jslint evil: true */
/*jslint evil: true, regexp: true */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
@@ -153,16 +155,16 @@
test, toJSON, toString, valueOf
*/
"use strict";
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
this.JSON = {};
if (typeof JSON !== 'object') {
JSON = {};
}
(function () {
'use strict';
function f(n) {
// Format integers to have at least two digits.
@@ -171,37 +173,30 @@ if (!this.JSON) {
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
Date.prototype.toJSON = function () {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z'
: null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function () {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
var cx,
escapable,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
meta,
rep;
@@ -213,17 +208,17 @@ if (!this.JSON) {
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
@@ -301,11 +296,11 @@ if (!this.JSON) {
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
v = partial.length === 0
? '[]'
: gap
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
: '[' + partial.join(',') + ']';
gap = mind;
return v;
}
@@ -315,8 +310,8 @@ if (!this.JSON) {
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
@@ -328,7 +323,7 @@ if (!this.JSON) {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
@@ -340,9 +335,11 @@ if (!this.JSON) {
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
return v;
}
@@ -351,7 +348,18 @@ if (!this.JSON) {
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
};
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
@@ -382,7 +390,7 @@ if (!this.JSON) {
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
@@ -397,6 +405,7 @@ if (!this.JSON) {
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
@@ -412,7 +421,7 @@ if (!this.JSON) {
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
@@ -430,6 +439,7 @@ if (!this.JSON) {
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
@@ -451,10 +461,10 @@ if (!this.JSON) {
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
@@ -466,8 +476,9 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
return typeof reviver === 'function'
? walk({'': j}, '')
: j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.

View File

@@ -0,0 +1,41 @@
/*
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.
*/
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);
extend(global, jasmineInterface);
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
return jasmine;
};

View File

@@ -4,6 +4,6 @@
#
module Jasmine
module Core
VERSION = "2.0.0.rc5"
VERSION = "2.3.2"
end
end

View File

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

22
release_notes/1.3.0.md Normal file
View File

@@ -0,0 +1,22 @@
# Jasmine Core 1.3.0 Release Notes
## Summary
This version was a very incremental release that merged in some pull requests for bug fixes.
## Features
* HTML Runner exposes UI to not swallow Exceptions, instead raising as soon as thrown
* Migrated homepage content to Wiki
* Made a far more useful [tutorial page](http://pivotal.github.com/jasmine)
* Added a `toBeNaN` matcher
## Fixes
* Better detection of in-browser vs. not
* `afterEach` functions will run now even when there is a timeout
* `toBeCloseTo` matcher is more accurate
* More explicit matcher messages for spies
* Better equality comparisons for regular expressions
* Improvements to the Pretty Printer: controllable recursion depth, don't include inherited properties
* Fix where `for` was being used as a property on an object (failed on IE)

12
release_notes/1.3.1.md Normal file
View File

@@ -0,0 +1,12 @@
# Jasmine Core 1.3.1 Release Notes
## Summary
This release is for browser compatibility fixes
## Changes
### Features
Fixing test runner failures in IE 6/7/8

70
release_notes/2.0.1.md Normal file
View File

@@ -0,0 +1,70 @@
# Jasmine Core 2.0.1 Release Notes
## Summary
This release is for small bug fixes and enhancements ahead of a real-soon-now 2.1.
## Changes
### Features
* NodeJS is now supported with a jasmine-core npm
* [Support browsers that don't supply a `Date.now()` by having a `mockDate` object](http://www.pivotaltracker.com/story/66606132) - Closes #361
* [Show message if no specs where loaded](http://www.pivotaltracker.com/story/12784235)
* When using `jasmine.any`, the `class` will now be included in the error message
* Reporters now receive the number of passed expectations in a spec
* Use default failure message for `toBeNaN`
* Use the latest `jasmine_selenium_runner` so we use the fix for printing objects with cycles
* Add jasmine logo image to HTML runner
* Stop Jasmine's CSS affecting the style of the body tag - Closes #600
* Standardized location of the standalone distributions - they now live in the repo in `/dist` as well as on the Releases page
### Bugs
* Don't allow calling the same done callback multiple times - Fixes #523
* [Remove 'empty' as an option as a spec result](http://www.pivotaltracker.com/story/73741032) as this was a breaking change
* Instead, we determine if a spec has no expectations using the added
key of `passedExpectations` in combination of the `failedExpectations`
to determine that there a spec is 'empty'
* Fix build in IE8 (IE8 doesn't support `Object.freeze`)
* Fix `ObjectContaining` to match recursively
### Documentation
* Update release doc to use GitHub releases
* Add installation instructions to README - Merges #621
* Add Ruby Gem and Python Egg to docs
* Add detailed steps on how to contribute - Merges #580 from @pablofiu
## Pull Requests and Issues
* Contains is explicitly false if actual is `undefined` or `null` - Fixes #627
* namespace `html-reporter` -> `jasmine_html-reporter` - Fixes #600
* Throw a more specific error when `expect` is used without a `currentSpec` - Fixes #602
* Reduced size of logo with PNG Gauntlet - Merges #588
* HTML Reporter resets previous DOM when re-initialized - Merges #594 from @plukevdh
* Narrow down raise exceptions query selector; Finding by any input tag is a little bit broad - Closes #605
* Pass through custom equality testers in toHaveBeenCalledWith - Fixes #536
* Fix outdated copyright year (update to 2014) - Merges #550 from @slothmonster
* [Add package.json to Python egg to get correct version number](http://www.pivotaltracker.com/story/67556148) - Fixes #551
* Allow users to set the maximum length of array that the pretty-printer
will print out - Fixes #323 @mikemoraned and #374 @futuraprime
* `matchersUtil.equals()` does not expect a matcher as its first argument,
so send the "actual" value first and the "expected" value second. - Merges #538 from @cbandy
* Add single quote check to `jshint` and fix src files for that - Closes #522
* Remove an `eval` in order to support running jasmine within CSP - Closes #503
* Allow matcher custom failure messages to be a function - Closes #520
* More color blind friendly CSS from @dleppik - Closes #463 &amp; #509
* Use `load-grunt-tasks` Merges #521 from @robinboehm
* Special case printing `-0` - Closes #496
* Allow stub or spy Date object safely using a closure to get a clean copy - Closes #506
* [Use `\d7` instead of plain 'x' for more square appearance](http://www.pivotaltracker.com/story/48434179)
* Better support in pretty printer when an object has null prototype - Fixes #500
* Update link at top of README to improve access to Jasmine 2.0 docs - Merges #486 from @nextmat
* Force query selector to seek within the html-reporter element - Merges #479 from @shprink
* Netbeans files are in gitignore - Merges #478 from @shprink
------
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_

25
release_notes/2.0.2.md Normal file
View File

@@ -0,0 +1,25 @@
# Release Notes
## Summary
## Changes
* keep the files for running in a webpage around in the npm package
* Expose files and paths necessary to embed jasmine in an html page for nodejs
* Pull out the building of the jasmine interface so node and web both get the same one.
* Show a dot with color of pending spec when no expectations
* Console reporter prints out failed expectation's message
### Bugs
* Allow mocked Date constructor to be called with a subset of full params
## Pull Requests and Issues
* a disabled suite should call resultCallback with status being disabled
* disabled suite should still call onStart callback
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

83
release_notes/2.1.0.md Normal file
View File

@@ -0,0 +1,83 @@
# Jasmine Core 2.1.0 Release Notes
## Summary
This is the release of Jasmine 2.1.
## Features
- Support for focused specs via `fit` and `fdescribe`
- Support for `beforeAll` and `afterAll`
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
- Spies now track return values
- Specs can now specify their own timeouts
- Testing in Node.js via the official Jasmine Node Module
- Spec results now have `suiteResults` method that behaves similarly to to `specResults`
- HtmlReporter shows error alerts for afterAllExceptions
## Bugs
- CI now works for IE8 (this was releated to `ConsoleReporter` below)
- Detect global object properly when getting the jasmine require obj
- Fixes Issue #[569][issue_569] - [Tracker Story #73684570](http://www.pivotaltracker.com/story/73684570)
## Deprecations
### `ConsoleReporter` as part of Jasmine core
The Console Reporter exists nearly entirely for the old manner of running Jasmine's own specs in node.js. As we are now supporting node.js officially, this reporter code no longer needs to be in this repo and instead will be in the Jasmine npm.
For now you will see a deprecation message. It will be removed entirely in Jasmine 3.0.
## Documentation
- Release Notes from previous releases now live at [Jasmine's GitHub release page][releases]. See Tracker Story #[54582902][tracker_1]
- Better instructions for releasing new documentation
[releases]: https://github.com/pivotal/jasmine/releases
[tracker_1]: http://www.pivotaltracker.com/story/54582902
## Pull Requests and Issues
- Simplification of HTMLtags in SpecRunner.html
- Merges #[700][issue_700] from @tkrotoff
- `toContain` works with array-like objects (Arguments, HTMLCollections, etc)
- Merges #[699][issue_699] from @charleshansen
- Fixed isPendingSpecException test title
- Merges #[691][issue_691] from @ertrzyiks
- Fixed an issue with example code in the npm
- Merges #[686][issue_686] from @akoptsov
- When the Jasmine clock is installed and date is mocked, `new Date() instanceof Date` should equal `true` Issue #[678][issue_678] & Issue #[679][issue_679] from @chernetsov
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
- Fixes Issue #[567][issue_567], Issue #[568][issue_568], and Issue #[563][issue_563]
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
- Fixes Issue #[483][issue_483] - specs can now specify their own timeouts
- Spies can track return values
- Fixes Issue #[660][issue_660], Merged Issue #[669][issue_669] from @mkhanal
- Interval handlers can now clear their interval
- Fixes Issue #[655][issue_655] Merged Issue #[658][issue_658] from @tgirardi
- Updated to the latest `json2.js`
- Merges #[616][issue_616] from @apaladox2015
------
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
[issue_569]: http://github.com/pivotal/jasmine/issues/569
[issue_700]: http://github.com/pivotal/jasmine/issues/700
[issue_699]: http://github.com/pivotal/jasmine/issues/699
[issue_691]: http://github.com/pivotal/jasmine/issues/691
[issue_678]: http://github.com/pivotal/jasmine/issues/678
[issue_679]: http://github.com/pivotal/jasmine/issues/679
[issue_567]: http://github.com/pivotal/jasmine/issues/567
[issue_568]: http://github.com/pivotal/jasmine/issues/568
[issue_563]: http://github.com/pivotal/jasmine/issues/563
[issue_483]: http://github.com/pivotal/jasmine/issues/483
[issue_660]: http://github.com/pivotal/jasmine/issues/660
[issue_669]: http://github.com/pivotal/jasmine/issues/669
[issue_655]: http://github.com/pivotal/jasmine/issues/655
[issue_658]: http://github.com/pivotal/jasmine/issues/658
[issue_616]: http://github.com/pivotal/jasmine/issues/616
[issue_686]: http://github.com/pivotal/jasmine/issues/686

14
release_notes/2.1.1.md Normal file
View File

@@ -0,0 +1,14 @@
# Jasmine Core 2.1.1 Release Notes
## Summary
This is a hotfix release of jasmine core to fix a breaking change with events emitted by the top-level suite
## Issues
- Top-level suite triggers suiteStarted and suiteEnd to be consistent
- Fixes [#706](http://github.com/pivotal/jasmine/issues/706)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

14
release_notes/2.1.2.md Normal file
View File

@@ -0,0 +1,14 @@
# Jasmine Core 2.1.2 Release Notes
## Summary
This is a hotfix release of jasmine core to fix a breaking change with reporting when all of the specs in a suite are pending.
## Changes
- Suites still run their children even if none are executable
- Fixes [#707](http://github.com/pivotal/jasmine/issues/707)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

21
release_notes/2.1.3.md Normal file
View File

@@ -0,0 +1,21 @@
# Jasmine Core 2.1.3 Release Notes
## Summary
This release is primarily a bug-fix release to clean up some recent regressions.
## Pull Requests & Issues
* Top level suite no longer reports suiteStart and suiteDone
- Fixes [#716](https://github.com/jasmine/jasmine/issues/716)
* Don't keep the expected and actual for a passed expectation
- Fixes [#640](https://github.com/jasmine/jasmine/issues/640)
- Fixes [#690](https://github.com/jasmine/jasmine/issues/690)
* Use the new build env on Travis
- Merges [#712](https://github.com/jasmine/jasmine/issues/712) from @joshk
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

98
release_notes/2.2.0.md Normal file
View File

@@ -0,0 +1,98 @@
# Jasmine Core 2.2.0 Release Notes
## Changes
* `ObjectContaining` no longer tries to track exact mismatches
* HTML reporter keeps extra query params when focusing on a spec or suite
* Check custom properties on Arrays when computing equality
* Better error message if `spyOn` is called without a method name
* Rename `jasmineMatches` to `asymmetricMatch`
* Don't double escape focus spec links
* Jasmine equality checks if either side implements `asymmetricMatch`
* Add asymmetric equality tester to match a string with a RegExp
* Add jshint to node build on Travis for pull request builds
* Restructure node examples directory to look more realistic
## Pull Requests & Issues
* Add a basic bower config
- Fixes [#719](https://github.com/jasmine/jasmine/issues/719)
* Allow `pending` to take a reason and show it in the HtmlReporter
- Fixes [#671](https://github.com/jasmine/jasmine/issues/671)
* Set jasmineGlobal correctly in GJS
- Merges [#757](https://github.com/jasmine/jasmine/issues/757) from @ptomato
- Fixes [#751](https://github.com/jasmine/jasmine/issues/751)
* Fix some SpiderMonkey lint warnings
- Merges [#752](https://github.com/jasmine/jasmine/issues/752) from @ptomato
- Fixes [#751](https://github.com/jasmine/jasmine/issues/751)
* Prevents *Alls from running when runnables are explicitly set
- Fixes [#732](https://github.com/jasmine/jasmine/issues/732)
* Update contribution guide to mention possible ffi dependencies for Ubuntu
- Fixes [#755](https://github.com/jasmine/jasmine/issues/755)
* Fix spelling mistake in contributors guide
- Merges [#746](https://github.com/jasmine/jasmine/issues/746) from @swirlycheetah
* Use new jasmine github repo url
- Merges [#745](https://github.com/jasmine/jasmine/issues/745) rohit
* Allow `createSpyObj` to be called with just an array of method names
- Fixes [#321](https://github.com/jasmine/jasmine/issues/321)
* Add `arrayContaining` matcher
- Merges [#440](https://github.com/jasmine/jasmine/issues/440) from @slackersoft
* Use the stack trace from the Error object if supplied
- Fixes [#734](https://github.com/jasmine/jasmine/issues/734)
* Update readme with link to upgrading doc and mention browser support.
- Fixes [#739](https://github.com/jasmine/jasmine/issues/739)
* Link to the Jasmine NPM module
- Merges [#736](https://github.com/jasmine/jasmine/issues/736) from @moonmaster9000
* Allow null prototype objects to be compared for equality
- Merges [#731](https://github.com/jasmine/jasmine/issues/731) from @rohit
- Fixes [#729](https://github.com/jasmine/jasmine/issues/729)
* Fix URL's of Jasmine repositories on Github
- Merges [#730](https://github.com/jasmine/jasmine/issues/730) from @rohit
* Add `anything` matcher to match any value that is neither null or undefined
- Fixes [#186](https://github.com/jasmine/jasmine/issues/186)
* Allow asymmetric equality testers to preempt their symmetric brethren
- Fixes [#540](https://github.com/jasmine/jasmine/issues/540)
* Check for `ObjectContaining` on either side of equality
- Fixes [#682](https://github.com/jasmine/jasmine/issues/682)
* Display the name of the constructor when pretty printing objects
- Fixes [#598](https://github.com/jasmine/jasmine/issues/598)
* `toMatch` requires the `expected` to be a String or RegExp
- Fixes [#723](https://github.com/jasmine/jasmine/issues/723)
* Better equality comparison of Dom nodes
- Merges [#657](https://github.com/jasmine/jasmine/issues/657) from @alexeibs
* Hide unnecessary files from the npm package
- Fixes [#726](https://github.com/jasmine/jasmine/issues/726)
* Properly record finishing an `xdescribe` so further cleanup works
- Fixes [#724](https://github.com/jasmine/jasmine/issues/724)
* Reschedule all functions for a tick before executing any. This allows any function run during a tick to cancel any other in the same tick.
- Fixes [#708](https://github.com/jasmine/jasmine/issues/708)
* Pass through all args from external interface for befores, afters, its
- Fixes [#483](https://github.com/jasmine/jasmine/issues/483)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

15
release_notes/2.2.1.md Normal file
View File

@@ -0,0 +1,15 @@
# Jasmine Core 2.2.1 Release Notes
## Summary
This is a hotfix release to fix the packaging for bower
## Changes
* Fix missing comma on bower.json
- Merges [#763](https://github.com/jasmine/jasmine/issues/763) from @gabrielhpugliese
- Merges [#764](https://github.com/jasmine/jasmine/issues/764) from @joshuacc
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

81
release_notes/2.3.0.md Normal file
View File

@@ -0,0 +1,81 @@
# Jasmine Core 2.3.0 Release Notes
## Changes
* Style disabled specs in the results list
* Use `onclick` directly to better support older webkit
* Don't use deprecated `onComplete` syntax for jasmine-npm
* Allow the clock to be installed for the duration of a single closure
* Add safari 7 & 8 to browser matrix
* Remove unused standaloneBuilder var from Gruntfile
* Add test script to package.json
* Update bower.json keywords to match package.json keywords
* Add keywords to package.json
* refuse to execute an order if it would cause a suite with a beforeAll or afterAll to be re-entered after leaving once
## Pull Requests & Issues
* Specify a main entry point for bower so it can be loaded easier
- Merges [#827](https://github.com/jasmine/jasmine/issues/827) from @davetron5000
* Use `instanceof` when checking Error types in toThrowError
- Fixes [#819](https://github.com/jasmine/jasmine/issues/819)
* Remove periods from bullet points for consistency with rest of document
- Merge [#818](https://github.com/jasmine/jasmine/issues/818) from @lpww
* Subjective readability improvements to CONTRIBUTING.md
- Merge [#815](https://github.com/jasmine/jasmine/issues/815) from @jhamon
* Don't install the clock if the current timing functions aren't the originals
- Fixes [#782](https://github.com/jasmine/jasmine/issues/782)
* Properly pass `j$` to `Any` so it can use other jasmine stuff
- Fixes [#806](https://github.com/jasmine/jasmine/issues/806)
* Correctly handle functions that are scheduled after the clock is uninstalled and reinstalled from within Clock#tick.
- Merges [#804](https://github.com/jasmine/jasmine/issues/804) from @sgravrock
- Fixes [#790](https://github.com/jasmine/jasmine/issues/790).
* Allow user to stop a specs execution when an expectation fails
- Fixes [#577](https://github.com/jasmine/jasmine/issues/577)
* Remove unnecessary conditional
- Merges [#788](https://github.com/jasmine/jasmine/issues/788) from @toddbranch
* Show the name of the constructor function when printing an `any` instead of a `toString` of the entire constructor
- Fixes [#796](https://github.com/jasmine/jasmine/issues/796)
* Don't use hardcoded temporary directory paths
- Merges [#789](https://github.com/jasmine/jasmine/issues/789) from sgravrock
* Execute beforeAll/afterAll once per suite instead of once per child when running focused specs/suites
- Fixes [#773](https://github.com/jasmine/jasmine/issues/773)
* Report children of an xdescribe similarly to how they would be reported if they were themselves x'd out
- Fixes [#774](https://github.com/jasmine/jasmine/issues/774)
- Fixes [#776](https://github.com/jasmine/jasmine/issues/776)
* Fixes issue where mock clock was being used by QueueRunner
- Fixes [#783](https://github.com/jasmine/jasmine/issues/783)
- Fixes [#792](https://github.com/jasmine/jasmine/issues/792)
* add missing semicolon
- Merges [#775](https://github.com/jasmine/jasmine/issues/775) from @joscha
* ObjectContaining matches prototype properties
- Fixes [#769](https://github.com/jasmine/jasmine/issues/769)
* Updates pretty printer to include array properties
- Fixes [#766](https://github.com/jasmine/jasmine/issues/766)
* Update year copyright
- Merges [#768](https://github.com/jasmine/jasmine/issues/768) from @danilovaz
* Allow arrays from different frames or contexts to be equal
- Merges [#767](https://github.com/jasmine/jasmine/issues/767) from @juliemr
- Fixes [#765](https://github.com/jasmine/jasmine/issues/765)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

14
release_notes/2.3.1.md Normal file
View File

@@ -0,0 +1,14 @@
# Jasmine 2.3.1 Release Notes
## Summary
This release is a packaging update for bower only.
## Pull Requests & Issues
* Point Bower's main field to jasmine.js, which is browser-friendly.
- Merge [#843](https://github.com/jasmine/jasmine/issues/843) from @evoL
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

14
release_notes/2.3.2.md Normal file
View File

@@ -0,0 +1,14 @@
# Jasmine 2.3.2 Release Notes
## Summary
This is a hotfix release to fix a regression with specs declared without a function body
## Pull Requests & Issues
* A spec without a function provided should be `pending` not `disabled`
- Fixes [#840](https://github.com/jasmine/jasmine/issues/840)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

@@ -2,48 +2,48 @@
## Summary
These notes are for RC5 of Jasmine Core 2.0.
These notes are for Jasmine Core 2.0.
## Breaking Changes
The [`introduction.js`][intro] page covers the current syntax, highlighting the changes. Here are known breaking interface changes that are not backwards compatible with 1.x.
The [`introduction.js`][intro] page covers the current syntax, highlighting the changes. Here are the known interface changes that are not backwards compatible with 1.x.
* New syntax for asynchronous specs
* New syntax for spies
* New interface for reporters
* Better Equality testing
* Easier custom matchers
* Replaced custom matchers for ease of use
* Change to `toThrow` matcher
* Clock does not uninstall itself at the end of a spec
* Clock now remains installed when a spec finishes
* More Jasmine internal variables/functions have been moved into closures
### New syntax for asynchronous specs
Similar to [Mocha][mocha], Jasmine befores, specs, and afters can take an optional "done" callback in order to force asynchronous tests. The next function, whether it's a before, spec or after, will wait until this function is called or if a timeout is reached.
Similar to [Mocha][mocha], Jasmine `before`s, `spec`s, and `after`s can take an optional `done` callback in order to force asynchronous tests. The next function, whether it's a `before`, `spec` or `after`, will wait until this function is called or until a timeout is reached.
### New syntax for spies
Spies have a slightly modified syntax. The ideas came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
Spies have a slightly modified syntax. The idea came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
### New interface for reporters
The reporter interface has changed. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to Jasmine implementation. The full suite execution time is also reported.
The reporter interface has been **replaced**. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to the Jasmine implementation. The Jasmine reporter API now includes a slot for a `timer` object.
### Better Equality testing
We have tossed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
We removed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
### Easier custom matchers
### Replaced custom matchers for ease of use
Custom matchers have always been possible, but this was barely documented and clunky to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that as custom matchers use. Dogfooding FTW.
The interface for adding custom matchers has been **replaced**. It has always been possible to add custom matchers, but the API was barely documented and difficult to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that custom matchers use. Dogfooding FTW.
### Change to `toThrow` matcher
We've changed the behavior of the `toThrow` matcher, moving some functionality to the `toThrowError` matcher. This should allow more of the requested use cases.
### Clock does not uninstall itself at the end of a spec
### Clock now remains installed when a spec finishes
After installing the Jasmine Clock, it will stay installed until uninstall is called -- clearing up any ambiguity for when those timing functions will go back to being the actual ones.
After installing the Jasmine Clock, it will stay installed until `uninstall` is called -- clearing up any ambiguity for when those timing functions will revert to using the global clock object.
## More Jasmine internal variables/functions have been moved into closures
@@ -53,9 +53,9 @@ Certain variables/functions like a function to get the next spec id have been mo
* Massive refactoring and better testing
* Environment setup now in `boot.js`
* Development & Build moved to Grunt
* Change in how Jasmine is loaded
* Change in how Jasmine is tested
* Development and Build moved to Grunt
* Changes to how Jasmine is loaded
* Changes to how Jasmine is tested
* Better node.js support
* Better Continuous Integration Environment at Travis
* Support matrix updated
@@ -64,39 +64,39 @@ Certain variables/functions like a function to get the next spec id have been mo
## Massive refactoring and better testing
This is the biggest set of changes. We've touched nearly every file and every object. We've slammed objects back together and pulled out new extractions. We've made the code more consistently styled. We've improved the tests nearly everywhere.
This is the biggest set of changes. We've touched nearly every file and every object. We've merged objects together and factored out code. We styled the code more consistently. We've improved nearly every test.
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to write, read, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to read, write, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
## Environment setup now in `boot.js`
Instantiation and setup of the Jasmine environment, including building reporters, exposing the "global" functions, and executing tests has moved into its own file: `boot.js`. This should make it easier to add custom reporters, configure some objects, or just in general change how you use Jasmine from the outside.
For example, during development, Jasmine uses it's own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
For example, during development, Jasmine uses its own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
## Development & Build moved to Grunt
## Development and Build moved to Grunt
We've moved away from Ruby and embraced Node.js and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browser and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
We've moved away from Ruby and embraced [Node.js][node] and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browsers and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
## Change in how Jasmine is loaded
## Changes to how Jasmine is loaded
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests that add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests which add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
## Change in how Jasmine is tested with Jasmine
## Changes to how Jasmine is tested with Jasmine
Writing a custom require system helped enforce self-testing - the built `jasmine.js` testing Jasmine from the source directories. Overall this has improved the stability of the code. When you look at Jasmine's tests, you'll see both `jasmine` and `j$` used. The former, `jasmine`, will always be used to test the code from source, which is loaded into the reference `j$`. Please adhere to this pattern when writing tests for contributions.
## Better node.js support
Node.js is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official npm is coming.
`Node.js` is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official `npm` is coming.
## Better Continuous Integration Environment at Travis
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, Phantom.js, Node.js, and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, [Phantom.js][phantom], [Node.js][node], and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
## Support Matrix Updated
We're dropping support for IE < 8. Jasmine 1.x remains for projects supporting earlier versions of browsers.
We're dropping support for IE < 8. [Jasmine 1.x][jasmine_downloads] remains for projects that need to support older browsers.
## Removed JsDoc Pages
@@ -108,7 +108,7 @@ Last year saw the posting of the [`introduction.js`][intro] page to document the
We are running Code Climate for Jasmine. We have some work to do here but it's helping us easily find code hotspots.
## Pull Requests & Issues
## Pull Requests and Issues
The following Pull Requests were merged:
@@ -122,12 +122,21 @@ The following Pull Requests were merged:
* Whitespace failures should be easier to understand #[332](https://github.com/pivotal/jasmine/issues/332) from bjornblomqvist
* Fix for more markdown-y image for Build status #[329](https://github.com/pivotal/jasmine/issues/329) from sunliwen
* UTF-8 encoding fixes #[333](https://github.com/pivotal/jasmine/issues/333) from bjornblomqvist
* Replaced deprecated octal literal with hexadecimal from kris7t
* Make getGlobal() work in strict mode from metaweta
* Clears timeout timer even when async spec throws an exception from tidoust
* Timeouts scheduled within a delayed function are correctly scheduled and executed from maciej-filip-sz
### Fixed in RC3
### Bug Fixes
* Improved the performance of the HTML output with a CSS change #[428](https://github.com/pivotal/jasmine/issues/428) - Thanks @tjgrathwell
* Removed an accidental global pollution of `j$` as a reference to Jasmine. Thanks to Morten Maxild from the mailing list
### Fixed in RC5
* There is now a consistent `this` between `beforeEach`, `it` and `afterEach` for a spec
* A spy's strategy now has properties `returnValue` and `throwError` because they are better names
* Make it easy to copy the title of failing specs from the HTML output
* Don't add periods to the full name of a spec fix #[427](https://github.com/pivotal/jasmine/issues/427)
* Allow Env to take optional spec/suite ids when asked to `execute`
* [Mock clock now less intrusive, replacing global timer functions only when clock is installed](http://www.pivotaltracker.com/story/54168708)
* Restore custom failure messages for `toHaveBeenCalledWith`
* Jasmine global object has a addCustomEqualityTester and addMatchers (no longer directly on global)
* Fixed a global leak of `timer`
* Remove currentRunner from Env (users can use topSuite from Env instead)
@@ -135,10 +144,11 @@ The following Pull Requests were merged:
* Improve error message when a spec does not call the async callback within the default time interval
* Allow passing a negativeCompare in a custom matcher for more custom implementations when `.not` is called
* Update favicon to be higher resolution
* Make all async functions be subject to the timeout
There were several other pull requests that either had already been fixed, or were good starting points for the various changes above. Thank you for all of the hard work to keep Jasmine awesome.
## Other Bugs & Features
## Other Bugs and Features
There were a few small changes and fixes that didn't fit into any of the above categories:
@@ -151,18 +161,12 @@ There were a few small changes and fixes that didn't fit into any of the above c
* Removed references to unused `jasmine.VERBOSE`
* Removed references to unused `jasmine.XmlHttpRequest`
### Fixed in RC3
* There is now a consistent `this` between `beforeEach`, `it` and `afterEach` for a spec
* A spy's strategy now has properties `returnValue` and `throwError` because they are better names
* Make it easy to copy the title of failing specs from the HTML output
* Don't add periods to the full name of a spec fix #[427](https://github.com/pivotal/jasmine/issues/427)
* Allow Env to take optional spec/suite ids when asked to `execute`
* [Mock clock now less intrusive, replacing global timer functions only when clock is installed](http://www.pivotaltracker.com/story/54168708)
* Restore custom failure messages for `toHaveBeenCalledWith`
[mocha]: http://visionmedia.github.io/mocha/
[underscore]: http://underscorejs.org/
[grunt]: http://gruntjs.com
[node]: http://nodejs.org
[phantom]: http://phantomjs.org
[jasmine_downloads]: https://github.com/pivotal/jasmine/downloads
[contrib]: https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md
[travis]: http://travis-ci.org
[travis_jasmine]: http://travis-ci.org/jasmine

View File

@@ -1,138 +0,0 @@
# Jasmine Core 2.0 Release Notes
## Summary
These notes are for RC1 of Jasmine Core 2.0.
## Breaking Changes
These changes have breaking interface changes and are not backwards compatible with 1.x.
* New syntax for asynchronous specs
* New syntax for spies
* New interface for reporters
* Better Equality testing
* Easier custom matchers
* Change to `toThrow` matcher
### New syntax for asynchronous specs
Similar to [Mocha][mocha], Jasmine befores, specs, and afters can take an optional "done" callback in order to force asynchronous tests. The next function, whether it's a before, spec or after, will wait until this function is called or if a timeout is reached.
### New syntax for spies
Spies have a slightly modified syntax. The ideas came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
### New interface for reporters
The reporter interface has changed. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to Jasmine implementation. The full suite execution time is also reported.
### Better Equality testing
We have tossed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
### Easier custom matchers
Custom matchers have always been possible, but this was barely documented and clunky to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that as custom matchers use. Dogfooding FTW.
### Change to `toThrow` matcher
We've changed the behavior of the `toThrow` matcher, moving some functionality to the `toThrowError` matcher. This should allow more of the requested use cases.
## Other Changes
* Massive refactoring and better testing
* Environment setup now in `boot.js`
* Development & Build moved to Grunt
* Change in how Jasmine is loaded
* Change in how Jasmine is tested
* Better node.js support
* Better Continuous Integration Environment at Travis
* Support matrix updated
* Removed JsDoc Pages
## Massive refactoring and better testing
This is the biggest set of changes. We've touched nearly every file and every object. We've slammed objects back together and pulled out new extractions. We've made the code more consistently styled. We've improved the tests nearly everywhere.
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to write, read, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
## Environment setup now in `boot.js`
Instantiation and setup of the Jasmine environment, including building reporters, exposing the "global" functions, and executing tests has moved into its own file: `boot.js`. This should make it easier to add custom reporters, configure some objects, or just in general change how you use Jasmine from the outside.
For example, during development, Jasmine uses it's own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
## Development & Build moved to Grunt
We've moved away from Ruby and embraced Node.js and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browser and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
## Change in how Jasmine is loaded
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests that add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
## Change in how Jasmine is tested with Jasmine
Writing a custom require system helped enforce self-testing - the built `jasmine.js` testing Jasmine from the source directories. Overall this has improved the stability of the code. When you look at Jasmine's tests, you'll see both `jasmine` and `j$` used. The former, `jasmine`, will always be used to test the code from source, which is loaded into the reference `j$`. Please adhere to this pattern when writing tests for contributions.
## Better node.js support
Node.js is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official npm is coming.
## Better Continuous Integration Environment at Travis
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, Phantom.js, Node.js, and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
## Support Matrix Updated
We're dropping support for IE < 8. Jasmine 1.x remains for projects supporting earlier versions of browsers.
## Removed JsDoc Pages
Comments in code are lies waiting to happen. Jasmine's JsDoc comments were no exception. The comments were out of date, the generated pages were even more out of date, and frankly they were not helpful. So they're gone.
Last year saw the posting of the [`introduction.js`][intro] page to document the real, practical interface for projects to use. This page has received a lot of positive feedback so expect more pages like this one.
## Pull Requests & Issues
The following Pull Requests were merged:
* ObjectContaining wrong filed value error message #[394](https://github.com/pivotal/jasmine/issues/394) from albertandrejev
* Removed unnecessary parameter from `suiteFactory()` call #[397](https://github.com/pivotal/jasmine/issues/397) from valera-rozuvan
* `jasmine.Any` supports `Boolean` #[392](https://github.com/pivotal/jasmine/issues/392) from albertandrejev
* Reporters get execution time #[30](https://github.com/pivotal/jasmine/issues/30)
* `toThrow` matchers handle falsy exceptions #[317](https://github.com/pivotal/jasmine/issues/371)
* Removed deprecated `jasmine.Matchers.pp` #[363](https://github.com/pivotal/jasmine/issues/363) from robinboehm
* Fix for Clock ticking to default to 0 #[340](https://github.com/pivotal/jasmine/issues/340) from Caio Cunha
* Whitespace failures should be easier to understand #[332](https://github.com/pivotal/jasmine/issues/332) from bjornblomqvist
* Fix for more markdown-y image for Build status #[329](https://github.com/pivotal/jasmine/issues/329) from sunliwen
* UTF-8 encoding fixes #[333](https://github.com/pivotal/jasmine/issues/333) from bjornblomqvist
There were several other pull requests that either had already been fixed, or were good starting points for the various changes above. Thank you for all of the hard work to keep Jasmine awesome.
## Other Bugs & Features
There were a few small changes and fixes that didn't fit into any of the above categories:
* HTML Reporter refactored for simplicity and performance
* Default character encoding on the HTML runner page is UTF-8
* [Escape special regex characters from the spec param](http://www.pivotaltracker.com/story/52731407)
* Favicon returns
* [Clock supports `eval`'d strings as functions](http://www.pivotaltracker.com/story/40853563)
* There should always be stack traces on failures
* Removed references to unused `jasmine.VERBOSE`
* Removed references to unused `jasmine.XmlHttpRequest`
------
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
[mocha]: http://visionmedia.github.io/mocha/
[underscore]: http://underscorejs.org/
[grunt]: http://gruntjs.com
[contrib]: https://github.com/pivotal/jasmine/blob/master/Contribute.markdown
[travis]: http://travis-ci.org
[travis_jasmine]: http://travis-ci.org/jasmine
[sauce]: http://saucelabs.com
[node_suite]: https://github.com/pivotal/jasmine/blob/master/spec/node_suite.js
[intro]: http://pivotal.github.com/jasmine/

View File

@@ -1,151 +0,0 @@
# Jasmine Core 2.0 Release Notes
## Summary
These notes are for RC3 of Jasmine Core 2.0.
## Breaking Changes
The [`introduction.js`][intro] page covers the current syntax, highlighting the changes. Here are known breaking interface changes that are not backwards compatible with 1.x.
* New syntax for asynchronous specs
* New syntax for spies
* New interface for reporters
* Better Equality testing
* Easier custom matchers
* Change to `toThrow` matcher
### New syntax for asynchronous specs
Similar to [Mocha][mocha], Jasmine befores, specs, and afters can take an optional "done" callback in order to force asynchronous tests. The next function, whether it's a before, spec or after, will wait until this function is called or if a timeout is reached.
### New syntax for spies
Spies have a slightly modified syntax. The ideas came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
### New interface for reporters
The reporter interface has changed. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to Jasmine implementation. The full suite execution time is also reported.
### Better Equality testing
We have tossed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
### Easier custom matchers
Custom matchers have always been possible, but this was barely documented and clunky to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that as custom matchers use. Dogfooding FTW.
### Change to `toThrow` matcher
We've changed the behavior of the `toThrow` matcher, moving some functionality to the `toThrowError` matcher. This should allow more of the requested use cases.
## Other Changes
* Massive refactoring and better testing
* Environment setup now in `boot.js`
* Development & Build moved to Grunt
* Change in how Jasmine is loaded
* Change in how Jasmine is tested
* Better node.js support
* Better Continuous Integration Environment at Travis
* Support matrix updated
* Removed JsDoc Pages
## Massive refactoring and better testing
This is the biggest set of changes. We've touched nearly every file and every object. We've slammed objects back together and pulled out new extractions. We've made the code more consistently styled. We've improved the tests nearly everywhere.
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to write, read, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
## Environment setup now in `boot.js`
Instantiation and setup of the Jasmine environment, including building reporters, exposing the "global" functions, and executing tests has moved into its own file: `boot.js`. This should make it easier to add custom reporters, configure some objects, or just in general change how you use Jasmine from the outside.
For example, during development, Jasmine uses it's own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
## Development & Build moved to Grunt
We've moved away from Ruby and embraced Node.js and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browser and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
## Change in how Jasmine is loaded
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests that add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
## Change in how Jasmine is tested with Jasmine
Writing a custom require system helped enforce self-testing - the built `jasmine.js` testing Jasmine from the source directories. Overall this has improved the stability of the code. When you look at Jasmine's tests, you'll see both `jasmine` and `j$` used. The former, `jasmine`, will always be used to test the code from source, which is loaded into the reference `j$`. Please adhere to this pattern when writing tests for contributions.
## Better node.js support
Node.js is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official npm is coming.
## Better Continuous Integration Environment at Travis
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, Phantom.js, Node.js, and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
## Support Matrix Updated
We're dropping support for IE < 8. Jasmine 1.x remains for projects supporting earlier versions of browsers.
## Removed JsDoc Pages
Comments in code are lies waiting to happen. Jasmine's JsDoc comments were no exception. The comments were out of date, the generated pages were even more out of date, and frankly they were not helpful. So they're gone.
Last year saw the posting of the [`introduction.js`][intro] page to document the real, practical interface for projects to use. This page has received a lot of positive feedback so expect more pages like this one.
## Pull Requests & Issues
The following Pull Requests were merged:
* ObjectContaining wrong filed value error message #[394](https://github.com/pivotal/jasmine/issues/394) from albertandrejev
* Removed unnecessary parameter from `suiteFactory()` call #[397](https://github.com/pivotal/jasmine/issues/397) from valera-rozuvan
* `jasmine.Any` supports `Boolean` #[392](https://github.com/pivotal/jasmine/issues/392) from albertandrejev
* Reporters get execution time #[30](https://github.com/pivotal/jasmine/issues/30)
* `toThrow` matchers handle falsy exceptions #[317](https://github.com/pivotal/jasmine/issues/371)
* Removed deprecated `jasmine.Matchers.pp` #[363](https://github.com/pivotal/jasmine/issues/363) from robinboehm
* Fix for Clock ticking to default to 0 #[340](https://github.com/pivotal/jasmine/issues/340) from Caio Cunha
* Whitespace failures should be easier to understand #[332](https://github.com/pivotal/jasmine/issues/332) from bjornblomqvist
* Fix for more markdown-y image for Build status #[329](https://github.com/pivotal/jasmine/issues/329) from sunliwen
* UTF-8 encoding fixes #[333](https://github.com/pivotal/jasmine/issues/333) from bjornblomqvist
### Fixed in RC3
* Improved the performance of the HTML output with a CSS change #[428](https://github.com/pivotal/jasmine/issues/428) - Thanks @tjgrathwell
* Removed an accidental global pollution of `j$` as a reference to Jasmine. Thanks to Morten Maxild from the mailing list
There were several other pull requests that either had already been fixed, or were good starting points for the various changes above. Thank you for all of the hard work to keep Jasmine awesome.
## Other Bugs & Features
There were a few small changes and fixes that didn't fit into any of the above categories:
* HTML Reporter refactored for simplicity and performance
* Default character encoding on the HTML runner page is UTF-8
* [Escape special regex characters from the spec param](http://www.pivotaltracker.com/story/52731407)
* Favicon returns
* [Clock supports `eval`'d strings as functions](http://www.pivotaltracker.com/story/40853563)
* There should always be stack traces on failures
* Removed references to unused `jasmine.VERBOSE`
* Removed references to unused `jasmine.XmlHttpRequest`
### Fixed in RC3
* There is now a consistent `this` between `beforeEach`, `it` and `afterEach` for a spec
* A spy's strategy now has properties `returnValue` and `throwError` because they are better names
* Make it easy to copy the title of failing specs from the HTML output
* Don't add periods to the full name of a spec fix #[427](https://github.com/pivotal/jasmine/issues/427)
* Allow Env to take optional spec/suite ids when asked to `execute`
* [Mock clock now less intrusive, replacing global timer functions only when clock is installed](http://www.pivotaltracker.com/story/54168708)
* Restore custom failure messages for `toHaveBeenCalledWith`
[mocha]: http://visionmedia.github.io/mocha/
[underscore]: http://underscorejs.org/
[grunt]: http://gruntjs.com
[contrib]: https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md
[travis]: http://travis-ci.org
[travis_jasmine]: http://travis-ci.org/jasmine
[sauce]: http://saucelabs.com
[node_suite]: https://github.com/pivotal/jasmine/blob/master/spec/node_suite.js
[intro]: http://jasmine.github.io/2.0/introduction.html
------
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_

View File

@@ -0,0 +1,110 @@
# Release 1.0.1.1 — November 9, 2010
## Jasmine Gem
## Bugs fixed
* Rails 3.0 and RSpec 2.0 are now supported.
## Known issues
* Rails 3 generators are not yet implemented -- coming soon!
-----
# Release 1.0.1 — October 5, 2010
-----
## Jasmine Core
## Bugs fixed
* Bug fixes for Internet Explorer (thanks fschwiet, fabiomcosta, and jfirebaugh).
## Jasmine Gem
## Bugs fixed
* Bug fix for Windows (thanks jfirebaugh).
-----
# Release 1.0 — September 14, 2010
-----
## Jasmine Core
## Features
* `waitsFor()` arguments can now be specified in any order. Timeout and message are optional.
* The default `waitsFor()` timeout period is now specified in `env.defaultTimeoutInterval`; the default value is 5 seconds.
* Added link to jasmine site from html runner.
* Added license file to standalone distribution.
* New friendly version number.
## Bugs fixed
* `waitsFor()` hanged forever if latch function never returned true.
* The `not.toThrow()` matcher threw an exception when used with no args.
* The `toThrow()` matcher, when inverted, gave misleading failure messages.
* Spy matchers, when inverted, gave misleading failure messages.
## Deprecations
* Deprecated `waits()` block in favor of `waitsFor()`; `waits()` will be removed in a future release.
* Deprecated `toNotBe()`, `toNotEqual()`, `toNotMatch()`, and `toNotContain()` matchers; they will be removed in a future release.
* Console X was removed from the distribution as it was no longer used.
* To give us some flexibility for future features, wrapped matcher functions now return `undefined` (they previously returned `true` or `false`, but this was undocumented).
## Jasmine Gem
## Features
* Jasmine now supports JRuby.
* Jasmine now supports Ruby 1.9.
## Bugs fixed
* Various generator issues fixed.
## Known issues
* Rails 3 and RSpec 2 are not yet fully supported.
-----
# Release 0.11.1 — June 25, 2010
-----
## Jasmine Core
### Features
* Jasmine no longer logs "Jasmine Running…" messages to the log by default. This can be enabled in runner.html by adding 'trivialReporter.logRunningSpecs = true;'.
* The `wasCalled()`, `wasCalledWith()`, `wasNotCalled()` and `wasNotCalledWith()` matchers have been deprecated. The new matchers `toHaveBeenCalled()` and `toHaveBeenCalledWith()` have been added. You can use the `not` prefix to achieve equivalent of the `wasNot…()` expectation (e.g. `not.toHaveBeenCalled()`).
## Notables
* A barebones version of Jasmine is now available on <a href="http://pivotal.github.com/jasmine/">http://pivotal.github.com/jasmine/</a>.
-----
# Release 0.11.0 — June 23, 2010
-----
## Jasmine Core
## Features
* The version number has been removed from the generated single-file /lib/jasmine.js. We're also now uploading this file, with the version number in the filename, to github's Downloads page.
* Old-style matchers (those using this.report(), from before 0.10.x) are no longer supported. See the <span class="caps">README</span> for instructions on writing new-style matchers.
* <strong>jasmine.log</strong> pretty-prints its parameters to the spec's output.
* Jasmine no longer depends on 'window'.
* <span class="caps">HTML</span> runner should show number of passes/fails by spec, not expectation.
* Small modification to JsApiReporter data format.
## Bugs fixed:
* If multiple beforeEach blocks were declared, they were executed in reverse order.
* Specs with duplicate names confused TrivialReporter output.
* Errors in describe functions caused later tests to be weirdly nested.
* Nested specs weren't reported properly by the JsApiReporter.
## Known issues:
* If you turn on the mock clock, you'll get a spurious log message at the end of your spec.

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
ordereddict==1.1

47
setup.py Normal file
View File

@@ -0,0 +1,47 @@
from setuptools import setup, find_packages, os
import json
with open('package.json') as packageFile:
version = json.load(packageFile)['version']
setup(
name="jasmine-core",
version=version,
url="http://jasmine.github.io",
author="Pivotal Labs",
author_email="jasmine-js@googlegroups.com",
description=('Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on '+
'browsers, DOM, or any JavaScript framework. Thus it\'s suited for websites, '+
'Node.js (http://nodejs.org) projects, or anywhere that JavaScript can run.'),
license='MIT',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'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',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Build Tools',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Software Development :: Testing',
],
packages=['jasmine_core', 'jasmine_core.images'],
package_dir={'jasmine_core': 'lib/jasmine-core', 'jasmine_core.images': 'images'},
package_data={'jasmine_core': ['*.js', '*.css'], 'jasmine_core.images': ['*.png']},
include_package_data=True,
install_requires=['glob2>=0.4.1', 'ordereddict==1.1']
)

View File

@@ -9,7 +9,7 @@ describe("ConsoleReporter", function() {
output += str;
},
getOutput: function() {
return output;
return output.replace('ConsoleReporter is deprecated and will be removed in a future version.', '');
},
clear: function() {
output = "";
@@ -80,7 +80,19 @@ describe("ConsoleReporter", function() {
expect(out.getOutput()).toEqual("*");
});
it("reports a summary when done (singluar spec and time)", function() {
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,
@@ -159,26 +171,44 @@ describe("ConsoleReporter", function() {
out.clear();
reporter.jasmineDone({});
reporter.jasmineDone();
expect(out.getOutput()).toMatch(/true to be false/);
expect(out.getOutput()).toMatch(/foo bar baz/);
});
it("calls the onComplete callback when the suite is done", function() {
var onComplete = jasmine.createSpy('onComplete'),
describe('onComplete callback', function(){
var onComplete, reporter;
beforeEach(function() {
onComplete = jasmine.createSpy('onComplete');
reporter = new j$.ConsoleReporter({
print: out.print,
onComplete: onComplete
});
reporter.jasmineStarted();
});
reporter.jasmineDone({});
it("is called when the suite is done", function() {
reporter.jasmineDone();
expect(onComplete).toHaveBeenCalledWith(true);
});
expect(onComplete).toHaveBeenCalled();
it('calls it with false if there are spec failures', function() {
reporter.specDone({status: "failed", failedExpectations: []});
reporter.jasmineDone();
expect(onComplete).toHaveBeenCalledWith(false);
});
it('calls it with false if there are suite failures', function() {
reporter.specDone({status: "passed"});
reporter.suiteDone({failedExpectations: [{ message: 'bananas' }] });
reporter.jasmineDone();
expect(onComplete).toHaveBeenCalledWith(false);
});
});
describe("with color", function() {
it("reports that the suite has started to the console", function() {
var reporter = new j$.ConsoleReporter({
print: out.print,
@@ -198,7 +228,7 @@ describe("ConsoleReporter", function() {
reporter.specDone({status: "passed"});
expect(out.getOutput()).toEqual("\033[32m.\033[0m");
expect(out.getOutput()).toEqual("\x1B[32m.\x1B[0m");
});
it("does not report a disabled spec", function() {
@@ -220,7 +250,21 @@ describe("ConsoleReporter", function() {
reporter.specDone({status: 'failed'});
expect(out.getOutput()).toEqual("\033[31mF\033[0m");
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

@@ -5,7 +5,8 @@ describe("Clock", function() {
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.setTimeout(delayedFn, 0);
@@ -26,7 +27,8 @@ describe("Clock", function() {
fakeGlobal = { clearTimeout: fakeClearTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.clearTimeout("foo");
@@ -47,7 +49,8 @@ describe("Clock", function() {
fakeGlobal = { setInterval: fakeSetInterval },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.setInterval(delayedFn, 0);
@@ -68,7 +71,8 @@ describe("Clock", function() {
fakeGlobal = { clearInterval: fakeClearInterval },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeGlobal.clearInterval("foo");
@@ -84,6 +88,78 @@ describe("Clock", function() {
expect(fakeClearInterval).not.toHaveBeenCalled();
});
it("does not install if the current setTimeout is not the original function on the global", function() {
var originalFakeSetTimeout = function() {},
replacedSetTimeout = function() {},
fakeGlobal = { setTimeout: originalFakeSetTimeout },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.setTimeout = replacedSetTimeout;
expect(function() {
clock.install();
}).toThrowError(/unable to install/);
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
expect(fakeGlobal.setTimeout).toBe(replacedSetTimeout);
});
it("does not install if the current clearTimeout is not the original function on the global", function() {
var originalFakeClearTimeout = function() {},
replacedClearTimeout = function() {},
fakeGlobal = { clearTimeout: originalFakeClearTimeout },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.clearTimeout = replacedClearTimeout;
expect(function() {
clock.install();
}).toThrowError(/unable to install/);
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
expect(fakeGlobal.clearTimeout).toBe(replacedClearTimeout);
});
it("does not install if the current setInterval is not the original function on the global", function() {
var originalFakeSetInterval = function() {},
replacedSetInterval = function() {},
fakeGlobal = { setInterval: originalFakeSetInterval },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.setInterval = replacedSetInterval;
expect(function() {
clock.install();
}).toThrowError(/unable to install/);
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
expect(fakeGlobal.setInterval).toBe(replacedSetInterval);
});
it("does not install if the current clearInterval is not the original function on the global", function() {
var originalFakeClearInterval = function() {},
replacedClearInterval = function() {},
fakeGlobal = { clearInterval: originalFakeClearInterval },
delayedFunctionSchedulerFactory = jasmine.createSpy('delayedFunctionSchedulerFactory'),
mockDate = {},
clock = new j$.Clock(fakeGlobal, delayedFunctionSchedulerFactory, mockDate);
fakeGlobal.clearInterval = replacedClearInterval;
expect(function() {
clock.install();
}).toThrowError(/unable to install/);
expect(delayedFunctionSchedulerFactory).not.toHaveBeenCalled();
expect(fakeGlobal.clearInterval).toBe(replacedClearInterval);
});
it("replaces the global timer functions on uninstall", function() {
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
@@ -97,7 +173,8 @@ describe("Clock", function() {
},
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.uninstall();
@@ -113,13 +190,111 @@ describe("Clock", function() {
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
});
it("can be installed for the duration of a passed in function and uninstalled when done", function() {
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
fakeSetInterval = jasmine.createSpy("global setInterval"),
fakeClearInterval = jasmine.createSpy("global clearInterval"),
fakeGlobal = {
setTimeout: fakeSetTimeout,
clearTimeout: fakeClearTimeout,
setInterval: fakeSetInterval,
clearInterval: fakeClearInterval
},
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset", "removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
passedFunctionCalled = false;
clock.withMock(function() {
fakeGlobal.setTimeout(delayedFn, 0);
fakeGlobal.clearTimeout("foo");
fakeGlobal.setInterval(delayedFn, 10);
fakeGlobal.clearInterval("bar");
passedFunctionCalled = true;
});
expect(passedFunctionCalled).toBe(true);
expect(fakeSetTimeout).not.toHaveBeenCalled();
expect(fakeClearTimeout).not.toHaveBeenCalled();
expect(fakeSetInterval).not.toHaveBeenCalled();
expect(fakeClearInterval).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
delayedFunctionScheduler.scheduleFunction.calls.reset();
fakeGlobal.setTimeout(delayedFn, 0);
fakeGlobal.clearTimeout("foo");
fakeGlobal.setInterval(delayedFn, 10);
fakeGlobal.clearInterval("bar");
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 10);
expect(fakeClearInterval).toHaveBeenCalledWith("bar");
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
});
it("can be installed for the duration of a passed in function and uninstalled if an error is thrown", function() {
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
fakeSetInterval = jasmine.createSpy("global setInterval"),
fakeClearInterval = jasmine.createSpy("global clearInterval"),
fakeGlobal = {
setTimeout: fakeSetTimeout,
clearTimeout: fakeClearTimeout,
setInterval: fakeSetInterval,
clearInterval: fakeClearInterval
},
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset", "removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
passedFunctionCalled = false;
expect(function() {
clock.withMock(function() {
fakeGlobal.setTimeout(delayedFn, 0);
fakeGlobal.clearTimeout("foo");
fakeGlobal.setInterval(delayedFn, 10);
fakeGlobal.clearInterval("bar");
passedFunctionCalled = true;
throw 'oops';
});
}).toThrow('oops');
expect(passedFunctionCalled).toBe(true);
expect(fakeSetTimeout).not.toHaveBeenCalled();
expect(fakeClearTimeout).not.toHaveBeenCalled();
expect(fakeSetInterval).not.toHaveBeenCalled();
expect(fakeClearInterval).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
delayedFunctionScheduler.scheduleFunction.calls.reset();
fakeGlobal.setTimeout(delayedFn, 0);
fakeGlobal.clearTimeout("foo");
fakeGlobal.setInterval(delayedFn, 10);
fakeGlobal.clearInterval("bar");
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 10);
expect(fakeClearInterval).toHaveBeenCalledWith("bar");
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
});
it("schedules the delayed function (via setTimeout) with the fake timer", function() {
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
scheduleFunction = jasmine.createSpy('scheduleFunction'),
delayedFunctionScheduler = { scheduleFunction: scheduleFunction },
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.setTimeout(delayedFn, 0, 'a', 'b');
@@ -135,7 +310,8 @@ describe("Clock", function() {
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
timeoutId;
clock.install();
@@ -149,7 +325,8 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
fakeGlobal = { setTimeout: fakeClearTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.clearTimeout(123);
@@ -164,7 +341,8 @@ describe("Clock", function() {
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.setInterval(delayedFn, 0, 'a', 'b');
@@ -180,7 +358,8 @@ describe("Clock", function() {
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate),
intervalId;
clock.install();
@@ -194,7 +373,8 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
fakeGlobal = { setInterval: clearInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
clock.clearInterval(123);
@@ -220,7 +400,8 @@ describe("Clock", function() {
setTimeout: fakeSetTimeout,
setInterval: fakeSetInterval
},
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, function () { return delayedFunctionScheduler; }, mockDate);
fakeSetTimeout.apply = null;
fakeSetInterval.apply = null;
@@ -239,7 +420,6 @@ describe("Clock", function() {
clock.setInterval(fn, 0, 'extra');
}).toThrow();
});
});
describe("Clock (acceptance)", function() {
@@ -249,7 +429,8 @@ describe("Clock (acceptance)", function() {
delayedFn3 = jasmine.createSpy('delayedFn3'),
recurring1 = jasmine.createSpy('recurring1'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
@@ -295,7 +476,8 @@ describe("Clock (acceptance)", function() {
it("can clear a previously set timeout", function() {
var clearedFn = jasmine.createSpy('clearedFn'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
timeoutId;
clock.install();
@@ -309,10 +491,29 @@ describe("Clock (acceptance)", function() {
expect(clearedFn).not.toHaveBeenCalled();
});
it("can clear a previously set interval using that interval's handler", function() {
var spy = jasmine.createSpy('spy'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setInterval: function() {}}, function () { return delayedFunctionScheduler; }, mockDate),
intervalId;
clock.install();
intervalId = clock.setInterval(function() {
spy();
clock.clearInterval(intervalId);
}, 100);
clock.tick(200);
expect(spy.calls.count()).toEqual(1);
});
it("correctly schedules functions after the Clock has advanced", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
@@ -328,7 +529,8 @@ describe("Clock (acceptance)", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 0); });
clock.install();
@@ -341,4 +543,113 @@ describe("Clock (acceptance)", function() {
clock.tick();
expect(delayedFn2).toHaveBeenCalled();
});
it("correctly calls functions scheduled while the Clock is advancing", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 1); });
clock.install();
clock.setTimeout(delayedFn1, 5);
clock.tick(6);
expect(delayedFn1).toHaveBeenCalled();
expect(delayedFn2).toHaveBeenCalled();
});
it("correctly schedules functions scheduled while the Clock is advancing but after the Clock is uninstalled", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, function () { return delayedFunctionScheduler; }, mockDate);
delayedFn1.and.callFake(function() {
clock.uninstall();
clock.install();
clock.setTimeout(delayedFn2, 0);
});
clock.install();
clock.setTimeout(delayedFn1, 1);
clock.tick(1);
expect(delayedFn1).toHaveBeenCalled();
expect(delayedFn2).not.toHaveBeenCalled();
clock.tick(1);
expect(delayedFn2).toHaveBeenCalled();
});
it("does not mock the Date object by default", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
expect(global.Date).toEqual(Date);
var now = new global.Date().getTime();
clock.tick(50);
expect(new global.Date().getTime() - now).not.toEqual(50);
});
it("mocks the Date object and sets it to current time", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate);
clock.install().mockDate();
var now = new global.Date().getTime();
clock.tick(50);
expect(new global.Date().getTime() - now).toEqual(50);
var timeoutDate = 0;
clock.setTimeout(function() {
timeoutDate = new global.Date().getTime();
}, 100);
clock.tick(100);
expect(timeoutDate - now).toEqual(150);
});
it("mocks the Date object and sets it to a given time", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, function () { return delayedFunctionScheduler; }, mockDate),
baseTime = new Date(2013, 9, 23);
clock.install().mockDate(baseTime);
var now = new global.Date().getTime();
expect(now).toEqual(baseTime.getTime());
clock.tick(50);
expect(new global.Date().getTime()).toEqual(baseTime.getTime() + 50);
var timeoutDate = 0;
clock.setTimeout(function() {
timeoutDate = new global.Date().getTime();
}, 100);
clock.tick(100);
expect(timeoutDate).toEqual(baseTime.getTime() + 150);
});
});

View File

@@ -14,7 +14,7 @@ describe("DelayedFunctionScheduler", function() {
it("schedules a string for later execution", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
strfn = "horrible = true;";
strfn = "horrible = true;";
scheduler.scheduleFunction(strfn, 0);
@@ -113,47 +113,6 @@ describe("DelayedFunctionScheduler", function() {
expect(fn).not.toHaveBeenCalled();
});
it("reset removes scheduled functions", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0);
expect(fn).not.toHaveBeenCalled();
scheduler.reset();
scheduler.tick(0);
expect(fn).not.toHaveBeenCalled();
});
it("reset resets the returned ids", function() {
var scheduler = new j$.DelayedFunctionScheduler();
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
scheduler.reset();
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
});
it("reset resets the current tick time", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
expect(fn).not.toHaveBeenCalled();
scheduler.tick(15);
scheduler.reset();
scheduler.scheduleFunction(fn, 20, [], false, 1, 20);
scheduler.tick(5);
expect(fn).not.toHaveBeenCalled();
});
it("executes recurring functions interleaved with regular functions in the correct order", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
@@ -175,5 +134,122 @@ describe("DelayedFunctionScheduler", function() {
expect(fn).toHaveBeenCalled();
});
it("schedules a function for later execution during a tick", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10;
scheduler.scheduleFunction(function () {
scheduler.scheduleFunction(fn, fnDelay);
}, 0);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(fnDelay);
expect(fn).toHaveBeenCalled();
});
it("#removeFunctionWithId removes a previously scheduled function with a given id during a tick", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
scheduler.scheduleFunction(function () {
scheduler.removeFunctionWithId(timeoutKey);
}, 0);
timeoutKey = scheduler.scheduleFunction(fn, fnDelay);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(fnDelay);
expect(fn).not.toHaveBeenCalled();
});
it("executes recurring functions interleaved with regular functions and functions scheduled during a tick in the correct order", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
recurringCallCount = 0,
recurring = jasmine.createSpy('recurring').and.callFake(function() {
recurringCallCount++;
if (recurringCallCount < 5) {
expect(fn).not.toHaveBeenCalled();
}
}),
innerFn = jasmine.createSpy('innerFn').and.callFake(function() {
expect(recurring.calls.count()).toBe(4);
expect(fn).not.toHaveBeenCalled();
}),
scheduling = jasmine.createSpy('scheduling').and.callFake(function() {
expect(recurring.calls.count()).toBe(3);
expect(fn).not.toHaveBeenCalled();
scheduler.scheduleFunction(innerFn, 10); // 41ms absolute
});
scheduler.scheduleFunction(recurring, 10, [], true);
scheduler.scheduleFunction(fn, 50);
scheduler.scheduleFunction(scheduling, 31);
scheduler.tick(60);
expect(recurring).toHaveBeenCalled();
expect(recurring.calls.count()).toBe(6);
expect(fn).toHaveBeenCalled();
expect(scheduling).toHaveBeenCalled();
expect(innerFn).toHaveBeenCalled();
});
it("executes recurring functions after rescheduling them", function () {
var scheduler = new j$.DelayedFunctionScheduler(),
recurring = function() {
expect(scheduler.scheduleFunction).toHaveBeenCalled();
};
scheduler.scheduleFunction(recurring, 10, [], true);
spyOn(scheduler, "scheduleFunction");
scheduler.tick(10);
});
it("removes functions during a tick that runs the function", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
scheduler.scheduleFunction(function () {
scheduler.removeFunctionWithId(timeoutKey);
}, 2 * fnDelay);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(3 * fnDelay);
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(2);
});
it("removes functions during the first tick that runs the function", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
scheduler.scheduleFunction(function () {
scheduler.removeFunctionWithId(timeoutKey);
}, fnDelay);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(3 * fnDelay);
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(1);
});
});

View File

@@ -5,91 +5,18 @@ describe("Env", function() {
env = new j$.Env();
});
it('removes all spies when env is executed', function(done) {
originalFoo = function() {},
testObj = {
foo: originalFoo
},
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
env.spyOn(testObj, 'foo');
}),
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
expect(testObj.foo).toBe(originalFoo);
});
env.describe('test suite', function() {
env.it('spec 0', firstSpec);
env.it('spec 1', secondSpec);
});
var assertions = function() {
expect(firstSpec).toHaveBeenCalled();
expect(secondSpec).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
describe("#spyOn", function() {
it("checks for the existance of the object", function() {
expect(function() {
env.spyOn(void 0, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks for the existance of the method", function() {
var subject = {};
expect(function() {
env.spyOn(subject, 'pants');
}).toThrowError(/method does not exist/);
});
it("checks if it has already been spied upon", function() {
var subject = { spiedFunc: function() {} };
env.spyOn(subject, 'spiedFunc');
expect(function() {
env.spyOn(subject, 'spiedFunc');
}).toThrowError(/has already been spied upon/);
});
it("overrides the method on the object and returns the spy", function() {
var originalFunctionWasCalled = false;
var subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
originalFunc = subject.spiedFunc;
var spy = env.spyOn(subject, 'spiedFunc');
expect(subject.spiedFunc).toEqual(spy);
expect(subject.spiedFunc.calls.any()).toEqual(false);
expect(subject.spiedFunc.calls.count()).toEqual(0);
subject.spiedFunc('foo');
expect(subject.spiedFunc.calls.any()).toEqual(true);
expect(subject.spiedFunc.calls.count()).toEqual(1);
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['foo']);
expect(subject.spiedFunc.calls.mostRecent().object).toEqual(subject);
expect(originalFunctionWasCalled).toEqual(false);
subject.spiedFunc('bar');
expect(subject.spiedFunc.calls.count()).toEqual(2);
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['bar']);
});
});
describe("#pending", function() {
it("throws the Pending Spec exception", function() {
expect(function() {
env.pending();
}).toThrow(j$.Spec.pendingSpecExceptionMessage);
});
it("throws the Pending Spec exception with a custom message", function() {
expect(function() {
env.pending('custom message');
}).toThrow(j$.Spec.pendingSpecExceptionMessage + 'custom message');
});
});
describe("#topSuite", function() {
@@ -98,467 +25,24 @@ describe("Env", function() {
expect(suite.description).toEqual('Jasmine__TopLevel__Suite');
});
});
});
// TODO: move these into a separate file
describe("Env integration", function() {
it('can configure specs to throw errors on expectation failures', function() {
env.throwOnExpectationFailure(true);
it("Suites execute as expected (no nesting)", function(done) {
var env = new j$.Env(),
calls = [];
var assertions = function() {
expect(calls).toEqual([
"with a spec",
"and another spec"
]);
done();
};
env.addReporter({ jasmineDone: assertions});
env.describe("A Suite", function() {
env.it("with a spec", function() {
calls.push("with a spec");
});
env.it("and another spec", function() {
calls.push("and another spec");
});
});
env.execute();
spyOn(j$, 'Spec');
env.it('foo', function() {});
expect(j$.Spec).toHaveBeenCalledWith(jasmine.objectContaining({
throwOnExpectationFailure: true
}));
});
it("Nested Suites execute as expected", function(done) {
var env = new j$.Env(),
calls = [];
var assertions = function() {
expect(calls).toEqual([
'an outer spec',
'an inner spec',
'another inner spec'
]);
done();
};
env.addReporter({ jasmineDone: assertions });
env.describe("Outer suite", function() {
env.it("an outer spec", function() {
calls.push('an outer spec')
});
env.describe("Inner suite", function() {
env.it("an inner spec", function() {
calls.push('an inner spec');
});
env.it("another inner spec", function() {
calls.push('another inner spec');
});
});
});
env.execute();
});
it("Multiple top-level Suites execute as expected", function(done) {
var env = new j$.Env(),
calls = [];
var assertions = function() {
expect(calls).toEqual([
'an outer spec',
'an inner spec',
'another inner spec',
'a 2nd outer spec'
]);
done();
};
env.addReporter({ jasmineDone: assertions });
env.describe("Outer suite", function() {
env.it("an outer spec", function() {
calls.push('an outer spec')
});
env.describe("Inner suite", function() {
env.it("an inner spec", function() {
calls.push('an inner spec');
});
env.it("another inner spec", function() {
calls.push('another inner spec');
});
});
});
env.describe("Another outer suite", function() {
env.it("a 2nd outer spec", function() {
calls.push('a 2nd outer spec')
});
});
env.execute();
});
it("calls associated befores/specs/afters with the same 'this'", function(done) {
var env = new j$.Env();
env.addReporter({jasmineDone: done});
env.describe("tests", function() {
var firstTimeThrough = true, firstSpecContext, secondSpecContext;
env.beforeEach(function() {
if (firstTimeThrough) {
firstSpecContext = this;
} else {
secondSpecContext = this;
}
expect(this).toEqual({});
});
env.it("sync spec", function() {
expect(this).toBe(firstSpecContext);
});
env.it("another sync spec", function() {
expect(this).toBe(secondSpecContext);
});
env.afterEach(function() {
if (firstTimeThrough) {
expect(this).toBe(firstSpecContext);
firstTimeThrough = false;
} else {
expect(this).toBe(secondSpecContext);
}
});
});
env.execute();
});
it("calls associated befores/its/afters with the same 'this' for an async spec", function(done) {
var env = new j$.Env();
env.addReporter({jasmineDone: done});
env.describe("with an async spec", function() {
var specContext;
env.beforeEach(function() {
specContext = this;
expect(this).toEqual({});
});
env.it("sync spec", function(underTestCallback) {
expect(this).toBe(specContext);
underTestCallback();
});
env.afterEach(function() {
expect(this).toBe(specContext);
});
});
env.execute();
});
it("Allows specifying which specs and suites to run", function(done) {
var env = new j$.Env(),
calls = [],
suiteCallback = jasmine.createSpy('suite callback'),
firstSpec,
secondSuite;
var assertions = function() {
expect(calls).toEqual([
'third spec',
'first spec'
]);
expect(suiteCallback).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions, suiteDone: suiteCallback});
env.describe("first suite", function() {
firstSpec = env.it("first spec", function() {
calls.push('first spec');
});
env.it("second spec", function() {
calls.push('second spec');
});
});
secondSuite = env.describe("second suite", function() {
env.it("third spec", function() {
calls.push('third spec');
});
});
env.execute([secondSuite.id, firstSpec.id]);
});
it("Mock clock can be installed and used in tests", function(done) {
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
delayedFunctionForMockClock = jasmine.createSpy('delayedFunctionForMockClock'),
env = new j$.Env({global: { setTimeout: globalSetTimeout }});
var assertions = function() {
expect(delayedFunctionForMockClock).toHaveBeenCalled();
expect(globalSetTimeout).toHaveBeenCalledWith(delayedFunctionForGlobalClock, 100);
done();
};
env.addReporter({ jasmineDone: assertions });
env.describe("tests", function() {
env.it("test with mock clock", function() {
env.clock.install();
env.clock.setTimeout(delayedFunctionForMockClock, 100);
env.clock.tick(100);
env.clock.uninstall();
});
env.it("test without mock clock", function() {
env.clock.setTimeout(delayedFunctionForGlobalClock, 100);
});
});
expect(globalSetTimeout).not.toHaveBeenCalled();
expect(delayedFunctionForMockClock).not.toHaveBeenCalled();
env.execute();
});
it("should run async specs in order, waiting for them to complete", function(done) {
var env = new j$.Env(), mutatedVar;
env.describe("tests", function() {
env.beforeEach(function() {
mutatedVar = 2;
});
env.it("async spec", function(underTestCallback) {
setTimeout(function() {
expect(mutatedVar).toEqual(2);
underTestCallback();
done();
}, 0);
});
env.it("after async spec", function() {
mutatedVar = 3;
});
});
env.execute();
});
describe("with a mock clock", function() {
var originalTimeout;
beforeEach(function() {
originalTimeout = j$.DEFAULT_TIMEOUT_INTERVAL;
jasmine.getEnv().clock.install();
});
afterEach(function() {
jasmine.getEnv().clock.uninstall();
j$.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
it("should wait a specified interval before failing specs haven't called done yet", function(done) {
var env = new j$.Env(),
reporter = jasmine.createSpyObj('fakeReporter', [ "specDone" ]);
reporter.specDone.and.callFake(function() {
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'failed'}));
done();
});
env.addReporter(reporter);
j$.DEFAULT_TIMEOUT_INTERVAL = 8414;
env.it("async spec that doesn't call done", function(underTestCallback) {
env.expect(true).toBeTruthy();
jasmine.getEnv().clock.tick(8414);
});
env.execute();
});
});
// TODO: something is wrong with this spec
it("should report as expected", function(done) {
var env = new j$.Env(),
reporter = jasmine.createSpyObj('fakeReporter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
reporter.jasmineDone.and.callFake(function() {
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
totalSpecsDefined: 3
});
var suiteResult = reporter.suiteStarted.calls.first().args[0];
expect(suiteResult.description).toEqual("A Suite");
done();
});
env.addReporter(reporter);
env.describe("A Suite", function() {
env.it("with a top level spec", function() {
env.expect(true).toBe(true);
});
env.describe("with a nested suite", function() {
env.xit("with a pending spec", function() {
env.expect(true).toBe(true);
});
env.it("with a spec", function() {
env.expect(true).toBe(false);
});
});
});
env.execute();
});
it("should be possible to get full name from a spec", function() {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
topLevelSpec, nestedSpec, doublyNestedSpec;
env.describe("my tests", function() {
topLevelSpec = env.it("are sometimes top level", function() {
});
env.describe("are sometimes", function() {
nestedSpec = env.it("singly nested", function() {
});
env.describe("even", function() {
doublyNestedSpec = env.it("doubly nested", function() {
});
});
});
});
expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level");
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested");
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested");
});
it("Custom equality testers should be per spec", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
reporter.jasmineDone.and.callFake(function() {
var firstSpecResult = reporter.specDone.calls.first().args[0],
secondSpecResult = reporter.specDone.calls.mostRecent().args[0];
expect(firstSpecResult.status).toEqual("passed");
expect(secondSpecResult.status).toEqual("failed");
done();
});
env.addReporter(reporter);
env.describe("testing custom equality testers", function() {
env.it("with a custom tester", function() {
env.addCustomEqualityTester(function(a, b) { return true; });
env.expect("a").toEqual("b");
});
env.it("without a custom tester", function() {
env.expect("a").toEqual("b");
});
});
env.execute();
});
it("Custom matchers should be per spec", function() {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
matchers = {
toFoo: function() {}
},
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("testing custom matchers", function() {
env.it("with a custom matcher", function() {
env.addMatchers(matchers);
expect(env.expect().toFoo).toBeDefined();
});
env.it("without a custom matcher", function() {
expect(env.expect().toFoo).toBeUndefined();
});
});
env.execute();
});
it("Custom equality testers for toContain should be per spec", function(done) {
var env = new j$.Env({global: { setTimeout: setTimeout }}),
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
reporter.jasmineDone.and.callFake(function() {
var firstSpecResult = reporter.specDone.calls.first().args[0],
secondSpecResult = reporter.specDone.calls.mostRecent().args[0];
expect(firstSpecResult.status).toEqual("passed");
expect(secondSpecResult.status).toEqual("failed");
done();
});
env.addReporter(reporter);
env.describe("testing custom equality testers", function() {
env.it("with a custom tester", function() {
env.addCustomEqualityTester(function(a, b) { return true; });
env.expect(["a"]).toContain("b");
});
env.it("without a custom tester", function() {
env.expect("a").toContain("b");
});
});
env.execute();
it('can configure suites to throw errors on expectation failures', function() {
env.throwOnExpectationFailure(true);
spyOn(j$, 'Suite');
env.describe('foo', function() {});
expect(j$.Suite).toHaveBeenCalledWith(jasmine.objectContaining({
throwOnExpectationFailure: true
}));
});
});

View File

@@ -35,7 +35,14 @@ describe("ExceptionFormatter", function() {
message = exceptionFormatter.message(sampleV8);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar');
});
it("formats thrown exceptions that aren't errors", function() {
var thrown = "crazy error",
exceptionFormatter = new j$.ExceptionFormatter(),
message = exceptionFormatter.message(thrown);
expect(message).toEqual("crazy error thrown");
});
});

View File

@@ -13,20 +13,20 @@ describe('Exceptions:', function() {
throw new Error('I should hit a breakpoint!');
});
});
var dont_change = 'I will never change!';
var spy = jasmine.createSpy('spy');
try {
env.execute();
dont_change = 'oops I changed';
spy();
}
catch (e) {}
expect(dont_change).toEqual('I will never change!');
expect(spy).not.toHaveBeenCalled();
});
});
describe("with catch on exception", function() {
it('should handle exceptions thrown, but continue', 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() {
@@ -35,11 +35,16 @@ describe('Exceptions:', function() {
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();
expect(secondTest).toHaveBeenCalled();
});
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
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 () {
@@ -50,8 +55,13 @@ describe('Exceptions:', function() {
});
env.describe("a suite that doesn't throw an exception", secondDescribe);
var expectations = function() {
expect(secondDescribe).toHaveBeenCalled();
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
expect(secondDescribe).toHaveBeenCalled();
});
});
});

View File

@@ -9,7 +9,7 @@ describe("buildExpectationResult", function() {
expect(result.message).toBe('Passed.');
});
it("message returns the message for failing expecations", function() {
it("message returns the message for failing expectations", function() {
var result = j$.buildExpectationResult({passed: false, message: 'some-value'});
expect(result.message).toBe('some-value');
});

View File

@@ -1,14 +1,14 @@
describe("Expectation", function() {
it(".addMatchers makes matchers available to any expectation", function() {
it("makes custom matchers available to this expectation", function() {
var matchers = {
toFoo: function() {},
toBar: function() {}
},
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({});
expectation = new j$.Expectation({
customMatchers: matchers
});
expect(expectation.toFoo).toBeDefined();
expect(expectation.toBar).toBeDefined();
@@ -27,26 +27,7 @@ describe("Expectation", function() {
expect(expectation.toQuux).toBeDefined();
});
it(".resetMatchers should keep only core matchers", function() {
var matchers = {
toFoo: function() {}
},
coreMatchers = {
toQuux: function() {}
},
expectation;
j$.Expectation.addCoreMatchers(coreMatchers);
j$.Expectation.addMatchers(matchers);
j$.Expectation.resetMatchers();
expectation = new j$.Expectation({});
expect(expectation.toQuux).toBeDefined();
expect(expectation.toFoo).toBeUndefined();
});
it("Factory builds an expectaion/negative expectation", function() {
it("Factory builds an expectation/negative expectation", function() {
var builtExpectation = j$.Expectation.Factory();
expect(builtExpectation instanceof j$.Expectation).toBe(true);
@@ -65,10 +46,9 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
util: util,
customMatchers: matchers,
customEqualityTesters: customEqualityTesters,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -94,10 +74,9 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
util: util,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult
});
@@ -121,10 +100,8 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -155,10 +132,8 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
util: util,
actual: "an actual",
addExpectationResult: addExpectationResult
@@ -191,10 +166,41 @@ describe("Expectation", function() {
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.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"
});
});
it("reports a failing result with a custom fail message function to the spec when the comparison fails", function() {
var matchers = {
toFoo: function() {
return {
compare: function() {
return {
pass: false,
message: function() { return "I am a custom message"; }
};
}
};
}
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult
});
@@ -225,10 +231,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
@@ -254,16 +258,14 @@ describe("Expectation", function() {
}
},
util = {
buildFailureMessage: function() { return "default messge"; }
buildFailureMessage: function() { return "default message"; }
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
util: util,
addExpectationResult: addExpectationResult,
@@ -277,7 +279,7 @@ describe("Expectation", function() {
passed: false,
expected: "hello",
actual: actual,
message: "default messge"
message: "default message"
});
});
@@ -298,10 +300,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
@@ -331,10 +331,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true
@@ -369,10 +367,8 @@ describe("Expectation", function() {
actual = "an actual",
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
customMatchers: matchers,
actual: "an actual",
addExpectationResult: addExpectationResult,
isNot: true

View File

@@ -178,6 +178,43 @@ describe("JsApiReporter", function() {
});
});
describe("#suiteResults", function(){
var reporter, suiteResult1, suiteResult2;
beforeEach(function() {
reporter = new j$.JsApiReporter({});
suiteStarted1 = {
id: 1
};
suiteResult1 = {
id: 1,
status: 'failed',
failedExpectations: [{ message: 'My After All Exception' }]
};
suiteResult2 = {
id: 2,
status: 'finished'
};
reporter.suiteStarted(suiteStarted1);
reporter.suiteDone(suiteResult1);
reporter.suiteDone(suiteResult2);
});
it('should not include suite starts', function(){
expect(reporter.suiteResults(0,3).length).toEqual(2);
});
it("should return a slice of results", function() {
expect(reporter.suiteResults(0, 1)).toEqual([suiteResult1]);
expect(reporter.suiteResults(1, 1)).toEqual([suiteResult2]);
});
it("returns nothing for out of bounds indicies", function() {
expect(reporter.suiteResults(0, 3)).toEqual([suiteResult1, suiteResult2]);
expect(reporter.suiteResults(2, 3)).toEqual([]);
});
});
describe("#executionTime", function() {
it("should start the timer when jasmine starts", function() {
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),

200
spec/core/MockDateSpec.js Normal file
View File

@@ -0,0 +1,200 @@
describe("FakeDate", function() {
it("does not fail if no global date is found", function() {
var fakeGlobal = {},
mockDate = new j$.MockDate(fakeGlobal);
expect(function() {
mockDate.install();
mockDate.tick(0);
mockDate.uninstall();
}).not.toThrow();
});
it("replaces the global Date when it is installed", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
expect(fakeGlobal.Date).toEqual(globalDate);
mockDate.install();
expect(fakeGlobal.Date).not.toEqual(globalDate);
});
it("replaces the global Date on uninstall", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
mockDate.uninstall();
expect(fakeGlobal.Date).toEqual(globalDate);
});
it("takes the current time as the base when installing without parameters", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
globalDate.calls.reset();
new fakeGlobal.Date();
expect(globalDate).toHaveBeenCalledWith(1000);
});
it("can accept a date as time base when installing", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal),
baseDate = new Date();
spyOn(baseDate, 'getTime').and.returnValue(123);
mockDate.install(baseDate);
expect(new fakeGlobal.Date().getTime()).toEqual(123);
});
it("makes real dates", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(new fakeGlobal.Date()).toEqual(jasmine.any(Date));
expect(new fakeGlobal.Date() instanceof fakeGlobal.Date).toBe(true);
});
it("fakes current time when using Date.now()", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(fakeGlobal.Date.now()).toEqual(1000);
});
it("does not stub Date.now() if it doesn't already exist", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(fakeGlobal.Date.now).toThrowError("Browser does not support Date.now()");
});
it("makes time passes using tick", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
mockDate.tick(100);
expect(fakeGlobal.Date.now()).toEqual(1100);
mockDate.tick(1000);
expect(fakeGlobal.Date.now()).toEqual(2100);
});
it("allows to increase 0 milliseconds using tick", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
mockDate.tick(0);
expect(fakeGlobal.Date.now()).toEqual(1000);
mockDate.tick();
expect(fakeGlobal.Date.now()).toEqual(1000);
});
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.install();
var otherDate = new fakeGlobal.Date(2013, 9, 23, 0, 0, 1, 0);
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23, 0, 0, 1, 0).getTime());
});
it("allows creation of a Date that isn't fully specified", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
var otherDate = new fakeGlobal.Date(2013, 9, 23);
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23).getTime());
});
it('allows creation of a Date with millis', function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal),
now = new Date(2014, 3, 15).getTime();
mockDate.install();
var otherDate = new fakeGlobal.Date(now);
expect(otherDate.getTime()).toEqual(now);
});
it("copies all Date properties to the mocked date", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(fakeGlobal.Date.UTC(2013, 9, 23)).toEqual(Date.UTC(2013, 9, 23));
});
});

View File

@@ -1,64 +0,0 @@
describe("ObjectContaining", function() {
it("matches any actual to an empty object", function() {
var containing = new j$.ObjectContaining({});
expect(containing.jasmineMatches("foo")).toBe(true);
});
it("does not match an empty object actual", function() {
var containing = new j$.ObjectContaining("foo");
expect(function() {
containing.jasmineMatches({})
}).toThrowError(/not 'foo'/)
});
it("matches when the key/value pair is present in the actual", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"})).toBe(true);
});
it("does not match when the key/value pair is not present in the actual", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
expect(containing.jasmineMatches({bar: "barVal", quux: "quuxVal"})).toBe(false);
});
it("does not match when the key is present but the value is different in the actual", function() {
var containing = new j$.ObjectContaining({foo: "other"});
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"})).toBe(false);
});
it("mismatchValues parameter must return array with mismatched reason", function() {
var containing = new j$.ObjectContaining({foo: "other"});
var mismatchKeys = [];
var mismatchValues = [];
containing.jasmineMatches({foo: "fooVal", bar: "barVal"}, mismatchKeys, mismatchValues);
expect(mismatchValues.length).toBe(1);
expect(mismatchValues[0]).toEqual("'foo' was 'fooVal' in actual, but was 'other' in expected.");
});
it("adds keys in expected but not actual to the mismatchKeys parameter", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
var mismatchKeys = [];
var mismatchValues = [];
containing.jasmineMatches({bar: "barVal"}, mismatchKeys, mismatchValues);
expect(mismatchKeys.length).toBe(1);
expect(mismatchKeys[0]).toEqual("expected has key 'foo', but missing from actual.");
});
it("jasmineToString's itself", function() {
var containing = new j$.ObjectContaining({});
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
});
});

View File

@@ -11,33 +11,81 @@ describe("j$.pp", function () {
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");
});
it("should stringify arrays properly", function() {
expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', { }, undefined, null ]");
});
describe('stringify arrays', function() {
it("should stringify arrays properly", function() {
expect(j$.pp([1, 2])).toEqual("[ 1, 2 ]");
expect(j$.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', Object({ }), undefined, null ]");
});
it("should indicate circular array references", function() {
var array1 = [1, 2];
var array2 = [array1];
array1.push(array2);
expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
it("should truncate arrays that are longer than j$.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var array = [1, 2, 3];
try {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(j$.pp(array)).toEqual("[ 1, 2, ... ]");
} finally {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
}
});
it("should stringify arrays with properties properly", function() {
var arr = [1, 2];
arr.foo = 'bar';
arr.baz = {};
expect(j$.pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
});
it("should stringify empty arrays with properties properly", function() {
var empty = [];
empty.foo = 'bar';
empty.baz = {};
expect(j$.pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
});
it("should stringify long arrays with properties properly", function() {
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var long = [1,2,3];
long.foo = 'bar';
long.baz = {};
try {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(j$.pp(long)).toEqual("[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]");
} finally {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
}
});
it("should indicate circular array references", function() {
var array1 = [1, 2];
var array2 = [array1];
array1.push(array2);
expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
});
it("should not indicate circular references incorrectly", function() {
var array = [ [1] ];
expect(j$.pp(array)).toEqual("[ [ 1 ] ]");
});
});
it("should stringify objects properly", function() {
expect(j$.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
expect(j$.pp({foo: 'bar'})).toEqual("Object({ foo: 'bar' })");
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })");
expect(j$.pp({foo: function () {
}, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
}, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
});
it("should not include inherited properties when stringifying an object", function() {
var SomeClass = function() {};
var SomeClass = function SomeClass() {};
SomeClass.prototype.foo = "inherited foo";
var instance = new SomeClass();
instance.bar = "my own bar";
expect(j$.pp(instance)).toEqual("{ bar : 'my own bar' }");
expect(j$.pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
});
it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
@@ -47,21 +95,30 @@ describe("j$.pp", function () {
try {
j$.MAX_PRETTY_PRINT_DEPTH = 2;
expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : Object } }");
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object }) })");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
j$.MAX_PRETTY_PRINT_DEPTH = 3;
expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : Object } } }");
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object }) }) })");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
j$.MAX_PRETTY_PRINT_DEPTH = 4;
expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : { level4 : 'leaf' } } } }");
expect(j$.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
} finally {
j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
}
});
it("should stringify immutable circular objects", function(){
if(Object.freeze){
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> })");
}
});
it("should stringify RegExp objects properly", function() {
expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
});
@@ -69,7 +126,7 @@ describe("j$.pp", function () {
it("should indicate circular object references", function() {
var sampleValue = {foo: 'hello'};
sampleValue.nested = sampleValue;
expect(j$.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
expect(j$.pp(sampleValue)).toEqual("Object({ foo: 'hello', nested: <circular reference: Object> })");
});
it("should indicate getters on objects as such", function() {
@@ -81,10 +138,10 @@ describe("j$.pp", function () {
});
}
if (sampleValue.__defineGetter__) {
expect(j$.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
expect(j$.pp(sampleValue)).toEqual("Object({ id: 1, calculatedValue: <getter> })");
}
else {
expect(j$.pp(sampleValue)).toEqual("{ id : 1 }");
expect(j$.pp(sampleValue)).toEqual("Object({ id: 1 })");
}
});
@@ -108,7 +165,9 @@ describe("j$.pp", function () {
},
env = new j$.Env();
env.spyOn(TestObject, 'someFunction');
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {return [];}});
spyRegistry.spyOn(TestObject, 'someFunction');
expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
@@ -121,5 +180,13 @@ describe("j$.pp", function () {
expect(j$.pp(obj)).toEqual("strung");
});
});
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' })");
});
});

View File

@@ -2,15 +2,15 @@ describe("QueueRunner", function() {
it("runs all the functions it's passed", function() {
var calls = [],
fn1 = jasmine.createSpy('fn1'),
fn2 = jasmine.createSpy('fn2'),
queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueRunner = new j$.QueueRunner({
fns: [fn1, fn2]
queueableFns: [queueableFn1, queueableFn2]
});
fn1.and.callFake(function() {
queueableFn1.fn.and.callFake(function() {
calls.push('fn1');
});
fn2.and.callFake(function() {
queueableFn2.fn.and.callFake(function() {
calls.push('fn2');
});
@@ -20,19 +20,19 @@ describe("QueueRunner", function() {
});
it("calls each function with a consistent 'this'-- an empty object", function() {
var fn1 = jasmine.createSpy('fn1'),
fn2 = jasmine.createSpy('fn2'),
fn3 = function(done) { asyncContext = this; done(); },
var queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
queueRunner = new j$.QueueRunner({
fns: [fn1, fn2, fn3]
queueableFns: [queueableFn1, queueableFn2, queueableFn3]
}),
asyncContext;
queueRunner.execute();
var context = fn1.calls.first().object;
var context = queueableFn1.fn.calls.first().object;
expect(context).toEqual({});
expect(fn2.calls.first().object).toBe(context);
expect(queueableFn2.fn.calls.first().object).toBe(context);
expect(asyncContext).toBe(context);
});
@@ -50,31 +50,25 @@ describe("QueueRunner", function() {
//createSpy('asyncfn').and.callFake(function(done) {});
var onComplete = jasmine.createSpy('onComplete'),
beforeCallback = jasmine.createSpy('beforeCallback'),
fnCallback = jasmine.createSpy('fnCallback'),
afterCallback = jasmine.createSpy('afterCallback'),
fn1 = function(done) {
beforeCallback();
setTimeout(function() {
done()
}, 100);
},
fn2 = function(done) {
fnCallback();
setTimeout(function() {
done()
}, 100);
},
fn3 = function(done) {
afterCallback();
setTimeout(function() {
done()
}, 100);
},
queueRunner = new j$.QueueRunner({
fns: [fn1, fn2, fn3],
onComplete: onComplete
});
beforeCallback = jasmine.createSpy('beforeCallback'),
fnCallback = jasmine.createSpy('fnCallback'),
afterCallback = jasmine.createSpy('afterCallback'),
queueableFn1 = { fn: function(done) {
beforeCallback();
setTimeout(done, 100);
} },
queueableFn2 = { fn: function(done) {
fnCallback();
setTimeout(done, 100);
} },
queueableFn3 = { fn: function(done) {
afterCallback();
setTimeout(done, 100);
} },
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn1, queueableFn2, queueableFn3],
onComplete: onComplete
});
queueRunner.execute();
@@ -98,52 +92,182 @@ describe("QueueRunner", function() {
expect(onComplete).toHaveBeenCalled();
});
it("explicitly fails an async function with a provided fail function and moves to the next function", function() {
var queueableFn1 = { fn: function(done) {
setTimeout(function() { done.fail('foo'); }, 100);
} },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
fail: failFn
});
queueRunner.execute();
expect(failFn).not.toHaveBeenCalled();
expect(queueableFn2.fn).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(failFn).toHaveBeenCalledWith('foo');
expect(queueableFn2.fn).toHaveBeenCalled();
});
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
var timeout = 3,
beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueableFns: [beforeFn, queueableFn],
onComplete: onComplete,
onException: onException
});
queueRunner.execute();
expect(queueableFn.fn).not.toHaveBeenCalled();
jasmine.clock().tick(timeout);
expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
expect(queueableFn.fn).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});
it("by default does not set a timeout for asynchronous functions", function() {
var beforeFn = { fn: function(done) { } },
queueableFn = { fn: jasmine.createSpy('fn') },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueableFns: [beforeFn, queueableFn],
onComplete: onComplete,
onException: onException,
});
queueRunner.execute();
expect(queueableFn.fn).not.toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(onException).not.toHaveBeenCalled();
expect(queueableFn.fn).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
});
it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
var queueableFn = { fn: function(done) { throw new Error("error!"); } },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn],
onComplete: onComplete,
onException: onException
});
queueRunner.execute();
expect(onComplete).toHaveBeenCalled();
expect(onException).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(onException.calls.count()).toEqual(1);
});
it("clears the timeout when the done callback is called", function() {
var queueableFn = { fn: function(done) { done(); } },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn],
onComplete: onComplete,
onException: onException
});
queueRunner.execute();
expect(onComplete).toHaveBeenCalled();
jasmine.clock().tick(j$.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]
});
queueRunner.execute();
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
});
it("does not move to the next spec if done is called after an exception has ended the spec", function() {
var queueableFn = { fn: function(done) {
setTimeout(done, 1);
throw new Error('error!');
} },
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
queueRunner.execute();
jasmine.clock().tick(1);
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
});
});
it("calls an exception handler when an exception is thrown in a fn", function() {
var fn = function() {
it("calls exception handlers when an exception is thrown in a fn", function() {
var queueableFn = { type: 'queueable',
fn: function() {
throw new Error('fake error');
},
exceptionCallback = jasmine.createSpy('exception callback'),
} },
onExceptionCallback = jasmine.createSpy('on exception callback'),
queueRunner = new j$.QueueRunner({
fns: [fn],
onException: exceptionCallback
queueableFns: [queueableFn],
onException: onExceptionCallback
});
queueRunner.execute();
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
});
it("rethrows an exception if told to", function() {
var fn = function() {
var queueableFn = { fn: function() {
throw new Error('fake error');
},
} },
queueRunner = new j$.QueueRunner({
fns: [fn],
queueableFns: [queueableFn],
catchException: function(e) { return false; }
});
expect(function() { queueRunner.execute(); }).toThrow();
expect(function() {
queueRunner.execute();
}).toThrowError('fake error');
});
it("continues running the functions even after an exception is thrown in an async spec", function() {
var fn = function(done) { throw new Error("error"); },
nextFn = jasmine.createSpy("nextFunction");
queueRunner = new j$.QueueRunner({
fns: [fn, nextFn]
});
var queueableFn = { fn: function(done) { throw new Error("error"); } },
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
queueRunner = new j$.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
});
queueRunner.execute();
expect(nextFn).toHaveBeenCalled();
expect(nextQueueableFn.fn).toHaveBeenCalled();
});
it("calls a provided complete callback when done", function() {
var fn = jasmine.createSpy('fn'),
var queueableFn = { fn: jasmine.createSpy('fn') },
completeCallback = jasmine.createSpy('completeCallback'),
queueRunner = new j$.QueueRunner({
fns: [fn],
queueableFns: [queueableFn],
onComplete: completeCallback
});
@@ -153,12 +277,12 @@ describe("QueueRunner", function() {
});
it("calls a provided stack clearing function when done", function() {
var asyncFn = function(done) { done() },
afterFn = jasmine.createSpy('afterFn'),
var asyncFn = { fn: function(done) { done() } },
afterFn = { fn: jasmine.createSpy('afterFn') },
completeCallback = jasmine.createSpy('completeCallback'),
clearStack = jasmine.createSpy('clearStack'),
queueRunner = new j$.QueueRunner({
fns: [asyncFn, afterFn],
queueableFns: [asyncFn, afterFn],
clearStack: clearStack,
onComplete: completeCallback
});
@@ -166,7 +290,7 @@ describe("QueueRunner", function() {
clearStack.and.callFake(function(fn) { fn(); });
queueRunner.execute();
expect(afterFn).toHaveBeenCalled();
expect(afterFn.fn).toHaveBeenCalled();
expect(clearStack).toHaveBeenCalledWith(completeCallback);
});
});

View File

@@ -1,307 +0,0 @@
// TODO: This should really be part of the Env Integration Spec
describe("jasmine spec running", function () {
var env;
var fakeTimer;
beforeEach(function() {
env = new j$.Env();
});
it('should assign spec ids sequentially', function() {
var it0, it1, it2, it3, it4;
env.describe('test suite', function() {
it0 = env.it('spec 0', function() {
});
it1 = env.it('spec 1', function() {
});
it2 = env.xit('spec 2', function() {
});
it3 = env.it('spec 3', function() {
});
});
env.describe('test suite 2', function() {
it4 = env.it('spec 4', function() {
});
});
expect(it0.id).toEqual('spec0');
expect(it1.id).toEqual('spec1');
expect(it2.id).toEqual('spec2');
expect(it3.id).toEqual('spec3');
expect(it4.id).toEqual('spec4');
});
it('nested suites', function (done) {
var foo = 0;
var bar = 0;
var baz = 0;
var quux = 0;
var nested = env.describe('suite', function () {
env.describe('nested', function () {
env.it('should run nested suites', function () {
foo++;
});
env.it('should run nested suites', function () {
bar++;
});
});
env.describe('nested 2', function () {
env.it('should run suites following nested suites', function () {
baz++;
});
});
env.it('should run tests following nested suites', function () {
quux++;
});
});
expect(foo).toEqual(0);
expect(bar).toEqual(0);
expect(baz).toEqual(0);
expect(quux).toEqual(0);
nested.execute(function() {
expect(foo).toEqual(1);
expect(bar).toEqual(1);
expect(baz).toEqual(1);
expect(quux).toEqual(1);
done();
});
});
it("should permit nested describes", function(done) {
var actions = [];
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 1",
"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 2",
"outer afterEach",
"topSuite afterEach",
"topSuite beforeEach",
"outer beforeEach",
"inner 2 beforeEach",
"inner 2 it",
"inner 2 afterEach",
"outer afterEach",
"topSuite afterEach"
];
expect(actions).toEqual(expected);
done();
}
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("should run multiple befores and afters in the order they are declared", function(done) {
var actions = [];
env.beforeEach(function () {
actions.push('runner beforeEach1');
});
env.afterEach(function () {
actions.push('runner afterEach1');
});
env.beforeEach(function () {
actions.push('runner beforeEach2');
});
env.afterEach(function () {
actions.push('runner afterEach2');
});
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('beforeEach1');
});
env.afterEach(function() {
actions.push('afterEach1');
});
env.beforeEach(function() {
actions.push('beforeEach2');
});
env.afterEach(function() {
actions.push('afterEach2');
});
env.it('does it 1', function() {
actions.push('outer it 1');
});
});
var assertions = function() {
var expected = [
"runner beforeEach1",
"runner beforeEach2",
"beforeEach1",
"beforeEach2",
"outer it 1",
"afterEach2",
"afterEach1",
"runner afterEach2",
"runner afterEach1"
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("shouldn't run disabled suites", function(done) {
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
suite = env.describe('A Suite', function() {
env.xdescribe('with a disabled suite', function(){
env.it('spec inside a disabled suite', specInADisabledSuite);
});
});
suite.execute(function() {
expect(specInADisabledSuite).not.toHaveBeenCalled();
done();
});
});
it("should set all pending specs to pending when a suite is run", function(done) {
var pendingSpec,
suite = env.describe('default current suite', function() {
pendingSpec = env.it("I am a pending spec");
});
suite.execute(function() {
expect(pendingSpec.status()).toBe("pending");
done();
});
});
// 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);
};
try {
env.describe("outer1", function() {
env.describe("inner1", function() {
env.it("should thingy", function() {
this.expect(true).toEqual(true);
});
throw new Error("fake error");
});
env.describe("inner2", function() {
env.it("should other thingy", function() {
this.expect(true).toEqual(true);
});
});
throw new Error("fake error");
});
} catch(e) {
}
env.describe("outer2", function() {
env.it("should xxx", function() {
this.expect(true).toEqual(true);
});
});
env.addReporter(superSimpleReporter);
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.'
));
});
});

View File

@@ -14,19 +14,27 @@ describe("Spec", function() {
expect(j$.Spec.isPendingSpecException(fakeError)).toBe(true);
});
it("#isPendingSpecException returns true for a pending spec exception", function() {
it("#isPendingSpecException returns true for a pending spec exception with a custom message", function() {
expect(j$.Spec.isPendingSpecException(j$.Spec.pendingSpecExceptionMessage + 'foo')).toBe(true);
});
it("#isPendingSpecException returns false for not a pending spec exception", function() {
var e = new Error("foo");
expect(j$.Spec.isPendingSpecException(e)).toBe(false);
});
it("#isPendingSpecException returns false for thrown values that don't have toString", function() {
expect(j$.Spec.isPendingSpecException(void 0)).toBe(false);
});
it("delegates execution to a QueueRunner", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
spec = new j$.Spec({
description: 'my test',
id: 'some-id',
fn: function() {},
queueRunner: fakeQueueRunner
queueableFn: { fn: function() {} },
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
@@ -40,9 +48,9 @@ describe("Spec", function() {
spec = new j$.Spec({
id: 123,
description: 'foo bar',
fn: function() {},
queueableFn: { fn: function() {} },
onStart: startCallback,
queueRunner: fakeQueueRunner
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
@@ -62,14 +70,14 @@ describe("Spec", function() {
expect(beforesWereCalled).toBe(false);
}),
spec = new j$.Spec({
fn: function() {},
queueableFn: { fn: function() {} },
beforeFns: function() {
return [function() {
beforesWereCalled = true
}]
},
onStart: startCallback,
queueRunner: fakeQueueRunner
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
@@ -81,25 +89,22 @@ describe("Spec", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
before = jasmine.createSpy('before'),
after = jasmine.createSpy('after'),
fn = jasmine.createSpy('test body').and.callFake(function() {
queueableFn = { fn: jasmine.createSpy('test body').and.callFake(function() {
expect(before).toHaveBeenCalled();
expect(after).not.toHaveBeenCalled();
}),
}) },
spec = new j$.Spec({
fn: fn,
beforeFns: function() {
return [before]
queueableFn: queueableFn,
beforeAndAfterFns: function() {
return {befores: [before], afters: [after]}
},
afterFns: function() {
return [after]
},
queueRunner: fakeQueueRunner
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].fns;
expect(allSpecFns).toEqual([before, fn, after]);
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
expect(allSpecFns).toEqual([before, queueableFn, after]);
});
it("is marked pending if created without a function body", function() {
@@ -109,12 +114,11 @@ describe("Spec", function() {
resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
onStart: startCallback,
fn: null,
queueableFn: { fn: null },
resultCallback: resultCallback,
queueRunner: fakeQueueRunner
queueRunnerFactory: fakeQueueRunner
});
expect(spec.status()).toBe('pending');
});
@@ -125,9 +129,9 @@ describe("Spec", function() {
resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
onStart:startCallback,
fn: specBody,
queueableFn: { fn: specBody },
resultCallback: resultCallback,
queueRunner: fakeQueueRunner
queueRunnerFactory: fakeQueueRunner
});
spec.disable();
@@ -143,6 +147,29 @@ describe("Spec", function() {
expect(resultCallback).toHaveBeenCalled();
});
it("can be disabled at execution time by a parent", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = jasmine.createSpy('startCallback'),
specBody = jasmine.createSpy('specBody'),
resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
onStart:startCallback,
queueableFn: { fn: specBody },
resultCallback: resultCallback,
queueRunnerFactory: fakeQueueRunner
});
spec.execute(undefined, false);
expect(spec.result.status).toBe('disabled');
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(startCallback).toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalled();
});
it("can be marked pending, but still calls callbacks when executed", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = jasmine.createSpy('startCallback'),
@@ -154,7 +181,8 @@ describe("Spec", function() {
getSpecName: function() {
return "a suite with a spec"
},
queueRunner: fakeQueueRunner
queueRunnerFactory: fakeQueueRunner,
queueableFn: { fn: null }
});
spec.pend();
@@ -171,17 +199,19 @@ describe("Spec", function() {
status: 'pending',
description: 'with a spec',
fullName: 'a suite with a spec',
failedExpectations: []
failedExpectations: [],
passedExpectations: [],
pendingReason: ''
});
});
it("should call the done callback on execution complete", function() {
var done = jasmine.createSpy('done callback'),
spec = new j$.Spec({
fn: function() {},
queueableFn: { fn: function() {} },
catchExceptions: function() { return false; },
resultCallback: function() {},
queueRunner: function(attrs) { attrs.onComplete(); }
queueRunnerFactory: function(attrs) { attrs.onComplete(); }
});
spec.execute(done);
@@ -190,33 +220,84 @@ describe("Spec", function() {
});
it("#status returns passing by default", function() {
var spec = new j$.Spec({fn: jasmine.createSpy("spec body")});
expect(spec.status()).toEqual('passed');
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
expect(spec.status()).toBe('passed');
});
it("#status returns passed if all expectations in the spec have passed", function() {
var spec = new j$.Spec({fn: jasmine.createSpy("spec body")});
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
spec.addExpectationResult(true);
expect(spec.status()).toBe('passed');
});
it("#status returns failed if any expectations in the spec have failed", function() {
var spec = new j$.Spec({ fn: jasmine.createSpy("spec body") });
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body") } });
spec.addExpectationResult(true);
spec.addExpectationResult(false);
expect(spec.status()).toBe('failed');
});
it("keeps track of passed and failed expectations", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
queueableFn: { fn: jasmine.createSpy("spec body") },
expectationResultFactory: function (data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
resultCallback: resultCallback
});
spec.addExpectationResult(true, 'expectation1');
spec.addExpectationResult(false, 'expectation2');
spec.execute();
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
});
spec.addExpectationResult(true, 'passed');
expect(function() {
spec.addExpectationResult(false, 'failed')
}).toThrowError(j$.errors.ExpectationFailed);
spec.execute();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['passed']);
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['failed']);
});
it("does not throw an ExpectationFailed error when handling an error", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
resultCallback: resultCallback,
throwOnExpectationFailure: true
});
spec.onException('failing exception');
});
it("can return its full name", function() {
var spec;
spec = new j$.Spec({
getSpecName: function(passedVal) {
// expect(passedVal).toBe(spec); TODO: a exec time, spec is undefined WTF?
return 'expected val';
}
var specNameSpy = jasmine.createSpy('specNameSpy').and.returnValue('expected val');
var spec = new j$.Spec({
getSpecName: specNameSpy,
queueableFn: { fn: null }
});
expect(spec.getFullName()).toBe('expected val');
expect(specNameSpy.calls.mostRecent().args[0].id).toEqual(spec.id);
});
describe("when a spec is marked pending during execution", function() {
@@ -227,13 +308,113 @@ describe("Spec", function() {
spec = new j$.Spec({
description: 'my test',
id: 'some-id',
fn: function() { },
queueRunner: fakeQueueRunner
queueableFn: { fn: function() { } },
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
expect(spec.status()).toEqual("pending");
expect(spec.result.pendingReason).toEqual('');
});
it("should set the pendingReason", function() {
var fakeQueueRunner = function(opts) {
opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage + 'custom message'));
},
spec = new j$.Spec({
description: 'my test',
id: 'some-id',
queueableFn: { fn: function() { } },
queueRunnerFactory: fakeQueueRunner
});
spec.execute();
expect(spec.status()).toEqual("pending");
expect(spec.result.pendingReason).toEqual('custom message');
});
});
it("should log a failure when handling an exception", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
resultCallback: resultCallback
});
spec.onException('foo');
spec.execute();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([{
error: 'foo',
matcherName: '',
passed: false,
expected: '',
actual: ''
}]);
});
it("should not log an additional failure when handling an ExpectationFailed error", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
queueableFn: { fn: function() {} },
expectationResultFactory: function(data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
resultCallback: resultCallback
});
spec.onException(new j$.errors.ExpectationFailed());
spec.execute();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
});
it("retrieves a result with updated status", function() {
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
expect(spec.getResult().status).toBe('passed');
});
it("retrives a result with disabled status", function() {
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
spec.disable();
expect(spec.getResult().status).toBe('disabled');
});
it("retrives a result with pending status", function() {
var spec = new j$.Spec({ queueableFn: { fn: function() {} } });
spec.pend();
expect(spec.getResult().status).toBe('pending');
});
it("should not be executable when disabled", function() {
var spec = new j$.Spec({
queueableFn: { fn: function() {} }
});
spec.disable();
expect(spec.isExecutable()).toBe(false);
});
it("should be executable when pending", function() {
var spec = new j$.Spec({
queueableFn: { fn: function() {} }
});
spec.pend();
expect(spec.isExecutable()).toBe(true);
});
it("should be executable when not disabled or pending", function() {
var spec = new j$.Spec({
queueableFn: { fn: function() {} }
});
expect(spec.isExecutable()).toBe(true);
});
});

View File

@@ -0,0 +1,64 @@
describe("SpyRegistry", function() {
describe("#spyOn", function() {
it("checks for the existence of the object", function() {
var spyRegistry = new j$.SpyRegistry();
expect(function() {
spyRegistry.spyOn(void 0, 'pants');
}).toThrowError(/could not find an object/);
});
it("checks that a method name was passed", function() {
var spyRegistry = new j$.SpyRegistry(),
subject = {};
expect(function() {
spyRegistry.spyOn(subject);
}).toThrowError(/No method name supplied/);
});
it("checks for the existence of the method", function() {
var spyRegistry = new j$.SpyRegistry(),
subject = {};
expect(function() {
spyRegistry.spyOn(subject, 'pants');
}).toThrowError(/method does not exist/);
});
it("checks if it has already been spied upon", function() {
var spies = [],
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
subject = { spiedFunc: function() {} };
spyRegistry.spyOn(subject, 'spiedFunc');
expect(function() {
spyRegistry.spyOn(subject, 'spiedFunc');
}).toThrowError(/has already been spied upon/);
});
it("overrides the method on the object and returns the spy", function() {
var originalFunctionWasCalled = false,
spyRegistry = new j$.SpyRegistry(),
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
expect(subject.spiedFunc).toEqual(spy);
});
});
describe("#clearSpies", function() {
it("restores the original functions on the spied-upon objects", function() {
var spies = [],
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
originalFunction = function() {},
subject = { spiedFunc: originalFunction };
spyRegistry.spyOn(subject, 'spiedFunc');
spyRegistry.clearSpies();
expect(subject.spiedFunc).toBe(originalFunction);
});
});
});

View File

@@ -7,14 +7,14 @@ describe('Spies', function () {
TestClass.prototype.someFunction = function() {};
TestClass.prototype.someFunction.bob = "test";
});
it("preserves the properties of the spied function", function() {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
expect(spy.bob).toEqual("test");
});
it("warns the user that we indend to overwrite an existing property", function() {
it("warns the user that we intend to overwrite an existing property", function() {
TestClass.prototype.someFunction.and = "turkey";
expect(function() {
@@ -28,6 +28,35 @@ describe('Spies', function () {
expect(spy.and).toEqual(jasmine.any(j$.SpyStrategy));
expect(spy.calls).toEqual(jasmine.any(j$.CallTracker));
});
it("tracks the argument of calls", function () {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var trackSpy = spyOn(spy.calls, "track");
spy("arg");
expect(trackSpy.calls.mostRecent().args[0].args).toEqual(["arg"]);
});
it("tracks the context of calls", function () {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var trackSpy = spyOn(spy.calls, "track");
var contextObject = { spyMethod: spy };
contextObject.spyMethod();
expect(trackSpy.calls.mostRecent().args[0].object).toEqual(contextObject);
});
it("tracks the return value of calls", function () {
var spy = j$.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
var trackSpy = spyOn(spy.calls, "track");
spy.and.returnValue("return value");
spy();
expect(trackSpy.calls.mostRecent().args[0].returnValue).toEqual("return value");
});
});
describe("createSpyObj", function() {
@@ -39,6 +68,14 @@ describe('Spies', function () {
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
});
it("should allow you to omit the baseName", function() {
var spyObj = j$.createSpyObj(['method1', 'method2']);
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
expect(spyObj.method1.and.identity()).toEqual('unknown.method1');
expect(spyObj.method2.and.identity()).toEqual('unknown.method2');
});
it("should throw if you do not pass an array argument", function() {
expect(function() {
j$.createSpyObj('BaseName');

View File

@@ -46,6 +46,19 @@ describe("SpyStrategy", function() {
expect(returnValue).toEqual(17);
});
it("can return specified values in order specified when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});
spyStrategy.returnValues('value1', 'value2', 'value3');
expect(spyStrategy.exec()).toEqual('value1');
expect(spyStrategy.exec()).toEqual('value2');
expect(spyStrategy.exec()).toBe('value3');
expect(spyStrategy.exec()).toBeUndefined();
expect(originalFn).not.toHaveBeenCalled();
});
it("allows an exception to be thrown when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});

View File

@@ -67,116 +67,79 @@ describe("Suite", function() {
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
});
it("can be disabled", function() {
var env = new j$.Env(),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
suite = new j$.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
});
it('has a status of failed if any afterAll expectations have failed', function() {
var suite = new j$.Suite({
expectationResultFactory: function() { return 'hi'; }
});
suite.addChild({ result: { status: 'done' } });
suite.addExpectationResult(false);
expect(suite.status()).toBe('failed');
});
it("retrieves a result with updated status", function() {
var suite = new j$.Suite({});
expect(suite.getResult().status).toBe('finished');
});
it("retrieves a result with disabled status", function() {
var suite = new j$.Suite({});
suite.disable();
expect(suite.disabled).toBe(true);
suite.execute();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(suite.getResult().status).toBe('disabled');
});
it("delegates execution of its specs and suites", function() {
var env = new j$.Env(),
parentSuiteDone = jasmine.createSpy('parent suite done'),
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
parentSuite = new j$.Suite({
env: env,
description: "I am a parent suite",
queueRunner: fakeQueueRunnerForParent
}),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
suite = new j$.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
it("is executable if not disabled", function() {
var suite = new j$.Suite({});
spyOn(suite, "execute");
parentSuite.addChild(fakeSpec1);
parentSuite.addChild(suite);
parentSuite.execute(parentSuiteDone);
var parentSuiteFns = fakeQueueRunnerForParent.calls.mostRecent().args[0].fns;
parentSuiteFns[0]();
expect(fakeSpec1.execute).toHaveBeenCalled();
parentSuiteFns[1]();
expect(suite.execute).toHaveBeenCalled();
expect(suite.isExecutable()).toBe(true);
});
it("calls a provided onStart callback when starting", function() {
var env = new j$.Env(),
suiteStarted = jasmine.createSpy('suiteStarted'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new j$.Suite({
env: env,
description: "with a child suite",
onStart: suiteStarted,
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
it("is not executable if disabled", function() {
var suite = new j$.Suite({});
suite.disable();
suite.execute();
expect(suiteStarted).toHaveBeenCalledWith(suite);
expect(suite.isExecutable()).toBe(false);
});
it("calls a provided onComplete callback when done", function() {
var env = new j$.Env(),
suiteCompleted = jasmine.createSpy('parent suite done'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new j$.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
it("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.execute(suiteCompleted);
suite.addChild(child1);
suite.addChild(child2);
expect(suiteCompleted).toHaveBeenCalled();
child1.addExpectationResult.and.throwError('foo');
suite.addExpectationResult('stuff');
expect(child1.addExpectationResult).toHaveBeenCalledWith('stuff');
expect(child2.addExpectationResult).toHaveBeenCalledWith('stuff');
});
it("calls a provided result callback when done", function() {
var env = new j$.Env(),
suiteResultsCallback = jasmine.createSpy('suite result callback'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new j$.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner,
resultCallback: suiteResultsCallback
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute();
expect(suiteResultsCallback).toHaveBeenCalledWith({
id: suite.id,
status: '',
description: "with a child suite",
fullName: "with a child suite"
it("throws an ExpectationFailed when receiving a failed expectation in an afterAll when throwOnExpectationFailure is set", function() {
var suite = new j$.Suite({
expectationResultFactory: function(data) { return data; },
throwOnExpectationFailure: true
});
suite.addChild({ result: { status: 'done' } });
expect(function() {
suite.addExpectationResult(false, 'failed');
}).toThrowError(j$.errors.ExpectationFailed);
expect(suite.status()).toBe('failed');
expect(suite.result.failedExpectations).toEqual(['failed']);
});
it("does not add an additional failure when an expectation fails in an afterAll", function(){
var suite = new j$.Suite({});
suite.addChild({ result: { status: 'done' } });
suite.onException(new j$.errors.ExpectationFailed());
expect(suite.getResult().failedExpectations).toEqual([]);
})
});

View File

@@ -10,4 +10,22 @@ describe("Timer", function() {
expect(timer.elapsed()).toEqual(100);
});
describe("when date is stubbed, perhaps by other testing helpers", function() {
var origDate = Date;
beforeEach(function() {
Date = jasmine.createSpy('date spy');
});
afterEach(function() {
Date = origDate;
});
it("does not throw even though Date was taken away", function() {
var timer = new j$.Timer();
expect(timer.start).not.toThrow();
expect(timer.elapsed()).toEqual(jasmine.any(Number));
});
});
});

View File

@@ -0,0 +1,633 @@
describe("TreeProcessor", function() {
var nodeNumber = 0, leafNumber = 0;
function Node(attrs) {
attrs = attrs || {};
this.id = 'node' + nodeNumber++;
this.children = attrs.children || [];
this.canBeReentered = function() {
return !attrs.noReenter;
};
this.isExecutable = function() {
return attrs.executable !== false;
};
this.sharedUserContext = function() {
return attrs.userContext || {};
};
this.getResult = jasmine.createSpy(this.id + '#execute');
this.beforeAllFns = attrs.beforeAllFns || [];
this.afterAllFns = attrs.afterAllFns || [];
}
function Leaf(attrs) {
attrs = attrs || {};
this.id = 'leaf' + leafNumber++;
this.isExecutable = function() {
return attrs.executable !== false;
};
this.execute = jasmine.createSpy(this.id + '#execute');
}
it("processes a single executable leaf", function() {
var leaf = new Leaf(),
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
executable: true,
segments: jasmine.any(Array)
});
});
it("processes a single non-executable leaf", function() {
var leaf = new Leaf({ executable: false }),
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [leaf.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
});
it("processes a single non-specified leaf", function() {
var leaf = new Leaf(),
processor = new j$.TreeProcessor({ tree: leaf, runnableIds: [] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[leaf.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
});
it("processes a tree with a single leaf with the root specified", function() {
var leaf = new Leaf(),
parent = new Node({ children: [leaf] }),
processor = new j$.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[parent.id]).toEqual({
executable: true,
segments: jasmine.any(Array)
});
expect(result[leaf.id]).toEqual({
executable: true,
segments: jasmine.any(Array)
});
});
it("processes a tree with a single non-executable leaf, with the root specified", function() {
var leaf = new Leaf({ executable: false }),
parent = new Node({ children: [leaf] }),
processor = new j$.TreeProcessor({ tree: parent, runnableIds: [parent.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[parent.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
expect(result[leaf.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
});
it("processes a complicated tree with the root specified", function() {
var nonExecutable = new Leaf({ executable: false }),
executable = new Leaf({ executable: true }),
parent = new Node({ children: [nonExecutable, executable] }),
childless = new Node(),
childOfDisabled = new Leaf({ executable: true }),
disabledNode = new Node({ executable: false, children: [childOfDisabled] }),
root = new Node({ children: [parent, childless, disabledNode] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [root.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
expect(result[root.id]).toEqual({
executable: true,
segments: jasmine.any(Array)
});
expect(result[childless.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
expect(result[nonExecutable.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
expect(result[executable.id]).toEqual({
executable: true,
segments: jasmine.any(Array)
});
expect(result[parent.id]).toEqual({
executable: true,
segments: jasmine.any(Array)
});
expect(result[disabledNode.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
expect(result[childOfDisabled.id]).toEqual({
executable: false,
segments: jasmine.any(Array)
});
});
it("marks the run order invalid if it would re-enter a node that does not allow re-entry", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
reentered = new Node({ noReenter: true, children: [leaf1, leaf2] }),
root = new Node({ children: [reentered, leaf3] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
result = processor.processTree();
expect(result).toEqual({ valid: false });
});
it("marks the run order valid if a node being re-entered allows re-entry", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
reentered = new Node({ children: [leaf1, leaf2] }),
root = new Node({ children: [reentered, leaf3] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf1.id, leaf3.id, leaf2.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
});
it("marks the run order valid if a node which can't be re-entered is only entered once", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
noReentry = new Node({ noReenter: true }),
root = new Node({ children: [noReentry] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [leaf2.id, leaf1.id, leaf3.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
});
it("marks the run order valid if a node which can't be re-entered is run directly", function() {
var leaf1 = new Leaf(),
noReentry = new Node({ noReenter: true }),
root = new Node({ children: [noReentry] }),
processor = new j$.TreeProcessor({ tree: root, runnableIds: [root.id] }),
result = processor.processTree();
expect(result.valid).toBe(true);
});
it("runs a single leaf", function() {
var leaf = new Leaf(),
node = new Node({ children: [leaf] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({ tree: node, runnableIds: [leaf.id], queueRunnerFactory: queueRunner }),
treeComplete = jasmine.createSpy('treeComplete');
processor.execute(treeComplete);
expect(queueRunner).toHaveBeenCalledWith({
onComplete: treeComplete,
onException: jasmine.any(Function),
queueableFns: [{ fn: jasmine.any(Function) }]
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
expect(leaf.execute).toHaveBeenCalledWith('foo', true);
});
it("runs a node with no children", function() {
var node = new Node({ userContext: { node: 'context' } }),
root = new Node({ children: [node] }),
nodeStart = jasmine.createSpy('nodeStart'),
nodeComplete = jasmine.createSpy('nodeComplete'),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
nodeStart: nodeStart,
nodeComplete: nodeComplete,
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
expect(queueRunner).toHaveBeenCalledWith({
onComplete: treeComplete,
onException: jasmine.any(Function),
queueableFns: [{ fn: jasmine.any(Function) }]
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn(nodeDone);
expect(nodeStart).toHaveBeenCalledWith(node);
expect(queueRunner).toHaveBeenCalledWith({
onComplete: jasmine.any(Function),
queueableFns: [],
userContext: { node: 'context' },
onException: jasmine.any(Function)
});
node.getResult.and.returnValue({ my: 'result' });
queueRunner.calls.mostRecent().args[0].onComplete();
expect(nodeComplete).toHaveBeenCalledWith(node, { my: 'result' });
expect(nodeDone).toHaveBeenCalled();
});
it("runs a node with children", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
node = new Node({ children: [leaf1, leaf2] }),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(2);
queueableFns[0].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', true);
queueableFns[1].fn('bar');
expect(leaf2.execute).toHaveBeenCalledWith('bar', true);
});
it("runs a disabled node", function() {
var leaf1 = new Leaf(),
node = new Node({ children: [leaf1], executable: false }),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
nodeStart = jasmine.createSpy('nodeStart'),
nodeComplete = jasmine.createSpy('nodeComplete'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner,
nodeStart: nodeStart,
nodeComplete: nodeComplete
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
expect(nodeStart).toHaveBeenCalledWith(node);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(1);
queueableFns[0].fn('foo');
expect(leaf1.execute).toHaveBeenCalledWith('foo', false);
node.getResult.and.returnValue({ im: 'disabled' });
queueRunner.calls.mostRecent().args[0].onComplete();
expect(nodeComplete).toHaveBeenCalledWith(node, { im: 'disabled' });
});
it("runs beforeAlls for a node with children", function() {
var leaf = new Leaf(),
node = new Node({
children: [leaf],
beforeAllFns: ['beforeAll1', 'beforeAll2']
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual(['beforeAll1', 'beforeAll2', { fn: jasmine.any(Function) }]);
});
it("runs afterAlls for a node with children", function() {
var leaf = new Leaf(),
node = new Node({
children: [leaf],
afterAllFns: ['afterAll1', 'afterAll2']
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }, 'afterAll1', 'afterAll2']);
});
it("does not run beforeAlls or afterAlls for a node with no children", function() {
var node = new Node({
beforeAllFns: ['before'],
afterAllFns: ['after']
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual([]);
});
it("does not run beforeAlls or afterAlls for a disabled node", function() {
var leaf = new Leaf(),
node = new Node({
children: [leaf],
beforeAllFns: ['before'],
afterAllFns: ['after'],
executable: false
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn(nodeDone);
queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns).toEqual([{ fn: jasmine.any(Function) }]);
});
it("runs leaves in the order specified", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
root = new Node({ children: [leaf1, leaf2] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [leaf2.id, leaf1.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn();
expect(leaf1.execute).not.toHaveBeenCalled();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[1].fn();
expect(leaf1.execute).toHaveBeenCalled();
});
it("runs specified leaves before non-specified leaves", function() {
var specified = new Leaf(),
nonSpecified = new Leaf(),
root = new Node({ children: [nonSpecified, specified] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [specified.id],
queueRunnerFactory: queueRunner
}),
treeComplete = jasmine.createSpy('treeComplete');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn();
expect(nonSpecified.execute).not.toHaveBeenCalled();
expect(specified.execute).toHaveBeenCalledWith(undefined, true);
queueableFns[1].fn();
expect(nonSpecified.execute).toHaveBeenCalledWith(undefined, false);
});
it("runs nodes and leaves with a specified order", function() {
var specifiedLeaf = new Leaf(),
childLeaf = new Leaf(),
specifiedNode = new Node({ children: [childLeaf] }),
root = new Node({ children: [specifiedLeaf, specifiedNode] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [specifiedNode.id, specifiedLeaf.id],
queueRunnerFactory: queueRunner
});
processor.execute();
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
queueableFns[0].fn();
expect(specifiedLeaf.execute).not.toHaveBeenCalled();
var nodeQueueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
nodeQueueableFns[0].fn();
expect(childLeaf.execute).toHaveBeenCalled();
queueableFns[1].fn();
expect(specifiedLeaf.execute).toHaveBeenCalled();
});
it("runs a node multiple times if the order specified leaves and re-enters it", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
leaf4 = new Leaf(),
leaf5 = new Leaf(),
reentered = new Node({ children: [leaf1, leaf2, leaf3] }),
root = new Node({ children: [reentered, leaf4, leaf5] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [leaf1.id, leaf4.id, leaf2.id, leaf5.id, leaf3.id],
queueRunnerFactory: queueRunner
});
processor.execute();
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(5);
queueableFns[0].fn();
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(leaf1.execute).toHaveBeenCalled();
queueableFns[1].fn();
expect(leaf4.execute).toHaveBeenCalled();
queueableFns[2].fn();
expect(queueRunner.calls.count()).toBe(3);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[3].fn();
expect(leaf5.execute).toHaveBeenCalled();
queueableFns[4].fn();
expect(queueRunner.calls.count()).toBe(4);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(leaf3.execute).toHaveBeenCalled();
});
it("runs a parent of a node with segments correctly", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
leaf4 = new Leaf(),
leaf5 = new Leaf(),
parent = new Node({ children: [leaf1, leaf2, leaf3] }),
grandparent = new Node({ children: [parent] }),
root = new Node({ children: [grandparent, leaf4, leaf5] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [leaf1.id, leaf4.id, leaf2.id, leaf5.id, leaf3.id],
queueRunnerFactory: queueRunner
});
processor.execute();
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(5);
queueableFns[0].fn();
expect(queueRunner.calls.count()).toBe(2);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(queueRunner.calls.count()).toBe(3);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(leaf1.execute).toHaveBeenCalled();
queueableFns[1].fn();
expect(leaf4.execute).toHaveBeenCalled();
queueableFns[2].fn();
expect(queueRunner.calls.count()).toBe(4);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(queueRunner.calls.count()).toBe(5);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(leaf2.execute).toHaveBeenCalled();
queueableFns[3].fn();
expect(leaf5.execute).toHaveBeenCalled();
queueableFns[4].fn();
expect(queueRunner.calls.count()).toBe(6);
expect(queueRunner.calls.mostRecent().args[0].queueableFns.length).toBe(1);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(queueRunner.calls.count()).toBe(7);
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
expect(leaf3.execute).toHaveBeenCalled();
});
it("runs nodes in the order they were declared", function() {
var leaf1 = new Leaf(),
leaf2 = new Leaf(),
leaf3 = new Leaf(),
parent = new Node({ children: [leaf2, leaf3] }),
root = new Node({ children: [leaf1, parent] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new j$.TreeProcessor({
tree: root,
runnableIds: [root.id],
queueRunnerFactory: queueRunner
});
processor.execute();
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(queueableFns.length).toBe(2);
queueableFns[0].fn();
expect(leaf1.execute).toHaveBeenCalled();
queueableFns[1].fn();
var childFns = queueRunner.calls.mostRecent().args[0].queueableFns;
expect(childFns.length).toBe(2);
childFns[0].fn();
expect(leaf2.execute).toHaveBeenCalled();
childFns[1].fn();
expect(leaf3.execute).toHaveBeenCalled();
});
});

View File

@@ -2,44 +2,44 @@ describe("Any", function() {
it("matches a string", function() {
var any = new j$.Any(String);
expect(any.jasmineMatches("foo")).toBe(true);
expect(any.asymmetricMatch("foo")).toBe(true);
});
it("matches a number", function() {
var any = new j$.Any(Number);
expect(any.jasmineMatches(1)).toBe(true);
expect(any.asymmetricMatch(1)).toBe(true);
});
it("matches a function", function() {
var any = new j$.Any(Function);
expect(any.jasmineMatches(function(){})).toBe(true);
expect(any.asymmetricMatch(function(){})).toBe(true);
});
it("matches an Object", function() {
var any = new j$.Any(Object);
expect(any.jasmineMatches({})).toBe(true);
expect(any.asymmetricMatch({})).toBe(true);
});
it("matches a Boolean", function() {
var any = new j$.Any(Boolean);
expect(any.jasmineMatches(true)).toBe(true);
expect(any.asymmetricMatch(true)).toBe(true);
});
it("matches another constructed object", function() {
var Thing = function() {},
any = new j$.Any(Thing);
expect(any.jasmineMatches(new Thing())).toBe(true);
expect(any.asymmetricMatch(new Thing())).toBe(true);
});
it("jasmineToString's itself", function() {
var any = new j$.Any(Number);
expect(any.jasmineToString()).toMatch('<jasmine.any');
expect(any.jasmineToString()).toEqual('<jasmine.any(Number)>');
});
});

View File

@@ -0,0 +1,44 @@
describe("Anything", function() {
it("matches a string", function() {
var anything = new j$.Anything();
expect(anything.asymmetricMatch('foo')).toBe(true);
});
it("matches a number", function() {
var anything = new j$.Anything();
expect(anything.asymmetricMatch(42)).toBe(true);
});
it("matches an object", function() {
var anything = new j$.Anything();
expect(anything.asymmetricMatch({ foo: 'bar' })).toBe(true);
});
it("matches an array", function() {
var anything = new j$.Anything();
expect(anything.asymmetricMatch([1,2,3])).toBe(true);
});
it("doesn't match undefined", function() {
var anything = new j$.Anything();
expect(anything.asymmetricMatch()).toBe(false);
expect(anything.asymmetricMatch(undefined)).toBe(false);
});
it("doesn't match null", function() {
var anything = new j$.Anything();
expect(anything.asymmetricMatch(null)).toBe(false);
});
it("jasmineToString's itself", function() {
var anything = new j$.Anything();
expect(anything.jasmineToString()).toEqual("<jasmine.anything>");
});
});

View File

@@ -0,0 +1,39 @@
describe("ArrayContaining", function() {
it("matches any actual to an empty array", function() {
var containing = new j$.ArrayContaining([]);
expect(containing.asymmetricMatch("foo")).toBe(true);
});
it("does not work when not passed an array", function() {
var containing = new j$.ArrayContaining("foo");
expect(function() {
containing.asymmetricMatch([]);
}).toThrowError(/not 'foo'/);
});
it("matches when the item is in the actual", function() {
var containing = new j$.ArrayContaining(["foo"]);
expect(containing.asymmetricMatch(["foo"])).toBe(true);
});
it("matches when additional items are in the actual", function() {
var containing = new j$.ArrayContaining(["foo"]);
expect(containing.asymmetricMatch(["foo", "bar"])).toBe(true);
});
it("does not match when the item is not in the actual", function() {
var containing = new j$.ArrayContaining(["foo"]);
expect(containing.asymmetricMatch(["bar"])).toBe(false);
});
it("jasmineToStrings itself", function() {
var containing = new j$.ArrayContaining([]);
expect(containing.jasmineToString()).toMatch("<jasmine.arrayContaining");
});
});

View File

@@ -0,0 +1,89 @@
describe("ObjectContaining", function() {
it("matches any actual to an empty object", function() {
var containing = new j$.ObjectContaining({});
expect(containing.asymmetricMatch("foo")).toBe(true);
});
it("does not match an empty object actual", function() {
var containing = new j$.ObjectContaining("foo");
expect(function() {
containing.asymmetricMatch({})
}).toThrowError(/not 'foo'/)
});
it("matches when the key/value pair is present in the actual", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(true);
});
it("does not match when the key/value pair is not present in the actual", function() {
var containing = new j$.ObjectContaining({foo: "fooVal"});
expect(containing.asymmetricMatch({bar: "barVal", quux: "quuxVal"})).toBe(false);
});
it("does not match when the key is present but the value is different in the actual", function() {
var containing = new j$.ObjectContaining({foo: "other"});
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"})).toBe(false);
});
it("jasmineToString's itself", function() {
var containing = new j$.ObjectContaining({});
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
});
it("matches recursively", function() {
var containing = new j$.ObjectContaining({one: new j$.ObjectContaining({two: {}})});
expect(containing.asymmetricMatch({one: {two: {}}})).toBe(true);
});
it("matches when key is present with undefined value", function() {
var containing = new j$.ObjectContaining({ one: undefined });
expect(containing.asymmetricMatch({ one: undefined })).toBe(true);
});
it("does not match when key with undefined value is not present", function() {
var containing = new j$.ObjectContaining({ one: undefined });
expect(containing.asymmetricMatch({})).toBe(false);
});
it("matches defined properties", function(){
// IE 8 doesn't support `definePropery` on non-DOM nodes
if (jasmine.getEnv().ieVersion < 9) { return; }
var containing = new j$.ObjectContaining({ foo: "fooVal" });
var definedPropertyObject = {};
Object.defineProperty(definedPropertyObject, "foo", {
get: function() { return "fooVal" }
});
expect(containing.asymmetricMatch(definedPropertyObject)).toBe(true);
});
it("matches prototype properties", function(){
var containing = new j$.ObjectContaining({ foo: "fooVal" });
var prototypeObject = {foo: "fooVal"};
var obj;
if (Object.create) {
obj = Object.create(prototypeObject);
} else {
function Foo() {}
Foo.prototype = prototypeObject;
Foo.prototype.constructor = Foo;
obj = new Foo();
}
expect(containing.asymmetricMatch(obj)).toBe(true);
});
});

View File

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

View File

@@ -38,13 +38,13 @@ describe("Custom Matchers (Integration)", function() {
});
it("passes the spec if the custom matcher passes", function(done) {
env.addMatchers({
toBeReal: function() {
return { compare: function() { return { pass: true }; } };
}
});
env.it("spec using custom matcher", function() {
env.addMatchers({
toBeReal: function() {
return { compare: function() { return { pass: true }; } };
}
});
env.expect(true).toBeReal();
});
@@ -57,16 +57,16 @@ describe("Custom Matchers (Integration)", function() {
});
it("uses the negative compare function for a negative comparison, if provided", function(done) {
env.addMatchers({
toBeReal: function() {
return {
compare: function() { return { pass: true }; },
negativeCompare: function() { return { pass: true }; }
};
}
});
env.it("spec with custom negative comparison matcher", function() {
env.addMatchers({
toBeReal: function() {
return {
compare: function() { return { pass: true }; },
negativeCompare: function() { return { pass: true }; }
};
}
});
env.expect(true).not.toBeReal();
});
@@ -79,17 +79,17 @@ describe("Custom Matchers (Integration)", function() {
});
it("generates messages with the same rules as built in matchers absent a custom message", function(done) {
env.addMatchers({
toBeReal: function() {
return {
compare: function() {
return { pass: false };
env.it('spec with an expectation', function() {
env.addMatchers({
toBeReal: function() {
return {
compare: function() {
return { pass: false };
}
}
}
}
});
});
env.it('spec with an expectation', function() {
env.expect("a").toBeReal();
});
@@ -103,13 +103,14 @@ describe("Custom Matchers (Integration)", function() {
it("passes the expected and actual arguments to the comparison function", function(done) {
var argumentSpy = jasmine.createSpy("argument spy").and.returnValue({ pass: true });
env.addMatchers({
toBeReal: function() {
return { compare: argumentSpy };
}
});
env.it('spec with an expectation', function () {
env.addMatchers({
toBeReal: function() {
return { compare: argumentSpy };
}
});
env.expect(true).toBeReal();
env.expect(true).toBeReal("arg");
env.expect(true).toBeReal("arg1", "arg2");
@@ -130,12 +131,13 @@ describe("Custom Matchers (Integration)", function() {
argumentSpy = jasmine.createSpy("argument spy").and.returnValue(matcherFactory),
customEqualityFn = function() { return true; };
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeReal: argumentSpy
});
env.it("spec with expectation", function() {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeReal: argumentSpy
});
env.expect(true).toBeReal();
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,699 @@
describe("jasmine spec running", function () {
var env;
beforeEach(function() {
env = new j$.Env();
});
it('should assign spec ids sequentially', function() {
var it0, it1, it2, it3, it4;
env.describe('test suite', function() {
it0 = env.it('spec 0', function() {
});
it1 = env.it('spec 1', function() {
});
it2 = env.xit('spec 2', function() {
});
it3 = env.it('spec 3', function() {
});
});
env.describe('test suite 2', function() {
it4 = env.it('spec 4', function() {
});
});
expect(it0.id).toEqual('spec0');
expect(it1.id).toEqual('spec1');
expect(it2.id).toEqual('spec2');
expect(it3.id).toEqual('spec3');
expect(it4.id).toEqual('spec4');
});
it('nested suites', function (done) {
var foo = 0;
var bar = 0;
var baz = 0;
var quux = 0;
var nested = env.describe('suite', function () {
env.describe('nested', function () {
env.it('should run nested suites', function () {
foo++;
});
env.it('should run nested suites', function () {
bar++;
});
});
env.describe('nested 2', function () {
env.it('should run suites following nested suites', function () {
baz++;
});
});
env.it('should run tests following nested suites', function () {
quux++;
});
});
expect(foo).toEqual(0);
expect(bar).toEqual(0);
expect(baz).toEqual(0);
expect(quux).toEqual(0);
var assertions = function() {
expect(foo).toEqual(1);
expect(bar).toEqual(1);
expect(baz).toEqual(1);
expect(quux).toEqual(1);
done();
};
env.addReporter({ jasmineDone: assertions });
env.execute();
});
it("should permit nested describes", function(done) {
var actions = [];
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 1",
"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 2",
"outer afterEach",
"topSuite afterEach",
"topSuite beforeEach",
"outer beforeEach",
"inner 2 beforeEach",
"inner 2 it",
"inner 2 afterEach",
"outer afterEach",
"topSuite afterEach"
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("should run multiple befores and afters in the order they are declared", function(done) {
var actions = [];
env.beforeEach(function () {
actions.push('runner beforeEach1');
});
env.afterEach(function () {
actions.push('runner afterEach1');
});
env.beforeEach(function () {
actions.push('runner beforeEach2');
});
env.afterEach(function () {
actions.push('runner afterEach2');
});
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('beforeEach1');
});
env.afterEach(function() {
actions.push('afterEach1');
});
env.beforeEach(function() {
actions.push('beforeEach2');
});
env.afterEach(function() {
actions.push('afterEach2');
});
env.it('does it 1', function() {
actions.push('outer it 1');
});
});
var assertions = function() {
var expected = [
"runner beforeEach1",
"runner beforeEach2",
"beforeEach1",
"beforeEach2",
"outer it 1",
"afterEach2",
"afterEach1",
"runner afterEach2",
"runner afterEach1"
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it('should run beforeAlls before beforeEachs and afterAlls after afterEachs', function(done) {
var actions = [];
env.beforeAll(function() {
actions.push('runner beforeAll');
});
env.afterAll(function() {
actions.push('runner afterAll');
});
env.beforeEach(function () {
actions.push('runner beforeEach');
});
env.afterEach(function () {
actions.push('runner afterEach');
});
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('inner beforeEach');
});
env.afterEach(function() {
actions.push('inner afterEach');
});
env.beforeAll(function() {
actions.push('inner beforeAll');
});
env.afterAll(function() {
actions.push('inner afterAll');
});
env.it('does something or other', function() {
actions.push('it');
});
});
var assertions = function() {
var expected = [
"runner beforeAll",
"inner beforeAll",
"runner beforeEach",
"inner beforeEach",
"it",
"inner afterEach",
"runner afterEach",
"inner afterAll",
"runner afterAll"
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it('should run beforeAlls and afterAlls in the order declared when runnablesToRun is provided', function(done) {
var actions = [],
spec,
spec2;
env.beforeAll(function() {
actions.push('runner beforeAll');
});
env.afterAll(function() {
actions.push('runner afterAll');
});
env.beforeEach(function () {
actions.push('runner beforeEach');
});
env.afterEach(function () {
actions.push('runner afterEach');
});
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('inner beforeEach');
});
env.afterEach(function() {
actions.push('inner afterEach');
});
env.beforeAll(function() {
actions.push('inner beforeAll');
});
env.afterAll(function() {
actions.push('inner afterAll');
});
spec = env.it('does something', function() {
actions.push('it');
});
spec2 = env.it('does something or other', function() {
actions.push('it2');
});
});
var assertions = function() {
var expected = [
"runner beforeAll",
"inner beforeAll",
"runner beforeEach",
"inner beforeEach",
"it2",
"inner afterEach",
"runner afterEach",
"runner beforeEach",
"inner beforeEach",
"it",
"inner afterEach",
"runner afterEach",
"inner afterAll",
"runner afterAll"
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute([spec2.id, spec.id]);
});
it('only runs *Alls once in a focused suite', function(done){
var actions = [];
env.fdescribe('Suite', function() {
env.beforeAll(function(){
actions.push('beforeAll');
});
env.it('should run beforeAll once', function() {
actions.push('spec');
});
env.afterAll(function(){
actions.push('afterAll');
});
});
var assertions = function() {
expect(actions).toEqual(['beforeAll', 'spec', 'afterAll']);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
describe('focused runnables', function() {
it('runs the relevant alls and eachs for each runnable', function(done) {
var actions = [];
env.beforeAll(function() {actions.push('beforeAll')});
env.afterAll(function() {actions.push('afterAll')});
env.beforeEach(function() {actions.push('beforeEach')});
env.afterEach(function() {actions.push('afterEach')});
env.fdescribe('a focused suite', function() {
env.it('is run', function() {
actions.push('spec in fdescribe')
});
});
env.describe('an unfocused suite', function() {
env.fit('has a focused spec', function() {
actions.push('focused spec')
});
});
var assertions = function() {
var expected = [
'beforeAll',
'beforeEach',
'spec in fdescribe',
'afterEach',
'beforeEach',
'focused spec',
'afterEach',
'afterAll'
];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it('focused specs in focused suites cause non-focused siblings to not run', function(done){
var actions = [];
env.fdescribe('focused suite', function() {
env.it('unfocused spec', function() {
actions.push('unfocused spec')
});
env.fit('focused spec', function() {
actions.push('focused spec')
});
});
var assertions = function() {
var expected = ['focused spec'];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it('focused suites in focused suites cause non-focused siblings to not run', function(done){
var actions = [];
env.fdescribe('focused suite', function() {
env.it('unfocused spec', function() {
actions.push('unfocused spec')
});
env.fdescribe('inner focused suite', function() {
env.it('inner spec', function() {
actions.push('inner spec');
});
});
});
var assertions = function() {
var expected = ['inner spec'];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it('focused runnables unfocus ancestor focused suites', function() {
var actions = [];
env.fdescribe('focused suite', function() {
env.it('unfocused spec', function() {
actions.push('unfocused spec')
});
env.describe('inner focused suite', function() {
env.fit('focused spec', function() {
actions.push('focused spec');
});
});
});
var assertions = function() {
var expected = ['focused spec'];
expect(actions).toEqual(expected);
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
});
it("shouldn't run disabled suites", function(done) {
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
suite = env.describe('A Suite', function() {
env.xdescribe('with a disabled suite', function(){
env.it('spec inside a disabled suite', specInADisabledSuite);
});
});
var assertions = function() {
expect(specInADisabledSuite).not.toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("should allow top level suites to be disabled", function() {
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
otherSpec = jasmine.createSpy("otherSpec");
env.xdescribe('A disabled suite', function() {
env.it('spec inside a disabled suite', specInADisabledSuite);
});
env.describe('Another suite', function() {
env.it('another spec', otherSpec);
});
var assertions = function() {
expect(specInADisabledSuite).not.toHaveBeenCalled();
expect(otherSpec).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
it("should set all pending specs to pending when a suite is run", function(done) {
var pendingSpec,
suite = env.describe('default current suite', function() {
pendingSpec = env.it("I am a pending spec");
});
var assertions = function() {
expect(pendingSpec.status()).toBe("pending");
done();
};
env.addReporter({jasmineDone: assertions});
env.execute();
});
// TODO: is this useful? It doesn't catch syntax errors
xit("should recover gracefully when there are errors in describe functions", function() {
var specs = [];
var superSimpleReporter = new j$.Reporter();
superSimpleReporter.reportSpecResults = function(result) {
specs.push("Spec: " + result.fullName);
};
try {
env.describe("outer1", function() {
env.describe("inner1", function() {
env.it("should thingy", function() {
this.expect(true).toEqual(true);
});
throw new Error("fake error");
});
env.describe("inner2", function() {
env.it("should other thingy", function() {
this.expect(true).toEqual(true);
});
});
throw new Error("fake error");
});
} catch(e) {
}
env.describe("outer2", function() {
env.it("should xxx", function() {
this.expect(true).toEqual(true);
});
});
env.addReporter(superSimpleReporter);
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) {
var actions = [],
spec1, spec2, spec3;
env.describe("top", function() {
spec1 = env.it("spec1", function() {
actions.push("spec1");
});
spec2 = env.it("spec2", function() {
actions.push("spec2");
});
});
spec3 = env.it("spec3", function() {
actions.push("spec3");
});
env.addReporter({
jasmineDone: function() {
expect(actions).toEqual(["spec2", "spec3", "spec1"]);
done();
}
});
env.execute([spec2.id, spec3.id, spec1.id]);
});
it("refuses to re-enter suites with a beforeAll", function() {
var actions = [],
spec1, spec2, spec3;
env.describe("top", function() {
env.beforeAll(function() {});
spec1 = env.it("spec1", function() {
actions.push("spec1");
});
spec2 = env.it("spec2", function() {
actions.push("spec2");
});
});
spec3 = env.it("spec3", function() {
actions.push("spec3");
});
env.addReporter({
jasmineDone: function() {
expect(actions).toEqual([]);
done();
}
});
expect(function() {
env.execute([spec2.id, spec3.id, spec1.id]);
}).toThrowError(/beforeAll/);
});
it("refuses to re-enter suites with a afterAll", function() {
var actions = [],
spec1, spec2, spec3;
env.describe("top", function() {
env.afterAll(function() {});
spec1 = env.it("spec1", function() {
actions.push("spec1");
});
spec2 = env.it("spec2", function() {
actions.push("spec2");
});
});
spec3 = env.it("spec3", function() {
actions.push("spec3");
});
env.addReporter({
jasmineDone: function() {
expect(actions).toEqual([]);
done();
}
});
expect(function() {
env.execute([spec2.id, spec3.id, spec1.id]);
}).toThrowError(/afterAll/);
});
});

View File

@@ -1,6 +1,6 @@
describe("matchersUtil", function() {
describe("equals", function() {
it("passes for literals that are threequal", 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);
});
@@ -58,6 +58,16 @@ describe("matchersUtil", function() {
expect(j$.matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
});
it("fails for Arrays whose contents are equivalent, but have differing properties", function() {
var one = [1,2,3],
two = [1,2,3];
one.foo = 'bar';
two.foo = 'baz';
expect(j$.matchersUtil.equals(one, two)).toBe(false);
});
it("passes for Errors that are the same type and have the same message", function() {
expect(j$.matchersUtil.equals(new Error("foo"), new Error("foo"))).toBe(true);
});
@@ -122,6 +132,72 @@ describe("matchersUtil", function() {
expect(j$.matchersUtil.equals(a,b)).toBe(true);
});
it("passes for equivalent DOM nodes", function() {
if (typeof document === 'undefined') {
return;
}
var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value")
a.appendChild(document.createTextNode('test'));
var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value")
b.appendChild(document.createTextNode('test'));
expect(j$.matchersUtil.equals(a,b)).toBe(true);
});
it("fails for DOM nodes with different attributes or child nodes", function() {
if (typeof document === 'undefined') {
return;
}
var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value")
a.appendChild(document.createTextNode('test'));
var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value2")
b.appendChild(document.createTextNode('test'));
expect(j$.matchersUtil.equals(a,b)).toBe(false);
b.setAttribute("test-attr", "attr-value");
expect(j$.matchersUtil.equals(a,b)).toBe(true);
b.appendChild(document.createTextNode('2'));
expect(j$.matchersUtil.equals(a,b)).toBe(false);
a.appendChild(document.createTextNode('2'));
expect(j$.matchersUtil.equals(a,b)).toBe(true);
});
it("passes for equivalent objects from different vm contexts", function() {
if (typeof require !== 'function') {
return;
}
var vm = require('vm');
var sandbox = {
obj: null
};
vm.runInNewContext('obj = {a: 1, b: 2}', sandbox);
expect(j$.matchersUtil.equals(sandbox.obj, {a: 1, b: 2})).toBe(true);
});
it("passes for equivalent arrays from different vm contexts", function() {
if (typeof require !== 'function') {
return;
}
var vm = require('vm');
var sandbox = {
arr: null
};
vm.runInNewContext('arr = [1, 2]', sandbox);
expect(j$.matchersUtil.equals(sandbox.arr, [1, 2])).toBe(true);
});
it("passes when Any is used", function() {
var number = 3,
anyNumber = new j$.Any(Number);
@@ -142,9 +218,31 @@ describe("matchersUtil", function() {
var obj = {
foo: 3,
bar: 7
};
},
containing = new j$.ObjectContaining({foo: 3});
expect(j$.matchersUtil.equals(obj, new j$.ObjectContaining({foo: 3}))).toBe(true);
expect(j$.matchersUtil.equals(obj, containing)).toBe(true);
expect(j$.matchersUtil.equals(containing, obj)).toBe(true);
});
it("passes when an asymmetric equality tester returns true", function() {
var tester = { asymmetricMatch: function(other) { return true; } };
expect(j$.matchersUtil.equals(false, tester)).toBe(true);
expect(j$.matchersUtil.equals(tester, false)).toBe(true);
});
it("fails when an asymmetric equality tester returns false", function() {
var tester = { asymmetricMatch: function(other) { return false; } };
expect(j$.matchersUtil.equals(true, tester)).toBe(false);
expect(j$.matchersUtil.equals(tester, true)).toBe(false);
});
it("passes when ArrayContaining is used", function() {
var arr = ["foo", "bar"];
expect(j$.matchersUtil.equals(arr, new j$.ArrayContaining(["bar"]))).toBe(true);
});
it("passes when a custom equality matcher returns true", function() {
@@ -170,11 +268,50 @@ describe("matchersUtil", function() {
expect(j$.matchersUtil.equals(1, 1, [tester])).toBe(false);
});
it("passes for an asymmetric equality tester that returns true when a custom equality tester return false", function() {
var asymmetricTester = { asymmetricMatch: function(other) { return true; } },
symmetricTester = function(a, b) { return false; };
expect(j$.matchersUtil.equals(asymmetricTester, true, [symmetricTester])).toBe(true);
expect(j$.matchersUtil.equals(true, asymmetricTester, [symmetricTester])).toBe(true);
});
it("passes when an Any is compared to an Any that checks for the same type", function() {
var any1 = new j$.Any(Function),
any2 = new j$.Any(Function);
expect(j$.matchersUtil.equals(any1, any2)).toBe(true);
});
it("passes for null prototype objects with same properties", function () {
if (jasmine.getEnv().ieVersion < 9) { return; }
var objA = Object.create(null),
objB = Object.create(null);
objA.name = 'test';
objB.name = 'test';
expect(j$.matchersUtil.equals(objA, objB)).toBe(true);
});
it("fails for null prototype objects with different properties", function () {
if (jasmine.getEnv().ieVersion < 9) { return; }
var objA = Object.create(null),
objB = Object.create(null);
objA.name = 'test';
objB.test = 'name';
expect(j$.matchersUtil.equals(objA, objB)).toBe(false);
});
});
describe("contains", function() {
it("passes when expected is a substring of actual", function() {
expect(j$.matchersUtil.contains("ABC", "B")).toBe(true);
expect(j$.matchersUtil.contains("ABC", "BC")).toBe(true);
});
it("fails when expected is a not substring of actual", function() {
@@ -199,6 +336,23 @@ describe("matchersUtil", function() {
expect(j$.matchersUtil.contains([1, 2], 2, [customTester])).toBe(true);
});
it("fails when actual is undefined", function() {
expect(j$.matchersUtil.contains(undefined, 'A')).toBe(false);
});
it("fails when actual is null", function() {
expect(j$.matchersUtil.contains(null, 'A')).toBe(false);
});
it("passes with array-like objects", function() {
var capturedArgs = null;
function testFunction(){
capturedArgs = arguments;
}
testFunction('foo', 'bar');
expect(j$.matchersUtil.contains(capturedArgs, 'bar')).toBe(true);
});
});
describe("buildMessage", function() {

View File

@@ -8,7 +8,8 @@ describe("toBeGreaterThan", function() {
});
it("fails when actual <= expected", function() {
var matcher = j$.matchers.toBeGreaterThan();
var matcher = j$.matchers.toBeGreaterThan(),
result;
result = matcher.compare(1, 1);
expect(result.pass).toBe(false);

View File

@@ -9,7 +9,8 @@ describe("toBeNaN", function() {
});
it("fails for anything not a NaN", function() {
var matcher = j$.matchers.toBeNaN();
var matcher = j$.matchers.toBeNaN(),
result;
result = matcher.compare(1);
expect(result.pass).toBe(false);
@@ -31,6 +32,6 @@ describe("toBeNaN", function() {
var matcher = j$.matchers.toBeNaN(),
result = matcher.compare(0);
expect(result.message).toEqual("Expected 0 to be NaN.");
expect(result.message()).toEqual("Expected 0 to be NaN.");
});
});

View File

@@ -9,7 +9,8 @@ describe("toBeUndefined", function() {
});
it("fails when matching defined values", function() {
var matcher = j$.matchers.toBeUndefined();
var matcher = j$.matchers.toBeUndefined(),
result;
result = matcher.compare('foo');
expect(result.pass).toBe(false);

View File

@@ -3,7 +3,8 @@ describe("toContain", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
matcher = j$.matchers.toContain(util);
matcher = j$.matchers.toContain(util),
result;
result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", []);
@@ -15,7 +16,8 @@ describe("toContain", function() {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
customEqualityTesters = ['a', 'b'],
matcher = j$.matchers.toContain(util, customEqualityTesters);
matcher = j$.matchers.toContain(util, customEqualityTesters),
result;
result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", ['a', 'b']);

View File

@@ -13,7 +13,8 @@ describe("toHaveBeenCalled", function() {
it("fails when the actual was not called", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
uncalledSpy = j$.createSpy('uncalled spy');
uncalledSpy = j$.createSpy('uncalled spy'),
result;
result = matcher.compare(uncalledSpy);
expect(result.pass).toBe(false);

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