Compare commits

..

152 Commits

Author SHA1 Message Date
Steve Gravrock
98c2f019c6 Bump version to 4.0.0 2022-01-01 12:43:29 -08:00
Steve Gravrock
507dad6d87 Set -npm and -browser-runner dev dependencies back to main 2022-01-01 12:10:24 -08:00
Steve Gravrock
6da7a32442 Merge branch '4.0' 2022-01-01 12:00:46 -08:00
Steve Gravrock
58d13570ac Bump version to 3.99.0 2022-01-01 10:47:59 -08:00
Steve Gravrock
005648acd8 Built distribution 2022-01-01 10:46:15 -08:00
Steve Gravrock
ff14c03a40 Test against the latest Node 12 2022-01-01 08:44:28 -08:00
Steve Gravrock
ff848c812a Merge branch 'main' into 4.0 2021-12-31 15:07:03 -08:00
Steve Gravrock
d963be5eec Log a deprecation warning on reentrant calls to Clock#tick
See #1929
2021-12-31 11:38:01 -08:00
Steve Gravrock
8444faab72 Use the clock from jasmineUnderTest in specs 2021-12-31 10:00:14 -08:00
Steve Gravrock
883f400074 Merge branch '4.0' of https://github.com/thw0rted/jasmine into 4.0
* Fixes handling of reentrant calls to `jasmine.clock().tick()`
* Merges #1948 from @thw0rted
* Fixes #1929
2021-12-31 09:50:09 -08:00
Steve Gravrock
3c16caa413 Link to the CONTRIBUTING guide from the PR template 2021-12-31 09:47:46 -08:00
Steve Gravrock
5d0be2e6cf Updated the contributing guide for 4.0
* Moved "Before Submitting a Pull Request" to the top
* Removed discussion of the standard Github PR workflow
  (Contributors who don't know how to create PRs on Github at all can find
  that information elsewhere. For the rest, it's just noise.)
* Misc copy edits
2021-12-31 09:43:46 -08:00
James Bromwell
c56631175f Fix time-travel in delayed function scheduler 2021-12-29 17:50:48 +01:00
Steve Gravrock
cef738966c Updated dev dependencies 2021-12-21 17:51:28 -08:00
Steve Gravrock
5fd0e49ccf Removed unused ejs dev dependency 2021-12-21 17:00:10 -08:00
Steve Gravrock
c431590d65 Fixed reporting of suites that are skipped due to a beforeAll failure 2021-12-20 13:39:24 -08:00
Steve Gravrock
656e6614da Built distribution 2021-12-15 20:36:44 -08:00
Steve Gravrock
24408a16ed Removed initialization of unused Promise config property 2021-12-15 20:34:00 -08:00
Steve Gravrock
ca90c76d12 Merge branch '3.99' into 4.0 2021-12-14 08:27:05 -08:00
Steve Gravrock
57c294b307 Added a migration guide link to multiple done call deprecations 2021-12-14 08:16:06 -08:00
Steve Gravrock
e73eb18753 Test against jasmine-browser-runner 1.0.0-dev 2021-12-13 21:41:09 -08:00
Steve Gravrock
0411b0567d Added a mention of 4.0 migration to the README 2021-12-11 16:13:51 -08:00
Steve Gravrock
30b93ccdbb Updated jsdocs for Env#execute 2021-12-11 15:53:25 -08:00
Steve Gravrock
067b91b3ef Removed IE/PhantomJS support code 2021-12-11 14:57:41 -08:00
Steve Gravrock
0b1385c3d3 Report start and end events for specs/suites that are skipped due to a beforeAll error
This is noisier, but it maintains compatibility with reporters that assume
(quite reasonably) that all specs and suites are either filtered out or
reported.
2021-12-11 12:34:23 -08:00
Steve Gravrock
f1cf6ee419 Resolve the execute() promise to the entire JasmineDoneInfo
This matches jasmine-npm.
2021-12-09 18:18:36 -08:00
Steve Gravrock
b37d989f13 Removed past-EOL Firefox versions 2021-12-07 18:16:00 -08:00
Steve Gravrock
89151d6e64 Dropped Safari 13 from build matrix 2021-12-07 17:04:19 -08:00
Steve Gravrock
75e3e14861 Merge remote-tracking branch 'upstream/safari-15' into 4.0 2021-12-07 17:03:40 -08:00
Steve Gravrock
ce7460d8d4 Fixed stack trace filtering on Safari 15 2021-12-07 16:50:07 -08:00
Steve Gravrock
b8dabf96ff HTML: Include top suite failures in the reported failure count 2021-12-03 08:18:18 -08:00
Steve Gravrock
40fac8b6a2 Renamed the trace feature to debugLog[s]
"trace" was ambiguous and could easily be understood to have something
to do with stack traces.
2021-12-02 14:46:56 -08:00
Steve Gravrock
5eb42d67a7 Added a note about async testing style to contributing guide 2021-12-02 12:40:14 -08:00
Steve Gravrock
d739c23401 Resolve the promise returned by Env#execute to the overall status 2021-12-02 12:40:14 -08:00
Steve Gravrock
42e6c45efa Allow use without creating globals
* Fixes #1235
2021-11-29 20:37:07 -08:00
Steve Gravrock
5942654856 Merge branch '3.99' into 4.0 2021-11-26 13:27:57 -08:00
Steve Gravrock
f3b26a0688 Merge branch 'main' into 3.99 2021-11-26 13:25:14 -08:00
Steve Gravrock
8804ddb8cf Updated boot file lists for the Ruby gem and Python egg
This prevents consumers that rely on those lists (especially the Jasmine
gem and egg) from getting a deprecation warning about boot.js.
2021-11-24 15:38:40 -08:00
Steve Gravrock
439be97c34 Rephrased note about verboseDeprecations 2021-11-24 11:45:32 -08:00
Steve Gravrock
871ba99a30 Allow custom spy strategies to be inherited like other runnable resources 2021-11-17 12:50:16 -08:00
Steve Gravrock
7a685b16f6 Removed duplicate message from errors (incl. matcher failures) on V8 2021-11-16 12:52:07 -08:00
Steve Gravrock
2a049015b0 Use custom equality testers in Spy#withArgs
Fixes #1836.
2021-11-15 18:55:09 -08:00
Steve Gravrock
c48fb0b0e7 Added Firefox 91 (current ESR) to CI matrix 2021-11-14 14:18:06 -08:00
Steve Gravrock
4c47bf6c0b Merge branch '3.10.1' into main 2021-10-22 16:34:57 -07:00
Steve Gravrock
2a39339755 Merge branch 'fix/pending-reason' of https://github.com/jan-molak/jasmine into main
* Fixes missing pendingReason in pending spec results
	* Fixes #1939
	* Merges #1940 from @jan-molak
2021-10-22 14:09:48 -07:00
Jan Molak
2c440b8e44 Fixed result.pendingReason for specs marked with xit. Closes #1939 2021-10-22 17:58:31 +01:00
Steve Gravrock
8e74529631 Merge branch '3.99' into 4.0 2021-10-15 10:37:51 -07:00
Steve Gravrock
b13329114c Set version to 3.99.0-dev 2021-10-15 10:33:21 -07:00
Steve Gravrock
ab34f272da Merge branch 'main' into 3.99 2021-10-15 10:29:50 -07:00
Steve Gravrock
1af0e62ef7 Revert "Revert "Dogfood the new jasmine-npm completion interface""
This reverts commit 4c043717a9.
2021-10-14 07:07:10 -07:00
Steve Gravrock
c1db8f2f82 Clarified deprecation message for this in describes 2021-10-12 15:40:13 -07:00
Steve Gravrock
41f5c53959 Consistently identify clenaup fns by a type tag, not position
This was already done for everything except spec cleanup fns, since the
various skip policies need to know the difference between afterEach and
afterAll.
2021-10-11 18:05:57 -07:00
Steve Gravrock
25c3f06839 Run afterAll fns after failure even if stopOnSpecFailure is true
[#160905297]
2021-10-08 14:19:56 -07:00
Steve Gravrock
976928c7ae Set version to 4.0.0-pre.0 2021-10-08 08:48:22 -07:00
Steve Gravrock
36a4ddf433 Revert "Removed jsdoc entry for SpecResult#trace"
This reverts commit 4482355885.
2021-10-07 10:56:52 -07:00
Steve Gravrock
53b1cd37b6 Merge branch '3.99' into 4.0 2021-10-07 10:56:41 -07:00
Steve Gravrock
8cadfbd829 Fixed deprecation warning in spec 2021-10-07 10:51:06 -07:00
Steve Gravrock
86aeb5c88a Merge branch 'main' into 3.99 2021-10-07 10:38:35 -07:00
Steve Gravrock
d4c15b8df4 No longer test Node <12.17 2021-10-06 17:58:28 -07:00
Steve Gravrock
6f0c51260f Depend on the 4.0 branch of -npm 2021-10-06 17:54:54 -07:00
Steve Gravrock
15710937b8 Added a test that verifies skip to cleanup fns after pending()
Because pending() is implemented via the standard exception handling
path, we effectively got this feature for free as a result of the changes
for #1533, particularly 457a2727.

* [#178598493]
* Fixes #1579
2021-10-06 11:07:53 -07:00
Steve Gravrock
1a9d16715d Clarify which behaviors are specific to different stopSpecOnExpectationFailure values
* #1533
2021-10-06 08:55:01 -07:00
Steve Gravrock
b67a3043c7 Skip afterEach fns in nested suites when a beforeEach fn errors
This matches the behavior of beforeAll errors.

* #1533
2021-10-06 08:55:01 -07:00
Steve Gravrock
5f1ef5ac2b Skip everything except afterAll fns when a beforeAll fn errors
* Fixes #1533
2021-10-06 08:55:01 -07:00
Steve Gravrock
5eaeeb0b6c Moved fn skipping policy out of QueueRunner
This should allow us to more easily support complex skipping strategies
like skipping nested cleanup fns when the corresponding befores were
skipped, or skipping specs and suites when a beforeAll fails.

* #1533
2021-10-06 08:55:01 -07:00
Steve Gravrock
457a2727ba Skip to afterEach fns when a beforeEach fn errors
* #1533
2021-10-06 08:55:01 -07:00
Steve Gravrock
a1f14efac6 Improved specs for stopSpecOnExpectationFailure
* #1533
2021-10-06 08:55:01 -07:00
Steve Gravrock
b2067d9ce0 Fixed references to Env#trace in jsdocs 2021-10-02 09:58:47 -07:00
Steve Gravrock
47081258cd Revert "Revert "Added the ability to associate trace information with failing specs""
This reverts commit fdad8849df.
2021-10-02 09:56:25 -07:00
Steve Gravrock
9c03d4d3e9 Merge branch '3.99' into 4.0 2021-10-02 09:52:43 -07:00
Steve Gravrock
7f0087b805 Merge branch 'main' into 3.99 2021-10-02 09:47:30 -07:00
Steve Gravrock
35064cf60e Merge branch '3.99' into 4.0 2021-09-24 14:31:02 -07:00
Steve Gravrock
fb4c16b23e Merge branch 'main' into 3.99 2021-09-24 14:27:15 -07:00
Steve Gravrock
3b28ee7c29 Fixed extra deprecation when passing custom equality testers to MatchersUtil#contains 2021-09-24 14:25:54 -07:00
Steve Gravrock
3a77ae3dfe Throw if the argument to jasmine.clock().mockDate() is not a Date 2021-09-23 16:10:59 -07:00
Steve Gravrock
1332f01ca4 Merge branch '3.99' into 4.0 2021-09-23 16:08:44 -07:00
Steve Gravrock
64d58ed1f0 Deprecate non-Date arguments to jasmine.clock().mockDate() 2021-09-23 16:04:39 -07:00
Steve Gravrock
497a7fc3e5 Merge branch 'main' into 3.99 2021-09-23 15:49:47 -07:00
Steve Gravrock
8d302d8dca Merge branch '3.99' into 4.0 2021-09-20 15:57:37 -07:00
Steve Gravrock
760f2d9003 Removed additional Ruby support files 2021-09-18 09:40:30 -07:00
Steve Gravrock
6e10f22403 Don't display late errors as AfterAll errors in the HTML reporter 2021-09-11 08:57:50 -07:00
Steve Gravrock
d092a59bd1 Treat multiple calls to done callbacks as errors 2021-09-10 18:07:35 -07:00
Steve Gravrock
af5984d5d6 Fixed flake list 2021-09-10 17:53:59 -07:00
Steve Gravrock
15f7013f85 Merge branch '3.99' into 4.0 2021-09-08 21:04:10 -07:00
Steve Gravrock
be23836c9d Deprecate multiple calls to done callbacks 2021-09-08 20:58:25 -07:00
Steve Gravrock
7944250290 Merge branch 'main' into 3.99 2021-09-06 17:39:28 -07:00
Steve Gravrock
bbcb5ff42f Fixed linter & formatter issues in boot files 2021-09-03 15:46:23 -07:00
Steve Gravrock
6603ed7ddc Don't distribute boot src files
[#179017951]
2021-09-03 15:42:06 -07:00
Steve Gravrock
d61800c5c8 Removed support for custom promise libraries
All supported platforms now provide promises, so there's no longer a need
for Jasmine to be able to create them via a user-provided library. Jasmine
can still consume non-native promises but will always use the built-in
Promise object to create promises.

[#179078103]
2021-08-30 19:07:26 -07:00
Steve Gravrock
37b9f8e420 Removed Ruby support
[#179247162]
2021-08-30 18:53:13 -07:00
Steve Gravrock
a63b0b0368 Merge branch '3.99' into 4.0 2021-08-30 18:44:32 -07:00
Steve Gravrock
de9815f436 Merge branch 'main' into 3.99 2021-08-30 18:41:02 -07:00
Steve Gravrock
2fd9d7b13f Merge branch 'main' into 3.99 2021-08-17 17:08:34 -07:00
Steve Gravrock
4e96514634 Deprecated the Promise config setting
4.0 will only support environments that have native promises, so there will
no longer be a need for a user-supplied promise library
2021-08-07 12:04:14 -07:00
Steve Gravrock
d8862aa583 Removed the failFast and oneFailurePerSpec config properties 2021-07-31 09:28:14 -07:00
Steve Gravrock
2480a0a93a Merge branch '3.99' into 4.0 2021-07-31 09:15:12 -07:00
Steve Gravrock
9c9836c5b3 Don't use deprecated config prooperties in boot*.js 2021-07-31 09:09:46 -07:00
Steve Gravrock
20b914c554 Deprecated the failFast and oneFailurePerSpec config properties 2021-07-31 08:42:01 -07:00
Steve Gravrock
058e77b824 Merge branch 'main' into 3.99 2021-07-31 08:15:29 -07:00
Steve Gravrock
13dfcacbb0 Remove access to non-public properties of suites and specs returned by describe, it, etc.
[#179064612]
2021-07-30 17:36:50 -07:00
Steve Gravrock
6d002d22af Merge branch '3.99' into 4.0 2021-07-29 21:46:48 -07:00
Steve Gravrock
799d9897fd Deprecated access to non-public members in specs and suites returned from it(), describe(), etc. 2021-07-29 21:28:47 -07:00
Steve Gravrock
2a2a671b65 Don't deprecate access to Suite#id and Spec#id 2021-07-29 20:15:04 -07:00
Steve Gravrock
a0b4f3748d Merge branch 'main' into 3.99 2021-07-29 20:09:25 -07:00
Steve Gravrock
09d2ce9bc9 Removed more code that supported browsers we no longer run on 2021-07-27 17:53:09 -07:00
Steve Gravrock
e9bddc7a06 Removed obsolete timing function hacks from boot1.js 2021-07-26 19:04:43 -07:00
Steve Gravrock
310e4d5e6c Removed legacy boot.js file 2021-07-26 18:29:54 -07:00
Steve Gravrock
0424d4ae99 Removed Python support 2021-07-26 18:28:38 -07:00
Steve Gravrock
0720c88252 Merge branch '3.99' into 4.0 2021-07-26 18:20:24 -07:00
Steve Gravrock
f26b005807 Deprecated the legacy boot.js file 2021-07-26 18:20:07 -07:00
Steve Gravrock
1206952ca6 Merge branch 'main' into 3.99 2021-07-26 18:19:11 -07:00
Steve Gravrock
c73df57720 MatchersUtil#contains uses deep equality rather than === for set members
[#169001712]
2021-07-24 14:23:05 -07:00
Steve Gravrock
0170005015 Treat any argument to the done callback as an error
This reduces the risk of incorrectly passing a spec due to not correctly
detecting that an argument is an `Error` instance. Detecting Error instances
in a way that's reliable and portable across different browsers, TrustedTypes,
and frames is difficult.

[Finishes #178267587]
2021-07-24 09:30:39 -07:00
Steve Gravrock
6f04044417 Merge branch '3.99' into 4.0 2021-07-24 09:25:19 -07:00
Steve Gravrock
70d49e5b57 Deprecate non-Error arguments passed to done()
[Finishes #178267600]
2021-07-24 09:18:24 -07:00
Steve Gravrock
ed9363f477 Removed bower.json
Bower itself has been deprecated for four years, so we should drop support
for it in 4.0.

[Finishes #178512921]
2021-07-24 08:23:09 -07:00
Steve Gravrock
fe0a83ba87 Removed support for Internet Explorer 2021-07-23 21:46:15 -07:00
Steve Gravrock
623eecdcec Removed json2.js
Environments that don't provide a JSON parser are ancient history.
2021-07-22 21:37:57 -07:00
Steve Gravrock
a27280e9e7 Merge branch '3.99' into 4.0 2021-07-20 17:55:18 -07:00
Steve Gravrock
10601f5af6 Merge branch 'main' into 3.99 2021-07-20 17:47:17 -07:00
Steve Gravrock
c10ab4e704 Updated deprecation links 2021-07-20 16:50:31 -07:00
Steve Gravrock
e399953174 Removed obsolete timing function hacks from boot.js 2021-07-17 17:49:53 -07:00
Steve Gravrock
4edac7d3d1 Dropped Safari <13 from test matrix 2021-07-10 09:21:41 -07:00
Steve Gravrock
9b3d4a2bf2 Merge branch '3.99' into 4.0 2021-07-10 09:13:28 -07:00
Steve Gravrock
17826cd044 Fixed deprecations in matchersUtilSpec 2021-07-10 09:11:10 -07:00
Steve Gravrock
6cb9507f62 Merge branch 'main' into 3.99 2021-07-10 08:58:14 -07:00
Steve Gravrock
a0f6b77c3e Remove access to non-public Suite and Spec members via Env#topSuite 2021-05-29 18:57:56 -07:00
Steve Gravrock
3f3fb38cf1 Merge branch '3.99' into 4.0 2021-05-29 18:42:31 -07:00
Steve Gravrock
00c1e3d608 Deprecate access to non-public Suite and Spec members via Env#topSuite
The deprecation warning relies on Proxy, and won't work in environments
that don't have it. Among Jasmine's supported environments, that's Safari 9,
Safari 8, and all versions of IE.
2021-05-29 15:45:10 -07:00
Steve Gravrock
6a2a30d540 Improved & unified deprecation handling
* De-duplication now happens in core, not in reporters. This ensures that
  the console doesn't get flooded.
* Stack traces are opt-out, not opt-in.
* The current runnable is not reported or logged for certain deprecations
  where it's irrelevant.
* HtmlReporter shows stack traces in expandable widgets.
* Env#deprecated and Env#deprecatedOnceWithStack are merged.
2021-05-29 15:39:28 -07:00
Steve Gravrock
e4e232864d Don't expose Suite objects as this of describe functions
This was a holdover from 1.x that should have been removed in 2.0,
but was missed. Suite is meant to be private, and almost none of
its methods can be safely called by user code.
2021-05-22 09:15:22 -07:00
Steve Gravrock
5acddcda4a Merge branch '3.99' into 4.0 2021-05-22 09:09:03 -07:00
Steve Gravrock
61fb353197 Deprecate access to Suite objects via this in describes
Jasmine 1.x exposed Suite objects to user code as the `this` in describe
functions. That should have been removed in 2.0 but it was missed. It
will be removed in 4.0. This change adds a deprecation warning if anything
on a describe's `this` is accessed.

The deprecation warning relies on Proxy, and won't work in environments
that don't have it. Among Jasmine's supported environments, that's Safari 9,
Safari 8, and all versions of IE. In those browsers, a describe's `this`
will still be a Suite for now, but there will be no deprecation warnings.
2021-05-22 09:07:31 -07:00
Steve Gravrock
752441a66f Merge branch '3.99' into 4.0 2021-05-18 17:12:29 -07:00
Steve Gravrock
3e2872a1df Merge branch 'main' into 3.99 2021-05-18 17:07:34 -07:00
Steve Gravrock
1b97795684 Merge branch '3.99' into 4.0 2021-04-23 08:41:12 -07:00
Steve Gravrock
5504965bea Merge branch 'main' into 3.99 2021-04-23 08:40:25 -07:00
Steve Gravrock
c2a714f168 Removed support for IE 10 and Safari 8 2021-04-23 08:14:19 -07:00
Steve Gravrock
c2b558a2da Fail specs that try to combine two forms of async 2021-04-22 22:44:37 -07:00
Steve Gravrock
235efe52f1 Fixed test failure in IE 2021-04-22 22:43:48 -07:00
Steve Gravrock
1e8619df88 Removed deprecated env methods 2021-04-22 22:38:08 -07:00
Steve Gravrock
4b2a14f1f3 Removed deprecated custom matcher, matchersUtil, pp, etc interfaces 2021-04-22 22:29:20 -07:00
Steve Gravrock
66189d742b Merge branch 'no-children' of https://github.com/johnjbarton/jasmine into 4.0
* Merges #1742 from @johnjbarton
2021-04-22 21:35:58 -07:00
Steve Gravrock
fb05da1fc3 Merge branch 'main' into 3.99 2021-04-22 17:23:08 -07:00
Steve Gravrock
8b3a6561b1 Merge branch 'main' into 3.99 2021-04-02 11:35:30 -07:00
Steve Gravrock
7a38db2e32 Fixed deprecations triggered from within asymmetricEqualityTesterArgCompatShim 2020-09-17 13:26:35 -07:00
Steve Gravrock
a1f1b4ae0f Merge branch 'main' into 3.99 2020-09-14 18:39:32 -07:00
Steve Gravrock
c39c110eca Deprecate describes with no children 2020-02-12 16:44:44 -08:00
Steve Gravrock
18b2646d1d Allow libraries to avoid "Passing custom equality testers to MatchersUtil#contains is deprecated" while remaining compatible with older jasmine versions
Previously, a custom matcher library that wanted to remain compatible with
Jasmine <= 3.5.x could not know whether or not Jasmine expected it to pass
custom equality testers to MatchersUtil#contains. Passing them would produce
a deprecation warning in newer versions and not passing them would break
compatibility with older versions. Now we use matcher factory arity to
determine whether to pass custom equality testers to the factory, which
allows libraries to do something like this:

function matcherFactory(util) {
   const customEqualityTesters = arguments[1];
   // customEqualityTesters will be undefined in newer versions of Jasmine
   // and defined in older versions that expect it to be passed back to
   // MatchersUtil#equals.
}
2020-02-12 15:24:43 -08:00
Steve Gravrock
9aed55bb91 Improved readability of matcher-related deprecations
* Include stack traces. This makes it easier to find the matcher that
needs to be updated, particularly when it comes from a library rather
than the user's own code.

* Show each deprecation only once unless `config.verboseDeprecations`
is set. Since matchers are often added in a global `beforeEach`, logging
deprecations every time can be overwhelming.
2020-02-12 15:24:43 -08:00
Steve Gravrock
90d6f9d73c Added deprecation messages to interfaces that will be removed in 4.0
* `jasmine.pp`
* `jasmine.matchersUtil`
* Matchers that expect to receive custom equality testers
* Passing custom equality testers to `matchersUtil.contains`
* Passing custom equality testers to `matchersUtil.equals`
2020-02-12 15:24:42 -08:00
johnjbarton
2369c8dba7 fix(env): Throw if nested describe has no children.
Users would like an error if it() is acciddently moved within a before/afterEach/All function.
The it() function calls ensureIsNotNested to report such an error. But if the user has no
other it() functions in the Suite, it() and thus ensureIsNotNested() is never called.

Here we check nested Suites for children; if none are found we throw.
2019-08-07 18:01:34 -07:00
148 changed files with 5591 additions and 4940 deletions

View File

@@ -15,13 +15,13 @@ executors:
docker:
- image: circleci/node:14
working_directory: ~/workspace
node12:
node12_latest:
docker:
- image: circleci/node:12
- image: circleci/node:12
working_directory: ~/workspace
node10:
node12_17:
docker:
- image: circleci/node:10
- image: circleci/node:12.17
working_directory: ~/workspace
jobs:
@@ -116,26 +116,26 @@ workflows:
executor: node14
name: build_node_14
- build:
executor: node12
name: build_node_12
executor: node12_latest
name: build_node_12_latest
- build:
executor: node10
name: build_node_10
executor: node12_17
name: build_node_12_17
- test_node:
executor: node16
name: test_node_16
requires:
- build_node_16
- test_node:
executor: node12
name: test_node_12
executor: node12_latest
name: test_node_12_latest
requires:
- build_node_12
- build_node_12_latest
- test_node:
executor: node10
name: test_node_10
executor: node12_17
name: test_node_12_17
requires:
- build_node_10
- build_node_12_17
- test_browsers:
requires:
- build_node_14
@@ -152,11 +152,11 @@ workflows:
executor: node14
name: build_node_14
- build:
executor: node12
name: build_node_12
executor: node12_latest
name: build_node_12_latest
- build:
executor: node10
name: build_node_10
executor: node12_17
name: build_node_12_17
- test_node:
executor: node16
name: test_node_16
@@ -168,15 +168,15 @@ workflows:
requires:
- build_node_14
- test_node:
executor: node12
name: test_node_12
executor: node12_latest
name: test_node_12_latest
requires:
- build_node_12
- build_node_12_latest
- test_node:
executor: node10
name: test_node_10
executor: node12_17
name: test_node_12_17
requires:
- build_node_10
- build_node_12_17
- test_browsers:
requires:
- build_node_14

View File

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

View File

@@ -12,24 +12,23 @@ should have enough detail to get started.
- [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)
- [Jasmine backlog](https://www.pivotaltracker.com/n/projects/10606)
## General Workflow
## Before Submitting a Pull Request
Please submit pull requests via feature branches using the semi-standard workflow of:
1. Ensure all specs are green in browsers *and* node.
* Use `npm test` to test in Node.
* Use `npm run serve` to test in browsers.
2. Fix any eslint or prettier errors reported at the end of `npm test`. Prettier
errors can be automatically fixed by running `npm run cleanup`.
3. Build `jasmine.js` with `npm run build` and run all specs again. This
ensures that your changes self-test well.
5. Revert your changes to `jasmine.js` and `jasmine-html.js`. When we accept
your pull request, we will generate these files as a separate commit and
merge the entire branch into master.
```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 # Fetch changes not present in your local repository
git merge upstream/main # Sync local main with upstream repository
git checkout -b my-new-feature # Create your feature branch
git commit -am 'Add some feature' # Commit your changes
git push origin my-new-feature # Push to the branch
```
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.
We only accept green pull requests. If you see that the CI build failed, please
fix it. Feel free to ask for help if you're stuck.
## Background
@@ -38,15 +37,16 @@ Once you've pushed a feature branch to your forked repo, you're ready to open a
* `/src` contains all of the source files
* `/src/core` - generic source files
* `/src/html` - browser-specific files
* `/src/boot` - sources for boot files (see below)
* `/spec` contains all of the tests
* mirrors the source directory
* there are some additional files
* `/lib` contains the compiled copy of Jasmine. This is used to self-test and
distributed as the `jasmine-core` Node, Ruby, and Python packages.
distributed as the `jasmine-core` Node, and Ruby packages.
### Self-testing
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `jasmineUnderTest`. So there are two copies of the code loaded under test.
Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `jasmineUnderTest`. So there are two copies of the code loaded under test.
The tests should always use `jasmineUnderTest` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
@@ -60,9 +60,8 @@ is appropriate for browsers, projects may wish to customize this file.
### Compatibility
Jasmine runs in both Node and browsers, including some older browsers that do
not support the latest JavaScript features. See the README for the list of
currently supported environments.
Jasmine runs in both Node and a variety of browsers. See the README for the
list of currently supported environments.
## Development
@@ -88,51 +87,35 @@ Or, How to make a successful pull request
* _Do not change the public interface_. Lots of projects depend on Jasmine and
if you aren't careful you'll break them.
* _Be environment agnostic_ - server-side developers are just as important as
browser developers.
* _Be environment agnostic_. Some people run their specs in browsers, others in
Node. Jasmine should support them all as much as possible.
* _Be browser agnostic_ - if you must rely on browser-specific functionality,
please write it in a way that degrades gracefully.
* _Write specs_ - Jasmine's a testing framework. Don't add functionality
without test-driving it.
* _Write code in the style of the rest of the repo_ - Jasmine should look like
a cohesive whole.
Key exceptions:
* Use `const` or `let` for new variable declarations, even if nearby code
uses `var`.
* New async specs should usually be async/await or promise-returning, not
callback based.
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and
ESLint. Your contribution shouldn't break Jasmine for other users.
ESLint/Prettier. Your contribution shouldn't break Jasmine for other users.
Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated.
### Running Specs
Be sure to run the tests in at least one supported Node version and at least a
couple of supported browsers. It's also a good idea to run the tests in Internet
Explorer if you've touched code in `src/html`, if your change involves newer
JavaScript language/runtime features, or if you're unfamiliar with writing code
for older browsers. To run the tests in Node, simply use `npm test` as described
above. To run the tests in a browser, run `npm run serve` and then visit
`http://localhost:8888`.
couple of supported browsers. To run the tests in Node, simply use `npm test`
as described above. To run the tests in a browser, run `npm run serve` and then
visit `http://localhost:8888`.
If you have the necessary Selenium drivers installed, you can also use Jasmine's
CI tooling:
If you have the necessary Selenium drivers installed (e.g. geckodriver or
chromedriver), you can also use Jasmine's CI tooling:
$ JASMINE_BROWSER=<name of browser> node spec/support/ci.js
The easiest way to run the tests in **Internet Explorer** is to run a VM that has IE installed. It's easy to do this with VirtualBox.
1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
1. Download a VM image [from Microsoft](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/). Select "VirtualBox" as the platform.
1. Unzip the downloaded archive. There should be an OVA file inside.
1. In VirtualBox, choose `File > Import Appliance` and select the OVA file. Accept the default settings in the dialog that appears. Now you have a Windows VM!
1. Run the VM and start IE.
1. With `npm run serve` running on your host machine, navigate to `http://<your IP address>:8888` in IE.
## Before Committing or Submitting a Pull Request
1. Ensure all specs are green in browser *and* node.
1. Ensure eslint and prettier are clean as part of your `npm test` command. You can run `npm run cleanup` to have prettier re-write the files.
1. Build `jasmine.js` with `npm run build` and run all specs again - this ensures that your changes self-test well.
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
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into main
Note that we use Circle CI for Continuous Integration. We only accept green pull requests.
$ JASMINE_BROWSER=<name of browser> npm run ci

View File

@@ -24,7 +24,7 @@
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the **CONTRIBUTING** document.
- [ ] I have read the [**CONTRIBUTING**](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md) guide.
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.

2
.gitignore vendored
View File

@@ -17,11 +17,9 @@ pkg/*
.sass-cache/*
src/html/.sass-cache/*
node_modules/
*.pyc
sauce_connect.log
*.swp
build/
*.egg-info/
dist
nbproject/
*.iml

1
.rspec
View File

@@ -1 +0,0 @@
--color

View File

@@ -1,2 +0,0 @@
source 'https://rubygems.org'
gemspec

View File

@@ -16,12 +16,6 @@ module.exports = function(grunt) {
grunt.registerTask('default', ['sass:dist', "cssUrlEmbed"]);
var version = require('./grunt/tasks/version.js');
grunt.registerTask('build:copyVersionToGem',
"Propagates the version from package.json to version.rb",
version.copyToGem);
grunt.registerTask('buildDistribution',
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
[
@@ -34,17 +28,21 @@ module.exports = function(grunt) {
grunt.registerTask("execSpecsInNode",
"Run Jasmine core specs in Node.js",
function() {
var done = this.async(),
verifyNoGlobals(() => require('./lib/jasmine-core.js').noGlobals());
const 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();
jasmine.exitOnCompletion = false;
jasmine.execute().then(
result => done(result.overallStatus === 'passed'),
err => {
console.error(err);
exit(1);
}
);
}
);
@@ -55,3 +53,14 @@ module.exports = function(grunt) {
}
);
};
function verifyNoGlobals(fn) {
const initialGlobals = Object.keys(global);
fn();
const extras = Object.keys(global).filter(k => !initialGlobals.includes(k));
if (extras.length !== 0) {
throw new Error('Globals were unexpectedly created: ' + extras.join(', '));
}
}

View File

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

View File

@@ -11,6 +11,9 @@ Jasmine is a Behavior Driven Development testing framework for JavaScript. It do
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
For a quick start guide of Jasmine, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html).
Upgrading from Jasmine 3.x? Check out the 4.0 release notes for a list of
what's new (including breaking changes). You can also read the [upgrade guide](https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0).
## Contributing
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md).
@@ -23,9 +26,6 @@ For the Jasmine NPM module:<br>
For the Jasmine browser runner:<br>
[https://github.com/jasmine/jasmine-browser](https://github.com/jasmine/jasmine-browser).
For the Jasmine Ruby Gem:<br>
[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem).
To install Jasmine standalone on your local box (where **_{#.#.#}_** below is substituted by the release number downloaded):
* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases).
@@ -47,21 +47,24 @@ Add the following to your HTML file:
## Supported environments
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, Microsoft Edge, and Internet Explorer) as well as nodejs.
Jasmine tests itself across popular browsers (Safari, Chrome, Firefox, and
Microsoft Edge) as well as nodejs.
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 10, 12, 14, 16 |
| Safari | 8-14 |
| Node | 12.17+, 14, 16 |
| Safari | 14-15 |
| Chrome | Evergreen |
| Firefox | Evergreen, 68, 78 |
| Firefox | Evergreen, 91 |
| Edge | Evergreen |
| Internet Explorer | 10, 11 |
For evergreen browsers, each version of Jasmine is tested against the version of the browser that is available to us
at the time of release. Other browsers, as well as older & newer versions of some supported browsers, are likely to work.
However, Jasmine isn't tested against them and they aren't actively supported.
See the [release notes](https://github.com/jasmine/jasmine/tree/main/release_notes)
for the supported environments for each Jasmine release.
## Support
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js).

View File

@@ -13,13 +13,14 @@ Please attempt to keep commits to `main` small, but cohesive. If a feature is co
We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` 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.
The current version lives in the file `/package.json`. This version will be
copied to `jasmine.js` when the distribution is built. When releasing a new
version, update `package.json` with the new version and `npm run build` to
update the gem version number.
Note that Jasmine should only use the "patch" version number in the following cases:
* Changes related to packaging for a specific platform (npm, gem, or pip).
* Changes related to packaging for a specific binding library (npm or browser-runner)
* Fixes for regressions.
When jasmine-core revs its major or minor version, the binding libraries should also rev to that version.
@@ -31,7 +32,6 @@ 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. Include a list of supported environments.
1. Update the version in `package.json`
1. Run `npm run build`.
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
### Commit and push core changes
@@ -45,18 +45,6 @@ When ready to release - specs are all green and the stories are done:
1. Build the standalone distribution with `grunt buildStandaloneDist`
1. This will generate `dist/jasmine-standalone-<version>.zip`, which you will upload later (see "Finally" below).
### Release the core Ruby gem
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release. See below.
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
### Release the core Python egg
Install [twine](https://github.com/pypa/twine)
1. `python setup.py sdist`
1. `twine upload dist/jasmine-core-<version>.tar.gz` You will need pypi credentials to upload the egg.
### Release the core NPM module
1. Run the tests on Windows. (CI only tests on Linux.)
@@ -83,15 +71,6 @@ Probably only need to do this when releasing a minor version, and not a patch ve
1. Run the tests on Windows locally.
1. `grunt release `. (Note: This will publish the package by running `npm publish`.)
#### Gem
1. Create release notes using Anchorman as above
1. Update the version number in `lib/jasmine/version.rb`.
1. Update the jasmine-core dependency version in `jasmine.gemspec`.
1. Commit and push.
1. Wait for Circle CI to go green again.
1. `rake release`
### Finally
For each of the above GitHub repos:

View File

@@ -1,2 +0,0 @@
require "bundler"
Bundler::GemHelper.install_tasks

View File

@@ -1,40 +0,0 @@
{
"name": "jasmine-core",
"homepage": "https://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"
]
}

View File

@@ -32,7 +32,7 @@ module.exports = {
src: [ "boot0.js", "boot1.js" ],
dest: standaloneLibDir,
expand: true,
cwd: libJasmineCore("boot")
cwd: libJasmineCore("")
},
{
src: [ "SpecRunner.html" ],

View File

@@ -37,20 +37,16 @@ module.exports = {
],
dest: 'lib/jasmine-core/jasmine.js'
},
boot: {
src: ['lib/jasmine-core/boot/boot.js'],
dest: 'lib/jasmine-core/boot.js'
},
boot0: {
src: ['lib/jasmine-core/boot/boot0.js'],
src: ['src/boot/boot0.js'],
dest: 'lib/jasmine-core/boot0.js'
},
boot1: {
src: ['lib/jasmine-core/boot/boot1.js'],
src: ['src/boot/boot1.js'],
dest: 'lib/jasmine-core/boot1.js'
},
nodeBoot: {
src: ['lib/jasmine-core/boot/node_boot.js'],
src: ['src/boot/node_boot.js'],
dest: 'lib/jasmine-core/node_boot.js'
},
options: {

View File

@@ -1,14 +0,0 @@
var grunt = require("grunt");
function gemLib(path) { return './lib/jasmine-core/' + path; }
function nodeToRuby(version) { return version.replace('-', '.'); }
module.exports = {
copyToGem: function() {
var versionRb = grunt.template.process(
grunt.file.read("grunt/templates/version.rb.jst"),
{ data: { jasmineVersion: nodeToRuby(global.jasmineVersion) }});
grunt.file.write(gemLib("version.rb"), versionRb);
}
};

View File

@@ -1,9 +0,0 @@
#
# DO NOT Edit this file. Canonical version of Jasmine lives in the repo's package.json. This file is generated
# by a grunt task when the standalone release is built.
#
module Jasmine
module Core
VERSION = "<%= jasmineVersion %>"
end
end

View File

View File

@@ -1,30 +0,0 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "jasmine-core/version"
Gem::Specification.new do |s|
s.name = "jasmine-core"
s.version = Jasmine::Core::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Gregg Van Hove"]
s.summary = %q{JavaScript BDD framework}
s.description = <<~DESC
Test your JavaScript without any framework dependencies, in any environment,
and with a nice descriptive syntax.
Jasmine for Ruby is deprecated. The direct replacment for the jasmine-core
gem is the jasmine-core NPM package. If you are also using the jasmine gem,
we recommend using the jasmine-browser-runner NPM package instead. It
supports all the same scenarios as the jasmine gem gem plus Webpacker. See
https://jasmine.github.io/setup/browser.html for setup instructions, and
https://github.com/jasmine/jasmine-gem/blob/main/release_notes/3.9.0.md
for other options.
DESC
s.email = %q{jasmine-js@googlegroups.com}
s.homepage = "http://jasmine.github.io"
s.license = "MIT"
s.files = Dir.glob("./lib/**/*")
s.require_paths = ["lib"]
s.add_development_dependency "rake"
end

View File

@@ -1,6 +1,42 @@
module.exports = require("./jasmine-core/jasmine.js");
/**
* Note: Only available on Node.
* @module jasmine-core
*/
const jasmineRequire = require('./jasmine-core/jasmine.js');
module.exports = jasmineRequire;
/**
* Boots a copy of Jasmine and returns an object as described in {@link jasmine}.
* @type {function}
* @return {jasmine}
*/
module.exports.boot = require('./jasmine-core/node_boot.js');
/**
* Boots a copy of Jasmine and returns an object containing the properties
* that would normally be added to the global object. If noGlobals is called
* multiple times, the same object is returned every time.
*
* Do not call boot() if you also call noGlobals().
*
* @example
* const {describe, beforeEach, it, expect, jasmine} = require('jasmine-core').noGlobals();
*/
module.exports.noGlobals = (function() {
let jasmineInterface;
return function bootWithoutGlobals() {
if (!jasmineInterface) {
const jasmine = jasmineRequire.core(jasmineRequire);
const env = jasmine.getEnv({ suppressLoadErrors: true });
jasmineInterface = jasmineRequire.interface(jasmine, env);
}
return jasmineInterface;
};
}());
var path = require('path'),
fs = require('fs');

View File

@@ -1,78 +0,0 @@
if ENV["SUPPRESS_JASMINE_DEPRECATION"].nil?
puts <<~END_DEPRECATION_MSG
The Jasmine Ruby gems are deprecated. There will be no further releases after
the end of the Jasmine 3.x series. We recommend that most users migrate to the
jasmine-browser-runner npm package, which is the direct replacement for the
jasmine gem. See <https://jasmine.github.io/setup/browser.html> for setup
instructions, including for Rails applications that use either Sprockets or
Webpacker.
If jasmine-browser-runner doesn't meet your needs, one of these might:
* The jasmine npm package to run specs in Node.js:
<https://github.com/jasmine/jasmine-npm>
* The standalone distribution to run specs in browsers with no additional
tools: <https://github.com/jasmine/jasmine#installation>
* The jasmine-core npm package if all you need is the Jasmine assets:
<https://github.com/jasmine/jasmine>. This is the direct equivalent of the
jasmine-core Ruby gem.
To prevent this message from appearing, set the SUPPRESS_JASMINE_DEPRECATION
environment variable.
END_DEPRECATION_MSG
end
module Jasmine
module Core
class << self
def path
File.join(File.dirname(__FILE__), "jasmine-core")
end
def js_files
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - ["boot0.js", "boot1.js"] - node_boot_files
end
SPEC_TYPES = ["core", "html", "node"]
def core_spec_files
spec_files("core")
end
def html_spec_files
spec_files("html")
end
def node_spec_files
spec_files("node")
end
def boot_files
["boot.js"]
end
def node_boot_files
["node_boot.js"]
end
def boot_dir
path
end
def spec_files(type)
raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type)
(Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq
end
def css_files
Dir.glob(File.join(path, "*.css")).map { |f| File.basename(f) }
end
def images_dir
File.join(File.dirname(__FILE__), '../images')
end
end
end
end

View File

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

View File

@@ -1,165 +0,0 @@
/*
Copyright (c) 2008-2021 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.
*/
/**
NOTE: This file is deprecated and will be removed in a future release.
Include both boot0.js and boot1.js (in that order) instead.
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.
The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
[jasmine-gem]: http://github.com/pivotal/jasmine-gem
*/
(function() {
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
/**
* ## Require &amp; Instantiate
*
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
*/
var jasmine = jasmineRequire.core(jasmineRequire),
global = jasmine.getGlobal();
global.jasmine = jasmine;
/**
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
*/
jasmineRequire.html(jasmine);
/**
* Create the Jasmine environment. This is used to run all specs in a project.
*/
var env = jasmine.getEnv();
/**
* ## The Global Interface
*
* 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 = jasmineRequire.interface(jasmine, env);
/**
* 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`.
*/
extend(global, jasmineInterface);
/**
* ## Runner Parameters
*
* More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
*/
var queryString = new jasmine.QueryString({
getWindowLocation: function() { return window.location; }
});
var filterSpecs = !!queryString.getParam("spec");
var config = {
failFast: queryString.getParam("failFast"),
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
hideDisabled: queryString.getParam("hideDisabled")
};
var random = queryString.getParam("random");
if (random !== undefined && random !== "") {
config.random = random;
}
var seed = queryString.getParam("seed");
if (seed) {
config.seed = seed;
}
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
timer: new jasmine.Timer(),
filterSpecs: filterSpecs
});
/**
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
*/
env.addReporter(jasmineInterface.jsApiReporter);
env.addReporter(htmlReporter);
/**
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
*/
var specFilter = new jasmine.HtmlSpecFilter({
filterString: function() { return queryString.getParam("spec"); }
});
config.specFilter = function(spec) {
return specFilter.matches(spec.getFullName());
};
env.configure(config);
/**
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
*/
window.setTimeout = window.setTimeout;
window.setInterval = window.setInterval;
window.clearTimeout = window.clearTimeout;
window.clearInterval = window.clearInterval;
/**
* ## Execution
*
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
*/
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
htmlReporter.initialize();
env.execute();
};
/**
* Helper function for readability above.
*/
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
}());

View File

@@ -1,143 +0,0 @@
/**
NOTE: This file is deprecated and will be removed in a future release.
Include both boot0.js and boot1.js (in that order) instead.
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.
The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
[jasmine-gem]: http://github.com/pivotal/jasmine-gem
*/
(function() {
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
/**
* ## Require &amp; Instantiate
*
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
*/
var jasmine = jasmineRequire.core(jasmineRequire),
global = jasmine.getGlobal();
global.jasmine = jasmine;
/**
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
*/
jasmineRequire.html(jasmine);
/**
* Create the Jasmine environment. This is used to run all specs in a project.
*/
var env = jasmine.getEnv();
/**
* ## The Global Interface
*
* 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 = jasmineRequire.interface(jasmine, env);
/**
* 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`.
*/
extend(global, jasmineInterface);
/**
* ## Runner Parameters
*
* More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
*/
var queryString = new jasmine.QueryString({
getWindowLocation: function() { return window.location; }
});
var filterSpecs = !!queryString.getParam("spec");
var config = {
failFast: queryString.getParam("failFast"),
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
hideDisabled: queryString.getParam("hideDisabled")
};
var random = queryString.getParam("random");
if (random !== undefined && random !== "") {
config.random = random;
}
var seed = queryString.getParam("seed");
if (seed) {
config.seed = seed;
}
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
timer: new jasmine.Timer(),
filterSpecs: filterSpecs
});
/**
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
*/
env.addReporter(jasmineInterface.jsApiReporter);
env.addReporter(htmlReporter);
/**
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
*/
var specFilter = new jasmine.HtmlSpecFilter({
filterString: function() { return queryString.getParam("spec"); }
});
config.specFilter = function(spec) {
return specFilter.matches(spec.getFullName());
};
env.configure(config);
/**
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
*/
window.setTimeout = window.setTimeout;
window.setInterval = window.setInterval;
window.clearTimeout = window.clearTimeout;
window.clearInterval = window.clearInterval;
/**
* ## Execution
*
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
*/
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
htmlReporter.initialize();
env.execute();
};
/**
* Helper function for readability above.
*/
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
}());

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2021 Pivotal Labs
Copyright (c) 2008-2022 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -61,4 +61,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
for (var property in jasmineInterface) {
global[property] = jasmineInterface[property];
}
}());
})();

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2021 Pivotal Labs
Copyright (c) 2008-2022 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.
*/
/**
This file finishes "booting" Jasmine, performing all of the necessary
This file finishes 'booting' 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 `boot0.js` but before any project
source files or spec files are loaded. Thus this file can also be used to
@@ -43,24 +43,28 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var queryString = new jasmine.QueryString({
getWindowLocation: function() { return window.location; }
getWindowLocation: function() {
return window.location;
}
});
var filterSpecs = !!queryString.getParam("spec");
var filterSpecs = !!queryString.getParam('spec');
var config = {
failFast: queryString.getParam("failFast"),
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
hideDisabled: queryString.getParam("hideDisabled")
stopOnSpecFailure: queryString.getParam('stopOnSpecFailure'),
stopSpecOnExpectationFailure: queryString.getParam(
'stopSpecOnExpectationFailure'
),
hideDisabled: queryString.getParam('hideDisabled')
};
var random = queryString.getParam("random");
var random = queryString.getParam('random');
if (random !== undefined && random !== "") {
if (random !== undefined && random !== '') {
config.random = random;
}
var seed = queryString.getParam("seed");
var seed = queryString.getParam('seed');
if (seed) {
config.seed = seed;
}
@@ -71,11 +75,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
navigateWithNewParam: function(key, value) {
return queryString.navigateWithNewParam(key, value);
},
addToExistingQueryString: function(key, value) {
return queryString.fullStringWithNewParam(key, value);
},
getContainer: function() {
return document.body;
},
createElement: function() {
return document.createElement.apply(document, arguments);
},
createTextNode: function() {
return document.createTextNode.apply(document, arguments);
},
timer: new jasmine.Timer(),
filterSpecs: filterSpecs
});
@@ -90,7 +104,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
*/
var specFilter = new jasmine.HtmlSpecFilter({
filterString: function() { return queryString.getParam("spec"); }
filterString: function() {
return queryString.getParam('spec');
}
});
config.specFilter = function(spec) {
@@ -99,14 +115,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
env.configure(config);
/**
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
*/
window.setTimeout = window.setTimeout;
window.setInterval = window.setInterval;
window.clearTimeout = window.clearTimeout;
window.clearInterval = window.clearInterval;
/**
* ## Execution
*
@@ -121,13 +129,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
htmlReporter.initialize();
env.execute();
};
/**
* Helper function for readability above.
*/
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
}());
})();

View File

@@ -1,94 +0,0 @@
import pkg_resources
import os
if 'SUPPRESS_JASMINE_DEPRECATION' not in os.environ:
print('DEPRECATION WARNING:\n' +
'\n' +
'The Jasmine packages for Python are deprecated. There will be no further\n' +
'releases after the end of the Jasmine 3.x series. We recommend migrating to the\n' +
'following options:\n' +
'\n' +
'* jasmine-browser-runner (<https://github.com/jasmine/jasmine-browser>,\n' +
' `npm install jasmine-browser-runner`) to run specs in browsers, including\n' +
' headless Chrome and Saucelabs. This is the most direct replacement for the\n' +
' jasmine server` and `jasmine ci` commands provided by the `jasmine` Python\n' +
' package.\n' +
'* The jasmine npm package (<https://github.com/jasmine/jasmine-npm>,\n' +
' `npm install jasmine`) to run specs under Node.js.\n' +
'* The standalone distribution from the latest Jasmine release\n' +
' <https://github.com/jasmine/jasmine/releases> to run specs in browsers with\n' +
' no additional tools.\n' +
'* The jasmine-core npm package (`npm install jasmine-core`) if all you need is\n' +
' the Jasmine assets. This is the direct equivalent of the jasmine-core Python\n' +
' package.\n' +
'\n' +
'Except for the standalone distribution, all of the above are distributed through\n' +
'npm.\n' +
'\n' +
'To prevent this message from appearing, set the SUPPRESS_JASMINE_DEPRECATION\n' +
'environment variable.\n')
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')
# Remove the new boot files. jasmine-py will continue to use the legacy
# boot.js.
js_files.remove('boot0.js')
js_files.remove('boot1.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

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2021 Pivotal Labs
Copyright (c) 2008-2022 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -72,6 +72,12 @@ jasmineRequire.HtmlReporter = function(j$) {
}
};
ResultsStateBuilder.prototype.jasmineDone = function(result) {
if (result.failedExpectations) {
this.failureCount += result.failedExpectations.length;
}
};
function HtmlReporter(options) {
var config = function() {
return (options.env && options.env.configuration()) || {};
@@ -187,6 +193,7 @@ jasmineRequire.HtmlReporter = function(j$) {
};
this.jasmineDone = function(doneResult) {
stateBuilder.jasmineDone(doneResult);
var banner = find('.jasmine-banner');
var alert = find('.jasmine-alert');
var order = doneResult && doneResult.order;
@@ -303,15 +310,18 @@ jasmineRequire.HtmlReporter = function(j$) {
} else {
return prefix;
}
} else {
} else if (failure.globalErrorType === 'afterAll') {
return afterAllMessagePrefix + failure.message;
} else {
return failure.message;
}
}
addDeprecationWarnings(doneResult);
for (i = 0; i < deprecationWarnings.length; i++) {
var context;
var children = [],
context;
switch (deprecationWarnings[i].runnableType) {
case 'spec':
@@ -324,13 +334,23 @@ jasmineRequire.HtmlReporter = function(j$) {
context = '';
}
deprecationWarnings[i].message.split('\n').forEach(function(line) {
children.push(line);
children.push(createDom('br'));
});
children[0] = 'DEPRECATION: ' + children[0];
children.push(context);
if (deprecationWarnings[i].stack) {
children.push(createExpander(deprecationWarnings[i].stack));
}
alert.appendChild(
createDom(
'span',
{ className: 'jasmine-bar jasmine-warning' },
'DEPRECATION: ' + deprecationWarnings[i].message,
createDom('br'),
context
children
)
);
}
@@ -423,9 +443,53 @@ jasmineRequire.HtmlReporter = function(j$) {
);
}
if (result.debugLogs) {
messages.appendChild(debugLogTable(result.debugLogs));
}
return failure;
}
function debugLogTable(debugLogs) {
var tbody = createDom('tbody');
debugLogs.forEach(function(entry) {
tbody.appendChild(
createDom(
'tr',
{},
createDom('td', {}, entry.timestamp.toString()),
createDom('td', {}, entry.message)
)
);
});
return createDom(
'div',
{ className: 'jasmine-debug-log' },
createDom(
'div',
{ className: 'jasmine-debug-log-header' },
'Debug logs'
),
createDom(
'table',
{},
createDom(
'thead',
{},
createDom(
'tr',
{},
createDom('th', {}, 'Time (ms)'),
createDom('th', {}, 'Message')
)
),
tbody
)
);
}
function summaryList(resultsTree, domParent) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
@@ -560,7 +624,7 @@ jasmineRequire.HtmlReporter = function(j$) {
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
failFastCheckbox.checked = config.stopOnSpecFailure;
failFastCheckbox.onclick = function() {
navigateWithNewParam('failFast', !config.stopOnSpecFailure);
navigateWithNewParam('stopOnSpecFailure', !config.stopOnSpecFailure);
};
var throwCheckbox = optionsMenuDom.querySelector(
@@ -569,7 +633,7 @@ jasmineRequire.HtmlReporter = function(j$) {
throwCheckbox.checked = config.stopSpecOnExpectationFailure;
throwCheckbox.onclick = function() {
navigateWithNewParam(
'oneFailurePerSpec',
'stopSpecOnExpectationFailure',
!config.stopSpecOnExpectationFailure
);
};
@@ -652,17 +716,44 @@ jasmineRequire.HtmlReporter = function(j$) {
if (result && result.deprecationWarnings) {
for (var i = 0; i < result.deprecationWarnings.length; i++) {
var warning = result.deprecationWarnings[i].message;
if (!j$.util.arrayContains(warning)) {
deprecationWarnings.push({
message: warning,
runnableName: result.fullName,
runnableType: runnableType
});
}
deprecationWarnings.push({
message: warning,
stack: result.deprecationWarnings[i].stack,
runnableName: result.fullName,
runnableType: runnableType
});
}
}
}
function createExpander(stackTrace) {
var expandLink = createDom('a', { href: '#' }, 'Show stack trace');
var root = createDom(
'div',
{ className: 'jasmine-expander' },
expandLink,
createDom(
'div',
{ className: 'jasmine-expander-contents jasmine-stack-trace' },
stackTrace
)
);
expandLink.addEventListener('click', function(e) {
e.preventDefault();
if (root.classList.contains('jasmine-expanded')) {
root.classList.remove('jasmine-expanded');
expandLink.textContent = 'Show stack trace';
} else {
root.classList.add('jasmine-expanded');
expandLink.textContent = 'Hide stack trace';
}
});
return root;
}
function find(selector) {
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
}
@@ -676,11 +767,23 @@ jasmineRequire.HtmlReporter = function(j$) {
}
}
function createDom(type, attrs, childrenVarArgs) {
var el = createElement(type);
function createDom(type, attrs, childrenArrayOrVarArgs) {
var el = createElement(type),
children,
i;
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (j$.isArray_(childrenArrayOrVarArgs)) {
children = childrenArrayOrVarArgs;
} else {
children = [];
for (i = 2; i < arguments.length; i++) {
children.push(arguments[i]);
}
}
for (i = 0; i < children.length; i++) {
var child = children[i];
if (typeof child === 'string') {
el.appendChild(createTextNode(child));

View File

@@ -165,6 +165,8 @@ body {
background-color: #bababa;
}
.jasmine_html-reporter .jasmine-bar.jasmine-warning {
margin-top: 14px;
margin-bottom: 14px;
background-color: #ba9d37;
color: #333;
}
@@ -268,4 +270,34 @@ body {
border: 1px solid #ddd;
background: white;
white-space: pre;
}
.jasmine_html-reporter .jasmine-expander a {
display: block;
margin-left: 14px;
color: blue;
text-decoration: underline;
}
.jasmine_html-reporter .jasmine-expander-contents {
display: none;
}
.jasmine_html-reporter .jasmine-expanded {
padding-bottom: 10px;
}
.jasmine_html-reporter .jasmine-expanded .jasmine-expander-contents {
display: block;
margin-left: 14px;
padding: 5px;
}
.jasmine_html-reporter .jasmine-debug-log {
margin: 5px 0 0 0;
padding: 5px;
color: #666;
border: 1px solid #ddd;
background: white;
}
.jasmine_html-reporter .jasmine-debug-log table {
border-spacing: 0;
}
.jasmine_html-reporter .jasmine-debug-log table, .jasmine_html-reporter .jasmine-debug-log th, .jasmine_html-reporter .jasmine-debug-log td {
border: 1px solid #ddd;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,489 +0,0 @@
/*
json2.js
2014-02-04
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
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.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, regexp: true */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (typeof JSON !== 'object') {
JSON = {};
}
(function () {
'use strict';
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
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;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function () {
return this.valueOf();
};
}
var cx,
escapable,
gap,
indent,
meta,
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// 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 + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// 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(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// 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(',') + '}';
gap = mind;
return v;
}
}
// 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.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// 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
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// 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) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// 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, ''))) {
// 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
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// 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;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2021 Pivotal Labs
Copyright (c) 2008-2022 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -23,7 +23,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire);
var env = jasmine.getEnv({suppressLoadErrors: true});
var env = jasmine.getEnv({ suppressLoadErrors: true });
var jasmineInterface = jasmineRequire.interface(jasmine, env);

View File

@@ -1,9 +0,0 @@
#
# DO NOT Edit this file. Canonical version of Jasmine lives in the repo's package.json. This file is generated
# by a grunt task when the standalone release is built.
#
module Jasmine
module Core
VERSION = "3.10.1"
end
end

View File

@@ -1,7 +1,7 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "3.10.1",
"version": "4.0.0",
"repository": {
"type": "git",
"url": "https://github.com/jasmine/jasmine.git"
@@ -34,22 +34,21 @@
"package.json"
],
"devDependencies": {
"ejs": "^2.5.5",
"eslint": "^6.8.0",
"eslint-plugin-compat": "^3.8.0",
"fast-glob": "^2.2.6",
"eslint": "^7.32.0",
"eslint-plugin-compat": "^4.0.0",
"glob": "^7.2.0",
"grunt": "^1.0.4",
"grunt-cli": "^1.3.2",
"grunt-contrib-compress": "^1.3.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-compress": "^2.0.0",
"grunt-contrib-concat": "^2.0.0",
"grunt-css-url-embed": "^1.11.1",
"grunt-sass": "^3.0.2",
"jasmine": "^3.4.0",
"jasmine": "github:jasmine/jasmine-npm#main",
"jasmine-browser-runner": "github:jasmine/jasmine-browser#main",
"jsdom": "^15.0.0",
"load-grunt-tasks": "^4.0.0",
"jsdom": "^19.0.0",
"load-grunt-tasks": "^5.1.0",
"prettier": "1.17.1",
"sass": "^1.32.12",
"sass": "^1.45.1",
"shelljs": "^0.8.3",
"temp": "^0.9.0"
},
@@ -60,8 +59,13 @@
"extends": [
"plugin:compat/recommended"
],
"env": {
"browser": true,
"node": true,
"es2017": true
},
"parserOptions": {
"ecmaVersion": 5
"ecmaVersion": 2018
},
"rules": {
"quotes": [
@@ -77,6 +81,7 @@
"args": "none"
}
],
"no-implicit-globals": "error",
"block-spacing": "error",
"func-call-spacing": [
"error",
@@ -94,11 +99,10 @@
}
},
"browserslist": [
"Safari >= 8",
"Safari >= 13",
"last 2 Chrome versions",
"last 2 Firefox versions",
"Firefox 68",
"last 2 Edge versions",
"IE >= 10"
"Firefox >= 68",
"last 2 Edge versions"
]
}

15
release_notes/3.99.0.md Normal file
View File

@@ -0,0 +1,15 @@
# Jasmine Core 3.99.0 Release Notes
## Summary
This release adds deprecation warnings for breaking changes that will be
introduced in Jasmine 4.0. Please see the
[migration guide](https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0)
for more information.
This is the last planned release of jasmine-core for Ruby or Python. Versions
4.0 and later will be offered only via NPM and the standalone distribution.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

197
release_notes/4.0.0.md Normal file
View File

@@ -0,0 +1,197 @@
# Jasmine Core 4.0.0 Release Notes
## Summary
This is a major release. In addition to new features and bug fixes it contains
a number of breaking changes that are intended to diagnose common errors,
improve awkward or outdated APIs, and make Jasmine easier to maintain
and contribute to. If you're upgrading from Jasmine 3.x, we recommend installing
3.99 and fixing any deprecation warnings that it emits before updating to 4.0.
Please see the [migration guide](https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0)
for more information. If you use the `jasmine` or `jasmine-browser-runner` NPM
packages, please read the release notes for those packages as well.
## Highlights
* Obsolete environments, most notably Internet Explorer, are no longer
supported. Jasmine now expects to run in an environment that provides most
of ES2017 and, in the case of Node, good interoperability between CommonJS
modules and ES modules.
* The Jasmine packages for Ruby and Python have been discontinued.
* Errors in `beforeAll` and `beforeEach` functions are handled better.
* Jasmine can optionally be used without creating globals in Node.
* Certain common async testing bugs are now reported as errors.
* A new debug logging feature makes it easier to debug failing specs,
particularly intermittent failures.
See details below.
## Breaking changes
### Changes to supported environments
The following previously supported environments are no longer supported:
* Internet Explorer
* PhantomJS
* Safari 8-13
* Firefox 68 and 78
* Node 10 and 12.0-12.16
* Python
* Ruby
* Bower
Although Jasmine 4.0 may still work in some of those environments, we no longer
test against them and won't try to maintain compatibility with them in future
4.x releases.
The [`jasmine-browser-runner`](https://jasmine.github.io/setup/browser.html)
NPM package is the direct replacement for the `jasmine` Ruby and Python
packages.
### Changes that affect how specs are written
* When a `beforeAll` function fails in any way other than a failed expectation,
Jasmine will not run the contents of the suite or any child suites except
for any `afterAll` functions defined in the same suite as the failed
`beforeAll` function. All affected specs will still be reported as failed.
See [#1533](https://github.com/jasmine/jasmine/issues/1533).
* When a `beforeEach` function fails in any way other than a failed expectation,
Jasmine will skip any subsequent `beforeEach` functions, the corresponding
spec, and any `afterEach` functions defined in child suites. `afterEach`
functions defined at the same or higher levels will still run. The spec will
still be reported as failed. See [#1533](https://github.com/jasmine/jasmine/issues/1533).
* `MatchersUtil#contains` and the `toContain` matcher use deep equality rather
than `===` to compare set members. This matches how arrays are handled but
may cause some previously passing `.not.toContain()` expectations to fail.
* `jasmine.clock().mockDate()` throws if its argument is not a `Date`. Previous
versions ignored non-`Date` arguments.
* Multiple calls to an asynchronous function's `done` callback are treated as
errors.
* Any argument passed to a `done` callback (other than `undefined`) is treated
as an error. Previous versions ignored any argument that wasn't an `Error`
instance.
* Jasmine will report an error rather than a warning when a function tries to
combine two different forms of async (e.g. taking a callback and also
returning a promise).
* `this` in `describe` functions is no longer a `Suite` object.
* Empty suites are treated as errors.
* Merges [#1742](https://github.com/jasmine/jasmine/pull/1742) from @johnjbarton
* The current time value does not decrease when `jasmine.clock().tick()` is
called from a `setTimeout` or `setInterval` callback.
* Merges [#1948](https://github.com/jasmine/jasmine/pull/1948) from @thw0rted
* Fixes [#1929](https://github.com/jasmine/jasmine/issues/1929).
### Changes to how Jasmine is configured
* Individual configuration property getters and setters such as
`Env#randomTests` and `Env#randomizeTests` have been removed. Use
`Env#configuration` and `Env#configure` instead.
* The `failFast` and `oneFailurePerSpec` configuration properties have been
removed. Use `stopOnSpecFailure` and `stopSpecOnExpectationFailure` instead.
* The `Promise` configuration property has been removed. Jasmine can still
consume non-native promises but will always use the global `Promise` to
create promises.
### Changes that affect custom matchers
* The old style of using custom equality testers, where matchers received them
from Jasmine and had to pass them back to `matchersUtil` methods, is no longer
supported.
* `matchersUtil` and `pp` are no longer available globally. Instead, use the
instances that are passed to custom matcher factories and to `jasmineToString`.
See the [migration guide](https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0)
for more information about these changes and how to update custom matchers that
use the old APIs.
### Changes that affect custom reporters
* The [`Suite`](https://jasmine.github.io/api/4.0/Suite.html) and
[`Spec`](https://jasmine.github.io/api/4.0/Spec.html) objects returned from
`describe`, `it`, and `Env#topSuite` no longer expose private APIs.
### Other breaking changes
* `boot.js` is no longer included. Use `boot0.js` and `boot1.js` instead.
* Boot files in `lib/jasmine-core/boot` are no longer included in the NPM
package. Use the boot files in `lib/jasmine-core` instead.
* `json2.js` is no longer included, since all supported environments provide a
JSON parser.
## Other new features and bug fixes
* Jasmine can optionally be used without creating globals in Node.js.
* See https://jasmine.github.io/api/4.0/module-jasmine-core.html#.noGlobals
* If you're using the `jasmine` package, see
[its documentation](https://jasmine.github.io/api/npm/4.0/JasmineOptions.html#globals).
* Fixes [#1235](https://github.com/jasmine/jasmine/issues/1235)
* Custom spy strategies are inherited from parent suites like other runnable
resources.
* `pending()` can now be called from `beforeEach` functions.
* Fixes [#1579](https://github.com/jasmine/jasmine/issues/1579)
* Removed duplicate message from errors (including. matcher failures) in
V8-based environments.
* `Spy#withArgs` supports custom equality testers.
* Fixes [#1836](https://github.com/jasmine/jasmine/issues/1836)
* The promise returned by `Env#execute` is resolved to the
[jasmineDoneInfo](https://jasmine.github.io/api/4.0/global.html#JasmineDoneInfo).
* Fixed stack trace filtering on Safari 15.
* The HTML reporter includes top suite failures in the reported failure count.
* `afterAll` functions are run after a failure even if the `stopOnSpecFailure`
config property is set.
* Added a debug logging feature to make it easier to debug failing specs.
* Call `jasmine#debugLog` during spec execution to add a log entry.
* If the spec fails, log entries are reported as part of the
[specDone](https://jasmine.github.io/api/4.0/Reporter.html#specDone) reporter
event.
* The HTML reporter no longer says that expectations occurring after the spec
finishes are AfterAll errors.
## Documentation updates
* Added a [4.0 migration guide](https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0)
* Updated the README and contributing guide for 4.0
## Supported environments
jasmine-core 4.0.0 has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 12.17+, 14, 16 |
| Safari | 14-15 |
| Chrome | 96 |
| Firefox | 91, 95 |
| Edge | 96 |
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

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

View File

@@ -23,17 +23,12 @@ run_browser() {
passfile=`mktemp -t jasmine-results.XXXXXX` || exit 1
failfile=`mktemp -t jasmine-results.XXXXXX` || exit 1
run_browser "internet explorer" 11
run_browser "internet explorer" 10
run_browser chrome latest
run_browser firefox latest
run_browser firefox 78
run_browser firefox 68
run_browser safari 14
run_browser safari 13
run_browser safari 9
run_browser safari 8
run_browser MicrosoftEdge latest
run_browser firefox 91
run_browser safari 15
run_browser safari 14
run_browser MicrosoftEdge latest
echo
cat "$passfile" "$failfile"

View File

@@ -1,70 +0,0 @@
from setuptools import setup, find_packages, os
import json
with open('package.json') as packageFile:
version = json.load(packageFile)['version']
short_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.')
deprecation=('The Jasmine packages for Python are deprecated. There will be no further\n' +
'releases after the end of the Jasmine 3.x series. We recommend migrating to the\n' +
'following options:\n' +
'\n' +
'* jasmine-browser-runner (<https://github.com/jasmine/jasmine-browser>,\n' +
' `npm install jasmine-browser-runner`) to run specs in browsers, including\n' +
' headless Chrome and Saucelabs. This is the most direct replacement for the\n' +
' jasmine server` and `jasmine ci` commands provided by the `jasmine` Python\n' +
' package.\n' +
'* The jasmine npm package (<https://github.com/jasmine/jasmine-npm>,\n' +
' `npm install jasmine`) to run specs under Node.js.\n' +
'* The standalone distribution from the latest Jasmine release\n' +
' <https://github.com/jasmine/jasmine/releases> to run specs in browsers with\n' +
' no additional tools.\n' +
'* The jasmine-core npm package (`npm install jasmine-core`) if all you need is\n' +
' the Jasmine assets. This is the direct equivalent of the jasmine-core Python\n' +
' package.\n' +
'\n' +
'Except for the standalone distribution, all of the above are distributed through\n'
'npm.\n')
long_description = short_description + '\n\n' + deprecation
setup(
name="jasmine-core",
version=version,
url="http://jasmine.github.io",
author="Pivotal Labs",
author_email="jasmine-js@googlegroups.com",
description=short_description,
long_description=long_description,
long_description_content_type='text/plain',
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 :: 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

@@ -1,4 +1,3 @@
/* eslint-disable compat/compat */
describe('AsyncExpectation', function() {
beforeEach(function() {
jasmineUnderTest.Expectation.addAsyncCoreMatchers(
@@ -6,23 +5,8 @@ describe('AsyncExpectation', function() {
);
});
describe('Factory', function() {
it('throws an Error if promises are not available', function() {
var thenable = { then: function() {} },
options = { global: {}, actual: thenable };
function f() {
jasmineUnderTest.Expectation.asyncFactory(options);
}
expect(f).toThrowError(
'expectAsync is unavailable because the environment does not support promises.'
);
});
});
describe('#not', function() {
it('converts a pass to a fail', function() {
jasmine.getEnv().requirePromises();
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.resolve(),
pp = jasmineUnderTest.makePrettyPrinter(),
@@ -44,8 +28,6 @@ describe('AsyncExpectation', function() {
});
it('converts a fail to a pass', function() {
jasmine.getEnv().requirePromises();
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.reject(),
expectation = jasmineUnderTest.Expectation.asyncFactory({
@@ -69,7 +51,6 @@ describe('AsyncExpectation', function() {
});
it('propagates rejections from the comparison function', function() {
jasmine.getEnv().requirePromises();
var error = new Error('ExpectationSpec failure');
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
@@ -93,8 +74,6 @@ describe('AsyncExpectation', function() {
describe('#withContext', function() {
it('prepends the context to the generated failure message', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = {
pp: function(val) {
return val.toString();
@@ -122,8 +101,6 @@ describe('AsyncExpectation', function() {
});
it('prepends the context to a custom failure message', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = {
buildFailureMessage: function() {
return 'failure message';
@@ -154,7 +131,6 @@ describe('AsyncExpectation', function() {
it('prepends the context to a custom failure message from a function', function() {
pending('should actually work, but no custom matchers for async yet');
jasmine.getEnv().requirePromises();
var matchersUtil = {
buildFailureMessage: function() {
@@ -183,8 +159,6 @@ describe('AsyncExpectation', function() {
});
it('works with #not', function() {
jasmine.getEnv().requirePromises();
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.resolve(),
pp = jasmineUnderTest.makePrettyPrinter(),
@@ -209,8 +183,6 @@ describe('AsyncExpectation', function() {
});
it('works with #not and a custom message', function() {
jasmine.getEnv().requirePromises();
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
actual = Promise.resolve('a'),
expectation = jasmineUnderTest.Expectation.asyncFactory({
@@ -238,8 +210,6 @@ describe('AsyncExpectation', function() {
describe('async matchers', function() {
it('makes custom matchers available to this expectation', function() {
jasmine.getEnv().requirePromises();
var asyncMatchers = {
toFoo: function() {},
toBar: function() {}
@@ -255,8 +225,6 @@ describe('AsyncExpectation', function() {
});
it("wraps matchers's compare functions, passing in matcher dependencies", function() {
jasmine.getEnv().requirePromises();
var fakeCompare = function() {
return Promise.resolve({ pass: true });
},
@@ -269,29 +237,22 @@ describe('AsyncExpectation', function() {
matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
},
customEqualityTesters = ['a'],
addExpectationResult = jasmine.createSpy('addExpectationResult'),
expectation;
expectation = jasmineUnderTest.Expectation.asyncFactory({
matchersUtil: matchersUtil,
customAsyncMatchers: matchers,
customEqualityTesters: customEqualityTesters,
actual: 'an actual',
addExpectationResult: addExpectationResult
});
return expectation.toFoo('hello').then(function() {
expect(matcherFactory).toHaveBeenCalledWith(
matchersUtil,
customEqualityTesters
);
expect(matcherFactory).toHaveBeenCalledWith(matchersUtil);
});
});
it("wraps matchers's compare functions, passing the actual and expected", function() {
jasmine.getEnv().requirePromises();
var fakeCompare = jasmine
.createSpy('fake-compare')
.and.returnValue(Promise.resolve({ pass: true })),
@@ -321,8 +282,6 @@ describe('AsyncExpectation', function() {
});
it('reports a passing result to the spec when the comparison passes', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -364,8 +323,6 @@ describe('AsyncExpectation', function() {
});
it('reports a failing result to the spec when the comparison fails', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -409,8 +366,6 @@ describe('AsyncExpectation', function() {
});
it('reports a failing result and a custom fail message to the spec when the comparison fails', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -451,8 +406,6 @@ describe('AsyncExpectation', function() {
});
it('reports a failing result with a custom fail message function to the spec when the comparison fails', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -495,8 +448,6 @@ describe('AsyncExpectation', function() {
});
it('reports a passing result to the spec when the comparison fails for a negative expectation', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -535,8 +486,6 @@ describe('AsyncExpectation', function() {
});
it('reports a failing result to the spec when the comparison passes for a negative expectation', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -581,8 +530,6 @@ describe('AsyncExpectation', function() {
});
it('reports a failing result and a custom fail message to the spec when the comparison passes for a negative expectation', function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -624,8 +571,6 @@ describe('AsyncExpectation', function() {
});
it("reports a passing result to the spec when the 'not' comparison passes, given a negativeCompare", function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -667,8 +612,6 @@ describe('AsyncExpectation', function() {
});
it("reports a failing result and a custom fail message to the spec when the 'not' comparison fails, given a negativeCompare", function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -713,8 +656,6 @@ describe('AsyncExpectation', function() {
});
it('reports errorWithStack when a custom error message is returned', function() {
jasmine.getEnv().requirePromises();
var customError = new Error('I am a custom error');
var matchers = {
toFoo: function() {
@@ -757,8 +698,6 @@ describe('AsyncExpectation', function() {
});
it("reports a custom message to the spec when a 'not' comparison fails", function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {
@@ -799,8 +738,6 @@ describe('AsyncExpectation', function() {
});
it("reports a custom message func to the spec when a 'not' comparison fails", function() {
jasmine.getEnv().requirePromises();
var matchers = {
toFoo: function() {
return {

View File

@@ -950,6 +950,25 @@ describe('Clock (acceptance)', function() {
expect(timeoutDate).toEqual(baseTime.getTime() + 150);
});
it('throws mockDate is called with a non-Date', function() {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = { Date: Date },
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock(
{ setTimeout: setTimeout },
function() {
return delayedFunctionScheduler;
},
mockDate
),
env = jasmineUnderTest.getEnv();
expect(() => clock.mockDate(12345)).toThrowError(
'The argument to jasmine.clock().mockDate(), if specified, should be ' +
'a Date instance.'
);
});
it('mocks the Date object and updates the date per delayed function', function() {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = { Date: Date },

View File

@@ -0,0 +1,131 @@
describe('CompleteOnFirstErrorSkipPolicy', function() {
describe('#skipTo', function() {
describe('Before anything has errored', function() {
it('returns the next index', function() {
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
arrayOfArbitraryFns(4),
4
);
expect(policy.skipTo(1)).toEqual(2);
});
});
describe('After something has errored', function() {
it('skips non cleanup fns', function() {
const fns = arrayOfArbitraryFns(4);
fns[2].type = arbitraryCleanupType();
fns[3].type = arbitraryCleanupType();
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(fns);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(2);
expect(policy.skipTo(2)).toEqual(3);
expect(policy.skipTo(3)).toEqual(4);
});
for (const type of ['afterEach', 'specCleanup', 'afterAll']) {
it(`does not skip ${type} fns`, function() {
const fns = arrayOfArbitraryFns(2);
fns[1].type = type;
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns
);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(1);
});
}
describe('When the error was in a beforeEach fn', function() {
it('runs cleanup fns defined by the current and containing suites', function() {
const parentSuite = { description: 'parentSuite' };
const suite = { description: 'suite', parentSuite };
const fns = [
{
suite: suite
},
{
fn: () => {}
},
{
fn: () => {},
suite: suite,
type: arbitraryCleanupType()
},
{
fn: () => {},
suite: parentSuite,
type: arbitraryCleanupType()
}
];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns
);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(2);
expect(policy.skipTo(2)).toEqual(3);
});
it('skips cleanup fns defined by nested suites', function() {
const parentSuite = { description: 'parentSuite' };
const suite = { description: 'suite', parentSuite };
const fns = [
{
fn: () => {},
type: 'beforeEach',
suite: parentSuite
},
{
fn: () => {}
},
{
fn: () => {},
suite: suite,
type: arbitraryCleanupType()
},
{
fn: () => {},
suite: parentSuite,
type: arbitraryCleanupType()
}
];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns
);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(3);
});
});
it('does not skip cleanup fns that have no suite, such as the spec complete fn', function() {
const fns = [
{ fn: () => {} },
{
fn: () => {},
type: arbitraryCleanupType()
}
];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(fns);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(1);
});
});
});
function arrayOfArbitraryFns(n) {
const result = [];
for (let i = 0; i < n; i++) {
result.push({ fn: () => {} });
}
return result;
}
function arbitraryCleanupType() {
return 'specCleanup';
}
});

View File

@@ -278,4 +278,58 @@ describe('DelayedFunctionScheduler', function() {
expect(tickDate).toHaveBeenCalledWith(0);
expect(tickDate).toHaveBeenCalledWith(1);
});
describe('ticking inside a scheduled function', function() {
let clock;
// Runner function calls the callback until it returns false
function runWork(workCallback) {
while (workCallback()) {}
}
// Make a worker that takes a little time and tracks when it finished
function mockWork(times) {
return () => {
clock.tick(1);
const now = new Date().getTime();
expect(lastWork)
.withContext('Previous function calls should always be in the past')
.toBeLessThan(now);
lastWork = now;
times--;
return times > 0;
};
}
let lastWork = 0;
beforeEach(() => {
clock = jasmineUnderTest.getEnv().clock;
clock.install();
clock.mockDate(new Date(1));
});
afterEach(function() {
jasmineUnderTest.getEnv().clock.uninstall();
});
it('preserves monotonically-increasing current time', () => {
const work1 = mockWork(3);
setTimeout(() => {
runWork(work1);
}, 1);
clock.tick(1);
expect(lastWork)
.withContext('tick should advance past last-scheduled function')
.toBeLessThanOrEqual(new Date().getTime());
const work2 = mockWork(3);
setTimeout(() => {
runWork(work2);
}, 1);
clock.tick(1);
expect(lastWork)
.withContext('tick should advance past last-scheduled function')
.toBeLessThanOrEqual(new Date().getTime());
});
});
});

329
spec/core/DeprecatorSpec.js Normal file
View File

@@ -0,0 +1,329 @@
/* eslint no-console: 0 */
describe('Deprecator', function() {
describe('#deprecate', function() {
beforeEach(function() {
spyOn(console, 'error');
});
it('logs the mesage without context when the runnable is the top suite', function() {
var runnable = { addDeprecationWarning: function() {} };
var deprecator = new jasmineUnderTest.Deprecator(runnable);
deprecator.verboseDeprecations(true);
deprecator.addDeprecationWarning(runnable, 'the message', {
omitStackTrace: true
});
expect(console.error).toHaveBeenCalledWith('DEPRECATION: the message');
});
it('logs the message in a descendant suite', function() {
var runnable = {
addDeprecationWarning: function() {},
getFullName: function() {
return 'the suite';
},
children: []
};
var deprecator = new jasmineUnderTest.Deprecator({});
deprecator.verboseDeprecations(true);
deprecator.addDeprecationWarning(runnable, 'the message', {
omitStackTrace: true
});
expect(console.error).toHaveBeenCalledWith(
'DEPRECATION: the message (in suite: the suite)'
);
});
it('logs and reports the message in a spec', function() {
var runnable = {
addDeprecationWarning: function() {},
getFullName: function() {
return 'the spec';
}
};
var deprecator = new jasmineUnderTest.Deprecator({});
deprecator.verboseDeprecations(true);
deprecator.addDeprecationWarning(runnable, 'the message', {
omitStackTrace: true
});
expect(console.error).toHaveBeenCalledWith(
'DEPRECATION: the message (in spec: the spec)'
);
});
it('logs and reports the message without runnable info when ignoreRunnable is true', function() {
var topSuite = jasmine.createSpyObj('topSuite', [
'addDeprecationWarning',
'getFullName'
]);
var deprecator = new jasmineUnderTest.Deprecator(topSuite);
var runnable = jasmine.createSpyObj('spec', [
'addDeprecationWarning',
'getFullName'
]);
runnable.getFullName.and.returnValue('a spec');
deprecator.addDeprecationWarning(runnable, 'the message', {
ignoreRunnable: true
});
expect(topSuite.addDeprecationWarning).toHaveBeenCalledWith(
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
);
expect(runnable.addDeprecationWarning).not.toHaveBeenCalled();
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(/the message/)
);
expect(console.error).not.toHaveBeenCalledWith(
jasmine.stringMatching(/a spec/)
);
});
describe('with no options', function() {
it('includes the stack trace', function() {
testStackTrace(undefined);
});
});
it('omits the stack trace when omitStackTrace is true', function() {
testNoStackTrace({ omitStackTrace: true });
});
it('includes the stack trace when omitStackTrace is false', function() {
testStackTrace({ omitStackTrace: false });
});
it('includes the stack trace when omitStackTrace is undefined', function() {
testStackTrace({ includeStackTrace: undefined });
});
it('emits the deprecation only once when verboseDeprecations is not set', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable1 = jasmine.createSpyObj('runnable1', [
'addDeprecationWarning',
'getFullName'
]);
var runnable2 = jasmine.createSpyObj('runnable2', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.addDeprecationWarning(runnable1, 'the message');
deprecator.addDeprecationWarning(runnable1, 'the message');
deprecator.addDeprecationWarning(runnable2, 'the message');
expect(runnable1.addDeprecationWarning).toHaveBeenCalledTimes(1);
expect(runnable2.addDeprecationWarning).not.toHaveBeenCalled();
});
it('emits the deprecation only once when verboseDeprecations is false', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable1 = jasmine.createSpyObj('runnable1', [
'addDeprecationWarning',
'getFullName'
]);
var runnable2 = jasmine.createSpyObj('runnable2', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.verboseDeprecations(false);
deprecator.addDeprecationWarning(runnable1, 'the message');
deprecator.addDeprecationWarning(runnable1, 'the message');
deprecator.addDeprecationWarning(runnable2, 'the message');
expect(runnable1.addDeprecationWarning).toHaveBeenCalledTimes(1);
expect(runnable2.addDeprecationWarning).not.toHaveBeenCalled();
});
it('emits the deprecation for each call when verboseDeprecations is true', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable1 = jasmine.createSpyObj('runnable1', [
'addDeprecationWarning',
'getFullName'
]);
var runnable2 = jasmine.createSpyObj('runnable2', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.verboseDeprecations(true);
deprecator.addDeprecationWarning(runnable1, 'the message');
deprecator.addDeprecationWarning(runnable1, 'the message');
deprecator.addDeprecationWarning(runnable2, 'the message');
expect(runnable1.addDeprecationWarning).toHaveBeenCalledTimes(2);
expect(runnable2.addDeprecationWarning).toHaveBeenCalled();
});
it('includes a note about verboseDeprecations', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.addDeprecationWarning(runnable, 'the message');
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
expect(
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
).toContain(verboseDeprecationsNote());
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0]).toContain(
verboseDeprecationsNote()
);
});
it('omits the note about verboseDeprecations when verboseDeprecations is true', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.verboseDeprecations(true);
deprecator.addDeprecationWarning(runnable, 'the message');
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
expect(
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
).not.toContain(verboseDeprecationsNote());
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0]).not.toContain(
verboseDeprecationsNote()
);
});
describe('When the deprecation is an Error', function() {
// This form is used by external systems like atom-jasmine3-test-runner
// to report their own deprecations through Jasmine. See
// <https://github.com/jasmine/jasmine/pull/1498>.
it('passes the error through unchanged', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
var exceptionFormatter = new jasmineUnderTest.ExceptionFormatter();
var deprecation, originalStack;
try {
throw new Error('the deprecation');
} catch (err) {
deprecation = err;
originalStack = err.stack;
}
deprecator.addDeprecationWarning(runnable, deprecation);
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
expect(
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
).toEqual('the deprecation');
expect(runnable.addDeprecationWarning.calls.argsFor(0)[0].stack).toBe(
originalStack
);
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0].message).toEqual(
'the deprecation'
);
expect(console.error.calls.argsFor(0)[0].stack).toEqual(originalStack);
});
it('reports the deprecation every time, regardless of config.verboseDeprecations', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
var deprecation;
try {
throw new Error('the deprecation');
} catch (err) {
deprecation = err;
}
deprecator.addDeprecationWarning(runnable, deprecation);
deprecator.addDeprecationWarning(runnable, deprecation);
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(2);
expect(console.error).toHaveBeenCalledTimes(2);
});
it('omits the note about verboseDeprecations', function() {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
var deprecation;
try {
throw new Error('the deprecation');
} catch (err) {
deprecation = err;
}
deprecator.addDeprecationWarning(runnable, deprecation);
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
expect(
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
).not.toContain(verboseDeprecationsNote());
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0]).not.toContain(
verboseDeprecationsNote()
);
});
});
function verboseDeprecationsNote() {
return (
'Note: This message will be shown only once. Set the ' +
'verboseDeprecations config property to true to see every occurrence.'
);
}
function testStackTrace(options) {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.addDeprecationWarning(runnable, 'the message', options);
expect(runnable.addDeprecationWarning).toHaveBeenCalledWith({
message: jasmine.stringMatching(/^the message/),
omitStackTrace: false
});
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0]).toContain('the message');
expect(console.error.calls.argsFor(0)[0]).toContain('DeprecatorSpec.js');
}
function testNoStackTrace(options) {
var deprecator = new jasmineUnderTest.Deprecator({});
var runnable = jasmine.createSpyObj('runnable', [
'addDeprecationWarning',
'getFullName'
]);
deprecator.addDeprecationWarning(runnable, 'the message', options);
expect(runnable.addDeprecationWarning).toHaveBeenCalledWith({
message: jasmine.stringMatching(/^the message/),
omitStackTrace: true
});
}
});
});

View File

@@ -26,9 +26,60 @@ describe('Env', function() {
});
describe('#topSuite', function() {
it('returns the Jasmine top suite for users to traverse the spec tree', function() {
var suite = env.topSuite();
it('returns an object that describes the tree of suites and specs', function() {
var suite;
spyOn(env, 'deprecated');
env.it('a top level spec');
env.describe('a suite', function() {
env.it('a spec');
env.describe('a nested suite', function() {
env.it('a nested spec');
});
});
suite = env.topSuite();
expect(suite).not.toBeInstanceOf(jasmineUnderTest.Suite);
expect(suite.description).toEqual('Jasmine__TopLevel__Suite');
expect(suite.getFullName()).toEqual('');
expect(suite.children.length).toEqual(2);
expect(suite.children[0]).not.toBeInstanceOf(jasmineUnderTest.Spec);
expect(suite.children[0].description).toEqual('a top level spec');
expect(suite.children[0].getFullName()).toEqual('a top level spec');
expect(suite.children[0].children).toBeFalsy();
expect(suite.children[1]).not.toBeInstanceOf(jasmineUnderTest.Suite);
expect(suite.children[1].description).toEqual('a suite');
expect(suite.children[1].getFullName()).toEqual('a suite');
expect(suite.children[1].parentSuite).toBe(suite);
expect(suite.children[1].children.length).toEqual(2);
expect(suite.children[1].children[0]).not.toBeInstanceOf(
jasmineUnderTest.Spec
);
expect(suite.children[1].children[0].description).toEqual('a spec');
expect(suite.children[1].children[0].getFullName()).toEqual(
'a suite a spec'
);
expect(suite.children[1].children[0].children).toBeFalsy();
expect(suite.children[1].children[1].description).toEqual(
'a nested suite'
);
expect(suite.children[1].children[1].getFullName()).toEqual(
'a suite a nested suite'
);
expect(suite.children[1].children[1].parentSuite).toBe(suite.children[1]);
expect(suite.children[1].children[1].children.length).toEqual(1);
expect(suite.children[1].children[1].children[0].description).toEqual(
'a nested spec'
);
expect(suite.children[1].children[1].children[0].getFullName()).toEqual(
'a suite a nested suite a nested spec'
);
expect(suite.children[1].children[1].children[0].children).toBeFalsy();
});
});
@@ -37,9 +88,9 @@ describe('Env', function() {
});
it('can configure specs to throw errors on expectation failures', function() {
env.configure({ oneFailurePerSpec: true });
env.configure({ stopSpecOnExpectationFailure: true });
spyOn(jasmineUnderTest, 'Spec');
spyOn(jasmineUnderTest, 'Spec').and.callThrough();
env.it('foo', function() {});
expect(jasmineUnderTest.Spec).toHaveBeenCalledWith(
jasmine.objectContaining({
@@ -49,7 +100,7 @@ describe('Env', function() {
});
it('can configure suites to throw errors on expectation failures', function() {
env.configure({ oneFailurePerSpec: true });
env.configure({ stopSpecOnExpectationFailure: true });
spyOn(jasmineUnderTest, 'Suite');
env.describe('foo', function() {});
@@ -61,12 +112,11 @@ describe('Env', function() {
});
it('ignores configuration properties that are present but undefined', function() {
spyOn(env, 'deprecated');
var initialConfig = {
random: true,
seed: '123',
failFast: true,
failSpecWithNoExpectations: true,
oneFailurePerSpec: true,
stopSpecOnExpectationFailure: true,
stopOnSpecFailure: true,
hideDisabled: true
@@ -76,9 +126,7 @@ describe('Env', function() {
env.configure({
random: undefined,
seed: undefined,
failFast: undefined,
failSpecWithNoExpectations: undefined,
oneFailurePerSpec: undefined,
stopSpecOnExpectationFailure: undefined,
stopOnSpecFailure: undefined,
hideDisabled: undefined
@@ -89,91 +137,8 @@ describe('Env', function() {
);
});
it('sets stopOnSpecFailure when failFast is set, and vice versa', function() {
env.configure({ failFast: true });
expect(env.configuration()).toEqual(
jasmine.objectContaining({
failFast: true,
stopOnSpecFailure: true
})
);
env.configure({ stopOnSpecFailure: false });
expect(env.configuration()).toEqual(
jasmine.objectContaining({
failFast: false,
stopOnSpecFailure: false
})
);
});
it('rejects a single call that sets stopOnSpecFailure and failFast to different values', function() {
expect(function() {
env.configure({ failFast: true, stopOnSpecFailure: false });
}).toThrowError(
'stopOnSpecFailure and failFast are aliases for each ' +
"other. Don't set failFast if you also set stopOnSpecFailure."
);
});
it('sets stopSpecOnExpectationFailure when oneFailurePerSpec is set, and vice versa', function() {
env.configure({ oneFailurePerSpec: true });
expect(env.configuration()).toEqual(
jasmine.objectContaining({
oneFailurePerSpec: true,
stopSpecOnExpectationFailure: true
})
);
env.configure({ stopSpecOnExpectationFailure: false });
expect(env.configuration()).toEqual(
jasmine.objectContaining({
oneFailurePerSpec: false,
stopSpecOnExpectationFailure: false
})
);
});
it('rejects a single call that sets stopSpecOnExpectationFailure and oneFailurePerSpec to different values', function() {
expect(function() {
env.configure({
oneFailurePerSpec: true,
stopSpecOnExpectationFailure: false
});
}).toThrowError(
'stopSpecOnExpectationFailure and oneFailurePerSpec are ' +
"aliases for each other. Don't set oneFailurePerSpec if you also set " +
'stopSpecOnExpectationFailure.'
);
});
describe('promise library', function() {
it('can be configured without a custom library', function() {
env.configure({});
env.configure({ Promise: undefined });
});
it('can be configured with a custom library', function() {
var myLibrary = {
resolve: jasmine.createSpy(),
reject: jasmine.createSpy()
};
env.configure({ Promise: myLibrary });
});
it('cannot be configured with an invalid promise library', function() {
var myLibrary = {};
expect(function() {
env.configure({ Promise: myLibrary });
}).toThrowError(
'Custom promise library missing `resolve`/`reject` functions'
);
});
});
it('defaults to multiple failures for specs', function() {
spyOn(jasmineUnderTest, 'Spec');
spyOn(jasmineUnderTest, 'Spec').and.callThrough();
env.it('bar', function() {});
expect(jasmineUnderTest.Spec).toHaveBeenCalledWith(
jasmine.objectContaining({
@@ -192,7 +157,40 @@ describe('Env', function() {
);
});
function behavesLikeDescribe(methodName) {
it('returns a suite metadata object', function() {
let innerSuite;
let spec;
const suite = env.describe('outer suite', function() {
innerSuite = env.describe('inner suite', function() {
spec = env.it('a spec');
});
});
expect(suite.parentSuite).toEqual(
jasmine.objectContaining({
description: 'Jasmine__TopLevel__Suite'
})
);
expect(suite.parentSuite.pend).toBeUndefined();
expect(suite.pend).toBeUndefined();
expect(suite.description).toEqual('outer suite');
expect(suite.getFullName()).toEqual('outer suite');
expect(suite.id).toBeInstanceOf(String);
expect(suite.id).not.toEqual('');
expect(suite.children.length).toEqual(1);
expect(suite.children[0]).toBe(innerSuite);
expect(innerSuite.children.length).toEqual(1);
expect(innerSuite.children[0]).toBe(spec);
expect(innerSuite.getFullName()).toEqual('outer suite inner suite');
expect(innerSuite.parentSuite).toBe(suite);
expect(spec.getFullName()).toEqual('outer suite inner suite a spec');
});
}
describe('#describe', function() {
behavesLikeDescribe('describe');
it('throws an error when given arguments', function() {
expect(function() {
env.describe('done method', function(done) {});
@@ -228,14 +226,56 @@ describe('Env', function() {
);
expect(function() {
env.describe('fn arg', function() {});
env.describe('fn arg', function() {
env.it('has a spec', function() {});
});
}).not.toThrowError(
'describe expects a function argument; received [object Function]'
);
});
it('throws an error when it has no children', function() {
expect(function() {
env.describe('done method', function() {});
}).toThrowError('describe with no children (describe() or it())');
});
});
describe('#fdescribe', function() {
behavesLikeDescribe('fdescribe');
});
describe('xdescribe', function() {
behavesLikeDescribe('xdescribe');
});
function behavesLikeIt(methodName) {
it('returns a spec metadata object', function() {
let spec;
env.describe('a suite', function() {
spec = env[methodName]('a spec', function() {});
});
expect(spec.description)
.withContext('description')
.toEqual('a spec');
expect(spec.getFullName())
.withContext('getFullName')
.toEqual('a suite a spec');
expect(spec.id)
.withContext('id')
.toBeInstanceOf(String);
expect(spec.id)
.withContext('id')
.not.toEqual('');
expect(spec.pend).toBeFalsy();
});
}
describe('#it', function() {
behavesLikeIt('it');
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.it('undefined arg', null);
@@ -251,9 +291,8 @@ describe('Env', function() {
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.it('async', jasmine.getEnv().makeAsyncAwaitFunction());
env.it('async', async function() {});
}).not.toThrow();
});
@@ -265,9 +304,11 @@ describe('Env', function() {
});
describe('#xit', function() {
behavesLikeIt('xit');
it('calls spec.exclude with "Temporarily disabled with xit"', function() {
var excludeSpy = jasmine.createSpy();
spyOn(env, 'it').and.returnValue({
spyOn(env, 'it_').and.returnValue({
exclude: excludeSpy
});
env.xit('foo', function() {});
@@ -278,7 +319,7 @@ describe('Env', function() {
var pendSpy = jasmine.createSpy();
var realExclude = jasmineUnderTest.Spec.prototype.exclude;
spyOn(env, 'it').and.returnValue({
spyOn(env, 'it_').and.returnValue({
exclude: realExclude,
pend: pendSpy
});
@@ -301,14 +342,15 @@ describe('Env', function() {
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.xit('async', jasmine.getEnv().makeAsyncAwaitFunction());
env.xit('async', async function() {});
}).not.toThrow();
});
});
describe('#fit', function() {
behavesLikeIt('fit');
it('throws an error when it receives a non-fn argument', function() {
expect(function() {
env.fit('undefined arg', undefined);
@@ -334,9 +376,8 @@ describe('Env', function() {
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.beforeEach(jasmine.getEnv().makeAsyncAwaitFunction());
env.beforeEach(async function() {});
}).not.toThrow();
});
@@ -357,9 +398,8 @@ describe('Env', function() {
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.beforeAll(jasmine.getEnv().makeAsyncAwaitFunction());
env.beforeAll(async function() {});
}).not.toThrow();
});
@@ -380,9 +420,8 @@ describe('Env', function() {
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.afterEach(jasmine.getEnv().makeAsyncAwaitFunction());
env.afterEach(async function() {});
}).not.toThrow();
});
@@ -403,9 +442,8 @@ describe('Env', function() {
});
it('accepts an async function', function() {
jasmine.getEnv().requireAsyncAwait();
expect(function() {
env.afterAll(jasmine.getEnv().makeAsyncAwaitFunction());
env.afterAll(async function() {});
}).not.toThrow();
});
@@ -514,36 +552,38 @@ describe('Env', function() {
});
});
it("does not expose the suite as 'this'", function() {
var suiteThis;
spyOn(env, 'deprecated');
env.describe('a suite', function() {
suiteThis = this;
env.it('has a spec');
});
expect(suiteThis).not.toBeInstanceOf(jasmineUnderTest.Suite);
});
describe('#execute', function() {
it('returns a promise when the environment supports promises', function() {
jasmine.getEnv().requirePromises();
it('returns a promise', function() {
expect(env.execute()).toBeInstanceOf(Promise);
});
it('returns a promise when a custom promise constructor is provided', function() {
function CustomPromise() {}
CustomPromise.resolve = function() {};
CustomPromise.reject = function() {};
env.configure({ Promise: CustomPromise });
expect(env.execute()).toBeInstanceOf(CustomPromise);
});
it('returns undefined when promises are unavailable', function() {
jasmine.getEnv().requireNoPromises();
expect(env.execute()).toBeUndefined();
});
it('should reset the topSuite when run twice', function() {
jasmine.getEnv().requirePromises();
spyOn(env.topSuite(), 'reset');
spyOn(jasmineUnderTest.Suite.prototype, 'reset');
return env
.execute() // 1
.then(function() {
return env.execute(); // 2
})
.then(function() {
expect(env.topSuite().reset).toHaveBeenCalledOnceWith();
var id;
expect(
jasmineUnderTest.Suite.prototype.reset
).toHaveBeenCalledOnceWith();
id = jasmineUnderTest.Suite.prototype.reset.calls.thisFor(0).id;
expect(id).toBeTruthy();
expect(id).toEqual(env.topSuite().id);
});
});
});

View File

@@ -225,5 +225,61 @@ describe('ExceptionFormatter', function() {
expect(result).toMatch(/error properties:.*someProperty.*hello there/);
});
describe('When omitMessage is true', function() {
it('filters the message from V8-style stack traces', function() {
const error = {
message: 'nope',
stack:
'Error: nope\n' +
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' at fn2 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
' at fn3 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)\n'
};
const subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
});
const result = subject.stack(error, { omitMessage: true });
expect(result).toEqual(
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
' at <Jasmine>\n' +
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)'
);
});
it('handles Webkit style traces that do not include a message', function() {
const error = {
stack:
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
'fn1@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
'fn2@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
};
const subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
});
const result = subject.stack(error, { omitMessage: true });
expect(result).toEqual(
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
'<Jasmine>\n' +
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
);
});
it('ensures that stack traces do not include the message in this environment', function() {
let error;
try {
throw new Error('an error');
} catch (e) {
error = e;
}
const subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: jasmine.util.jasmineFile()
});
const result = subject.stack(error, { omitMessage: true });
expect(result).not.toContain('an error');
});
});
});
});

View File

@@ -33,7 +33,11 @@ describe('Exceptions:', function() {
});
it('should handle exceptions thrown directly in top-level describe blocks and continue', function(done) {
var secondDescribe = jasmine.createSpy('second describe');
var secondDescribe = jasmine
.createSpy('second describe')
.and.callFake(function() {
env.it('has a test', function() {});
});
env.describe('a suite that throws an exception', function() {
env.it('is a test that should pass', function() {
this.expect(true).toEqual(true);

View File

@@ -50,7 +50,9 @@ describe('buildExpectationResult', function() {
stackFormatter: stackFormatter
});
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
expect(stackFormatter).toHaveBeenCalledWith(fakeError, {
omitMessage: true
});
expect(result.stack).toEqual('foo');
});
@@ -66,7 +68,9 @@ describe('buildExpectationResult', function() {
stackFormatter: stackFormatter
});
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
expect(stackFormatter).toHaveBeenCalledWith(fakeError, {
omitMessage: true
});
expect(result.stack).toEqual('foo');
});

View File

@@ -40,24 +40,19 @@ describe('Expectation', function() {
matchersUtil = {
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
},
customEqualityTesters = ['a'],
addExpectationResult = jasmine.createSpy('addExpectationResult'),
expectation;
expectation = jasmineUnderTest.Expectation.factory({
matchersUtil: matchersUtil,
customMatchers: matchers,
customEqualityTesters: customEqualityTesters,
actual: 'an actual',
addExpectationResult: addExpectationResult
});
expectation.toFoo('hello');
expect(matcherFactory).toHaveBeenCalledWith(
matchersUtil,
customEqualityTesters
);
expect(matcherFactory).toHaveBeenCalledWith(matchersUtil);
});
it("wraps matchers's compare functions, passing the actual and expected", function() {

View File

@@ -99,7 +99,7 @@ describe('JsApiReporter', function() {
});
describe('#suiteResults', function() {
var reporter, suiteResult1, suiteResult2;
var reporter, suiteStarted1, suiteResult1, suiteResult2;
beforeEach(function() {
reporter = new jasmineUnderTest.JsApiReporter({});
suiteStarted1 = {

View File

@@ -96,24 +96,6 @@ describe('FakeDate', function() {
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 jasmineUnderTest.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 {

View File

@@ -18,8 +18,7 @@ describe('PrettyPrinter', function() {
describe('stringify sets', function() {
it('should stringify sets properly', function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set(); // eslint-disable-line compat/compat
var set = new Set();
set.add(1);
set.add(2);
var pp = jasmineUnderTest.makePrettyPrinter();
@@ -27,12 +26,11 @@ describe('PrettyPrinter', function() {
});
it('should truncate sets with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
jasmine.getEnv().requireFunctioningSets();
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
var set = new Set(); // eslint-disable-line compat/compat
var set = new Set();
set.add('a');
set.add('b');
set.add('c');
@@ -46,20 +44,18 @@ describe('PrettyPrinter', function() {
describe('stringify maps', function() {
it('should stringify maps properly', function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map(); // eslint-disable-line compat/compat
var map = new Map();
map.set(1, 2);
var pp = jasmineUnderTest.makePrettyPrinter();
expect(pp(map)).toEqual('Map( [ 1, 2 ] )');
});
it('should truncate maps with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
jasmine.getEnv().requireFunctioningMaps();
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
try {
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
var map = new Map(); // eslint-disable-line compat/compat
var map = new Map();
map.set('a', 1);
map.set('b', 2);
map.set('c', 3);
@@ -272,15 +268,13 @@ describe('PrettyPrinter', function() {
});
it('should stringify immutable circular objects', function() {
if (Object.freeze) {
var pp = jasmineUnderTest.makePrettyPrinter();
var frozenObject = { foo: { bar: 'baz' } };
frozenObject.circular = frozenObject;
frozenObject = Object.freeze(frozenObject);
expect(pp(frozenObject)).toEqual(
"Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })"
);
}
var pp = jasmineUnderTest.makePrettyPrinter();
var frozenObject = { foo: { bar: 'baz' } };
frozenObject.circular = frozenObject;
frozenObject = Object.freeze(frozenObject);
expect(pp(frozenObject)).toEqual(
"Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })"
);
});
it('should stringify RegExp objects properly', function() {
@@ -299,20 +293,15 @@ describe('PrettyPrinter', function() {
it('should indicate getters on objects as such', function() {
var pp = jasmineUnderTest.makePrettyPrinter();
var sampleValue = { id: 1 };
if (sampleValue.__defineGetter__) {
//not supported in IE!
sampleValue.__defineGetter__('calculatedValue', function() {
var sampleValue = {
id: 1,
get calculatedValue() {
throw new Error("don't call me!");
});
}
if (sampleValue.__defineGetter__) {
expect(pp(sampleValue)).toEqual(
'Object({ id: 1, calculatedValue: <getter> })'
);
} else {
expect(pp(sampleValue)).toEqual('Object({ id: 1 })');
}
}
};
expect(pp(sampleValue)).toEqual(
'Object({ id: 1, calculatedValue: <getter> })'
);
});
it('should not do HTML escaping of strings', function() {

View File

@@ -18,26 +18,6 @@ describe('QueueRunner', function() {
expect(calls).toEqual(['fn1', 'fn2']);
});
it('runs cleanup functions after the others', function() {
var calls = [],
queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1],
cleanupFns: [queueableFn2]
});
queueableFn1.fn.and.callFake(function() {
calls.push('fn1');
});
queueableFn2.fn.and.callFake(function() {
calls.push('fn2');
});
queueRunner.execute();
expect(calls).toEqual(['fn1', 'fn2']);
});
it("calls each function with a consistent 'this'-- an empty object", function() {
var queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
@@ -149,31 +129,33 @@ describe('QueueRunner', function() {
expect(queueableFn2.fn).toHaveBeenCalled();
});
it('explicitly fails an async function when next is called with an Error and moves to the next function', function() {
var err = new Error('foo'),
queueableFn1 = {
fn: function(done) {
setTimeout(function() {
done(err);
}, 100);
}
},
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
fail: failFn
});
describe('When next is called with an argument', function() {
it('explicitly fails and moves to the next function', function() {
var err = 'anything except undefined',
queueableFn1 = {
fn: function(done) {
setTimeout(function() {
done(err);
}, 100);
}
},
queueableFn2 = { fn: jasmine.createSpy('fn2') },
failFn = jasmine.createSpy('fail'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
fail: failFn
});
queueRunner.execute();
queueRunner.execute();
expect(failFn).not.toHaveBeenCalled();
expect(queueableFn2.fn).not.toHaveBeenCalled();
expect(failFn).not.toHaveBeenCalled();
expect(queueableFn2.fn).not.toHaveBeenCalled();
jasmine.clock().tick(100);
jasmine.clock().tick(100);
expect(failFn).toHaveBeenCalledWith(err);
expect(queueableFn2.fn).toHaveBeenCalled();
expect(failFn).toHaveBeenCalledWith(err);
expect(queueableFn2.fn).toHaveBeenCalled();
});
});
it('does not cause an explicit fail if execution is being stopped', function() {
@@ -225,6 +207,32 @@ describe('QueueRunner', function() {
expect(onComplete).toHaveBeenCalled();
});
it('does not call onMultipleDone if an asynchrnous function completes after timing out', function() {
var timeout = 3,
queueableFn = {
fn: function(done) {
queueableFnDone = done;
},
type: 'queueable',
timeout: timeout
},
onComplete = jasmine.createSpy('onComplete'),
onMultipleDone = jasmine.createSpy('onMultipleDone'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
onComplete: onComplete,
onMultipleDone: onMultipleDone
}),
queueableFnDone;
queueRunner.execute();
jasmine.clock().tick(timeout);
queueableFnDone();
expect(onComplete).toHaveBeenCalled();
expect(onMultipleDone).not.toHaveBeenCalled();
});
it('by default does not set a timeout for asynchronous functions', function() {
var beforeFn = { fn: function(done) {} },
queueableFn = { fn: jasmine.createSpy('fn') },
@@ -300,13 +308,16 @@ describe('QueueRunner', function() {
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
onMultipleDone = jasmine.createSpy('onMultipleDone'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn]
queueableFns: [queueableFn, nextQueueableFn],
onMultipleDone: onMultipleDone
});
queueRunner.execute();
jasmine.clock().tick(1);
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
expect(onMultipleDone).toHaveBeenCalled();
});
it('does not move to the next spec if done is called after an exception has ended the spec', function() {
@@ -317,13 +328,17 @@ describe('QueueRunner', function() {
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
deprecated = jasmine.createSpy('deprecated'),
queueRunner = new jasmineUnderTest.QueueRunner({
deprecated: deprecated,
queueableFns: [queueableFn, nextQueueableFn]
});
queueRunner.execute();
jasmine.clock().tick(1);
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
// Don't issue a deprecation. The error already tells the user that
// something went wrong.
expect(deprecated).not.toHaveBeenCalled();
});
it('should return a null when you call done', function() {
@@ -456,20 +471,20 @@ describe('QueueRunner', function() {
}, 100);
return p1;
}
};
(queueableFn2 = {
fn: function() {
fnCallback();
setTimeout(function() {
p2.resolveHandler();
}, 100);
return p2;
}
}),
(queueRunner = new jasmineUnderTest.QueueRunner({
},
queueableFn2 = {
fn: function() {
fnCallback();
setTimeout(function() {
p2.resolveHandler();
}, 100);
return p2;
}
},
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
onComplete: onComplete
}));
});
queueRunner.execute();
expect(fnCallback).not.toHaveBeenCalled();
@@ -513,46 +528,43 @@ describe('QueueRunner', function() {
expect(queueableFn2.fn).toHaveBeenCalled();
});
it('issues a deprecation if the function also takes a parameter', function() {
it('issues an error if the function also takes a parameter', function() {
var queueableFn = {
fn: function(done) {
return new StubPromise();
}
},
deprecated = jasmine.createSpy('deprecated'),
onException = jasmine.createSpy('onException'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
deprecated: deprecated
}),
env = jasmineUnderTest.getEnv();
onException: onException
});
queueRunner.execute();
expect(deprecated).toHaveBeenCalledWith(
expect(onException).toHaveBeenCalledWith(
'An asynchronous ' +
'before/it/after function took a done callback but also returned a ' +
'promise. This is not supported and will stop working in the future. ' +
'promise. ' +
'Either remove the done callback (recommended) or change the function ' +
'to not return a promise.'
);
});
it('issues a more specific deprecation if the function is `async`', function() {
jasmine.getEnv().requireAsyncAwait();
it('issues a more specific error if the function is `async`', function() {
eval('var fn = async function(done){};');
var deprecated = jasmine.createSpy('deprecated'),
var onException = jasmine.createSpy('onException'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [{ fn: fn }],
deprecated: deprecated
onException: onException
});
queueRunner.execute();
expect(deprecated).toHaveBeenCalledWith(
expect(onException).toHaveBeenCalledWith(
'An asynchronous ' +
'before/it/after function was defined with the async keyword but ' +
'also took a done callback. This is not supported and will stop ' +
'working in the future. Either remove the done callback ' +
'also took a done callback. Either remove the done callback ' +
'(recommended) or remove the async keyword.'
);
});
@@ -617,6 +629,67 @@ describe('QueueRunner', function() {
expect(nextQueueableFn.fn).toHaveBeenCalled();
});
describe('When configured with a skip policy', function() {
it('instantiates the skip policy', function() {
const SkipPolicy = jasmine.createSpy('SkipPolicy ctor');
const queueableFns = [{ fn: () => {} }, { fn: () => {} }];
new jasmineUnderTest.QueueRunner({
queueableFns,
SkipPolicy
});
expect(SkipPolicy).toHaveBeenCalledWith(queueableFns);
});
it('uses the skip policy to determine which fn to run next', function() {
const queueableFns = [
{ fn: jasmine.createSpy('fn0') },
{ fn: jasmine.createSpy('fn1') },
{ fn: jasmine.createSpy('fn2').and.throwError(new Error('nope')) },
{ fn: jasmine.createSpy('fn3') }
];
const skipPolicy = jasmine.createSpyObj('skipPolicy', [
'skipTo',
'fnErrored'
]);
skipPolicy.skipTo.and.callFake(function(lastRanIx) {
return lastRanIx === 0 ? 2 : lastRanIx + 1;
});
const queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns,
SkipPolicy: function() {
return skipPolicy;
}
});
queueRunner.execute();
expect(skipPolicy.skipTo).toHaveBeenCalledWith(0);
expect(skipPolicy.skipTo).toHaveBeenCalledWith(2);
expect(skipPolicy.fnErrored).toHaveBeenCalledWith(2);
expect(queueableFns[0].fn).toHaveBeenCalled();
expect(queueableFns[1].fn).not.toHaveBeenCalled();
expect(queueableFns[2].fn).toHaveBeenCalled();
expect(queueableFns[3].fn).toHaveBeenCalled();
});
it('throws if the skip policy returns the current fn', function() {
const skipPolicy = { skipTo: i => i };
const queueableFns = [{ fn: () => {} }];
const queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns,
SkipPolicy: function() {
return skipPolicy;
}
});
expect(function() {
queueRunner.execute();
}).toThrowError("Can't skip to the same queueable fn that just finished");
});
});
describe('When configured to complete on first error', function() {
it('skips to cleanup functions on the first exception', function() {
var queueableFn = {
@@ -625,13 +698,15 @@ describe('QueueRunner', function() {
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
cleanupFn = {
fn: jasmine.createSpy('cleanup'),
type: 'specCleanup'
},
onComplete = jasmine.createSpy('onComplete'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
onComplete: onComplete,
completeOnFirstError: true
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
});
queueRunner.execute();
@@ -647,13 +722,16 @@ describe('QueueRunner', function() {
cleanupFn1 = {
fn: function() {
throw new Error('error');
}
},
type: 'afterEach'
},
cleanupFn2 = {
fn: jasmine.createSpy('cleanupFn2'),
type: 'afterEach'
},
cleanupFn2 = { fn: jasmine.createSpy('cleanupFn2') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
cleanupFns: [cleanupFn1, cleanupFn2],
completeOnFirstError: true
queueableFns: [queueableFn, cleanupFn1, cleanupFn2],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
});
queueRunner.execute();
@@ -677,7 +755,7 @@ describe('QueueRunner', function() {
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
cleanupFn = { fn: jasmine.createSpy('cleanup'), type: 'specCleanup' },
queueRunner = new jasmineUnderTest.QueueRunner({
globalErrors: {
pushListener: function(f) {
@@ -687,9 +765,8 @@ describe('QueueRunner', function() {
errorListeners.pop();
}
},
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true
queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
}),
queueableFnDone;
@@ -708,11 +785,10 @@ describe('QueueRunner', function() {
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
cleanupFn = { fn: jasmine.createSpy('cleanup'), type: 'specCleanup' },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true
queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
});
queueRunner.execute();
@@ -728,11 +804,13 @@ describe('QueueRunner', function() {
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
cleanupFn = {
fn: jasmine.createSpy('cleanup'),
type: 'specCleanup'
},
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true
queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
});
queueRunner.execute();

View File

@@ -0,0 +1,84 @@
describe('SkipAfterBeforeAllErrorPolicy', function() {
describe('#skipTo', function() {
describe('When nothing has errored', function() {
it('does not skip anything', function() {
const policy = new jasmineUnderTest.SkipAfterBeforeAllErrorPolicy(
arrayOfArbitraryFns(4)
);
expect(policy.skipTo(0)).toEqual(1);
expect(policy.skipTo(1)).toEqual(2);
expect(policy.skipTo(2)).toEqual(3);
expect(policy.skipTo(3)).toEqual(4);
});
});
describe('When anything but a beforeAll has errored', function() {
it('does not skip anything', function() {
const policy = new jasmineUnderTest.SkipAfterBeforeAllErrorPolicy(
arrayOfArbitraryFns(4)
);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(1);
policy.fnErrored(1);
expect(policy.skipTo(1)).toEqual(2);
policy.fnErrored(2);
expect(policy.skipTo(2)).toEqual(3);
policy.fnErrored(3);
expect(policy.skipTo(3)).toEqual(4);
});
});
describe('When a beforeAll has errored', function() {
it('skips subsequent functions other than afterAll', function() {
const suite = {};
const fns = [
{ type: 'beforeAll', fn: () => {}, suite },
{ fn: () => {} },
{ fn: () => {} },
{ type: 'afterAll', fn: () => {} },
{ type: 'afterAll', fn: () => {} }
];
const policy = new jasmineUnderTest.SkipAfterBeforeAllErrorPolicy(fns);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(3);
expect(policy.skipTo(3)).toEqual(4);
});
});
});
describe('#fnErrored', function() {
describe('When the fn is a beforeAll', function() {
it("sets the suite's hadBeforeAllFailure property to true", function() {
const suite = {};
const fns = [{ type: 'beforeAll', fn: () => {}, suite }];
const policy = new jasmineUnderTest.SkipAfterBeforeAllErrorPolicy(fns);
policy.fnErrored(0);
expect(suite.hadBeforeAllFailure).toBeTrue();
});
});
describe('When the fn is not a beforeAll', function() {
it('does not try to access the suite, which is probably not there', function() {
const fns = [{ fn: () => {} /* no suite */ }];
const policy = new jasmineUnderTest.SkipAfterBeforeAllErrorPolicy(fns);
expect(() => policy.fnErrored(0)).not.toThrow();
});
});
});
});
function arrayOfArbitraryFns(n) {
const result = [];
for (let i = 0; i < n; i++) {
result.push({ fn: () => {} });
}
return result;
}

View File

@@ -61,10 +61,6 @@ describe('Spec', function() {
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
// TODO: due to some issue with the Pretty Printer, this line fails, but the other two pass.
// This means toHaveBeenCalledWith on IE8 will always be broken.
// expect(startCallback).toHaveBeenCalledWith(spec);
expect(startCallback).toHaveBeenCalled();
expect(startCallback.calls.first().object).toEqual(spec);
});
@@ -120,9 +116,13 @@ describe('Spec', function() {
expect(options.queueableFns).toEqual([
{ fn: jasmine.any(Function) },
before,
queueableFn
queueableFn,
after,
{
fn: jasmine.any(Function),
type: 'specCleanup'
}
]);
expect(options.cleanupFns).toEqual([after, { fn: jasmine.any(Function) }]);
});
it("tells the queue runner that it's a leaf node", function() {
@@ -175,8 +175,13 @@ describe('Spec', function() {
expect(fakeQueueRunner).toHaveBeenCalledWith(
jasmine.objectContaining({
onComplete: jasmine.any(Function),
queueableFns: [{ fn: jasmine.any(Function) }],
cleanupFns: [{ fn: jasmine.any(Function) }]
queueableFns: [
{ fn: jasmine.any(Function) },
{
fn: jasmine.any(Function),
type: 'specCleanup'
}
]
})
);
expect(specBody).not.toHaveBeenCalled();
@@ -184,7 +189,7 @@ describe('Spec', function() {
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled();
args.cleanupFns[0].fn();
args.queueableFns[args.queueableFns.length - 1].fn();
expect(resultCallback).toHaveBeenCalled();
expect(spec.result.status).toBe('excluded');
@@ -216,7 +221,7 @@ describe('Spec', function() {
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled();
args.cleanupFns[0].fn('things');
args.queueableFns[1].fn('things');
expect(resultCallback).toHaveBeenCalledWith(
{
id: spec.id,
@@ -228,7 +233,8 @@ describe('Spec', function() {
deprecationWarnings: [],
pendingReason: '',
duration: jasmine.any(Number),
properties: null
properties: null,
debugLogs: null
},
'things'
);
@@ -287,9 +293,6 @@ describe('Spec', function() {
config.queueableFns.forEach(function(qf) {
qf.fn();
});
config.cleanupFns.forEach(function(qf) {
qf.fn();
});
config.onComplete();
},
timer: timer
@@ -357,7 +360,9 @@ describe('Spec', function() {
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
const fns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
fns[fns.length - 1].fn();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
'expectation1'
]);
@@ -386,7 +391,8 @@ describe('Spec', function() {
spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
const fns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
fns[fns.length - 1].fn();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
'passed'
]);
@@ -485,7 +491,7 @@ describe('Spec', function() {
spec.execute();
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.cleanupFns[0].fn();
args.queueableFns[args.queueableFns.length - 1].fn();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
{
error: 'foo',
@@ -513,7 +519,140 @@ describe('Spec', function() {
spec.execute();
var args = fakeQueueRunner.calls.mostRecent().args[0];
args.cleanupFns[0].fn();
args.queueableFns[args.queueableFns.length - 1].fn();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
});
it('treats multiple done calls as late errors', function() {
var queueRunnerFactory = jasmine.createSpy('queueRunnerFactory'),
onLateError = jasmine.createSpy('onLateError'),
spec = new jasmineUnderTest.Spec({
onLateError: onLateError,
queueableFn: { fn: function() {} },
queueRunnerFactory: queueRunnerFactory,
getSpecName: function() {
return 'a spec';
}
});
spec.execute();
expect(queueRunnerFactory).toHaveBeenCalled();
queueRunnerFactory.calls.argsFor(0)[0].onMultipleDone();
expect(onLateError).toHaveBeenCalledTimes(1);
expect(onLateError.calls.argsFor(0)[0]).toBeInstanceOf(Error);
expect(onLateError.calls.argsFor(0)[0].message).toEqual(
'An asynchronous spec, beforeEach, or afterEach function called its ' +
"'done' callback more than once.\n(in spec: a spec)"
);
});
describe('#trace', function() {
it('adds the messages to the result', function() {
var timer = jasmine.createSpyObj('timer', ['start', 'elapsed']),
spec = new jasmineUnderTest.Spec({
queueableFn: {
fn: function() {}
},
queueRunnerFactory: function() {},
timer: timer
}),
t1 = 123,
t2 = 456;
spec.execute();
expect(spec.result.debugLogs).toBeNull();
timer.elapsed.and.returnValue(t1);
spec.debugLog('msg 1');
expect(spec.result.debugLogs).toEqual([
{ message: 'msg 1', timestamp: t1 }
]);
timer.elapsed.and.returnValue(t2);
spec.debugLog('msg 2');
expect(spec.result.debugLogs).toEqual([
{ message: 'msg 1', timestamp: t1 },
{ message: 'msg 2', timestamp: t2 }
]);
});
describe('When the spec passes', function() {
it('omits the messages from the reported result', function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
queueableFn: {
fn: function() {}
},
resultCallback: resultCallback,
queueRunnerFactory: function(config) {
spec.debugLog('msg');
for (const fn of config.queueableFns) {
fn.fn();
}
config.onComplete(false);
}
});
spec.execute(function() {});
expect(resultCallback).toHaveBeenCalledWith(
jasmine.objectContaining({ debugLogs: null }),
undefined
);
});
it('removes the messages to save memory', function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new jasmineUnderTest.Spec({
queueableFn: {
fn: function() {}
},
resultCallback: resultCallback,
queueRunnerFactory: function(config) {
spec.debugLog('msg');
for (const fn of config.queueableFns) {
fn.fn();
}
config.onComplete(false);
}
});
spec.execute(function() {});
expect(resultCallback).toHaveBeenCalled();
expect(spec.result.debugLogs).toBeNull();
});
});
describe('When the spec fails', function() {
it('includes the messages in the reported result', function() {
var resultCallback = jasmine.createSpy('resultCallback'),
timer = jasmine.createSpyObj('timer', ['start', 'elapsed']),
spec = new jasmineUnderTest.Spec({
queueableFn: {
fn: function() {}
},
resultCallback: resultCallback,
queueRunnerFactory: function(config) {
spec.debugLog('msg');
spec.onException(new Error('nope'));
for (const fn of config.queueableFns) {
fn.fn();
}
config.onComplete(true);
},
timer: timer
}),
timestamp = 12345;
timer.elapsed.and.returnValue(timestamp);
spec.execute(function() {});
expect(resultCallback).toHaveBeenCalledWith(
jasmine.objectContaining({
debugLogs: [{ message: 'msg', timestamp: timestamp }]
}),
undefined
);
});
});
});
});

View File

@@ -31,12 +31,7 @@ describe('Spies', function() {
var fn = function test() {};
var spy = env.createSpy(fn);
// IE doesn't do `.name`
if (fn.name === 'test') {
expect(spy.and.identity).toEqual('test');
} else {
expect(spy.and.identity).toEqual('unknown');
}
expect(spy.and.identity).toEqual('test');
});
it('warns the user that we intend to overwrite an existing property', function() {
@@ -236,7 +231,7 @@ describe('Spies', function() {
expect(spy('baz', 'grault', 'waldo')).toEqual(42);
});
it('uses custom equality testers when selecting a strategy', function() {
it('uses asymmetric equality testers when selecting a strategy', function() {
var spy = env.createSpy('foo');
spy.and.returnValue(42);
spy.withArgs(jasmineUnderTest.any(String)).and.returnValue(-1);
@@ -245,6 +240,23 @@ describe('Spies', function() {
expect(spy({})).toEqual(42);
});
it('uses the provided matchersUtil selecting a strategy', function() {
const matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [
function(a, b) {
if ((a === 'bar' && b === 'baz') || (a === 'baz' && b === 'bar')) {
return true;
}
}
]
});
const spy = new jasmineUnderTest.Spy('aSpy', matchersUtil);
spy.and.returnValue('default strategy return value');
spy.withArgs('bar').and.returnValue('custom strategy return value');
expect(spy('foo')).toEqual('default strategy return value');
expect(spy('baz')).toEqual('custom strategy return value');
});
it('can reconfigure an argument-specific strategy', function() {
var spy = env.createSpy('foo');
spy.withArgs('foo').and.returnValue(42);
@@ -253,9 +265,7 @@ describe('Spies', function() {
});
describe('any promise-based strategy', function() {
it('works with global Promise library when available', function(done) {
jasmine.getEnv().requirePromises();
it('works with global Promise library', function(done) {
var spy = env.createSpy('foo').and.resolveTo(42);
spy()
.then(function(result) {
@@ -264,19 +274,6 @@ describe('Spies', function() {
})
.catch(done.fail);
});
it('works with a custom Promise library', function() {
var customPromise = {
resolve: jasmine.createSpy(),
reject: jasmine.createSpy()
};
customPromise.resolve.and.returnValue('resolved');
env.configure({ Promise: customPromise });
var spy = env.createSpy('foo').and.resolveTo(42);
expect(spy()).toEqual('resolved');
expect(customPromise.resolve).toHaveBeenCalledWith(42);
});
});
describe('when withArgs is used without a base strategy', function() {

View File

@@ -108,7 +108,6 @@ describe('SpyStrategy', function() {
});
it('allows a fake async function to be called instead', function(done) {
jasmine.getEnv().requireAsyncAwait();
var originalFn = jasmine.createSpy('original'),
fakeFn = jasmine
.createSpy('fake')
@@ -131,15 +130,9 @@ describe('SpyStrategy', function() {
describe('#resolveTo', function() {
it('allows a resolved promise to be returned', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
fn: originalFn
});
spyStrategy.resolveTo(37);
@@ -153,15 +146,9 @@ describe('SpyStrategy', function() {
});
it('allows an empty resolved promise to be returned', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
fn: originalFn
});
spyStrategy.resolveTo();
@@ -173,30 +160,13 @@ describe('SpyStrategy', function() {
})
.catch(done.fail);
});
it('fails if promises are not available', function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: originalFn });
expect(function() {
spyStrategy.resolveTo(37);
}).toThrowError(
'resolveTo requires global Promise, or `Promise` configured with `jasmine.getEnv().configure()`'
);
});
});
describe('#rejectWith', function() {
it('allows a rejected promise to be returned', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
fn: originalFn
});
spyStrategy.rejectWith(new Error('oops'));
@@ -211,15 +181,9 @@ describe('SpyStrategy', function() {
});
it('allows an empty rejected promise to be returned', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
fn: originalFn
});
spyStrategy.rejectWith();
@@ -234,15 +198,9 @@ describe('SpyStrategy', function() {
});
it('allows a non-Error to be rejected', function(done) {
jasmine.getEnv().requirePromises();
var originalFn = jasmine.createSpy('original'),
getPromise = function() {
return Promise;
},
spyStrategy = new jasmineUnderTest.SpyStrategy({
fn: originalFn,
getPromise: getPromise
fn: originalFn
});
spyStrategy.rejectWith('oops');
@@ -255,17 +213,6 @@ describe('SpyStrategy', function() {
})
.catch(done.fail);
});
it('fails if promises are not available', function() {
var originalFn = jasmine.createSpy('original'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: originalFn });
expect(function() {
spyStrategy.rejectWith(new Error('oops'));
}).toThrowError(
'rejectWith requires global Promise, or `Promise` configured with `jasmine.getEnv().configure()`'
);
});
});
it('allows a custom strategy to be used', function() {
@@ -335,9 +282,9 @@ describe('SpyStrategy', function() {
});
it('allows generator functions to be passed to callFake strategy', function() {
jasmine.getEnv().requireGeneratorFunctions();
var generator = jasmine.getEnv().makeGeneratorFunction('yield "ok";'),
var generator = function*() {
yield 'ok';
},
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: function() {} });
spyStrategy.callFake(generator);

View File

@@ -1,5 +1,5 @@
describe('StackTrace', function() {
it('understands Chrome/IE/Edge style traces', function() {
it('understands Chrome/Edge style traces', function() {
var error = {
message: 'nope',
stack:
@@ -30,7 +30,7 @@ describe('StackTrace', function() {
]);
});
it('understands Chrome/IE/Edge style traces with multiline messages', function() {
it('understands Chrome/Edge style traces with multiline messages', function() {
var error = {
message: 'line 1\nline 2',
stack:
@@ -95,7 +95,7 @@ describe('StackTrace', function() {
]);
});
it('understands Safari/Firefox/Phantom-OS X style traces', function() {
it('understands Safari <=14/Firefox/Phantom-OS X style traces', function() {
var error = {
message: 'nope',
stack:
@@ -122,6 +122,33 @@ describe('StackTrace', function() {
]);
});
it('understands Safari 15 style traces', function() {
var error = {
message: 'nope',
stack:
'@http://localhost:8888/__spec__/core/FooSpec.js:164:24\n' +
'attempt@http://localhost:8888/__jasmine__/jasmine.js:8074:44\n'
};
var result = new jasmineUnderTest.StackTrace(error);
expect(result.message).toBeFalsy();
expect(result.style).toEqual('webkit');
expect(result.frames).toEqual([
{
raw: '@http://localhost:8888/__spec__/core/FooSpec.js:164:24',
func: undefined,
file: 'http://localhost:8888/__spec__/core/FooSpec.js',
line: 164
},
{
raw: 'attempt@http://localhost:8888/__jasmine__/jasmine.js:8074:44',
func: 'attempt',
file: 'http://localhost:8888/__jasmine__/jasmine.js',
line: 8074
}
]);
});
it('does not mistake gibberish for Safari/Firefox/Phantom-OS X style traces', function() {
var error = {
message: 'nope',

View File

@@ -43,32 +43,83 @@ describe('Suite', function() {
expect(suite.getFullName()).toEqual('I am a parent suite I am a suite');
});
it('adds before functions in order of needed execution', function() {
it('adds beforeEach functions in order of needed execution', function() {
var suite = new jasmineUnderTest.Suite({
env: env,
description: 'I am a suite'
}),
outerBefore = jasmine.createSpy('outerBeforeEach'),
innerBefore = jasmine.createSpy('insideBeforeEach');
outerBefore = { fn: 'outerBeforeEach' },
innerBefore = { fn: 'insideBeforeEach' };
suite.beforeEach(outerBefore);
suite.beforeEach(innerBefore);
expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
expect(suite.beforeFns).toEqual([
{ fn: innerBefore.fn, suite },
{ fn: outerBefore.fn, suite }
]);
});
it('adds after functions in order of needed execution', function() {
it('adds beforeAll functions in order of needed execution', function() {
var suite = new jasmineUnderTest.Suite({
env: env,
description: 'I am a suite'
}),
outerAfter = jasmine.createSpy('outerAfterEach'),
innerAfter = jasmine.createSpy('insideAfterEach');
outerBefore = { fn: 'outerBeforeAll' },
innerBefore = { fn: 'insideBeforeAll' };
suite.beforeAll(outerBefore);
suite.beforeAll(innerBefore);
function sameInstance(expected) {
return {
asymmetricMatch: function(actual) {
return actual === expected;
},
jasmineToString: function() {
return `<same instance as ${expected}>`;
}
};
}
expect(suite.beforeAllFns).toEqual([
{ fn: outerBefore.fn, type: 'beforeAll', suite: sameInstance(suite) },
{ fn: innerBefore.fn, type: 'beforeAll', suite: sameInstance(suite) }
]);
});
it('adds afterEach functions in order of needed execution', function() {
var suite = new jasmineUnderTest.Suite({
env: env,
description: 'I am a suite'
}),
outerAfter = { fn: 'outerAfterEach' },
innerAfter = { fn: 'insideAfterEach' };
suite.afterEach(outerAfter);
suite.afterEach(innerAfter);
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
expect(suite.afterFns).toEqual([
{ fn: innerAfter.fn, suite, type: 'afterEach' },
{ fn: outerAfter.fn, suite, type: 'afterEach' }
]);
});
it('adds afterAll functions in order of needed execution', function() {
const suite = new jasmineUnderTest.Suite({
env: env,
description: 'I am a suite'
}),
outerAfter = { fn: 'outerAfterAll' },
innerAfter = { fn: 'insideAfterAl' };
suite.afterAll(outerAfter);
suite.afterAll(innerAfter);
expect(suite.afterAllFns).toEqual([
{ fn: innerAfter.fn, type: 'afterAll' },
{ fn: outerAfter.fn, type: 'afterAll' }
]);
});
it('has a status of failed if any expectations have failed', function() {
@@ -224,4 +275,44 @@ describe('Suite', function() {
expect(result.failedExpectations).toHaveSize(0);
});
});
describe('#onMultipleDone', function() {
it('reports a special error when it is the top suite', function() {
const onLateError = jasmine.createSpy('onLateError');
const suite = new jasmineUnderTest.Suite({
onLateError,
parentSuite: null
});
suite.onMultipleDone();
expect(onLateError).toHaveBeenCalledTimes(1);
expect(onLateError.calls.argsFor(0)[0]).toBeInstanceOf(Error);
expect(onLateError.calls.argsFor(0)[0].message).toEqual(
'A top-level beforeAll or afterAll function called its ' +
"'done' callback more than once."
);
});
it('reports an error including the suite name when it is a normal suite', function() {
const onLateError = jasmine.createSpy('onLateError');
var suite = new jasmineUnderTest.Suite({
onLateError,
description: 'the suite',
parentSuite: {
description: 'the parent suite',
parentSuite: {}
}
});
suite.onMultipleDone();
expect(onLateError).toHaveBeenCalledTimes(1);
expect(onLateError.calls.argsFor(0)[0]).toBeInstanceOf(Error);
expect(onLateError.calls.argsFor(0)[0].message).toEqual(
"An asynchronous beforeAll or afterAll function called its 'done' " +
'callback more than once.\n(in suite: the parent suite the suite)'
);
});
});
});

View File

@@ -14,10 +14,12 @@ describe('Timer', function() {
describe('when date is stubbed, perhaps by other testing helpers', function() {
var origDate = Date;
beforeEach(function() {
// eslint-disable-next-line no-implicit-globals
Date = jasmine.createSpy('date spy');
});
afterEach(function() {
// eslint-disable-next-line no-implicit-globals
Date = origDate;
});

View File

@@ -291,7 +291,8 @@ describe('TreeProcessor', function() {
onComplete: treeComplete,
onException: jasmine.any(Function),
userContext: { root: 'context' },
queueableFns: [{ fn: jasmine.any(Function) }]
queueableFns: [{ fn: jasmine.any(Function) }],
onMultipleDone: null
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
@@ -321,16 +322,19 @@ describe('TreeProcessor', function() {
onComplete: treeComplete,
onException: jasmine.any(Function),
userContext: { root: 'context' },
queueableFns: [{ fn: jasmine.any(Function) }]
queueableFns: [{ fn: jasmine.any(Function) }],
onMultipleDone: null
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn(nodeDone);
expect(queueRunner).toHaveBeenCalledWith({
onComplete: jasmine.any(Function),
onMultipleDone: null,
queueableFns: [{ fn: jasmine.any(Function) }],
userContext: { node: 'context' },
onException: jasmine.any(Function)
onException: jasmine.any(Function),
onMultipleDone: null
});
queueRunner.calls.mostRecent().args[0].queueableFns[0].fn('foo');
@@ -478,7 +482,10 @@ describe('TreeProcessor', function() {
var leaf = new Leaf(),
node = new Node({
children: [leaf],
beforeAllFns: ['beforeAll1', 'beforeAll2']
beforeAllFns: [
{ fn: 'beforeAll1', timeout: 1 },
{ fn: 'beforeAll2', timeout: 2 }
]
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
@@ -498,17 +505,18 @@ describe('TreeProcessor', function() {
expect(queueableFns).toEqual([
{ fn: jasmine.any(Function) },
'beforeAll1',
'beforeAll2',
{ fn: 'beforeAll1', timeout: 1 },
{ fn: 'beforeAll2', timeout: 2 },
{ fn: jasmine.any(Function) }
]);
});
it('runs afterAlls for a node with children', function() {
var leaf = new Leaf(),
afterAllFns = [{ fn: 'afterAll1' }, { fn: 'afterAll2' }],
node = new Node({
children: [leaf],
afterAllFns: ['afterAll1', 'afterAll2']
afterAllFns
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
@@ -529,15 +537,15 @@ describe('TreeProcessor', function() {
expect(queueableFns).toEqual([
{ fn: jasmine.any(Function) },
{ fn: jasmine.any(Function) },
'afterAll1',
'afterAll2'
afterAllFns[0],
afterAllFns[1]
]);
});
it('does not run beforeAlls or afterAlls for a node with no children', function() {
var node = new Node({
beforeAllFns: ['before'],
afterAllFns: ['after']
beforeAllFns: [{ fn: 'before' }],
afterAllFns: [{ fn: 'after' }]
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
@@ -562,8 +570,8 @@ describe('TreeProcessor', function() {
var leaf = new Leaf({ markedPending: true }),
node = new Node({
children: [leaf],
beforeAllFns: ['before'],
afterAllFns: ['after'],
beforeAllFns: [{ fn: 'before' }],
afterAllFns: [{ fn: 'after' }],
markedPending: false
}),
root = new Node({ children: [node] }),

View File

@@ -39,8 +39,7 @@ describe('jasmineUnderTest.util', function() {
};
beforeEach(function() {
jasmine.getEnv().requirePromises();
mockNativePromise = new Promise(function(res, rej) {}); // eslint-disable-line compat/compat
mockNativePromise = new Promise(function(res, rej) {});
mockPromiseLikeObject = new mockPromiseLike();
});

View File

@@ -1,139 +0,0 @@
describe('asymmetricEqualityTesterArgCompatShim', function() {
it('provides all the properties of the MatchersUtil', function() {
var matchersUtil = {
foo: function() {},
bar: function() {}
},
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim(
matchersUtil,
[]
);
expect(shim.foo).toBe(matchersUtil.foo);
expect(shim.bar).toBe(matchersUtil.bar);
});
it('provides all the properties of the customEqualityTesters', function() {
var customEqualityTesters = [function() {}, function() {}],
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim(
{},
customEqualityTesters
);
expect(shim.length).toBe(2);
expect(shim[0]).toBe(customEqualityTesters[0]);
expect(shim[1]).toBe(customEqualityTesters[1]);
});
it('provides all the properties of Array.prototype', function() {
var shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim({}, []);
expect(shim.filter).toBe(Array.prototype.filter);
expect(shim.forEach).toBe(Array.prototype.forEach);
expect(shim.map).toBe(Array.prototype.map);
});
it('provides properties of Array.prototype', function() {
var keys = [
'concat',
'every',
'filter',
'forEach',
'indexOf',
'join',
'lastIndexOf',
'length',
'map',
'pop',
'push',
'reduce',
'reduceRight',
'reverse',
'shift',
'slice',
'some',
'sort',
'splice',
'unshift'
],
optionalKeys = [
'copyWithin',
'entries',
'fill',
'find',
'findIndex',
'flat',
'flatMap',
'includes',
'keys',
'values'
],
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim({}, []),
i,
k;
// Properties that are present on all supported runtimes
for (i = 0; i < keys.length; i++) {
k = keys[i];
expect(shim[k])
.withContext(k)
.not.toBeUndefined();
expect(shim[k])
.withContext(k)
.toBe(Array.prototype[k]);
}
// Properties that are present on only some supported runtimes
for (i = 0; i < optionalKeys.length; i++) {
k = optionalKeys[i];
if (shim[k] !== undefined) {
expect(shim[k])
.withContext(k)
.toBe(Array.prototype[k]);
}
}
});
describe('When Array.prototype additions collide with MatchersUtil methods', function() {
function keys() {
return [
'contains',
'buildFailureMessage',
'asymmetricDiff_',
'asymmetricMatch_',
'equals',
'eq_'
];
}
beforeEach(function() {
keys().forEach(function(k) {
expect(Array.prototype[k])
.withContext('Array.prototype already had ' + k)
.toBeUndefined();
Array.prototype[k] = function() {};
});
});
afterEach(function() {
keys().forEach(function(k) {
delete Array.prototype[k];
});
});
it('uses the MatchersUtil methods', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({}),
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim(
matchersUtil,
[]
);
keys().forEach(function(k) {
expect(shim[k])
.withContext(k + ' was overwritten')
.toBe(jasmineUnderTest.MatchersUtil.prototype[k]);
});
});
});
});

View File

@@ -30,33 +30,27 @@ describe('Any', function() {
});
it('matches a Map', function() {
jasmine.getEnv().requireFunctioningMaps();
var any = new jasmineUnderTest.Any(Map);
expect(any.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(new Map())).toBe(true);
});
it('matches a Set', function() {
jasmine.getEnv().requireFunctioningSets();
var any = new jasmineUnderTest.Any(Set);
expect(any.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(new Set())).toBe(true);
});
it('matches a TypedArray', function() {
var any = new jasmineUnderTest.Any(Uint32Array);
expect(any.asymmetricMatch(new Uint32Array([]))).toBe(true); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(new Uint32Array([]))).toBe(true);
});
it('matches a Symbol', function() {
jasmine.getEnv().requireFunctioningSymbols();
var any = new jasmineUnderTest.Any(Symbol);
var any = new jasmineUnderTest.Any(Symbol); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(Symbol())).toBe(true); // eslint-disable-line compat/compat
expect(any.asymmetricMatch(Symbol())).toBe(true);
});
it('matches another constructed object', function() {

View File

@@ -24,33 +24,27 @@ describe('Anything', function() {
});
it('matches a Map', function() {
jasmine.getEnv().requireFunctioningMaps();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
expect(anything.asymmetricMatch(new Map())).toBe(true);
});
it('matches a Set', function() {
jasmine.getEnv().requireFunctioningSets();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
expect(anything.asymmetricMatch(new Set())).toBe(true);
});
it('matches a TypedArray', function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true); // eslint-disable-line compat/compat
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true);
});
it('matches a Symbol', function() {
jasmine.getEnv().requireFunctioningSymbols();
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(Symbol())).toBe(true); // eslint-disable-line compat/compat
expect(anything.asymmetricMatch(Symbol())).toBe(true);
});
it("doesn't match undefined", function() {

View File

@@ -22,29 +22,27 @@ describe('Empty', function() {
});
it('matches an empty map', function() {
jasmine.getEnv().requireFunctioningMaps();
var empty = new jasmineUnderTest.Empty();
var fullMap = new Map(); // eslint-disable-line compat/compat
var fullMap = new Map();
fullMap.set('thing', 2);
expect(empty.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(new Map())).toBe(true);
expect(empty.asymmetricMatch(fullMap)).toBe(false);
});
it('matches an empty set', function() {
jasmine.getEnv().requireFunctioningSets();
var empty = new jasmineUnderTest.Empty();
var fullSet = new Set(); // eslint-disable-line compat/compat
var fullSet = new Set();
fullSet.add(3);
expect(empty.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(new Set())).toBe(true);
expect(empty.asymmetricMatch(fullSet)).toBe(false);
});
it('matches an empty typed array', function() {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch(new Int16Array())).toBe(true); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(new Int16Array([1, 2]))).toBe(false); // eslint-disable-line compat/compat
expect(empty.asymmetricMatch(new Int16Array())).toBe(true);
expect(empty.asymmetricMatch(new Int16Array([1, 2]))).toBe(false);
});
});

View File

@@ -1,33 +1,19 @@
/* eslint-disable compat/compat */
describe('MapContaining', function() {
function MapI(iterable) {
// for IE11
var map = new Map();
iterable.forEach(function(kv) {
map.set(kv[0], kv[1]);
});
return map;
}
beforeEach(function() {
jasmine.getEnv().requireFunctioningMaps();
});
it('matches any actual map to an empty map', function() {
var actualMap = new MapI([['foo', 'bar']]);
var actualMap = new Map([['foo', 'bar']]);
var containing = new jasmineUnderTest.MapContaining(new Map());
expect(containing.asymmetricMatch(actualMap)).toBe(true);
});
it('matches when all the key/value pairs in sample have matches in actual', function() {
var actualMap = new MapI([
var actualMap = new Map([
['foo', [1, 2, 3]],
[{ foo: 'bar' }, 'baz'],
['other', 'any']
]);
var containingMap = new MapI([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2, 3]]]);
var containingMap = new Map([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2, 3]]]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -35,12 +21,12 @@ describe('MapContaining', function() {
});
it('does not match when a key is not in actual', function() {
var actualMap = new MapI([
var actualMap = new Map([
['foo', [1, 2, 3]],
[{ foo: 'not a bar' }, 'baz']
]);
var containingMap = new MapI([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2, 3]]]);
var containingMap = new Map([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2, 3]]]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -48,9 +34,9 @@ describe('MapContaining', function() {
});
it('does not match when a value is not in actual', function() {
var actualMap = new MapI([['foo', [1, 2, 3]], [{ foo: 'bar' }, 'baz']]);
var actualMap = new Map([['foo', [1, 2, 3]], [{ foo: 'bar' }, 'baz']]);
var containingMap = new MapI([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2]]]);
var containingMap = new Map([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2]]]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -58,13 +44,13 @@ describe('MapContaining', function() {
});
it('matches when all the key/value pairs in sample have asymmetric matches in actual', function() {
var actualMap = new MapI([
var actualMap = new Map([
['foo1', 'not a bar'],
['foo2', 'bar'],
['baz', [1, 2, 3, 4]]
]);
var containingMap = new MapI([
var containingMap = new Map([
[jasmineUnderTest.stringMatching(/^foo\d/), 'bar'],
['baz', jasmineUnderTest.arrayContaining([2, 3])]
]);
@@ -75,9 +61,9 @@ describe('MapContaining', function() {
});
it('does not match when a key in sample has no asymmetric matches in actual', function() {
var actualMap = new MapI([['a-foo1', 'bar'], ['baz', [1, 2, 3, 4]]]);
var actualMap = new Map([['a-foo1', 'bar'], ['baz', [1, 2, 3, 4]]]);
var containingMap = new MapI([
var containingMap = new Map([
[jasmineUnderTest.stringMatching(/^foo\d/), 'bar'],
['baz', jasmineUnderTest.arrayContaining([2, 3])]
]);
@@ -88,9 +74,9 @@ describe('MapContaining', function() {
});
it('does not match when a value in sample has no asymmetric matches in actual', function() {
var actualMap = new MapI([['foo1', 'bar'], ['baz', [1, 2, 3, 4]]]);
var actualMap = new Map([['foo1', 'bar'], ['baz', [1, 2, 3, 4]]]);
var containingMap = new MapI([
var containingMap = new Map([
[jasmineUnderTest.stringMatching(/^foo\d/), 'bar'],
['baz', jasmineUnderTest.arrayContaining([4, 5])]
]);
@@ -101,15 +87,15 @@ describe('MapContaining', function() {
});
it('matches recursively', function() {
var actualMap = new MapI([
['foo', new MapI([['foo1', 1], ['foo2', 2]])],
[new MapI([[1, 'bar1'], [2, 'bar2']]), 'bar'],
var actualMap = new Map([
['foo', new Map([['foo1', 1], ['foo2', 2]])],
[new Map([[1, 'bar1'], [2, 'bar2']]), 'bar'],
['other', 'any']
]);
var containingMap = new MapI([
['foo', new jasmineUnderTest.MapContaining(new MapI([['foo1', 1]]))],
[new jasmineUnderTest.MapContaining(new MapI([[2, 'bar2']])), 'bar']
var containingMap = new Map([
['foo', new jasmineUnderTest.MapContaining(new Map([['foo1', 1]]))],
[new jasmineUnderTest.MapContaining(new Map([[2, 'bar2']])), 'bar']
]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -124,10 +110,8 @@ describe('MapContaining', function() {
? a < 0 && b < 0
: a === b;
}
var actualMap = new MapI([['foo', -1]]);
var containing = new jasmineUnderTest.MapContaining(
new MapI([['foo', -2]])
);
var actualMap = new Map([['foo', -1]]);
var containing = new jasmineUnderTest.MapContaining(new Map([['foo', -2]]));
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
@@ -136,7 +120,7 @@ describe('MapContaining', function() {
});
it('does not match when actual is not a map', function() {
var containingMap = new MapI([['foo', 'bar']]);
var containingMap = new Map([['foo', 'bar']]);
expect(
new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch('foo')
).toBe(false);

View File

@@ -22,22 +22,20 @@ describe('NotEmpty', function() {
});
it('matches a non empty map', function() {
jasmine.getEnv().requireFunctioningMaps();
var notEmpty = new jasmineUnderTest.NotEmpty();
var fullMap = new Map(); // eslint-disable-line compat/compat
var fullMap = new Map();
fullMap.set('one', 1);
var emptyMap = new Map(); // eslint-disable-line compat/compat
var emptyMap = new Map();
expect(notEmpty.asymmetricMatch(fullMap)).toBe(true);
expect(notEmpty.asymmetricMatch(emptyMap)).toBe(false);
});
it('matches a non empty set', function() {
jasmine.getEnv().requireFunctioningSets();
var notEmpty = new jasmineUnderTest.NotEmpty();
var filledSet = new Set(); // eslint-disable-line compat/compat
var filledSet = new Set();
filledSet.add(1);
var emptySet = new Set(); // eslint-disable-line compat/compat
var emptySet = new Set();
expect(notEmpty.asymmetricMatch(filledSet)).toBe(true);
expect(notEmpty.asymmetricMatch(emptySet)).toBe(false);
@@ -46,7 +44,7 @@ describe('NotEmpty', function() {
it('matches a non empty typed array', function() {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch(new Int16Array([1, 2, 3]))).toBe(true); // eslint-disable-line compat/compat
expect(notEmpty.asymmetricMatch(new Int16Array())).toBe(false); // eslint-disable-line compat/compat
expect(notEmpty.asymmetricMatch(new Int16Array([1, 2, 3]))).toBe(true);
expect(notEmpty.asymmetricMatch(new Int16Array())).toBe(false);
});
});

View File

@@ -110,16 +110,7 @@ describe('ObjectContaining', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
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();
}
var obj = Object.create(prototypeObject);
expect(containing.asymmetricMatch(obj, matchersUtil)).toBe(true);
});

View File

@@ -1,29 +1,15 @@
/* eslint-disable compat/compat */
describe('SetContaining', function() {
function SetI(iterable) {
// for IE11
var set = new Set();
iterable.forEach(function(v) {
set.add(v);
});
return set;
}
beforeEach(function() {
jasmine.getEnv().requireFunctioningSets();
});
it('matches any actual set to an empty set', function() {
var actualSet = new SetI(['foo', 'bar']);
var actualSet = new Set(['foo', 'bar']);
var containing = new jasmineUnderTest.SetContaining(new Set());
expect(containing.asymmetricMatch(actualSet)).toBe(true);
});
it('matches when all the values in sample have matches in actual', function() {
var actualSet = new SetI([{ foo: 'bar' }, 'baz', [1, 2, 3]]);
var actualSet = new Set([{ foo: 'bar' }, 'baz', [1, 2, 3]]);
var containingSet = new SetI([[1, 2, 3], { foo: 'bar' }]);
var containingSet = new Set([[1, 2, 3], { foo: 'bar' }]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -31,9 +17,9 @@ describe('SetContaining', function() {
});
it('does not match when a value is not in actual', function() {
var actualSet = new SetI([{ foo: 'bar' }, 'baz', [1, 2, 3]]);
var actualSet = new Set([{ foo: 'bar' }, 'baz', [1, 2, 3]]);
var containingSet = new SetI([[1, 2], { foo: 'bar' }]);
var containingSet = new Set([[1, 2], { foo: 'bar' }]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -41,9 +27,9 @@ describe('SetContaining', function() {
});
it('matches when all the values in sample have asymmetric matches in actual', function() {
var actualSet = new SetI([[1, 2, 3, 4], 'other', 'foo1']);
var actualSet = new Set([[1, 2, 3, 4], 'other', 'foo1']);
var containingSet = new SetI([
var containingSet = new Set([
jasmineUnderTest.stringMatching(/^foo\d/),
jasmineUnderTest.arrayContaining([2, 3])
]);
@@ -54,9 +40,9 @@ describe('SetContaining', function() {
});
it('does not match when a value in sample has no asymmetric matches in actual', function() {
var actualSet = new SetI(['a-foo1', [1, 2, 3, 4], 'other']);
var actualSet = new Set(['a-foo1', [1, 2, 3, 4], 'other']);
var containingSet = new SetI([
var containingSet = new Set([
jasmine.stringMatching(/^foo\d/),
jasmine.arrayContaining([2, 3])
]);
@@ -67,10 +53,10 @@ describe('SetContaining', function() {
});
it('matches recursively', function() {
var actualSet = new SetI(['foo', new SetI([1, 'bar', 2]), 'other']);
var actualSet = new Set(['foo', new Set([1, 'bar', 2]), 'other']);
var containingSet = new SetI([
new jasmineUnderTest.SetContaining(new SetI(['bar'])),
var containingSet = new Set([
new jasmineUnderTest.SetContaining(new Set(['bar'])),
'foo'
]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
@@ -86,8 +72,8 @@ describe('SetContaining', function() {
? a < 0 && b < 0
: a === b;
}
var actualSet = new SetI(['foo', -1]);
var containing = new jasmineUnderTest.SetContaining(new SetI([-2, 'foo']));
var actualSet = new Set(['foo', -1]);
var containing = new jasmineUnderTest.SetContaining(new Set([-2, 'foo']));
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
@@ -96,7 +82,7 @@ describe('SetContaining', function() {
});
it('does not match when actual is not a set', function() {
var containingSet = new SetI(['foo']);
var containingSet = new Set(['foo']);
expect(
new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch('foo')
).toBe(false);

View File

@@ -91,8 +91,7 @@ describe('base helpers', function() {
describe('isSet', function() {
it('returns true when the object is a Set', function() {
jasmine.getEnv().requireFunctioningSets();
expect(jasmineUnderTest.isSet(new Set())).toBe(true); // eslint-disable-line compat/compat
expect(jasmineUnderTest.isSet(new Set())).toBe(true);
});
it('returns false when the object is not a Set', function() {
@@ -102,21 +101,38 @@ describe('base helpers', function() {
describe('isURL', function() {
it('returns true when the object is a URL', function() {
jasmine.getEnv().requireUrls();
// eslint-disable-next-line compat/compat
expect(jasmineUnderTest.isURL(new URL('http://localhost/'))).toBe(true);
});
it('returns false when the object is not a URL', function() {
jasmine.getEnv().requireUrls();
expect(jasmineUnderTest.isURL({})).toBe(false);
});
});
describe('isIterable_', function() {
it('returns true when the object is an Array', function() {
expect(jasmineUnderTest.isIterable_([])).toBe(true);
});
it('returns true when the object is a Set', function() {
expect(jasmineUnderTest.isIterable_(new Set())).toBe(true);
});
it('returns true when the object is a Map', function() {
expect(jasmineUnderTest.isIterable_(new Map())).toBe(true);
});
it('returns true when the object implements @@iterator', function() {
const myIterable = { [Symbol.iterator]: function() {} };
expect(jasmineUnderTest.isIterable_(myIterable)).toBe(true);
});
it('returns false when the object does not implement @@iterator', function() {
expect(jasmineUnderTest.isIterable_({})).toBe(false);
});
});
describe('isPending_', function() {
it('returns a promise that resolves to true when the promise is pending', function() {
jasmine.getEnv().requirePromises();
// eslint-disable-next-line compat/compat
var promise = new Promise(function() {});
return expectAsync(jasmineUnderTest.isPending_(promise)).toBeResolvedTo(
true
@@ -124,8 +140,6 @@ describe('base helpers', function() {
});
it('returns a promise that resolves to false when the promise is resolved', function() {
jasmine.getEnv().requirePromises();
// eslint-disable-next-line compat/compat
var promise = Promise.resolve();
return expectAsync(jasmineUnderTest.isPending_(promise)).toBeResolvedTo(
false
@@ -133,8 +147,6 @@ describe('base helpers', function() {
});
it('returns a promise that resolves to false when the promise is rejected', function() {
jasmine.getEnv().requirePromises();
// eslint-disable-next-line compat/compat
var promise = Promise.reject();
return expectAsync(jasmineUnderTest.isPending_(promise)).toBeResolvedTo(
false
@@ -186,4 +198,14 @@ describe('base helpers', function() {
});
});
});
describe('debugLog', function() {
it("forwards to the current env's debugLog function", function() {
spyOn(jasmineUnderTest.getEnv(), 'debugLog');
jasmineUnderTest.debugLog('a message');
expect(jasmineUnderTest.getEnv().debugLog).toHaveBeenCalledWith(
'a message'
);
});
});
});

View File

@@ -122,40 +122,24 @@ describe('Asymmetric equality testers (Integration)', function() {
});
describe('mapContaining', function() {
if (jasmine.getEnv().hasFunctioningMaps()) {
verifyPasses(function(env) {
var actual = new Map();
actual.set('a', '2');
var expected = new Map();
expected.set('a', 2);
verifyPasses(function(env) {
var actual = new Map();
actual.set('a', '2');
var expected = new Map();
expected.set('a', 2);
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect(actual).toEqual(jasmineUnderTest.mapContaining(expected));
});
} else {
it('passes', function() {
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Maps');
});
}
env.expect(actual).toEqual(jasmineUnderTest.mapContaining(expected));
});
if (jasmine.getEnv().hasFunctioningMaps()) {
verifyFails(function(env) {
env
.expect('something')
.toEqual(jasmineUnderTest.mapContaining(new Map()));
});
} else {
it('fails', function() {
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Maps');
});
}
verifyFails(function(env) {
env
.expect('something')
.toEqual(jasmineUnderTest.mapContaining(new Map()));
});
});
describe('notEmpty', function() {
@@ -185,40 +169,24 @@ describe('Asymmetric equality testers (Integration)', function() {
});
describe('setContaining', function() {
if (jasmine.getEnv().hasFunctioningSets()) {
verifyPasses(function(env) {
var actual = new Set();
actual.add('1');
var expected = new Set();
actual.add(1);
verifyPasses(function(env) {
var actual = new Set();
actual.add('1');
var expected = new Set();
actual.add(1);
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect(actual).toEqual(jasmineUnderTest.setContaining(expected));
});
} else {
it('pases', function() {
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Sets');
});
}
env.expect(actual).toEqual(jasmineUnderTest.setContaining(expected));
});
if (jasmine.getEnv().hasFunctioningSets()) {
verifyFails(function(env) {
env
.expect('something')
.toEqual(jasmineUnderTest.setContaining(new Set()));
});
} else {
it('fails', function() {
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Sets');
});
}
verifyFails(function(env) {
env
.expect('something')
.toEqual(jasmineUnderTest.setContaining(new Set()));
});
});
describe('stringMatching', function() {

View File

@@ -1,4 +1,3 @@
/* eslint-disable compat/compat */
describe('Custom Async Matchers (Integration)', function() {
var env;
@@ -12,8 +11,6 @@ describe('Custom Async Matchers (Integration)', function() {
});
it('passes the spec if the custom async matcher passes', function(done) {
jasmine.getEnv().requirePromises();
env.it('spec using custom async matcher', function() {
env.addAsyncMatchers({
toBeReal: function() {
@@ -37,8 +34,6 @@ describe('Custom Async Matchers (Integration)', function() {
});
it('uses the negative compare function for a negative comparison, if provided', function(done) {
jasmine.getEnv().requirePromises();
env.it('spec with custom negative comparison matcher', function() {
env.addAsyncMatchers({
toBeReal: function() {
@@ -65,8 +60,6 @@ describe('Custom Async Matchers (Integration)', function() {
});
it('generates messages with the same rules as built in matchers absent a custom message', function(done) {
jasmine.getEnv().requirePromises();
env.it('spec with an expectation', function() {
env.addAsyncMatchers({
toBeReal: function() {
@@ -91,26 +84,20 @@ describe('Custom Async Matchers (Integration)', function() {
env.execute(null, done);
});
// TODO: remove this in the next major release.
it('passes the jasmine utility and current equality testers to the matcher factory', function(done) {
jasmine.getEnv().requirePromises();
var matcherFactory = function() {
it('passes the jasmine utility to the matcher factory', function(done) {
var matcherFactory = function(util) {
return {
compare: function() {
return Promise.resolve({ pass: true });
}
};
},
matcherFactorySpy = jasmine
.createSpy('matcherFactorySpy')
.and.callFake(matcherFactory),
customEqualityFn = function() {
return true;
};
matcherFactorySpy = jasmine.createSpy(
'matcherFactorySpy',
matcherFactory
);
env.it('spec with expectation', function() {
env.addCustomEqualityTester(customEqualityFn);
env.addAsyncMatchers({
toBeReal: matcherFactorySpy
});
@@ -120,8 +107,7 @@ describe('Custom Async Matchers (Integration)', function() {
var specExpectations = function() {
expect(matcherFactorySpy).toHaveBeenCalledWith(
jasmine.any(jasmineUnderTest.MatchersUtil),
[customEqualityFn]
jasmine.any(jasmineUnderTest.MatchersUtil)
);
};
@@ -130,8 +116,6 @@ describe('Custom Async Matchers (Integration)', function() {
});
it('provides custom equality testers to the matcher factory via matchersUtil', function(done) {
jasmine.getEnv().requirePromises();
var matcherFactory = function(matchersUtil) {
return {
compare: function(actual, expected) {

View File

@@ -108,40 +108,6 @@ describe('Custom Matchers (Integration)', function() {
env.execute(null, done);
});
it('supports asymmetric equality testers that take a list of custom equality testers', function(done) {
// TODO: remove this in the next major release.
spyOn(jasmineUnderTest, 'getEnv').and.returnValue(env);
env.it('spec using custom asymmetric equality tester', function() {
var customEqualityFn = function(a, b) {
if (a === 2 && b === 'two') {
return true;
}
};
var arrayWithFirstElement = function(sample) {
return {
asymmetricMatch: function(actual, customEqualityTesters) {
return jasmineUnderTest.matchersUtil.equals(
sample,
actual[0],
customEqualityTesters
);
}
};
};
env.addCustomEqualityTester(customEqualityFn);
env.expect(['two']).toEqual(arrayWithFirstElement(2));
});
var specExpectations = function(result) {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it('displays an appropriate failure message if a custom equality matcher fails', function(done) {
env.it('spec using custom equality matcher', function() {
var customEqualityFn = function(a, b) {
@@ -244,9 +210,8 @@ describe('Custom Matchers (Integration)', function() {
env.execute(null, done);
});
// TODO: remove this in the next major release.
it('passes the jasmine utility and current equality testers to the matcher factory', function(done) {
var matcherFactory = function() {
it('passes the jasmine utility to the matcher factory', function(done) {
var matcherFactory = function(util) {
return {
compare: function() {
return { pass: true };
@@ -255,13 +220,9 @@ describe('Custom Matchers (Integration)', function() {
},
matcherFactorySpy = jasmine
.createSpy('matcherFactorySpy')
.and.callFake(matcherFactory),
customEqualityFn = function() {
return true;
};
.and.callFake(matcherFactory);
env.it('spec with expectation', function() {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeReal: matcherFactorySpy
});
@@ -271,8 +232,7 @@ describe('Custom Matchers (Integration)', function() {
var specExpectations = function() {
expect(matcherFactorySpy).toHaveBeenCalledWith(
jasmine.any(jasmineUnderTest.MatchersUtil),
[customEqualityFn]
jasmine.any(jasmineUnderTest.MatchersUtil)
);
};

View File

@@ -10,13 +10,12 @@ describe('Custom Spy Strategies (Integration)', function() {
env.cleanup_();
});
it('allows adding more strategies local to a suite', function(done) {
it('allows adding more strategies local to a suite', async function() {
var plan = jasmine.createSpy('custom strategy plan').and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy').and.returnValue(plan);
var jasmineDone = jasmine.createSpy('jasmineDone');
env.describe('suite defining a custom spy strategy', function() {
env.beforeEach(function() {
env.beforeAll(function() {
env.addSpyStrategy('frobnicate', strategy);
});
@@ -32,20 +31,13 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute(null, expectations);
const result = await env.execute();
expect(result.overallStatus).toEqual('passed');
});
it('allows adding more strategies local to a spec', function(done) {
it('allows adding more strategies local to a spec', async function() {
var plan = jasmine.createSpy('custom strategy plan').and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy').and.returnValue(plan);
var jasmineDone = jasmine.createSpy('jasmineDone');
env.it('spec defining a custom spy strategy', function() {
env.addSpyStrategy('frobnicate', strategy);
@@ -59,20 +51,13 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute(null, expectations);
const result = await env.execute();
expect(result.overallStatus).toEqual('passed');
});
it('allows using custom strategies on a per-argument basis', function(done) {
it('allows using custom strategies on a per-argument basis', async function() {
var plan = jasmine.createSpy('custom strategy plan').and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy').and.returnValue(plan);
var jasmineDone = jasmine.createSpy('jasmineDone');
env.it('spec defining a custom spy strategy', function() {
env.addSpyStrategy('frobnicate', strategy);
@@ -92,23 +77,16 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute(null, expectations);
const result = await env.execute();
expect(result.overallStatus).toEqual('passed');
});
it('allows multiple custom strategies to be used', function(done) {
it('allows multiple custom strategies to be used', async function() {
var plan1 = jasmine.createSpy('plan 1').and.returnValue(42),
strategy1 = jasmine.createSpy('strat 1').and.returnValue(plan1),
plan2 = jasmine.createSpy('plan 2').and.returnValue(24),
strategy2 = jasmine.createSpy('strat 2').and.returnValue(plan2),
specDone = jasmine.createSpy('specDone'),
jasmineDone = jasmine.createSpy('jasmineDone');
specDone = jasmine.createSpy('specDone');
env.beforeEach(function() {
env.addSpyStrategy('frobnicate', strategy1);
@@ -133,14 +111,9 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(plan2).toHaveBeenCalled();
});
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
expect(specDone.calls.count()).toBe(2);
done();
}
env.addReporter({ jasmineDone: jasmineDone, specDone: specDone });
env.execute(null, expectations);
env.addReporter({ specDone: specDone });
const result = await env.execute();
expect(result.overallStatus).toEqual('passed');
expect(specDone.calls.count()).toBe(2);
});
});

View File

@@ -10,7 +10,7 @@ describe('Default Spy Strategy (Integration)', function() {
env.cleanup_();
});
it('allows defining a default spy strategy', function(done) {
it('allows defining a default spy strategy', async function() {
env.describe('suite with default strategy', function() {
env.beforeEach(function() {
env.setDefaultSpyStrategy(function(and) {
@@ -29,18 +29,11 @@ describe('Default Spy Strategy (Integration)', function() {
expect(spy()).toBeUndefined();
});
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
var jasmineDone = jasmine.createSpy('jasmineDone');
env.addReporter({ jasmineDone: jasmineDone });
env.execute(null, expectations);
const result = await env.execute();
expect(result.overallStatus).toEqual('passed');
});
it('uses the default spy strategy defined when the spy is created', function(done) {
it('uses the default spy strategy defined when the spy is created', async function() {
env.it('spec', function() {
var a = env.createSpy('a');
env.setDefaultSpyStrategy(function(and) {
@@ -67,14 +60,7 @@ describe('Default Spy Strategy (Integration)', function() {
expect(d.and.isConfigured()).toBe(false);
});
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
var jasmineDone = jasmine.createSpy('jasmineDone');
env.addReporter({ jasmineDone: jasmineDone });
env.execute(null, expectations);
const result = await env.execute();
expect(result.overallStatus).toEqual('passed');
});
});

View File

@@ -0,0 +1,322 @@
/* eslint no-console: 0 */
describe('Deprecation (integration)', function() {
var env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
});
afterEach(function() {
env.cleanup_();
});
it('reports a deprecation on the top suite', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.beforeAll(function() {
env.deprecated('the message');
});
env.it('a spec', function() {});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(/^DEPRECATION: the message/)
);
done();
});
});
it('reports a deprecation on a descendent suite', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['suiteDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.describe('a suite', function() {
env.beforeAll(function() {
env.deprecated('the message');
});
env.it('a spec', function() {});
});
env.execute(null, function() {
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(
/^DEPRECATION: the message \(in suite: a suite\)/
)
);
done();
});
});
it('reports a deprecation on a spec', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['specDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.describe('a suite', function() {
env.it('a spec', function() {
env.deprecated('the message');
});
});
env.execute(null, function() {
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(
/^DEPRECATION: the message \(in spec: a suite a spec\)/
)
);
done();
});
});
it('omits the suite or spec context when ignoreRunnable is true', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.it('a spec', function() {
env.deprecated('the message', { ignoreRunnable: true });
});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(/the message/)
);
expect(console.error).not.toHaveBeenCalledWith(
jasmine.stringMatching(/a spec/)
);
done();
});
});
it('includes the stack trace', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['specDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.describe('a suite', function() {
env.it('a spec', function() {
env.deprecated('the message');
});
});
env.execute(null, function() {
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
stack: jasmine.stringMatching(/DeprecationSpec.js/)
})
]
})
);
expect(console.error).toHaveBeenCalled();
expect(console.error.calls.argsFor(0)[0].replace(/\n/g, 'NL')).toMatch(
/^DEPRECATION: the message \(in spec: a suite a spec\)NL.*DeprecationSpec.js/
);
done();
});
});
it('excludes the stack trace when omitStackTrace is true', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['specDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.describe('a suite', function() {
env.it('a spec', function() {
env.deprecated('the message', { omitStackTrace: true });
});
});
env.execute(null, function() {
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
stack: jasmine.falsy()
})
]
})
);
expect(console.error).toHaveBeenCalled();
expect(console.error).not.toHaveBeenCalledWith(
jasmine.stringMatching(/DeprecationSpec.js/)
);
done();
});
});
it('emits a given deprecation only once', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['specDone', 'suiteDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.describe('a suite', function() {
env.beforeAll(function() {
env.deprecated('the message');
env.deprecated('the message');
});
env.it('a spec', function() {
env.deprecated('the message');
env.deprecated('a different message');
});
});
env.execute(null, function() {
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
// only one
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
// only the other one
jasmine.objectContaining({
message: jasmine.stringMatching(/^a different message/)
})
]
})
);
expect(console.error).toHaveBeenCalledTimes(2);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(
/^DEPRECATION: the message \(in suite: a suite\)/
)
);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(
/^DEPRECATION: a different message \(in spec: a suite a spec\)/
)
);
done();
});
});
it('emits a given deprecation each time when config.verboseDeprecations is true', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['specDone', 'suiteDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.configure({ verboseDeprecations: true });
env.describe('a suite', function() {
env.beforeAll(function() {
env.deprecated('the message');
env.deprecated('the message');
});
env.it('a spec', function() {
env.deprecated('the message');
});
});
env.execute(null, function() {
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
}),
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(console.error).toHaveBeenCalledTimes(3);
expect(console.error.calls.argsFor(0)[0]).toMatch(
/^DEPRECATION: the message \(in suite: a suite\)/
);
expect(console.error.calls.argsFor(1)[0]).toMatch(
/^DEPRECATION: the message \(in suite: a suite\)/
);
expect(console.error.calls.argsFor(2)[0]).toMatch(
/^DEPRECATION: the message \(in spec: a suite a spec\)/
);
expect(console.error.calls.argsFor(2)[0]).toMatch(
/^DEPRECATION: the message \(in spec: a suite a spec\)/
);
done();
});
});
it('handles deprecations that occur before execute() is called', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
env.addReporter(reporter);
spyOn(console, 'error');
env.deprecated('the message');
env.it('a spec', function() {});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalledWith(
jasmine.objectContaining({
deprecationWarnings: [
jasmine.objectContaining({
message: jasmine.stringMatching(/^the message/)
})
]
})
);
expect(console.error).toHaveBeenCalledWith(
jasmine.stringMatching(/^DEPRECATION: the message/)
);
done();
});
});
});

View File

@@ -156,10 +156,6 @@ describe('Env integration', function() {
message: 'Failed: error message',
stack: {
asymmetricMatch: function(other) {
if (!other) {
// IE doesn't give us a stacktrace so just ignore it.
return true;
}
var split = other.split('\n'),
firstLine = split[0];
if (firstLine.indexOf('error message') >= 0) {
@@ -513,6 +509,173 @@ describe('Env integration', function() {
env.execute(null, assertions);
});
it('reports multiple calls to done in the top suite as errors', function(done) {
var reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
var message =
'A top-level beforeAll or afterAll function called its ' +
"'done' callback more than once.";
env.addReporter(reporter);
env.beforeAll(function(innerDone) {
innerDone();
innerDone();
});
env.it('a spec, so the beforeAll runs', function() {});
env.afterAll(function(innerDone) {
innerDone();
innerDone();
});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalled();
const errors = reporter.jasmineDone.calls.argsFor(0)[0]
.failedExpectations;
expect(errors.length).toEqual(2);
expect(errors[0].message)
.withContext('top beforeAll')
.toContain(message);
expect(errors[0].globalErrorType).toEqual('lateError');
expect(errors[1].message)
.withContext('top afterAll')
.toContain(message);
expect(errors[1].globalErrorType).toEqual('lateError');
done();
});
});
it('reports multiple calls to done in a non-top suite as errors', function(done) {
var reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
var message =
"An asynchronous beforeAll or afterAll function called its 'done' " +
'callback more than once.\n(in suite: a suite)';
env.addReporter(reporter);
env.describe('a suite', function() {
env.beforeAll(function(innerDone) {
innerDone();
innerDone();
});
env.it('a spec, so that before/afters run', function() {});
env.afterAll(function(innerDone) {
innerDone();
innerDone();
});
});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalled();
const errors = reporter.jasmineDone.calls.argsFor(0)[0]
.failedExpectations;
expect(errors.length).toEqual(2);
expect(errors[0].message)
.withContext('suite beforeAll')
.toContain(message);
expect(errors[0].globalErrorType).toEqual('lateError');
expect(errors[1].message)
.withContext('suite afterAll')
.toContain(message);
expect(errors[1].globalErrorType).toEqual('lateError');
done();
});
});
it('reports multiple calls to done in a spec as errors', function(done) {
var reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
var message =
'An asynchronous spec, beforeEach, or afterEach function called its ' +
"'done' callback more than once.\n(in spec: a suite a spec)";
env.addReporter(reporter);
env.describe('a suite', function() {
env.beforeEach(function(innerDone) {
innerDone();
innerDone();
});
env.it('a spec', function(innerDone) {
innerDone();
innerDone();
});
env.afterEach(function(innerDone) {
innerDone();
innerDone();
});
});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalled();
const errors = reporter.jasmineDone.calls.argsFor(0)[0]
.failedExpectations;
expect(errors.length).toEqual(3);
expect(errors[0].message)
.withContext('error caused by beforeEach')
.toContain(message);
expect(errors[0].globalErrorType).toEqual('lateError');
expect(errors[1].message)
.withContext('error caused by it')
.toContain(message);
expect(errors[1].globalErrorType).toEqual('lateError');
expect(errors[2].message)
.withContext('error caused by afterEach')
.toContain(message);
expect(errors[2].globalErrorType).toEqual('lateError');
done();
});
});
it('reports multiple calls to done in reporters as errors', function(done) {
var message =
"An asynchronous reporter callback called its 'done' callback more " +
'than once.';
var reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone']);
reporter.specDone = function(result, done) {
done();
done();
};
env.addReporter(reporter);
env.it('a spec', function() {});
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalled();
const errors = reporter.jasmineDone.calls.argsFor(0)[0]
.failedExpectations;
expect(errors.length).toEqual(1);
expect(errors[0].message).toContain(message);
expect(errors[0].globalErrorType).toEqual('lateError');
done();
});
});
it('does not report an error for a call to done that comes after a timeout', function(done) {
var reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']),
firstSpecDone;
reporter.specDone = function(result, reporterDone) {
setTimeout(function() {
firstSpecDone();
reporterDone();
});
};
env.addReporter(reporter);
env.it(
'a spec',
function(innerDone) {
firstSpecDone = innerDone;
},
1
);
env.execute(null, function() {
expect(reporter.jasmineDone).toHaveBeenCalledWith(
jasmine.objectContaining({
failedExpectations: []
})
);
done();
});
});
describe('suiteDone reporting', function() {
it('reports when an afterAll fails an expectation', function(done) {
var reporter = jasmine.createSpyObj('fakeReport', ['suiteDone']);
@@ -1964,6 +2127,7 @@ describe('Env integration', function() {
} catch (e) {
exception = e;
}
env.it('has a test', function() {});
});
env.execute(null, function() {
@@ -1988,6 +2152,7 @@ describe('Env integration', function() {
} catch (e) {
exception = e;
}
env.it('has a test', function() {});
});
env.execute(null, function() {
@@ -2010,6 +2175,7 @@ describe('Env integration', function() {
} catch (e) {
exception = e;
}
env.it('has a test', function() {});
});
env.execute(null, function() {
@@ -2049,6 +2215,7 @@ describe('Env integration', function() {
} catch (e) {
exception = e;
}
env.it('has a test', function() {});
});
env.execute(null, function() {
@@ -2516,7 +2683,7 @@ describe('Env integration', function() {
return setTimeout(fn, delay);
},
clearTimeout: function(fn, delay) {
clearTimeout(fn, delay);
return clearTimeout(fn, delay);
}
};
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
@@ -2623,70 +2790,6 @@ describe('Env integration', function() {
});
});
it('should report deprecation warnings on the correct specs and suites', function(done) {
var reporter = jasmine.createSpyObj('reporter', [
'jasmineDone',
'suiteDone',
'specDone'
]);
// prevent deprecation from being displayed, as well as letting us observe calls
spyOn(console, 'error');
env.addReporter(reporter);
env.deprecated('top level deprecation');
env.describe('suite', function() {
env.beforeAll(function() {
env.deprecated('suite level deprecation');
});
env.it('spec', function() {
env.deprecated('spec level deprecation');
});
});
env.execute(null, function() {
var result = reporter.jasmineDone.calls.argsFor(0)[0];
expect(result.deprecationWarnings).toEqual([
jasmine.objectContaining({ message: 'top level deprecation' })
]);
/* eslint-disable-next-line no-console */
expect(console.error).toHaveBeenCalledWith(
'DEPRECATION: top level deprecation'
);
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'suite',
deprecationWarnings: [
jasmine.objectContaining({ message: 'suite level deprecation' })
]
})
);
/* eslint-disable-next-line no-console */
expect(console.error).toHaveBeenCalledWith(
'DEPRECATION: suite level deprecation (in suite: suite)'
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'suite spec',
deprecationWarnings: [
jasmine.objectContaining({ message: 'spec level deprecation' })
]
})
);
/* eslint-disable-next-line no-console */
expect(console.error).toHaveBeenCalledWith(
'DEPRECATION: spec level deprecation (in spec: suite spec)'
);
done();
});
});
it('should report deprecation stack with an error object', function(done) {
var exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
reporter = jasmine.createSpyObj('reporter', [
@@ -2736,7 +2839,7 @@ describe('Env integration', function() {
expect(result.deprecationWarnings).toEqual([
jasmine.objectContaining({
message: topLevelError.message,
stack: exceptionFormatter.stack(topLevelError)
stack: exceptionFormatter.stack(topLevelError, { omitMessage: true })
})
]);
@@ -2746,7 +2849,9 @@ describe('Env integration', function() {
deprecationWarnings: [
jasmine.objectContaining({
message: suiteLevelError.message,
stack: exceptionFormatter.stack(suiteLevelError)
stack: exceptionFormatter.stack(suiteLevelError, {
omitMessage: true
})
})
]
})
@@ -2758,7 +2863,9 @@ describe('Env integration', function() {
deprecationWarnings: [
jasmine.objectContaining({
message: specLevelError.message,
stack: exceptionFormatter.stack(specLevelError)
stack: exceptionFormatter.stack(specLevelError, {
omitMessage: true
})
})
]
})
@@ -2769,8 +2876,6 @@ describe('Env integration', function() {
});
it('supports async matchers', function(done) {
jasmine.getEnv().requirePromises();
var specDone = jasmine.createSpy('specDone'),
suiteDone = jasmine.createSpy('suiteDone'),
jasmineDone = jasmine.createSpy('jasmineDone');
@@ -2783,7 +2888,6 @@ describe('Env integration', function() {
function fail(innerDone) {
var resolve;
// eslint-disable-next-line compat/compat
var p = new Promise(function(res, rej) {
resolve = res;
});
@@ -2835,7 +2939,9 @@ describe('Env integration', function() {
});
it('provides custom equality testers to async matchers', function(done) {
jasmine.getEnv().requirePromises();
if (jasmine.getEnv().skipBrowserFlake) {
jasmine.getEnv().skipBrowserFlake();
}
var specDone = jasmine.createSpy('specDone');
@@ -2845,7 +2951,7 @@ describe('Env integration', function() {
env.addCustomEqualityTester(function() {
return true;
});
var p = Promise.resolve('something'); // eslint-disable-line compat/compat
var p = Promise.resolve('something');
return env.expectAsync(p).toBeResolvedTo('something else');
});
@@ -2861,8 +2967,6 @@ describe('Env integration', function() {
});
it('includes useful stack frames in async matcher failures', function(done) {
jasmine.getEnv().requirePromises();
var specDone = jasmine.createSpy('specDone');
env.addReporter({ specDone: specDone });
@@ -2871,7 +2975,7 @@ describe('Env integration', function() {
env.addCustomEqualityTester(function() {
return true;
});
var p = Promise.resolve(); // eslint-disable-line compat/compat
var p = Promise.resolve();
return env.expectAsync(p).toBeRejected();
});
@@ -2890,11 +2994,8 @@ describe('Env integration', function() {
});
it('reports an error when an async expectation occurs after the spec finishes', function(done) {
jasmine.getEnv().requirePromises();
var resolve,
jasmineDone = jasmine.createSpy('jasmineDone'),
// eslint-disable-next-line compat/compat
promise = new Promise(function(res) {
resolve = res;
});
@@ -2957,11 +3058,8 @@ describe('Env integration', function() {
});
it('reports an error when an async expectation occurs after the suite finishes', function(done) {
jasmine.getEnv().requirePromises();
var resolve,
jasmineDone = jasmine.createSpy('jasmineDone'),
// eslint-disable-next-line compat/compat
promise = new Promise(function(res) {
resolve = res;
});
@@ -3050,7 +3148,6 @@ describe('Env integration', function() {
});
it('is resolved after reporter events are dispatched', function() {
jasmine.getEnv().requirePromises();
var reporter = jasmine.createSpyObj('reporter', [
'specDone',
'suiteDone',
@@ -3070,7 +3167,6 @@ describe('Env integration', function() {
});
it('is resolved after the stack is cleared', function(done) {
jasmine.getEnv().requirePromises();
var realClearStack = jasmineUnderTest.getClearStack(
jasmineUnderTest.getGlobal()
),
@@ -3098,7 +3194,6 @@ describe('Env integration', function() {
});
it('is resolved after QueueRunner timeouts are cleared', function() {
jasmine.getEnv().requirePromises();
var setTimeoutSpy = spyOn(
jasmineUnderTest.getGlobal(),
'setTimeout'
@@ -3134,15 +3229,21 @@ describe('Env integration', function() {
});
});
it('is resolved even if specs fail', function() {
jasmine.getEnv().requirePromises();
it('is resolved to the value of the jasmineDone event', async function() {
env.describe('suite', function() {
env.it('spec', function() {
env.expect(true).toBe(false);
});
});
return expectAsync(env.execute(null)).toBeResolved();
let event;
env.addReporter({
jasmineDone: e => (event = e)
});
const result = await env.execute();
expect(event.overallStatus).toEqual('failed');
expect(result).toEqual(event);
});
});
@@ -3240,4 +3341,139 @@ describe('Env integration', function() {
});
});
});
it('sends debug logs to the reporter when the spec fails', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['specDone']),
startTime,
endTime;
env.addReporter(reporter);
env.configure({ random: false });
env.it('fails', function() {
startTime = new Date().getTime();
env.debugLog('message 1');
env.debugLog('message 2');
env.expect(1).toBe(2);
endTime = new Date().getTime();
});
env.it('passes', function() {
env.debugLog('message that should not be reported');
});
env.execute(null, function() {
function numberInRange(min, max) {
return {
asymmetricMatch: function(compareTo) {
return compareTo >= min && compareTo <= max;
},
jasmineToString: function(pp) {
return '<number from ' + min + ' to ' + max + ' inclusive>';
}
};
}
var duration;
expect(reporter.specDone).toHaveBeenCalledTimes(2);
duration = reporter.specDone.calls.argsFor(0)[0].duration;
expect(reporter.specDone.calls.argsFor(0)[0]).toEqual(
jasmine.objectContaining({
debugLogs: [
{
timestamp: numberInRange(0, duration),
message: 'message 1'
},
{
timestamp: numberInRange(0, duration),
message: 'message 2'
}
]
})
);
expect(reporter.specDone.calls.argsFor(1)[0].debugLogs).toBeFalsy();
done();
});
});
it('reports an error when debugLog is used when a spec is not running', function(done) {
var reporter = jasmine.createSpyObj('reporter', ['suiteDone']);
env.describe('a suite', function() {
env.beforeAll(function() {
env.debugLog('a message');
});
env.it('a spec', function() {});
});
env.addReporter(reporter);
env.execute(null, function() {
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
failedExpectations: [
jasmine.objectContaining({
message: jasmine.stringContaining(
"'debugLog' was called when there was no current spec"
)
})
]
})
);
done();
});
});
it('uses custom equality testers in Spy#withArgs', async function() {
env.it('a spec', function() {
const createSpySpy = env.createSpy('via createSpy');
const spiedOn = { foo: function() {} };
env.spyOn(spiedOn, 'foo');
const spyObj = env.createSpyObj('spyObj', ['foo']);
const spiedOnAllFuncs = { foo: function() {} };
env.spyOnAllFunctions(spiedOnAllFuncs);
for (const spy of [
createSpySpy,
spiedOn.foo,
spyObj.foo,
spiedOnAllFuncs.foo
]) {
spy.and.returnValue('default strategy');
spy.withArgs(42).and.returnValue('custom strategy');
}
env.addCustomEqualityTester(function(a, b) {
if ((a === 'x' && b === 42) || (a === 42 && b === 'x')) {
return true;
}
});
env
.expect(createSpySpy('x'))
.withContext('createSpy')
.toEqual('custom strategy');
env
.expect(spiedOn.foo('x'))
.withContext('spyOn')
.toEqual('custom strategy');
env
.expect(spyObj.foo('x'))
.withContext('createSpyObj')
.toEqual('custom strategy');
env
.expect(spiedOnAllFuncs.foo('x'))
.withContext('spyOnAllFunctions')
.toEqual('custom strategy');
});
let failedExpectations;
env.addReporter({
specDone: r => (failedExpectations = r.failedExpectations)
});
await env.execute();
expect(failedExpectations).toEqual([]);
});
});

View File

@@ -90,8 +90,6 @@ describe('Matchers (Integration)', function() {
function verifyPassesAsync(expectations) {
it('passes', function(done) {
jasmine.getEnv().requirePromises();
env.it('a spec', function() {
return expectations(env);
});
@@ -118,8 +116,6 @@ describe('Matchers (Integration)', function() {
function verifyFailsAsync(expectations) {
it('fails', function(done) {
jasmine.getEnv().requirePromises();
env.it('a spec', function() {
return expectations(env);
});
@@ -147,7 +143,6 @@ describe('Matchers (Integration)', function() {
function verifyFailsWithCustomObjectFormattersAsync(config) {
it('uses custom object formatters', function(done) {
var env = new jasmineUnderTest.Env();
jasmine.getEnv().requirePromises();
env.it('a spec', function() {
env.addCustomObjectFormatter(config.formatter);
return config.expectations(env);
@@ -348,12 +343,10 @@ describe('Matchers (Integration)', function() {
describe('toBeResolved', function() {
verifyPassesAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeResolved();
});
verifyFailsAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject()).toBeResolved();
});
});
@@ -363,12 +356,10 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve('5')).toBeResolvedTo(5);
});
verifyFailsAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar');
});
@@ -377,7 +368,6 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y');
},
expectedMessage:
@@ -388,12 +378,10 @@ describe('Matchers (Integration)', function() {
describe('toBeRejected', function() {
verifyPassesAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject('nope')).toBeRejected();
});
verifyFailsAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeRejected();
});
});
@@ -403,12 +391,10 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject('5')).toBeRejectedWith(5);
});
verifyFailsAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope');
});
@@ -417,7 +403,6 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y');
},
expectedMessage:
@@ -428,16 +413,12 @@ describe('Matchers (Integration)', function() {
describe('toBeRejectedWithError', function() {
verifyPassesAsync(function(env) {
return (
env
// eslint-disable-next-line compat/compat
.expectAsync(Promise.reject(new Error()))
.toBeRejectedWithError(Error)
);
return env
.expectAsync(Promise.reject(new Error()))
.toBeRejectedWithError(Error);
});
verifyFailsAsync(function(env) {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error);
});
@@ -446,12 +427,9 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return (
env
// eslint-disable-next-line compat/compat
.expectAsync(Promise.reject('foo'))
.toBeRejectedWithError('foo')
);
return env
.expectAsync(Promise.reject('foo'))
.toBeRejectedWithError('foo');
},
expectedMessage:
'Expected a promise to be rejected with Error: |foo| ' +
@@ -757,10 +735,7 @@ describe('Matchers (Integration)', function() {
describe('When an async matcher is used with .already()', function() {
it('propagates the matcher result when the promise is resolved', function(done) {
jasmine.getEnv().requirePromises();
env.it('a spec', function() {
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).already.toBeRejected();
});
@@ -782,15 +757,10 @@ describe('Matchers (Integration)', function() {
});
it('propagates the matcher result when the promise is rejected', function(done) {
jasmine.getEnv().requirePromises();
env.it('a spec', function() {
return (
env
// eslint-disable-next-line compat/compat
.expectAsync(Promise.reject(new Error('nope')))
.already.toBeResolved()
);
return env
.expectAsync(Promise.reject(new Error('nope')))
.already.toBeResolved();
});
var specExpectations = function(result) {
@@ -812,9 +782,6 @@ describe('Matchers (Integration)', function() {
});
it('fails when the promise is pending', function(done) {
jasmine.getEnv().requirePromises();
// eslint-disable-next-line compat/compat
var promise = new Promise(function() {});
env.it('a spec', function() {

View File

@@ -550,10 +550,17 @@ describe('spec running', function() {
var pendingSpec,
suite = env.describe('default current suite', function() {
pendingSpec = env.it('I am a pending spec');
});
}),
reporter = jasmine.createSpyObj('reporter', ['specDone']);
env.addReporter(reporter);
env.execute(null, function() {
expect(pendingSpec.status()).toBe('pending');
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
status: 'pending'
})
);
done();
});
});
@@ -785,9 +792,9 @@ describe('spec running', function() {
});
});
describe('When throwOnExpectationFailure is set', function() {
it('skips to cleanup functions after an error', function(done) {
var actions = [];
function hasStandardErrorHandlingBehavior() {
it('skips to cleanup functions after a thrown error', async function() {
const actions = [];
env.describe('Something', function() {
env.beforeEach(function() {
@@ -814,79 +821,18 @@ describe('spec running', function() {
});
});
env.configure({ oneFailurePerSpec: true });
await env.execute();
env.execute(null, function() {
expect(actions).toEqual([
'outer beforeEach',
'inner afterEach',
'outer afterEach'
]);
done();
});
expect(actions).toEqual(['outer beforeEach', 'outer afterEach']);
});
it('skips to cleanup functions after done.fail is called', function(done) {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function(done) {
actions.push('beforeEach');
done.fail('error');
actions.push('after done.fail');
});
env.afterEach(function() {
actions.push('afterEach');
});
env.it('does it', function() {
actions.push('it');
});
});
env.configure({ oneFailurePerSpec: true });
env.execute(null, function() {
expect(actions).toEqual(['beforeEach', 'afterEach']);
done();
});
});
it('skips to cleanup functions when an async function times out', function(done) {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function(innerDone) {
actions.push('beforeEach');
}, 1);
env.afterEach(function() {
actions.push('afterEach');
});
env.it('does it', function() {
actions.push('it');
});
});
env.configure({ oneFailurePerSpec: true });
env.execute(null, function() {
expect(actions).toEqual(['beforeEach', 'afterEach']);
done();
});
});
it('skips to cleanup functions after an error with deprecations', function(done) {
var actions = [];
spyOn(env, 'deprecated');
it('skips to cleanup functions after a rejected promise', async function() {
const actions = [];
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('outer beforeEach');
throw new Error('error');
return Promise.reject(new Error('error'));
});
env.afterEach(function() {
@@ -908,29 +854,18 @@ describe('spec running', function() {
});
});
env.throwOnExpectationFailure(true);
await env.execute();
env.execute(null, function() {
expect(actions).toEqual([
'outer beforeEach',
'inner afterEach',
'outer afterEach'
]);
expect(env.deprecated).toHaveBeenCalled();
done();
});
expect(actions).toEqual(['outer beforeEach', 'outer afterEach']);
});
it('skips to cleanup functions after done.fail is called with deprecations', function(done) {
var actions = [];
spyOn(env, 'deprecated');
it('skips to cleanup functions after done.fail is called', async function() {
const actions = [];
env.describe('Something', function() {
env.beforeEach(function(done) {
actions.push('beforeEach');
done.fail('error');
actions.push('after done.fail');
});
env.afterEach(function() {
@@ -942,19 +877,13 @@ describe('spec running', function() {
});
});
env.throwOnExpectationFailure(true);
await env.execute();
env.execute(null, function() {
expect(actions).toEqual(['beforeEach', 'afterEach']);
expect(env.deprecated).toHaveBeenCalled();
done();
});
expect(actions).toEqual(['beforeEach', 'afterEach']);
});
it('skips to cleanup functions when an async function times out with deprecations', function(done) {
var actions = [];
spyOn(env, 'deprecated');
it('skips to cleanup functions when an async function times out', async function() {
const actions = [];
env.describe('Something', function() {
env.beforeEach(function(innerDone) {
@@ -970,17 +899,405 @@ describe('spec running', function() {
});
});
env.throwOnExpectationFailure(true);
await env.execute();
env.execute(null, function() {
expect(actions).toEqual(['beforeEach', 'afterEach']);
expect(env.deprecated).toHaveBeenCalled();
done();
expect(actions).toEqual(['beforeEach', 'afterEach']);
});
it('skips to cleanup functions after pending() is called', async function() {
const actions = [];
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('outer beforeEach');
pending();
});
env.afterEach(function() {
actions.push('outer afterEach');
});
env.describe('Inner', function() {
env.beforeEach(function() {
actions.push('inner beforeEach');
});
env.afterEach(function() {
actions.push('inner afterEach');
});
env.it('does it', function() {
actions.push('inner it');
});
});
});
await env.execute();
expect(actions).toEqual(['outer beforeEach', 'outer afterEach']);
});
it('runs all reporter callbacks even if one fails', async function() {
const laterReporter = jasmine.createSpyObj('laterReporter', ['specDone']);
env.it('a spec', function() {});
env.addReporter({
specDone: function() {
throw new Error('nope');
}
});
env.addReporter(laterReporter);
await env.execute();
expect(laterReporter.specDone).toHaveBeenCalled();
});
it('skips cleanup functions that are defined in child suites when a beforeEach errors', async function() {
const parentAfterEachFn = jasmine.createSpy('parentAfterEachFn');
const childAfterEachFn = jasmine.createSpy('childAfterEachFn');
env.describe('parent suite', function() {
env.beforeEach(function() {
throw new Error('nope');
});
env.afterEach(parentAfterEachFn);
env.describe('child suite', function() {
env.it('a spec', function() {});
env.afterEach(childAfterEachFn);
});
});
await env.execute();
expect(parentAfterEachFn).toHaveBeenCalled();
expect(childAfterEachFn).not.toHaveBeenCalled();
});
}
describe('When stopSpecOnExpectationFailure is true', function() {
beforeEach(function() {
env.configure({ stopSpecOnExpectationFailure: true });
});
hasStandardErrorHandlingBehavior();
it('skips to cleanup functions after an expectation failure', async function() {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('outer beforeEach');
env.expect(1).toBe(2);
});
env.afterEach(function() {
actions.push('outer afterEach');
});
env.describe('Inner', function() {
env.beforeEach(function() {
actions.push('inner beforeEach');
});
env.afterEach(function() {
actions.push('inner afterEach');
});
env.it('does it', function() {
actions.push('inner it');
});
});
});
await env.execute();
expect(actions).toEqual(['outer beforeEach', 'outer afterEach']);
});
});
function behavesLikeStopOnSpecFailureIsOn(configureFn) {
describe('When stopSpecOnExpectationFailure is false', function() {
beforeEach(function() {
env.configure({ stopSpecOnExpectationFailure: false });
});
hasStandardErrorHandlingBehavior();
it('does not skip anything after an expectation failure', async function() {
var actions = [];
env.describe('Something', function() {
env.beforeEach(function() {
actions.push('outer beforeEach');
env.expect(1).toBe(2);
});
env.afterEach(function() {
actions.push('outer afterEach');
});
env.describe('Inner', function() {
env.beforeEach(function() {
actions.push('inner beforeEach');
});
env.afterEach(function() {
actions.push('inner afterEach');
});
env.it('does it', function() {
actions.push('inner it');
});
});
});
await env.execute();
expect(actions).toEqual([
'outer beforeEach',
'inner beforeEach',
'inner it',
'inner afterEach',
'outer afterEach'
]);
});
});
describe('When a top-level beforeAll function fails', function() {
it('skips and reports contained specs', async function() {
const outerBeforeEach = jasmine.createSpy('outerBeforeEach');
const nestedBeforeEach = jasmine.createSpy('nestedBeforeEach');
const outerAfterEach = jasmine.createSpy('outerAfterEach');
const nestedAfterEach = jasmine.createSpy('nestedAfterEach');
const outerIt = jasmine.createSpy('outerIt');
const nestedIt = jasmine.createSpy('nestedIt');
const nestedBeforeAll = jasmine.createSpy('nestedBeforeAll');
env.beforeAll(function() {
throw new Error('nope');
});
env.beforeEach(outerBeforeEach);
env.it('a spec', outerIt);
env.describe('a nested suite', function() {
env.beforeAll(nestedBeforeAll);
env.beforeEach(nestedBeforeEach);
env.it('a nested spec', nestedIt);
env.afterEach(nestedAfterEach);
});
env.afterEach(outerAfterEach);
const reporter = jasmine.createSpyObj('reporter', [
'suiteStarted',
'suiteDone',
'specStarted',
'specDone'
]);
env.addReporter(reporter);
await env.execute();
expect(outerBeforeEach).not.toHaveBeenCalled();
expect(outerIt).not.toHaveBeenCalled();
expect(nestedBeforeAll).not.toHaveBeenCalled();
expect(nestedBeforeEach).not.toHaveBeenCalled();
expect(nestedIt).not.toHaveBeenCalled();
expect(nestedAfterEach).not.toHaveBeenCalled();
expect(outerAfterEach).not.toHaveBeenCalled();
expect(reporter.suiteStarted).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a nested suite'
})
);
// The child suite should be reported as passed, for consistency with
// suites that contain failing specs but no suite-level errors.
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a nested suite',
status: 'passed',
failedExpectations: []
})
);
expect(reporter.specStarted).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a spec'
})
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a spec',
status: 'failed',
failedExpectations: [
jasmine.objectContaining({
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
})
]
})
);
expect(reporter.specStarted).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a nested suite a nested spec'
})
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a nested suite a nested spec',
status: 'failed',
failedExpectations: [
jasmine.objectContaining({
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
})
]
})
);
});
});
describe('When a suite beforeAll function fails', function() {
it('skips and reports contained specs', async function() {
const outerBeforeEach = jasmine.createSpy('outerBeforeEach');
const nestedBeforeEach = jasmine.createSpy('nestedBeforeEach');
const outerAfterEach = jasmine.createSpy('outerAfterEach');
const nestedAfterEach = jasmine.createSpy('nestedAfterEach');
const outerIt = jasmine.createSpy('outerIt');
const nestedIt = jasmine.createSpy('nestedIt');
const nestedBeforeAll = jasmine.createSpy('nestedBeforeAll');
env.describe('a suite', function() {
env.beforeAll(function() {
throw new Error('nope');
});
env.beforeEach(outerBeforeEach);
env.it('a spec', outerIt);
env.describe('a nested suite', function() {
env.beforeAll(nestedBeforeAll);
env.beforeEach(nestedBeforeEach);
env.it('a nested spec', nestedIt);
env.afterEach(nestedAfterEach);
});
env.afterEach(outerAfterEach);
});
const reporter = jasmine.createSpyObj('reporter', [
'suiteStarted',
'suiteDone',
'specStarted',
'specDone'
]);
env.addReporter(reporter);
await env.execute();
expect(outerBeforeEach).not.toHaveBeenCalled();
expect(outerIt).not.toHaveBeenCalled();
expect(nestedBeforeAll).not.toHaveBeenCalled();
expect(nestedBeforeEach).not.toHaveBeenCalled();
expect(nestedIt).not.toHaveBeenCalled();
expect(nestedAfterEach).not.toHaveBeenCalled();
expect(outerAfterEach).not.toHaveBeenCalled();
expect(reporter.suiteStarted).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a suite a nested suite'
})
);
// The child suite should be reported as passed, for consistency with
// suites that contain failing specs but no suite-level errors.
expect(reporter.suiteDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a suite a nested suite',
status: 'passed',
failedExpectations: []
})
);
expect(reporter.specStarted).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a suite a spec'
})
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a suite a spec',
status: 'failed',
failedExpectations: [
jasmine.objectContaining({
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
})
]
})
);
expect(reporter.specStarted).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a suite a nested suite a nested spec'
})
);
expect(reporter.specDone).toHaveBeenCalledWith(
jasmine.objectContaining({
fullName: 'a suite a nested suite a nested spec',
status: 'failed',
failedExpectations: [
jasmine.objectContaining({
passed: false,
message:
'Not run because a beforeAll function failed. The ' +
'beforeAll failure will be reported on the suite that ' +
'caused it.'
})
]
})
);
});
it('runs afterAll functions in the current suite and outer scopes', async function() {
const outerAfterAll = jasmine.createSpy('outerAfterAll');
const nestedAfterAll = jasmine.createSpy('nestedAfterAll');
const secondNestedAfterAll = jasmine.createSpy('secondNestedAfterAll');
env.describe('a nested suite', function() {
env.beforeAll(function() {
throw new Error('nope');
});
env.describe('more nesting', function() {
env.it('a nested spec', function() {});
env.afterAll(secondNestedAfterAll);
});
env.afterAll(nestedAfterAll);
});
env.afterAll(outerAfterAll);
await env.execute();
expect(secondNestedAfterAll).not.toHaveBeenCalled();
expect(nestedAfterAll).toHaveBeenCalled();
expect(outerAfterAll).toHaveBeenCalled();
});
});
describe('when stopOnSpecFailure is on', function() {
it('does not run further specs when one fails', function(done) {
var actions = [],
config;
@@ -999,31 +1316,47 @@ describe('spec running', function() {
});
env.configure({ random: false });
configureFn(env);
env.configure({ stopOnSpecFailure: true });
env.execute(null, function() {
expect(actions).toEqual(['fails']);
done();
});
});
}
describe('when failFast is on', function() {
behavesLikeStopOnSpecFailureIsOn(function(env) {
env.configure({ failFast: true });
});
});
it('runs afterAll functions', async function() {
const actions = [];
env.describe('outer suite', function() {
env.describe('inner suite', function() {
env.it('fails', function() {
actions.push('fails');
env.expect(1).toBe(2);
});
env.afterAll(function() {
actions.push('inner afterAll');
});
});
env.afterAll(function() {
actions.push('outer afterAll');
});
});
env.afterAll(function() {
actions.push('top afterAll');
});
describe('when stopOnSpecFailure is on', function() {
behavesLikeStopOnSpecFailureIsOn(function(env) {
env.configure({ stopOnSpecFailure: true });
});
});
await env.execute();
describe('when stopOnSpecFailure is enabled via the deprecated method', function() {
behavesLikeStopOnSpecFailureIsOn(function(env) {
spyOn(env, 'deprecated');
env.stopOnSpecFailure(true);
expect(actions).toEqual([
'fails',
'inner afterAll',
'outer afterAll',
'top afterAll'
]);
});
});

View File

@@ -112,7 +112,7 @@ describe('DiffBuilder', function() {
return '[number:' + x + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});
@@ -131,7 +131,7 @@ describe('DiffBuilder', function() {
return '[thing with a=' + x.a + ', b=' + JSON.stringify(x.b) + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});

View File

@@ -1,8 +1,5 @@
/* eslint-disable compat/compat */
describe('toBePending', function() {
it('passes if the actual promise is pending', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = new Promise(function() {});
@@ -13,8 +10,6 @@ describe('toBePending', function() {
});
it('fails if the actual promise is resolved', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = Promise.resolve();
@@ -25,8 +20,6 @@ describe('toBePending', function() {
});
it('fails if the actual promise is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = Promise.reject(new Error('promise was rejected'));

View File

@@ -1,8 +1,5 @@
/* eslint-disable compat/compat */
describe('toBeRejected', function() {
it('passes if the actual is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejected(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec rejection');
@@ -13,8 +10,6 @@ describe('toBeRejected', function() {
});
it('fails if the actual is resolved', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejected(matchersUtil),
actual = Promise.resolve();

View File

@@ -1,8 +1,5 @@
/* eslint-disable compat/compat */
describe('#toBeRejectedWithError', function() {
it('passes when Error type matches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -23,8 +20,6 @@ describe('#toBeRejectedWithError', function() {
});
it('passes when Error type and message matches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -45,8 +40,6 @@ describe('#toBeRejectedWithError', function() {
});
it('passes when Error matches and is exactly Error', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -67,8 +60,6 @@ describe('#toBeRejectedWithError', function() {
});
it('passes when Error message matches a string', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -89,8 +80,6 @@ describe('#toBeRejectedWithError', function() {
});
it('passes when Error message matches a RegExp', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -111,8 +100,6 @@ describe('#toBeRejectedWithError', function() {
});
it('passes when Error message is empty', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -133,8 +120,6 @@ describe('#toBeRejectedWithError', function() {
});
it('passes when no arguments', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -155,8 +140,6 @@ describe('#toBeRejectedWithError', function() {
});
it('fails when resolved', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -176,8 +159,6 @@ describe('#toBeRejectedWithError', function() {
});
it('fails when rejected with non Error type', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -198,8 +179,6 @@ describe('#toBeRejectedWithError', function() {
});
it('fails when Error type mismatches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -220,8 +199,6 @@ describe('#toBeRejectedWithError', function() {
});
it('fails when Error message mismatches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),

View File

@@ -1,8 +1,5 @@
/* eslint-disable compat/compat */
describe('#toBeRejectedWith', function() {
it('should return true if the promise is rejected with the expected value', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject({ error: 'PEBCAK' });
@@ -13,8 +10,6 @@ describe('#toBeRejectedWith', function() {
});
it('should fail if the promise resolves', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.resolve();
@@ -25,8 +20,6 @@ describe('#toBeRejectedWith', function() {
});
it('should fail if the promise is rejected with a different value', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -45,8 +38,6 @@ describe('#toBeRejectedWith', function() {
});
it('should build its error correctly when negated', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -64,8 +55,6 @@ describe('#toBeRejectedWith', function() {
});
it('should support custom equality testers', function() {
jasmine.getEnv().requirePromises();
var customEqualityTesters = [
function() {
return true;

View File

@@ -1,8 +1,5 @@
/* eslint-disable compat/compat */
describe('toBeResolved', function() {
it('passes if the actual is resolved', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolved(matchersUtil),
actual = Promise.resolve();
@@ -13,8 +10,6 @@ describe('toBeResolved', function() {
});
it('fails if the actual is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter([])
}),

View File

@@ -1,8 +1,5 @@
/* eslint-disable compat/compat */
describe('#toBeResolvedTo', function() {
it('passes if the promise is resolved to the expected value', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve({ foo: 42 });
@@ -13,8 +10,6 @@ describe('#toBeResolvedTo', function() {
});
it('fails if the promise is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -34,8 +29,6 @@ describe('#toBeResolvedTo', function() {
});
it('fails if the promise is resolved to a different value', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -54,8 +47,6 @@ describe('#toBeResolvedTo', function() {
});
it('builds its message correctly when negated', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
@@ -73,8 +64,6 @@ describe('#toBeResolvedTo', function() {
});
it('supports custom equality testers', function() {
jasmine.getEnv().requirePromises();
var customEqualityTesters = [
function() {
return true;

View File

@@ -94,7 +94,7 @@ describe('matchersUtil', function() {
});
it('fails for Arrays that have different lengths', function() {
matchersUtil = new jasmineUnderTest.MatchersUtil();
const matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
});
@@ -232,8 +232,8 @@ describe('matchersUtil', function() {
return;
}
var p1 = new Promise(function() {}), // eslint-disable-line compat/compat
p2 = new Promise(function() {}), // eslint-disable-line compat/compat
var p1 = new Promise(function() {}),
p2 = new Promise(function() {}),
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(p1, p1)).toBe(true);
@@ -367,13 +367,11 @@ describe('matchersUtil', function() {
});
it('passes when MapContaining is used', function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var obj = new Map(); // eslint-disable-line compat/compat
var obj = new Map();
obj.set(1, 2);
obj.set('foo', 'bar');
var containing = new jasmineUnderTest.MapContaining(new Map()); // eslint-disable-line compat/compat
var containing = new jasmineUnderTest.MapContaining(new Map());
containing.sample.set('foo', 'bar');
expect(matchersUtil.equals(obj, containing)).toBe(true);
@@ -381,13 +379,11 @@ describe('matchersUtil', function() {
});
it('passes when SetContaining is used', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var obj = new Set(); // eslint-disable-line compat/compat
var obj = new Set();
obj.add(1);
obj.add('foo');
var containing = new jasmineUnderTest.SetContaining(new Set()); // eslint-disable-line compat/compat
var containing = new jasmineUnderTest.SetContaining(new Set());
containing.sample.add(1);
expect(matchersUtil.equals(obj, containing)).toBe(true);
@@ -427,17 +423,7 @@ describe('matchersUtil', function() {
).toBe(true);
});
it('passes when a custom equality matcher passed to equals returns true', function() {
// TODO: remove this in the next major release.
var tester = function(a, b) {
return true;
},
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(1, 2, [tester])).toBe(true);
});
it('passes when a custom equality matcher passed to the constructor returns true', function() {
it('passes when a custom equality matcher returns true', function() {
var tester = function(a, b) {
return true;
},
@@ -454,19 +440,7 @@ describe('matchersUtil', function() {
expect(matchersUtil.equals({}, {})).toBe(true);
});
describe("when a custom equality matcher is passed to equals that returns 'undefined'", function() {
// TODO: remove this in the next major release.
var tester = function(a, b) {
return jasmine.undefined;
};
it('passes for two empty Objects', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals({}, {}, [tester])).toBe(true);
});
});
describe("when a custom equality matcher is passed to the constructor that returns 'undefined'", function() {
describe("when a custom equality matcher returns 'undefined'", function() {
var tester = function(a, b) {
return jasmine.undefined;
};
@@ -480,17 +454,7 @@ describe('matchersUtil', function() {
});
});
it('fails for equivalents when a custom equality matcher passed to equals returns false', function() {
// TODO: remove this in the next major release.
var tester = function(a, b) {
return false;
},
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(1, 1, [tester])).toBe(false);
});
it('fails for equivalents when a custom equality matcher passed to the constructor returns false', function() {
it('fails for equivalents when a custom equality matcher returns false', function() {
var tester = function(a, b) {
return false;
},
@@ -502,27 +466,7 @@ describe('matchersUtil', function() {
expect(matchersUtil.equals(1, 1)).toBe(false);
});
it('passes for an asymmetric equality tester that returns true when a custom equality tester passed to equals return false', function() {
// TODO: remove this in the next major release.
var asymmetricTester = {
asymmetricMatch: function(other) {
return true;
}
},
symmetricTester = function(a, b) {
return false;
},
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(
matchersUtil.equals(asymmetricTester, true, [symmetricTester])
).toBe(true);
expect(
matchersUtil.equals(true, asymmetricTester, [symmetricTester])
).toBe(true);
});
it('passes for an asymmetric equality tester that returns true when a custom equality tester passed to the constructor return false', function() {
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;
@@ -540,45 +484,6 @@ describe('matchersUtil', function() {
expect(matchersUtil.equals(true, asymmetricTester)).toBe(true);
});
describe('The compatibility shim passed to asymmetric equality testers', function() {
describe('When equals is called with custom equality testers', function() {
it('is both a matchersUtil and the custom equality testers passed to equals', function() {
var asymmetricTester = jasmine.createSpyObj('tester', [
'asymmetricMatch'
]),
symmetricTester = function() {},
matchersUtil = new jasmineUnderTest.MatchersUtil(),
shim;
matchersUtil.equals(true, asymmetricTester, [symmetricTester]);
shim = asymmetricTester.asymmetricMatch.calls.argsFor(0)[1];
expect(shim).toEqual(jasmine.any(jasmineUnderTest.MatchersUtil));
expect(shim.length).toEqual(1);
expect(shim[0]).toEqual(symmetricTester);
});
});
describe('When equals is called with custom equality testers', function() {
it('is both a matchersUtil and the custom equality testers passed to the constructor', function() {
var asymmetricTester = jasmine.createSpyObj('tester', [
'asymmetricMatch'
]),
symmetricTester = function() {},
matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [symmetricTester],
pp: function() {}
}),
shim;
matchersUtil.equals(true, asymmetricTester);
shim = asymmetricTester.asymmetricMatch.calls.argsFor(0)[1];
expect(shim).toEqual(jasmine.any(jasmineUnderTest.MatchersUtil));
expect(shim.length).toEqual(1);
expect(shim[0]).toEqual(symmetricTester);
});
});
});
it('passes when an Any is compared to an Any that checks for the same type', function() {
var any1 = new jasmineUnderTest.Any(Function),
any2 = new jasmineUnderTest.Any(Function),
@@ -610,19 +515,16 @@ describe('matchersUtil', function() {
});
it('passes when comparing two empty sets', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Set(), new Set())).toBe(true); // eslint-disable-line compat/compat
expect(matchersUtil.equals(new Set(), new Set())).toBe(true);
});
it('passes when comparing identical sets', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); // eslint-disable-line compat/compat
var setA = new Set();
setA.add(6);
setA.add(5);
var setB = new Set(); // eslint-disable-line compat/compat
var setB = new Set();
setB.add(6);
setB.add(5);
@@ -630,13 +532,11 @@ describe('matchersUtil', function() {
});
it('passes when comparing identical sets with different insertion order and simple elements', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); // eslint-disable-line compat/compat
var setA = new Set();
setA.add(3);
setA.add(6);
var setB = new Set(); // eslint-disable-line compat/compat
var setB = new Set();
setB.add(6);
setB.add(3);
@@ -644,26 +544,24 @@ describe('matchersUtil', function() {
});
it('passes when comparing identical sets with different insertion order and complex elements 1', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA1 = new Set(); // eslint-disable-line compat/compat
var setA1 = new Set();
setA1.add(['a', 3]);
setA1.add([6, 1]);
var setA2 = new Set(); // eslint-disable-line compat/compat
var setA2 = new Set();
setA1.add(['y', 3]);
setA1.add([6, 1]);
var setA = new Set(); // eslint-disable-line compat/compat
var setA = new Set();
setA.add(setA1);
setA.add(setA2);
var setB1 = new Set(); // eslint-disable-line compat/compat
var setB1 = new Set();
setB1.add([6, 1]);
setB1.add(['a', 3]);
var setB2 = new Set(); // eslint-disable-line compat/compat
var setB2 = new Set();
setB1.add([6, 1]);
setB1.add(['y', 3]);
var setB = new Set(); // eslint-disable-line compat/compat
var setB = new Set();
setB.add(setB1);
setB.add(setB2);
@@ -671,13 +569,11 @@ describe('matchersUtil', function() {
});
it('passes when comparing identical sets with different insertion order and complex elements 2', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); // eslint-disable-line compat/compat
var setA = new Set();
setA.add([[1, 2], [3, 4]]);
setA.add([[5, 6], [7, 8]]);
var setB = new Set(); // eslint-disable-line compat/compat
var setB = new Set();
setB.add([[5, 6], [7, 8]]);
setB.add([[1, 2], [3, 4]]);
@@ -685,13 +581,12 @@ describe('matchersUtil', function() {
});
it('fails for sets with different elements', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); // eslint-disable-line compat/compat
var setA = new Set();
setA.add(6);
setA.add(3);
setA.add(5);
var setB = new Set(); // eslint-disable-line compat/compat
var setB = new Set();
setB.add(6);
setB.add(4);
setB.add(5);
@@ -700,12 +595,11 @@ describe('matchersUtil', function() {
});
it('fails for sets of different size', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setA = new Set(); // eslint-disable-line compat/compat
var setA = new Set();
setA.add(6);
setA.add(3);
var setB = new Set(); // eslint-disable-line compat/compat
var setB = new Set();
setB.add(6);
setB.add(4);
setB.add(5);
@@ -714,40 +608,36 @@ describe('matchersUtil', function() {
});
it('passes when comparing two empty maps', function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(new Map(), new Map())).toBe(true); // eslint-disable-line compat/compat
expect(matchersUtil.equals(new Map(), new Map())).toBe(true);
});
it('passes when comparing identical maps', function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); // eslint-disable-line compat/compat
var mapA = new Map();
mapA.set(6, 5);
var mapB = new Map(); // eslint-disable-line compat/compat
var mapB = new Map();
mapB.set(6, 5);
expect(matchersUtil.equals(mapA, mapB)).toBe(true);
});
it('passes when comparing identical maps with different insertion order', function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); // eslint-disable-line compat/compat
var mapA = new Map();
mapA.set('a', 3);
mapA.set(6, 1);
var mapB = new Map(); // eslint-disable-line compat/compat
var mapB = new Map();
mapB.set(6, 1);
mapB.set('a', 3);
expect(matchersUtil.equals(mapA, mapB)).toBe(true);
});
it('fails for maps with different elements', function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); // eslint-disable-line compat/compat
var mapA = new Map();
mapA.set(6, 3);
mapA.set(5, 1);
var mapB = new Map(); // eslint-disable-line compat/compat
var mapB = new Map();
mapB.set(6, 4);
mapB.set(5, 1);
@@ -755,93 +645,75 @@ describe('matchersUtil', function() {
});
it('fails for maps of different size', function() {
jasmine.getEnv().requireFunctioningMaps();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var mapA = new Map(); // eslint-disable-line compat/compat
var mapA = new Map();
mapA.set(6, 3);
var mapB = new Map(); // eslint-disable-line compat/compat
var mapB = new Map();
mapB.set(6, 4);
mapB.set(5, 1);
expect(matchersUtil.equals(mapA, mapB)).toBe(false);
});
it('passes when comparing two identical URLs', function() {
jasmine.getEnv().requireUrls();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(
matchersUtil.equals(
// eslint-disable-next-line compat/compat
new URL('http://localhost/1'),
// eslint-disable-next-line compat/compat
new URL('http://localhost/1')
)
).toBe(true);
});
it('fails when comparing two different URLs', function() {
jasmine.getEnv().requireUrls();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
// eslint-disable-next-line compat/compat
url1 = new URL('http://localhost/1');
// eslint-disable-next-line compat/compat
expect(matchersUtil.equals(url1, new URL('http://localhost/2'))).toBe(
false
);
// eslint-disable-next-line compat/compat
expect(matchersUtil.equals(url1, new URL('http://localhost/1?foo'))).toBe(
false
);
// eslint-disable-next-line compat/compat
expect(matchersUtil.equals(url1, new URL('http://localhost/1#foo'))).toBe(
false
);
// eslint-disable-next-line compat/compat
expect(matchersUtil.equals(url1, new URL('https://localhost/1'))).toBe(
false
);
expect(
// eslint-disable-next-line compat/compat
matchersUtil.equals(url1, new URL('http://localhost:8080/1'))
).toBe(false);
// eslint-disable-next-line compat/compat
expect(matchersUtil.equals(url1, new URL('http://example.com/1'))).toBe(
false
);
});
it('passes for ArrayBuffers with same length and content', function() {
jasmine.getEnv().requireFunctioningArrayBuffers();
var buffer1 = new ArrayBuffer(4); // eslint-disable-line compat/compat
var buffer2 = new ArrayBuffer(4); // eslint-disable-line compat/compat
expect(jasmineUnderTest.matchersUtil.equals(buffer1, buffer2)).toBe(true);
var buffer1 = new ArrayBuffer(4);
var buffer2 = new ArrayBuffer(4);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(buffer1, buffer2)).toBe(true);
});
it('fails for ArrayBuffers with same length but different content', function() {
jasmine.getEnv().requireFunctioningArrayBuffers();
var buffer1 = new ArrayBuffer(4); // eslint-disable-line compat/compat
var buffer2 = new ArrayBuffer(4); // eslint-disable-line compat/compat
var array1 = new Uint8Array(buffer1); // eslint-disable-line compat/compat
var buffer1 = new ArrayBuffer(4);
var buffer2 = new ArrayBuffer(4);
var array1 = new Uint8Array(buffer1);
array1[0] = 1;
expect(jasmineUnderTest.matchersUtil.equals(buffer1, buffer2)).toBe(
false
);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals(buffer1, buffer2)).toBe(false);
});
describe('Typed arrays', function() {
it('fails for typed arrays of same length and contents but different types', function() {
// eslint-disable-next-line compat/compat
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new Int8Array(1);
// eslint-disable-next-line compat/compat
var a2 = new Uint8Array(1);
a1[0] = a2[0] = 0;
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(false);
expect(matchersUtil.equals(a1, a2)).toBe(false);
});
// eslint-disable-next-line compat/compat
[
'Int8Array',
'Uint8Array',
@@ -853,59 +725,50 @@ describe('matchersUtil', function() {
'Float32Array',
'Float64Array'
].forEach(function(typeName) {
function requireType() {
var TypedArrayCtor = jasmine.getGlobal()[typeName];
if (!TypedArrayCtor) {
pending('Browser does not support ' + typeName);
}
return TypedArrayCtor;
}
var TypedArrayCtor = jasmine.getGlobal()[typeName];
it(
'passes for ' + typeName + 's with same length and content',
function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(2);
var a2 = new TypedArrayCtor(2);
a1[0] = a2[0] = 0;
a1[1] = a2[1] = 1;
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(true);
expect(matchersUtil.equals(a1, a2)).toBe(true);
}
);
it('fails for ' + typeName + 's with different length', function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(2);
var a2 = new TypedArrayCtor(1);
a1[0] = a1[1] = a2[0] = 0;
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(false);
expect(matchersUtil.equals(a1, a2)).toBe(false);
});
it(
'fails for ' + typeName + 's with same length but different content',
function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(1);
var a2 = new TypedArrayCtor(1);
a1[0] = 0;
a2[0] = 1;
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(false);
expect(matchersUtil.equals(a1, a2)).toBe(false);
}
);
it('checks nonstandard properties of ' + typeName, function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(1);
var a2 = new TypedArrayCtor(1);
a1[0] = a2[0] = 0;
a1.extra = 'yes';
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(false);
expect(matchersUtil.equals(a1, a2)).toBe(false);
});
it('works with custom equality testers with ' + typeName, function() {
var TypedArrayCtor = requireType();
var a1 = new TypedArrayCtor(1);
var a2 = new TypedArrayCtor(1);
var matchersUtil = new jasmineUnderTest.MatchersUtil({
@@ -936,36 +799,39 @@ describe('matchersUtil', function() {
'passes for ' + typeName + 's with same length and content',
function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(2);
var a2 = new TypedArrayCtor(2);
// eslint-disable-next-line compat/compat
a1[0] = a2[0] = BigInt(0);
// eslint-disable-next-line compat/compat
a1[1] = a2[1] = BigInt(1);
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(true);
expect(matchersUtil.equals(a1, a2)).toBe(true);
}
);
it('fails for ' + typeName + 's with different length', function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(2);
var a2 = new TypedArrayCtor(1);
// eslint-disable-next-line compat/compat
a1[0] = a1[1] = a2[0] = BigInt(0);
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(false);
expect(matchersUtil.equals(a1, a2)).toBe(false);
});
it(
'fails for ' + typeName + 's with same length but different content',
function() {
var TypedArrayCtor = requireType();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var a1 = new TypedArrayCtor(2);
var a2 = new TypedArrayCtor(2);
// eslint-disable-next-line compat/compat
a1[0] = a1[1] = a2[0] = BigInt(0);
// eslint-disable-next-line compat/compat
a2[1] = BigInt(1);
expect(jasmineUnderTest.matchersUtil.equals(a1, a2)).toBe(false);
expect(matchersUtil.equals(a1, a2)).toBe(false);
}
);
});
@@ -976,11 +842,16 @@ describe('matchersUtil', function() {
Array.prototype,
'findIndex'
);
if (!findIndexDescriptor) {
return;
}
beforeEach(function() {
if (!findIndexDescriptor) {
jasmine
.getEnv()
.pending(
'Environment does not have a property descriptor for Array.prototype.findIndex'
);
}
Object.defineProperty(Array.prototype, 'findIndex', {
enumerable: true,
value: function(predicate) {
@@ -1043,12 +914,13 @@ describe('matchersUtil', function() {
'recordMismatch',
'withPath',
'setRoots'
]);
]),
matchersUtil = new jasmineUnderTest.MatchersUtil();
diffBuilder.withPath.and.callFake(function(p, block) {
block();
});
jasmineUnderTest.matchersUtil.equals(actual, expected, [], diffBuilder);
matchersUtil.equals(actual, expected, diffBuilder);
expect(diffBuilder.setRoots).toHaveBeenCalledWith(actual, expected);
expect(diffBuilder.withPath).toHaveBeenCalledWith(
@@ -1070,11 +942,13 @@ describe('matchersUtil', function() {
'recordMismatch',
'withPath',
'setRoots'
]);
]),
matchersUtil = new jasmineUnderTest.MatchersUtil();
diffBuilder.withPath.and.callFake(function(p, block) {
block();
});
jasmineUnderTest.matchersUtil.equals(actual, expected, [], diffBuilder);
matchersUtil.equals(actual, expected, diffBuilder);
expect(diffBuilder.setRoots).toHaveBeenCalledWith(actual, expected);
expect(diffBuilder.withPath).toHaveBeenCalledWith(
@@ -1085,26 +959,6 @@ describe('matchersUtil', function() {
});
});
it('uses a diffBuilder if one is provided as the fourth argument', function() {
// TODO: remove this in the next major release.
var diffBuilder = new jasmineUnderTest.DiffBuilder(),
matchersUtil = new jasmineUnderTest.MatchersUtil();
spyOn(diffBuilder, 'recordMismatch');
spyOn(diffBuilder, 'withPath').and.callThrough();
matchersUtil.equals([1], [2], [], diffBuilder);
expect(diffBuilder.withPath).toHaveBeenCalledWith(
'length',
jasmine.any(Function)
);
expect(diffBuilder.withPath).toHaveBeenCalledWith(
0,
jasmine.any(Function)
);
expect(diffBuilder.recordMismatch).toHaveBeenCalledWith();
});
it('uses a diffBuilder if one is provided as the third argument', function() {
var diffBuilder = new jasmineUnderTest.DiffBuilder(),
matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -1154,17 +1008,7 @@ describe('matchersUtil', function() {
).toBe(true);
});
it('uses custom equality testers if passed to contains and actual is an Array', function() {
// TODO: remove this in the next major release.
var customTester = function(a, b) {
return true;
},
matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains([1, 2], 3, [customTester])).toBe(true);
});
it('uses custom equality testers if passed to the constructor and actual is an Array', function() {
it('uses custom equality testers if actual is an Array', function() {
var customTester = function(a, b) {
return true;
},
@@ -1186,7 +1030,7 @@ describe('matchersUtil', function() {
expect(matchersUtil.contains(null, 'A')).toBe(false);
});
it('passes with array-like objects', function() {
it('works with array-like objects that implement iterable', function() {
var capturedArgs = null,
matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -1196,28 +1040,36 @@ describe('matchersUtil', function() {
testFunction('foo', 'bar');
expect(matchersUtil.contains(capturedArgs, 'bar')).toBe(true);
expect(matchersUtil.contains(capturedArgs, 'baz')).toBe(false);
});
it("passes with array-like objects that don't implement iterable", function() {
const arrayLike = {
0: 'a',
1: 'b',
length: 2
};
const matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.contains(arrayLike, 'b')).toBe(true);
expect(matchersUtil.contains(arrayLike, 'c')).toBe(false);
});
it('passes for set members', function() {
jasmine.getEnv().requireFunctioningSets();
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var setItem = { foo: 'bar' };
var set = new Set(); // eslint-disable-line compat/compat
var set = new Set();
set.add(setItem);
expect(matchersUtil.contains(set, setItem)).toBe(true);
});
// documenting current behavior
it('fails (!) for objects that equal to a set member', function() {
jasmine.getEnv().requireFunctioningSets();
it('passes for objects that equal to a set member', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var set = new Set(); // eslint-disable-line compat/compat
var set = new Set();
set.add({ foo: 'bar' });
expect(matchersUtil.contains(set, { foo: 'bar' })).toBe(false);
expect(matchersUtil.contains(set, { foo: 'bar' })).toBe(true);
});
});

View File

@@ -104,8 +104,6 @@ describe('toBeInstanceOf', function() {
});
it('passes for an async function', function() {
jasmine.getEnv().requireAsyncAwait();
var fn = eval("(async function fn() { return 'foo'; })");
var matcher = jasmineUnderTest.matchers.toBeInstanceOf();

View File

@@ -257,8 +257,8 @@ describe('toEqual', function() {
});
it('reports mismatches between arrays of different types', function() {
var actual = new Uint32Array([1, 2, 3]), // eslint-disable-line compat/compat
expected = new Uint16Array([1, 2, 3]), // eslint-disable-line compat/compat
var actual = new Uint32Array([1, 2, 3]),
expected = new Uint16Array([1, 2, 3]),
message =
'Expected Uint32Array [ 1, 2, 3 ] to equal Uint16Array [ 1, 2, 3 ].';
@@ -460,11 +460,9 @@ describe('toEqual', function() {
// == Sets ==
it('reports mismatches between Sets', function() {
jasmine.getEnv().requireFunctioningSets();
var actual = new Set(); // eslint-disable-line compat/compat
var actual = new Set();
actual.add(1);
var expected = new Set(); // eslint-disable-line compat/compat
var expected = new Set();
expected.add(2);
var message = 'Expected Set( 1 ) to equal Set( 2 ).';
@@ -472,11 +470,9 @@ describe('toEqual', function() {
});
it('reports deep mismatches within Sets', function() {
jasmine.getEnv().requireFunctioningSets();
var actual = new Set(); // eslint-disable-line compat/compat
var actual = new Set();
actual.add({ x: 1 });
var expected = new Set(); // eslint-disable-line compat/compat
var expected = new Set();
expected.add({ x: 2 });
var message =
'Expected Set( Object({ x: 1 }) ) to equal Set( Object({ x: 2 }) ).';
@@ -485,11 +481,9 @@ describe('toEqual', function() {
});
it('reports mismatches between Sets nested in objects', function() {
jasmine.getEnv().requireFunctioningSets();
var actualSet = new Set(); // eslint-disable-line compat/compat
var actualSet = new Set();
actualSet.add(1);
var expectedSet = new Set(); // eslint-disable-line compat/compat
var expectedSet = new Set();
expectedSet.add(2);
var actual = { sets: [actualSet] };
@@ -500,12 +494,10 @@ describe('toEqual', function() {
});
it('reports mismatches between Sets of different lengths', function() {
jasmine.getEnv().requireFunctioningSets();
var actual = new Set(); // eslint-disable-line compat/compat
var actual = new Set();
actual.add(1);
actual.add(2);
var expected = new Set(); // eslint-disable-line compat/compat
var expected = new Set();
expected.add(2);
var message = 'Expected Set( 1, 2 ) to equal Set( 2 ).';
@@ -513,13 +505,11 @@ describe('toEqual', function() {
});
it('reports mismatches between Sets where actual is missing a value from expected', function() {
jasmine.getEnv().requireFunctioningSets();
// Use 'duplicate' object in actual so sizes match
var actual = new Set(); // eslint-disable-line compat/compat
var actual = new Set();
actual.add({ x: 1 });
actual.add({ x: 1 });
var expected = new Set(); // eslint-disable-line compat/compat
var expected = new Set();
expected.add({ x: 1 });
expected.add({ x: 2 });
var message =
@@ -529,13 +519,11 @@ describe('toEqual', function() {
});
it('reports mismatches between Sets where actual has a value missing from expected', function() {
jasmine.getEnv().requireFunctioningSets();
// Use 'duplicate' object in expected so sizes match
var actual = new Set(); // eslint-disable-line compat/compat
var actual = new Set();
actual.add({ x: 1 });
actual.add({ x: 2 });
var expected = new Set(); // eslint-disable-line compat/compat
var expected = new Set();
expected.add({ x: 1 });
expected.add({ x: 1 });
var message =
@@ -547,23 +535,19 @@ describe('toEqual', function() {
// == Maps ==
it('does not report mismatches between deep equal Maps', function() {
jasmine.getEnv().requireFunctioningMaps();
// values are the same but with different object identity
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set('a', { x: 1 });
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set('a', { x: 1 });
expect(compareEquals(actual, expected).pass).toBe(true);
});
it('reports deep mismatches within Maps', function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set('a', { x: 1 });
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set('a', { x: 2 });
var message =
"Expected Map( [ 'a', Object({ x: 1 }) ] ) to equal Map( [ 'a', Object({ x: 2 }) ] ).";
@@ -572,11 +556,9 @@ describe('toEqual', function() {
});
it('reports mismatches between Maps nested in objects', function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = { Maps: [new Map()] }; // eslint-disable-line compat/compat
var actual = { Maps: [new Map()] };
actual.Maps[0].set('a', 1);
var expected = { Maps: [new Map()] }; // eslint-disable-line compat/compat
var expected = { Maps: [new Map()] };
expected.Maps[0].set('a', 2);
var message =
@@ -586,11 +568,9 @@ describe('toEqual', function() {
});
it('reports mismatches between Maps of different lengths', function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set('a', 1);
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set('a', 2);
expected.set('b', 1);
var message =
@@ -600,11 +580,9 @@ describe('toEqual', function() {
});
it('reports mismatches between Maps with equal values but differing keys', function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set('a', 1);
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set('b', 1);
var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'b', 1 ] ).";
@@ -612,22 +590,19 @@ describe('toEqual', function() {
});
it('does not report mismatches between Maps with keys with same object identity', function() {
jasmine.getEnv().requireFunctioningMaps();
var key = { x: 1 };
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set(key, 2);
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set(key, 2);
expect(compareEquals(actual, expected).pass).toBe(true);
});
it('reports mismatches between Maps with identical keys with different object identity', function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set({ x: 1 }, 2);
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set({ x: 1 }, 2);
var message =
'Expected Map( [ Object({ x: 1 }), 2 ] ) to equal Map( [ Object({ x: 1 }), 2 ] ).';
@@ -636,37 +611,29 @@ describe('toEqual', function() {
});
it('does not report mismatches when comparing Map key to jasmine.anything()', function() {
jasmine.getEnv().requireFunctioningMaps();
var actual = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set('a', 1);
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set(jasmineUnderTest.anything(), 1);
expect(compareEquals(actual, expected).pass).toBe(true);
});
it('does not report mismatches when comparing Maps with the same symbol keys', function() {
jasmine.getEnv().requireFunctioningMaps();
jasmine.getEnv().requireFunctioningSymbols();
var key = Symbol(); // eslint-disable-line compat/compat
var actual = new Map(); // eslint-disable-line compat/compat
var key = Symbol();
var actual = new Map();
actual.set(key, 1);
var expected = new Map(); // eslint-disable-line compat/compat
var expected = new Map();
expected.set(key, 1);
expect(compareEquals(actual, expected).pass).toBe(true);
});
it('reports mismatches between Maps with different symbol keys', function() {
jasmine.getEnv().requireFunctioningMaps();
jasmine.getEnv().requireFunctioningSymbols();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set(Symbol(), 1); // eslint-disable-line compat/compat
var expected = new Map(); // eslint-disable-line compat/compat
expected.set(Symbol(), 1); // eslint-disable-line compat/compat
var actual = new Map();
actual.set(Symbol(), 1);
var expected = new Map();
expected.set(Symbol(), 1);
var message =
'Expected Map( [ Symbol(), 1 ] ) to equal Map( [ Symbol(), 1 ] ).';
@@ -674,12 +641,9 @@ describe('toEqual', function() {
});
it('does not report mismatches when comparing Map symbol key to jasmine.anything()', function() {
jasmine.getEnv().requireFunctioningMaps();
jasmine.getEnv().requireFunctioningSymbols();
var actual = new Map(); // eslint-disable-line compat/compat
actual.set(Symbol(), 1); // eslint-disable-line compat/compat
var expected = new Map(); // eslint-disable-line compat/compat
var actual = new Map();
actual.set(Symbol(), 1);
var expected = new Map();
expected.set(jasmineUnderTest.anything(), 1);
expect(compareEquals(actual, expected).pass).toBe(true);

View File

@@ -30,7 +30,7 @@ describe('toHaveBeenCalledBefore', function() {
secondSpy();
result = matcher.compare(firstSpy, secondSpy);
const result = matcher.compare(firstSpy, secondSpy);
expect(result.pass).toBe(false);
expect(result.message).toMatch(
/Expected spy first spy to have been called./
@@ -44,7 +44,7 @@ describe('toHaveBeenCalledBefore', function() {
firstSpy();
result = matcher.compare(firstSpy, secondSpy);
const result = matcher.compare(firstSpy, secondSpy);
expect(result.pass).toBe(false);
expect(result.message).toMatch(
/Expected spy second spy to have been called./

View File

@@ -1,4 +1,3 @@
/* eslint-disable compat/compat */
describe('toHaveSize', function() {
'use strict';
@@ -59,8 +58,6 @@ describe('toHaveSize', function() {
});
it('passes for a Map whose length matches', function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map();
map.set('a', 1);
map.set('b', 2);
@@ -72,8 +69,6 @@ describe('toHaveSize', function() {
});
it('fails for a Map whose length does not match', function() {
jasmine.getEnv().requireFunctioningMaps();
var map = new Map();
map.set('a', 1);
map.set('b', 2);
@@ -85,8 +80,6 @@ describe('toHaveSize', function() {
});
it('passes for a Set whose length matches', function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set();
set.add('a');
set.add('b');
@@ -98,8 +91,6 @@ describe('toHaveSize', function() {
});
it('fails for a Set whose length does not match', function() {
jasmine.getEnv().requireFunctioningSets();
var set = new Set();
set.add('a');
set.add('b');
@@ -111,7 +102,6 @@ describe('toHaveSize', function() {
});
it('throws an error for WeakSet', function() {
jasmine.getEnv().requireWeakSets();
var matcher = jasmineUnderTest.matchers.toHaveSize();
expect(function() {
@@ -120,7 +110,6 @@ describe('toHaveSize', function() {
});
it('throws an error for WeakMap', function() {
jasmine.getEnv().requireWeakMaps();
var matcher = jasmineUnderTest.matchers.toHaveSize();
expect(function() {

View File

@@ -92,16 +92,9 @@ describe('toThrowError', function() {
iframe.src = 'about:blank';
var iframeDocument = iframe.contentWindow.document;
if (iframeDocument.body) {
iframeDocument.body.appendChild(
iframeDocument.createElement('script')
).textContent = "function method() { throw new Error('foo'); }";
} else {
// IE 10 and older
iframeDocument.write(
"<html><head><script>function method() { throw new Error('foo'); }</script></head></html>"
);
}
iframeDocument.body.appendChild(
iframeDocument.createElement('script')
).textContent = "function method() { throw new Error('foo'); }";
var result = matcher.compare(iframe.contentWindow.method);
expect(result.pass).toBe(true);

View File

@@ -1,26 +0,0 @@
(function(env) {
function getAsyncCtor() {
try {
eval('var func = async function(){};');
} catch (e) {
return null;
}
return Object.getPrototypeOf(func).constructor;
}
function hasAsyncAwaitSupport() {
return getAsyncCtor() !== null;
}
env.makeAsyncAwaitFunction = function() {
var AsyncFunction = getAsyncCtor();
return new AsyncFunction('');
};
env.requireAsyncAwait = function() {
if (!hasAsyncAwaitSupport()) {
env.pending('Environment does not support async/await functions');
}
};
})(jasmine.getEnv());

View File

@@ -1,24 +0,0 @@
/* eslint-disable compat/compat */
(function(env) {
function hasFunctioningArrayBuffers() {
if (typeof ArrayBuffer === 'undefined') {
return false;
}
try {
var buffer = new ArrayBuffer(2);
var view8bit = new Uint8Array(buffer);
var view16bit = new Uint16Array(buffer);
view16bit[0] = 0xabcd;
return view8bit[0] === 0xcd && view8bit[1] === 0xab;
} catch (e) {
return false;
}
}
env.requireFunctioningArrayBuffers = function() {
if (!hasFunctioningArrayBuffers()) {
env.pending('Browser has incomplete or missing support for ArrayBuffer');
}
};
})(jasmine.getEnv());

View File

@@ -1,53 +0,0 @@
/* eslint-disable compat/compat */
(function(env) {
env.hasFunctioningMaps = function() {
if (typeof Map === 'undefined') {
return false;
}
try {
var s = new Map();
s.set('a', 1);
s.set('b', 2);
if (s.size !== 2) {
return false;
}
if (s.has('a') !== true) {
return false;
}
var iterations = 0;
var ifForEachWorking = true;
s.forEach(function(value, key, map) {
ifForEachWorking = ifForEachWorking && map === s;
if (key === 'a') {
ifForEachWorking = ifForEachWorking && value === 1;
}
iterations++;
});
if (iterations !== 2) {
return false;
}
if (ifForEachWorking !== true) {
return false;
}
return true;
} catch (e) {
return false;
}
};
env.requireFunctioningMaps = function() {
if (!env.hasFunctioningMaps()) {
env.pending('Browser has incomplete or missing support for Maps');
}
};
env.requireWeakMaps = function() {
if (typeof WeakMap === 'undefined') {
env.pending('Browser does not have support for WeakMap');
}
};
})(jasmine.getEnv());

View File

@@ -1,57 +0,0 @@
/* eslint-disable compat/compat */
(function(env) {
env.hasFunctioningSets = function() {
if (typeof Set === 'undefined') {
return false;
}
try {
var s = new Set();
s.add(1);
s.add(2);
if (s.size !== 2) {
return false;
}
if (s.has(1) !== true) {
return false;
}
var iterations = 0;
var isForEachWorking = true;
s.forEach(function(value, key, set) {
isForEachWorking = isForEachWorking && set === s;
if (iterations === 0) {
isForEachWorking = isForEachWorking && key === value && value === 1;
} else if (iterations === 1) {
isForEachWorking = isForEachWorking && key === value && value === 2;
}
iterations++;
});
if (iterations !== 2) {
return false;
}
if (isForEachWorking !== true) {
return false;
}
return true;
} catch (e) {
return false;
}
};
env.requireFunctioningSets = function() {
if (!env.hasFunctioningSets()) {
env.pending('Browser has incomplete or missing support for Sets');
}
};
env.requireWeakSets = function() {
if (typeof WeakSet === 'undefined') {
env.pending('Browser does not have support for WeakSet');
}
};
})(jasmine.getEnv());

View File

@@ -1,28 +0,0 @@
/* eslint-disable compat/compat */
(function(env) {
function hasFunctioningSymbols() {
if (typeof Symbol === 'undefined') {
return false;
}
try {
var s1 = Symbol();
var s2 = Symbol();
if (typeof s1 !== 'symbol') {
return false;
}
if (s1 === s2) {
return false;
}
return true;
} catch (e) {
return false;
}
}
env.requireFunctioningSymbols = function() {
if (!hasFunctioningSymbols()) {
env.pending('Browser has incomplete or missing support for Symbols');
}
};
})(jasmine.getEnv());

View File

@@ -1,17 +0,0 @@
/* eslint-disable compat/compat */
(function(env) {
function hasUrlConstructor() {
try {
new URL('http://localhost/');
return true;
} catch (e) {
return false;
}
}
env.requireUrls = function() {
if (!hasUrlConstructor()) {
env.pending('Environment does not support URLs');
}
};
})(jasmine.getEnv());

View File

@@ -1,22 +0,0 @@
(function(env) {
function getGeneratorFuncCtor() {
try {
eval('var func = function*() {}');
} catch (e) {
return null;
}
return Object.getPrototypeOf(func).constructor;
}
env.makeGeneratorFunction = function(text) {
var GeneratorFunction = getGeneratorFuncCtor();
return new GeneratorFunction(text || '');
};
env.requireGeneratorFunctions = function() {
if (!getGeneratorFuncCtor()) {
env.pending('Environment does not support generator functions');
}
};
})(jasmine.getEnv());

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