Compare commits

...

146 Commits

Author SHA1 Message Date
Steve Gravrock
e86a7f00a6 Bump version to 3.10.1 2021-10-22 16:15:54 -07:00
Jan Molak
504ef27899 Fixed result.pendingReason for specs marked with xit. Closes #1939 2021-10-22 14:12:28 -07:00
Steve Gravrock
572452a15a Added supported environments to 3.10.0 release notes 2021-10-13 16:47:48 -07:00
Steve Gravrock
896412367a Bump version to 3.10.0 2021-10-13 15:46:21 -07:00
Steve Gravrock
503a7409f0 Merge branch 'issue-1854-asyncerror' of https://github.com/AndreWillomitzer/jasmine into main
* Improves error message when an async expectation occurs after the spec
  finishes
* Merges #1937 from @AndreWillomitzer
* Fixes #1854
2021-10-12 17:15:53 -07:00
Andre Willomitzer
bb9175cb66 added additional error msg for delayedExpectation
added matching error msgs in jasmine objects

Ran prettier.

removed indenting, formatted column length < 80
2021-10-12 13:17:24 -04:00
Steve Gravrock
469b557828 Merge branch 'fix/ie' of https://github.com/nicojs/jasmine into main
* Merges #1936 from @nicojs
2021-10-07 10:17:16 -07:00
Nico Jansen
503715c275 test(ie): refactor promises to callbacks 2021-10-07 10:23:52 +02:00
Steve Gravrock
4482355885 Removed jsdoc entry for SpecResult#trace
Deferred to 4.0.
2021-10-06 11:31:29 -07:00
Steve Gravrock
6542364381 Merge branch 'feat/support-multiple-runs' of https://github.com/nicojs/jasmine into main
* Merges #1934 from @nicojs
* Fixes #1925
2021-10-06 11:20:34 -07:00
Nico Jansen
1fc911e0fa Support running jasmine multiple times
Add support for running jasmine multiple times.

```js
const Jasmine = require('jasmine');

async function main() {
  const jasmine = new Jasmine({ projectBaseDir: process.cwd() });
  let specId = 'spec0';
  jasmine.loadConfigFile('./spec/support/jasmine.json');
  jasmine.env.configure({
    specFilter(sp) {
      return sp.id === specId;
    },
    autoCleanClosures: false
  });
  jasmine.exit = () => {};
  await jasmine.execute();
  specId = 'spec2';
  await jasmine.execute();
}

main().catch((err) => {
  console.error(err);
  process.exitCode = 1;
});
```

With `jasmine.env.configure({ autoCleanClosures: false })` you disable Jasmine's feature to automatically clean closures (functions) during the test run. This is a requirement to be able to rerun.

When `execute` is called more than once, the `topSuite.reset` is called, which will reset the state for the next run as well as reset any child suites.

Add a function `exclude` to the `Suite` and `Spec` clases. This functions similar to `pend`, but will allow the "pending" state to persist over multiple runs. This is useful when `xit` is used.

Revert changes to jasmine.js

fix: make sure to call hooks during second run

Remove jsdoc from private apis

Fix elint issue

Add new line
2021-10-06 20:12:45 +02:00
Steve Gravrock
fdad8849df Revert "Added the ability to associate trace information with failing specs"
Pushing this back to 4.0 in hopes of increasing the chance that third
party reporters will notice it and add support.

This reverts commit 7a289f1de7.
2021-10-02 09:45:15 -07:00
Steve Gravrock
7a289f1de7 Added the ability to associate trace information with failing specs
This is meant to aid in debugging failures, particularly intermittent
failures, in cases where interactive debugging or console.log aren't
suitable.
2021-09-25 16:19:28 -07:00
Steve Gravrock
ef981bb794 Run the browser-flakes build on the debugging branch 2021-09-25 15:50:34 -07:00
Steve Gravrock
c3fb3e985a Reject timeout values that are too large for setTimeout
See #1930
2021-09-25 15:43:31 -07:00
Steve Gravrock
7fc3408051 Expanded jsdocs for jasmine.DEFAULT_TIMEOUT_INTERVAL 2021-09-25 13:29:44 -07:00
Steve Gravrock
af1b43eeff Merge branch 'patch-1' of https://github.com/trusktr/jasmine into main
* Merges #1931 from @trusktr
* Adds discussion of max timeout value to jsdocs
2021-09-25 13:28:34 -07:00
Steve Gravrock
4c043717a9 Revert "Dogfood the new jasmine-npm completion interface"
This works, but until the -npm 3.10.0 is out, it creates a chicken and egg
problem where each of core 3.10.0 and -npm 3.10.0 needs to be released
after the other.

This reverts commit 1c9382c990.
2021-09-25 12:11:20 -07:00
Steve Gravrock
40be00310d Don't immediately move to the next queueable fn on async error
This allows assertion failures and other errors that occcur after the async
error to be routed to the correct spec/suite.

Previously, Jasmine treated global errors and unhandled promise rejections
just like exceptions thrown from a synchronous spec: it recorded the error
as a spec failure and moved on. Now, global errors and uhandled rejections
are recorded as failures but the current queueable fn will continue until
it either signals completion or times out. Global errors and unhandled
rejections are different from synchronous exceptions: it's common for the
queueable fn that caused them to continue executing. Immediately moving on
often meant that the queueable fn would produce expectation failures or
other errors when a different spec or suite was running, thus causing
those failures to be routed to the wrong place.
2021-09-24 11:22:04 -07:00
Steve Gravrock
1f318c3c93 Added missing @since annotations 2021-09-23 13:38:52 -07:00
Steve Gravrock
be29aa95eb Improved jsdocs for asymmetric equality testers 2021-09-23 11:59:20 -07:00
Steve Gravrock
e3c9a59c6c Added a stringContaining asymmetric equality tester
* Fixes #1923.
2021-09-22 11:28:24 -07:00
Joe Pea
b312ed4940 update base.js docs, mention setting DEFAULT_TIMEOUT_INTERVAL to a high number while debugging
This info is useful because if someone does not set the number to a high enough value while stepping through test code, before or after hooks may be triggered mid-test while the user is debugging which will be confusing.
2021-09-21 21:39:21 -07:00
Steve Gravrock
00f6708e1f Removed unused submodule 2021-09-18 09:43:02 -07:00
Steve Gravrock
3a47a3bd04 Fixed flaky spec 2021-09-06 15:35:37 -07:00
Steve Gravrock
1c9382c990 Dogfood the new jasmine-npm completion interface 2021-09-04 13:39:17 -07:00
Steve Gravrock
394be99832 Fixed sass deprecation warnings
See <https://sass-lang.com/documentation/breaking-changes/slash-div>.
[#179260511]
2021-09-03 15:51:51 -07:00
Steve Gravrock
62a667a8e3 Added a deprecation notice to the gem's description
[#179330717]
2021-08-30 18:37:31 -07:00
Steve Gravrock
d277827d5e Fixed typo in 3.9.0 release notes 2021-08-21 19:09:01 -07:00
Steve Gravrock
644c175338 Print a deprecation message when the jasmine-core gem is loaded
[#179247158]
[#179247160]
2021-08-21 18:35:38 -07:00
Steve Gravrock
a6d7eb2a06 Bump version to 3.9.0 2021-08-21 12:00:23 -07:00
Steve Gravrock
dd8a65cb60 Better reporting of unhandled promise rejections with truthy but non-Error reasons on Node
[#179227413]
2021-08-14 14:03:03 -07:00
Steve Gravrock
e72d161fab Return a promise from Env#execute in environments that support promises
[#178373231]
2021-08-07 13:05:55 -07:00
Steve Gravrock
dcaac62a6c Updated deprecaton messages for Env#throwOnExpectationFailure() and Env#stopOnSpecFailure() 2021-07-31 08:02:39 -07:00
Steve Gravrock
b696bec9e3 Renamed failFast and oneFailurePerSpec config props to stopOnSpecFailure and stopSpecOnExpectationFailure
The new names are more self-explanatory and consistent with jasmine-npm. The
old names are deprecated but still work.

[#178682783]
2021-07-31 07:51:50 -07:00
Steve Gravrock
43073b3bc5 Added API docs for Suite#id and Spec#id
These properties are the only way to obtain runnable IDs, without which
you can't call the form of Env#execute that takes an array of IDs.
2021-07-29 19:32:15 -07:00
Steve Gravrock
286524959b Split boot.js in two to allow the env to be configured in between
This is mainly intended to support jasmine-browser-runner, which will load
a script that configures the env in between the two boot files (boot0.js and
boot1.js). The single-file boot.js is retained for now but will be removed
in a future release.
2021-07-26 18:05:36 -07:00
Steve Gravrock
2c32dd5703 Run browser-flakes build before regular cron build 2021-07-20 17:57:54 -07:00
Steve Gravrock
c1d1d69be2 Fixed test failures in Chrome and Edge 2021-07-19 12:08:40 -07:00
Steve Gravrock
3513249d73 Built distribution 2021-07-19 12:08:18 -07:00
Steve Gravrock
21bfbbb721 Merge branch 'iserror-tt' of https://github.com/bjarkler/jasmine into main
* Fixes Trusted Types error in Chromium-based browsers
* Merges #1921 from @bjarkler
* Fixes #1910
2021-07-19 12:06:12 -07:00
Steve Gravrock
88b90ec258 Backfilled unit tests for j$.isError_ 2021-07-19 10:31:53 -07:00
Steve Gravrock
50c88e7774 Mark Env#hideDisabled deprecated in jsdocs 2021-07-08 18:53:21 -07:00
Steve Gravrock
3e64ce3310 Removed property tests for MatchersUtil#equals
These might be useful for a function with a more restricted domain. But for
equals, which accepts two of literally anything, the short run was too short
to catch any problems and the long run tended to exceed the CircleCi timeout.
2021-07-03 08:37:15 -07:00
Steve Gravrock
00586e50e0 Bump version to 3.8.0 2021-07-01 17:06:14 -07:00
Bjarki
dc80a282ba Make j$.isError_ compatible with Trusted Types
The isError_ check uses a heuristic that calls the Function constructor
to determine if the given value is an Error object. This results in a
runtime violation in test suites that enforce Trusted Types.

Since Trusted Types are only supported in modern browsers (currently,
Chromium-based browsers), we can use a more straightforward heuristic in
environments where Trusted Types are supported.

Fixes #1910. See that thread for more details.
2021-07-01 20:21:44 +00:00
Steve Gravrock
27c650ec08 Updated package description 2021-06-30 17:10:51 -07:00
Steve Gravrock
56daa6f461 Merge branch 'select-spec' of https://github.com/jlpstolwijk/jasmine into main
* Merges #1920 from @jlpstolwijk
* Fixes spec filtering in Karma
* Fixes #1906
2021-06-29 17:10:06 -07:00
Joris Stolwijk
e4c7d8af45 new attempt for fixing #1906: add window.location.pathname to hrefs + comments + fixed tests 2021-06-29 14:03:25 +02:00
Steve Gravrock
ee88ecc614 Revert "add url pathName in toQueryString function - fixes (https://github.com/jasmine/jasmine/issues/1906 ) + comment + test"
Reverted because it breaks the option checkboxes in the HTML reporter, both
in the standalone distribution and in jasmine-browser-runner.

Reopens #1906.

This reverts commit 1e4f0d1545.
2021-06-28 12:42:05 -07:00
Steve Gravrock
ec038273f1 Updated contributing guide
* Removed outdated steps
* Replaced list of environments with a pointer to the README
* Misc copy edits
2021-06-26 11:33:03 -07:00
Steve Gravrock
c5bdd79a1e Added TS typings and jasmine-browser-runner to issue template 2021-06-26 11:21:19 -07:00
Steve Gravrock
dbc1a0aa56 Added expectAsync(...).already
* Causes async matchers to immediately fail if the promise is pending
* Fixes #1845
2021-06-23 20:13:01 -07:00
Steve Gravrock
5862b22aef Include rejection details in failure messages for toBeResolved and toBeResolvedWith
[#178559119]
2021-06-21 16:43:51 -07:00
Steve Gravrock
163f93d6ff Removed constructors from jsdocs of classes that aren't user-constructable 2021-06-21 14:19:31 -07:00
Steve Gravrock
1893bf6c16 Added jsdocs for asymmetric equality testers 2021-06-21 14:09:14 -07:00
Steve Gravrock
095745ab12 Removed gulp-jasmine-browser mention from README 2021-06-21 13:31:28 -07:00
Steve Gravrock
68db3f6fcf Merge branch 'select-spec' of https://github.com/jlpstolwijk/jasmine into main
* Merges #1907 from @jlpstolwijk
* Fixes #1906
* Fixes spec filtering in karma-jasmine-html-reporter
2021-06-14 17:59:29 -07:00
Joris Stolwijk
1e4f0d1545 add url pathName in toQueryString function - fixes (https://github.com/jasmine/jasmine/issues/1906 ) + comment + test 2021-06-14 15:05:12 +02:00
Steve Gravrock
c546d2cb6d Merge branch 'patch-1' of https://github.com/eltociear/jasmine into main
* Fixes typo in spec name
* Merges #1918 from @eltociear
2021-06-13 09:57:23 -07:00
Steve Gravrock
6e097528f5 Include only specified files in the NPM package 2021-06-13 09:52:01 -07:00
Ikko Ashimine
4e1f36cbb0 Fix typo in SpySpec.js
ommitted -> omitted
2021-06-12 10:00:36 +09:00
Steve Gravrock
0aee81cfb9 Remvoed checks for typed array support in the test suite
All supported browsers have all typed arrays except for Uint8ClampedArray,
BigInt64Array, and BigUint64Array.
2021-06-05 13:31:26 -07:00
Steve Gravrock
1e50b49092 Fixed test failures on IE 10 2021-06-05 13:13:46 -07:00
Steve Gravrock
6aecf16cde Test coverage for MatchersUtil#equals with typed arrays 2021-06-05 12:03:11 -07:00
Steve Gravrock
f2de1be96a Fixed "stop spec on expectation failure" checkbox in standalone
Fixes [#178248968].
2021-06-01 08:49:34 -07:00
Steve Gravrock
5f4a1c4276 Merge branch 'issue/1897' of https://github.com/Dari-K/jasmine into main
* Adds option for spyOnAllFunctions to include non-enumerable props
* Merges #1909 from @Dari-k
* Fixes #1897
2021-05-26 17:44:54 -07:00
Darius Keeley
a4ef3687ee Add optional param to spyOnAllFunctions to include non-enumerable properties 2021-05-25 11:37:24 +01:00
Steve Gravrock
9065b4c3b7 Added a jsdoc cross-reference from Configuration to its usage 2021-05-21 17:13:07 -07:00
Steve Gravrock
140225e7c3 Isolate specs that are flaky in browsers
* Don't run them in browsers in the regular CI build
* Run them in browsers in a special nightly build
* Run them in Node in the regular CI build
* Run them when developers manually run the suite

This should allow the regular CI build to give us a more useful signal,
while keeping us from losing sight of the flaky specs.
2021-05-15 07:44:25 -07:00
Steve Gravrock
8b38389d56 Test against Node 16
* Replaced node-sass dependency that isn't compatible with Node 16
* Added Node 16 to CI matrix
* Fixes #1894
2021-05-13 17:18:57 -07:00
Steve Gravrock
b7c2a2f6fb Removed unused dev dependencies 2021-05-13 12:52:44 -07:00
Steve Gravrock
c5d4a40219 Deprecated Python 2021-05-08 12:06:49 -07:00
Steve Gravrock
c7c8b6b93e Added Chrome back to CI browser list 2021-05-04 17:24:06 -07:00
Steve Gravrock
8a42437059 Added a note about testing on Windows to the releasing instructions 2021-05-04 09:28:35 -07:00
Steve Gravrock
cacc6f4278 Skip the middle Safari versions to speed up CI 2021-04-24 15:07:23 -07:00
Steve Gravrock
d815e99456 Added jsdocs for Spy.callData.returnValue 2021-04-24 14:57:33 -07:00
Steve Gravrock
5e3f937221 Added a note about correct usage of async matchers 2021-04-24 12:43:25 -07:00
Steve Gravrock
d666f1efbb Run browser tests on push, except for PRs 2021-04-23 08:39:02 -07:00
Steve Gravrock
4515b76f07 Run browser tests on all non-PR branches 2021-04-23 08:37:29 -07:00
Steve Gravrock
0897e31a2d Run cron builds on 3.99 and 4.0 branches 2021-04-23 08:37:18 -07:00
Steve Gravrock
9555cb9842 Pass Sauce tunnel identifier correctly 2021-04-17 16:14:45 -07:00
Steve Gravrock
d6fa9dd1a0 Fixed jsdocs for Spy#calls#thisFor 2021-04-17 12:32:59 -07:00
Steve Gravrock
25fbe0646a Merge branch 'spy-calls-thisFor' of https://github.com/ajvincent/jasmine into main
* Merges #1903 from @ajvincent
* Adds Spy#calls#thisFor
2021-04-17 12:14:41 -07:00
Steve Gravrock
316ce1e2d3 Updated contributing guide etc. 2021-04-17 11:54:11 -07:00
Steve Gravrock
82cc1083b6 Migrated from Travis to Circle CI 2021-04-17 11:34:56 -07:00
Steve Gravrock
c2f04ba627 Further compensate for clock jitter 2021-04-17 11:34:56 -07:00
Steve Gravrock
97a46f4560 Fixed test failures on Safari 8 and 9 2021-04-17 11:34:56 -07:00
Steve Gravrock
113134cdbd Fixed test failure in Firefox 68 ESR 2021-04-17 11:34:56 -07:00
Steve Gravrock
dad5f5fd6b Fixed test failure in Safari 8 2021-04-17 11:34:53 -07:00
Alexander J. Vincent
fa72544974 CallTracker.thisFor(): add test for undefined context object. 2021-04-13 18:35:04 -07:00
Alexander J. Vincent
e303de52ed Implement CallTracker.thisFor(). 2021-04-11 22:59:43 -07:00
Steve Gravrock
5f9315731e Improved handling of unhandled promise rejections with no error in Node
* Fixes #1759
2021-04-06 18:48:56 -07:00
Steve Gravrock
ce850c472a API docs for Env#topSuite and Suite 2021-04-03 11:09:30 -07:00
Steve Gravrock
2fc5182ddc Added missing jsdocs
* Env#execute
* Env#allowRespy
* Enough of Spec to support spec filters
2021-03-31 18:16:58 -07:00
Steve Gravrock
6be2102b64 Built distribution 2021-03-26 17:27:14 -07:00
Steve Gravrock
c6a79d3ab7 Merge branch 'patch-2' of https://github.com/UziTech/jasmine into main
* Merges #1892 from @UziTech
* Fixes config.seed type in jsdocs
2021-03-26 17:25:30 -07:00
Tony Brix
3f232fba80 docs: seed can be number or string 2021-03-26 00:10:15 -05:00
Tony Brix
cde6ea79a3 docs: fix jsdoc seed type 2021-03-25 22:05:02 -05:00
Steve Gravrock
0782a73a98 Merge branch 'array_buffer' of https://github.com/Finesse/jasmine into main
* Adds support for ArrayBuffers to matchersUtil.equals
* Merges #1891 from @Finesse
* Merges #1689 from @dankurka
* Fixes #1687
2021-03-22 13:06:40 -07:00
Surgie Finesse
37073e2768 Fix the review notices 2021-03-22 19:26:33 +10:00
Surgie Finesse
f7f928fdd3 Merge remote-tracking branch 'upstream/main' into array_buffer
# Conflicts:
#	spec/core/matchers/matchersUtilSpec.js
2021-03-22 18:33:50 +10:00
Steve Gravrock
503b653a10 Travis browser matrix updates
* Added latest Safari
* Added the Firefox version that's closest to current ESR
2021-03-21 11:30:21 -07:00
Steve Gravrock
cb044aa273 Bump version to 3.7.1 2021-03-18 17:28:04 -07:00
Steve Gravrock
5c17456925 Updated release instructions 2021-03-17 19:44:16 -07:00
Steve Gravrock
592fba22b8 Bump version to 3.7.0 2021-03-17 18:38:34 -07:00
Steve Gravrock
58ef707bc6 Added jasmine.isSpy to the public interface
* Fixes #1880
2021-03-17 17:58:51 -07:00
Steve Gravrock
050c1f051c Fixed intermittent test failures 2021-03-14 12:23:17 -07:00
Steve Gravrock
8d0c52e2ec Temporarily removed global error handler stack validation
This fails somewhat frequently (every 2-4 runs of Jasmine's own test
suite) on Safari. Until we get to the bottom of that, it's removed.
2021-03-14 11:46:23 -07:00
Steve Gravrock
de91427356 Fixed instructions for running Jasmine's ci script 2021-03-14 11:43:38 -07:00
Steve Gravrock
324bc201c2 Built distribution 2021-03-13 13:52:10 -08:00
Steve Gravrock
76f34e90dc Allow custom object formatters to be added in beforeAll
Fixes #1876.
2021-03-13 13:49:30 -08:00
Steve Gravrock
46e7158c77 Removed unused util.htmlEscape 2021-03-04 12:46:23 -08:00
Steve Gravrock
9ab039e330 Merge branch 'expectAllTruthyAndFalsy' of https://github.com/yasinkocak/jasmine into main
* Merges #1875 from @yasinkocak
* Adds additional assertions to tests for toBeTruthy and toBeFalsy
2021-02-27 10:31:31 -08:00
Yasin Kocak
3f5c47dff3 expect all truthy and falsy 2021-01-02 10:55:14 +01:00
Steve Gravrock
1320b0614f Merge branch 'use-global-onerror' into main
* Merges #1860 from @greghuc
* Allows specs to disable Jasmine's global error handling by overwriting
  `onerror`.
2020-11-24 11:13:24 -08:00
Gregory Huczynski
905e3fc3f9 Enable custom promise error handling through overriding of global.onerror 2020-11-24 11:04:04 -08:00
Steve Gravrock
89331bb1bb Fixed comparison between URL objects
* Fixes #1866
2020-11-21 13:47:44 -08:00
Steve Gravrock
88de272c89 Merge branch 'main' of https://github.com/JannesMeyer/jasmine into main
* Merges #1862 from @JannesMeyer
* Adds support for stack traces created by `node --enable-source-maps`
  with tools like the Typescript compiler.
2020-11-09 12:15:37 -08:00
Jannes Meyer
60bbe68148 Support source maps 2020-11-05 11:40:04 +01:00
Steve Gravrock
623e638cd4 Updated supported Node versions in README 2020-11-02 16:26:55 -08:00
Steve Gravrock
b1bcd6e825 Pointed Travis badge at travis-ci.com, not .org 2020-10-29 15:10:54 -07:00
Steve Gravrock
204acf7297 Updated Node versions in .travis.yml 2020-10-20 14:14:24 -07:00
Steve Gravrock
cd1131354b Merge branch 'enumerable' of https://github.com/DCtheTall/jasmine into main
* Merges #1859 from DCtheTall
* Fixes #1837
2020-10-10 18:01:48 -07:00
Steve Gravrock
c24aef15b1 Built distribution 2020-10-10 18:00:09 -07:00
DCtheTall
d5d5d1965f Have properties added by createSpyObj() be enumerable. 2020-10-02 13:49:34 -04:00
Steve Gravrock
d27bb8fa96 Run Prettier on all files 2020-09-29 18:05:38 -07:00
Steve Gravrock
7d5ca27b9d Check for forgotten console and debugger statements 2020-09-17 13:33:25 -07:00
Steve Gravrock
795651d3b6 Removed debugger statements 2020-09-13 13:40:15 -07:00
Steve Gravrock
e7daa429a1 Show the name of the spec/suite that caused a deprecation 2020-09-13 12:59:25 -07:00
Steve Gravrock
51ad18cb28 Warn if a runable both takes a callback and returns a promise 2020-09-13 12:47:24 -07:00
Steve Gravrock
0b81705c11 Detect global error handler stack corruption 2020-09-02 14:43:17 -07:00
Steve Gravrock
00feef8632 Fixed global error handler stack corruption in Jasmine's own tests 2020-09-02 14:01:57 -07:00
Steve Gravrock
5a715aecee Removed unnecessary console.log 2020-09-01 15:25:44 -07:00
Steve Gravrock
8cb44582bc Don't overwrite MatchersUtil methods with ones that were added to Array.prototype, esp. contains
Fixes #1849.
2020-09-01 15:18:53 -07:00
Steve Gravrock
53d8073707 Allow generator functions to be passed to .and.callFake
Fixes #1848.
2020-08-29 13:15:14 -07:00
Steve Gravrock
e0eb4755cb Merge branch 'fix-to-be-pending-typo' of https://github.com/SnailCoil/jasmine into main
* Merges #1847 from @SnailCoil
2020-08-20 17:51:02 -07:00
Aaron Snailwood
6277046213 fix typo in asyncMatcher toBePending comment 2020-08-20 10:07:35 -07:00
Steve Gravrock
6b9739030d Fixed future deprecations 2020-08-02 12:57:28 -07:00
Steve Gravrock
b0d949e0d5 Merge branch 'patch-1' of https://github.com/snowman/jasmine into main
* Merges #1839 from @snowman
    * Fixes script and CSS URLs in standalone example
2020-07-25 09:21:08 -07:00
snowman
dfdcfc5be5 Update README.md
Remove extra "jasmine/" directory in code example
2020-07-25 13:27:00 +08:00
Steve Gravrock
e5bb89847f Use jasmine-browser from npm
The current released version now works with IE, so we no longer need to
depend on main.
2020-07-23 17:29:14 -07:00
Steve Gravrock
1f68ed836e Updated the release docs 2020-07-23 17:26:43 -07:00
Steve Gravrock
c4e65e4a9a wip 2020-07-23 16:50:54 -07:00
Steve Gravrock
0cfeb0b9c3 Fixed link to custom object formatter tutorial 2020-07-23 16:36:56 -07:00
Daniel Kurka
2745d7d515 Add support for ArrayBuffers to matcherUtil.equals.
Fixes #1687
2019-05-02 09:49:21 -07:00
193 changed files with 11003 additions and 4990 deletions

205
.circleci/config.yml Normal file
View File

@@ -0,0 +1,205 @@
# Run tests against supported Node versions, and (except for pull requests)
# against supported browsers.
version: 2.1
orbs:
node: circleci/node@3.0.0
executors:
node16:
docker:
- image: cimg/node:16.1.0-browsers
working_directory: ~/workspace
node14:
docker:
- image: circleci/node:14
working_directory: ~/workspace
node12:
docker:
- image: circleci/node:12
working_directory: ~/workspace
node10:
docker:
- image: circleci/node:10
working_directory: ~/workspace
jobs:
build:
parameters:
executor:
type: executor
executor: << parameters.executor >>
steps:
- checkout
- run:
name: Report Node and NPM versions
command: echo "Using Node $(node --version) and NPM $(npm --version)"
- run:
name: Install dependencies
command: npm install
- run:
name: Build
command: npm run build
- persist_to_workspace:
root: .
paths:
- .
test_node: &test_node
parameters:
executor:
type: executor
executor: << parameters.executor >>
steps:
- attach_workspace:
at: .
- run:
name: Run tests
command: npm test
test_browsers: &test_browsers
executor: node14
environment:
SKIP_JASMINE_BROWSER_FLAKES: "true"
steps:
- attach_workspace:
at: .
- run:
name: Install Sauce Connect
command: |
cd /tmp
curl https://saucelabs.com/downloads/sc-4.6.4-linux.tar.gz | tar zxf -
chmod +x sc-4.6.4-linux/bin/sc
mkdir ~/workspace/bin
cp sc-4.6.4-linux/bin/sc ~/workspace/bin
~/workspace/bin/sc --version
- run:
name: Run tests
command: |
# Do everything in one step because Sauce Connect won't exit
# cleanly if we kill it from a different step than it started in.
export PATH=$PATH:$HOME/workspace/bin
export SAUCE_TUNNEL_IDENTIFIER=$CIRCLE_BUILD_NUM
scripts/start-sauce-connect sauce-pidfile
set +o errexit
scripts/run-all-browsers
exitcode=$?
set -o errexit
scripts/stop-sauce-connect $(cat sauce-pidfile)
exit $exitcode
test_browser_flakes:
<<: *test_browsers
environment:
SKIP_JASMINE_BROWSER_FLAKES: "false"
workflows:
version: 2
cron:
triggers:
- schedule:
# Times are UTC.
cron: "0 11 * * *"
filters:
branches:
only:
- main
- "3.99"
- "4.0"
jobs:
- build:
executor: node16
name: build_node_16
- build:
executor: node14
name: build_node_14
- build:
executor: node12
name: build_node_12
- build:
executor: node10
name: build_node_10
- test_node:
executor: node16
name: test_node_16
requires:
- build_node_16
- test_node:
executor: node12
name: test_node_12
requires:
- build_node_12
- test_node:
executor: node10
name: test_node_10
requires:
- build_node_10
- test_browsers:
requires:
- build_node_14
filters:
branches:
ignore: /pull\/.*/ # Don't run on pull requests.
push:
jobs:
- build:
executor: node16
name: build_node_16
- build:
executor: node14
name: build_node_14
- build:
executor: node12
name: build_node_12
- build:
executor: node10
name: build_node_10
- test_node:
executor: node16
name: test_node_16
requires:
- build_node_16
- test_node:
executor: node14
name: test_node_14
requires:
- build_node_14
- test_node:
executor: node12
name: test_node_12
requires:
- build_node_12
- test_node:
executor: node10
name: test_node_10
requires:
- build_node_10
- test_browsers:
requires:
- build_node_14
filters:
branches:
ignore: /pull\/.*/ # Don't run on pull requests.
browser-flakes:
triggers:
- schedule:
# Times are UTC.
cron: "0 10 * * *"
filters:
branches:
only:
- browser-flakes
jobs:
- build:
executor: node14
name: build_node_14
- test_browser_flakes:
requires:
- build_node_14
filters:
branches:
ignore: /pull\/.*/ # Don't run on pull requests.

View File

@@ -1,6 +1,12 @@
# Developing for Jasmine Core
We welcome your contributions! Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better. If you want to contribute but don't know what to work on, [issues tagged ready for work](https://github.com/jasmine/jasmine/labels/ready%20for%20work) should have enough detail to get started.
We welcome your contributions! Thanks for helping make Jasmine a better project
for everyone. Please review the backlog and discussion lists before starting
work. What you're looking for may already have been done. If it hasn't, the
community can help make your contribution better. If you want to contribute but
don't know what to work on,
[issues tagged help needed](https://github.com/jasmine/jasmine/labels/help%20needed)
should have enough detail to get started.
## Links
@@ -35,8 +41,8 @@ Once you've pushed a feature branch to your forked repo, you're ready to open a
* `/spec` contains all of the tests
* mirrors the source directory
* there are some additional files
* `/dist` contains the standalone distributions as zip files
* `/lib` contains the generated files for distribution as the Jasmine Rubygem and the Python package
* `/lib` contains the compiled copy of Jasmine. This is used to self-test and
distributed as the `jasmine-core` Node, Ruby, and Python packages.
### Self-testing
@@ -44,39 +50,31 @@ Note that Jasmine tests itself. The files in `lib` are loaded first, defining th
The tests should always use `jasmineUnderTest` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
### `boot.js`
### `boot0.js` and `boot1.js`
This file does all of the setup necessary for Jasmine to work. It loads all of the code, creates an `Env`, attaches the global functions, and builds the reporter. It also sets up the execution of the `Env` - for browsers this is in `window.onload`. While the default in `lib` is appropriate for browsers, projects may wish to customize this file.
For example, for Jasmine development there is a different `dev_boot.js` for Jasmine development that does more work.
These files file does all of the setup necessary for Jasmine to work in a
browser. They load all of the code, create an `Env`, attach the global
functions, and build the reporter. It also sets up the execution of the
`Env` - for browsers this is in `window.onload`. While the default in `lib`
is appropriate for browsers, projects may wish to customize this file.
### Compatibility
Jasmine supports the following environments:
* Browsers
* IE10+
* Edge Latest
* Firefox Latest
* Chrome Latest
* Safari 8+
* Node.js
* 8
* 10
* 12
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.
## Development
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
### Install Dependencies
### Install Dev Dependencies
Jasmine Core relies on Node.js.
To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http://gruntjs.com/), the [grunt-cli](https://github.com/gruntjs/grunt-cli) and ensure that `grunt` is on your path.
To install the Node dependencies, you will need Node.js and npm.
$ npm install --local
$ npm install
...will install all of the node modules locally. Now run
@@ -88,22 +86,35 @@ To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http:/
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 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
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and ESLint - your contribution shouldn't break Jasmine for other users
* _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 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.
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and
ESLint. 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
Jasmine uses some internal tooling to test itself in browser on Travis. This tooling _should_ work locally as well.
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`.
$ node ci.js
If you have the necessary Selenium drivers installed, you can also use Jasmine's
CI tooling:
You can also set the `JASMINE_BROWSER` environment variable to specify which browser should be used.
$ 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.
@@ -112,16 +123,16 @@ The easiest way to run the tests in **Internet Explorer** is to run a VM that ha
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://10.0.2.2:8888` in 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 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. 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 Travis for Continuous Integration. We only accept green pull requests.
Note that we use Circle CI for Continuous Integration. We only accept green pull requests.

View File

@@ -3,9 +3,12 @@
- When in doubt, create an issue here.
- If you have an issue with the Jasmine docs, file an issue in the docs repo
here: https://github.com/jasmine/jasmine.github.io
- If you have an issue with TypeScript typings, start a discussion at
[DefinitelyTpyed](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/new?category=issues-with-a-types-package)
- This repository is for the core Jasmine framework
- If you are using a test runner that wraps Jasmine, consider filing an issue with that library if appropriate:
- [Jasmine npm](https://github.com/jasmine/jasmine-npm/issues)
- [Jasmine browser runner](https://github.com/jasmine/jasmine-browser/issues)
- [Jasmine gem](https://github.com/jasmine/jasmine-gem/issues)
- [Jasmine py](https://github.com/jasmine/jasmine-py/issues)
- [Gulp Jasmine Browser](https://github.com/jasmine/gulp-jasmine-browser/issues)

1
.gitignore vendored
View File

@@ -25,3 +25,4 @@ build/
dist
nbproject/
*.iml
.envrc

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "pages"]
path = pages
url = https://github.com/pivotal/jasmine.git

View File

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

View File

@@ -1,52 +0,0 @@
language: node_js
node_js: 10
script: $TEST_COMMAND
env:
global:
- USE_SAUCE=true
- TEST_COMMAND="bash travis-core-script.sh"
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
matrix:
include:
- node_js: "10"
env: JASMINE_LONG_PROPERTY_TESTS="y" TEST_COMMAND="npm test"
- node_js: "12"
env: TEST_COMMAND="npm test"
- node_js: "8"
env: TEST_COMMAND="npm test"
- env: JASMINE_BROWSER="internet explorer" SAUCE_BROWSER_VERSION=11 SAUCE_OS="Windows 8.1"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="internet explorer" SAUCE_BROWSER_VERSION=10 SAUCE_OS="Windows 8"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="firefox" SAUCE_BROWSER_VERSION='' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="firefox" SAUCE_BROWSER_VERSION='68' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="chrome" SAUCE_BROWSER_VERSION='' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="safari" SAUCE_BROWSER_VERSION="13" SAUCE_OS="OS X 10.13"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="safari" SAUCE_BROWSER_VERSION="8" SAUCE_OS="OS X 10.10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="MicrosoftEdge" SAUCE_BROWSER_VERSION="" SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true

View File

@@ -1,6 +1,6 @@
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/main/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=main)](https://travis-ci.org/jasmine/jasmine)
[![Build Status](https://circleci.com/gh/jasmine/jasmine.svg?style=shield)](https://circleci.com/gh/jasmine/jasmine)
[![Open Source Helpers](https://www.codetriage.com/jasmine/jasmine/badges/users.svg)](https://www.codetriage.com/jasmine/jasmine)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine?ref=badge_shield)
@@ -11,8 +11,6 @@ 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 2.x? Check out the [3.0 release notes](https://github.com/jasmine/jasmine/blob/v3.0.0/release_notes/3.0.md) for a list of what's new (including breaking changes).
## Contributing
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md).
@@ -22,15 +20,12 @@ Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/ma
For the Jasmine NPM module:<br>
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm).
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).
For the Jasmine Python Egg:<br>
[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py).
For the Jasmine headless browser gulp plugin:<br>
[https://github.com/jasmine/gulp-jasmine-browser](https://github.com/jasmine/gulp-jasmine-browser).
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).
@@ -42,12 +37,12 @@ To install Jasmine standalone on your local box (where **_{#.#.#}_** below is su
Add the following to your HTML file:
```html
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-{#.#.#}/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-{#.#.#}/jasmine.css">
<link rel="shortcut icon" type="image/png" href="lib/jasmine-{#.#.#}/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-{#.#.#}/jasmine.css">
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-{#.#.#}/boot.js"></script>
<script type="text/javascript" src="lib/jasmine-{#.#.#}/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-{#.#.#}/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-{#.#.#}/boot.js"></script>
```
## Supported environments
@@ -56,10 +51,10 @@ Jasmine tests itself across many browsers (Safari, Chrome, Firefox, Microsoft Ed
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 8, 10, 12 |
| Safari | 8-13 |
| Node | 10, 12, 14, 16 |
| Safari | 8-14 |
| Chrome | Evergreen |
| Firefox | Evergreen, 68 |
| Firefox | Evergreen, 68, 78 |
| Edge | Evergreen |
| Internet Explorer | 10, 11 |

View File

@@ -28,31 +28,38 @@ When jasmine-core revs its major or minor version, the binding libraries should
When ready to release - specs are all green and the stories are done:
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly
1. Update the version in `package.json` to a release candidate
1. Update any links or top-level landing page for the Github Pages
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
1. Run the browser tests using `scripts/run-all-browsers`.
1. Commit release notes and version changes (jasmine.js, version.rb, package.json)
1. Push
1. Wait for Circle CI to go green
### Build standalone distribution
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 Python egg
### 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 Ruby gem
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile.
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release.
1. Push these changes to GitHub and verify that this SHA is green
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
### Release the NPM
### Release the core NPM module
1. Run the tests on Windows. (CI only tests on Linux.)
1. `npm adduser` to save your credentials locally
1. `npm publish .` to publish what's in `package.json`
@@ -60,15 +67,35 @@ Install [twine](https://github.com/pypa/twine)
Probably only need to do this when releasing a minor version, and not a patch version.
1. `cp -R edge ${version}` to copy the current edge docs to the new version
1. Add a link to the new version in `index.html`
1. `rake update_edge_jasmine`
1. `npm run jsdoc`
1. `rake release[${version}]` to copy the current edge docs to the new version
1. Commit and push.
### Release the binding libraries
#### NPM
1. Create release notes using Anchorman as above
1. In `package.json`, update both the package version and the jasmine-core dependency version
1. Commit and push.
1. Wait for Circle CI to go green again.
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
1. Visit the [Releases page for Jasmine](https://github.com/jasmine/jasmine/releases), find the tag just pushed.
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
1. If it is a pre-release, mark it as such.
1. Attach the standalone zipfile
There should be a post to Pivotal Labs blog and a tweet to that link.
For each of the above GitHub repos:
1. Visit the releases page and find the tag just published.
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
1. If it is a pre-release, mark it as such.
1. For core, attach the standalone zipfile.

View File

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

View File

@@ -41,6 +41,14 @@ module.exports = {
src: ['lib/jasmine-core/boot/boot.js'],
dest: 'lib/jasmine-core/boot.js'
},
boot0: {
src: ['lib/jasmine-core/boot/boot0.js'],
dest: 'lib/jasmine-core/boot0.js'
},
boot1: {
src: ['lib/jasmine-core/boot/boot1.js'],
dest: 'lib/jasmine-core/boot1.js'
},
nodeBoot: {
src: ['lib/jasmine-core/boot/node_boot.js'],
dest: 'lib/jasmine-core/node_boot.js'

View File

@@ -1,9 +1,8 @@
const sass = require('node-sass');
const sass = require('sass');
module.exports = {
options: {
implementation: sass,
outputStyle: 'compact',
sourceComments: false
},
dist: {

View File

@@ -9,7 +9,9 @@
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine.js"></script>
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine-html.js"></script>
<script src="lib/jasmine-<%= jasmineVersion %>/boot.js"></script>
<script src="lib/jasmine-<%= jasmineVersion %>/boot0.js"></script>
<!-- optional: include a file here that configures the Jasmine env -->
<script src="lib/jasmine-<%= jasmineVersion %>/boot1.js"></script>
<!-- include source files here... -->
<script src="src/Player.js"></script>

View File

@@ -8,7 +8,18 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.authors = ["Gregg Van Hove"]
s.summary = %q{JavaScript BDD framework}
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
s.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"

View File

@@ -5,11 +5,12 @@ var path = require('path'),
fs = require('fs');
var rootPath = path.join(__dirname, "jasmine-core"),
bootFiles = ['boot.js'],
bootFiles = ['boot0.js', 'boot1.js'],
legacyBootFiles = ['boot.js'],
nodeBootFiles = ['node_boot.js'],
cssFiles = [],
jsFiles = [],
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles);
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, legacyBootFiles, nodeBootFiles);
fs.readdirSync(rootPath).forEach(function(file) {
if(fs.statSync(path.join(rootPath, file)).isFile()) {

View File

@@ -1,3 +1,28 @@
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
@@ -6,7 +31,7 @@ module Jasmine
end
def js_files
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - node_boot_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"]

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2020 Pivotal Labs
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
@@ -21,6 +21,10 @@ 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.

View File

@@ -1,4 +1,8 @@
/**
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.

View File

@@ -0,0 +1,42 @@
/**
This file starts the process of "booting" Jasmine. It initializes Jasmine,
makes its globals available, and creates the env. This file should be loaded
after `jasmine.js` and `jasmine_html.js`, but before `boot1.js` or any project
source files or spec files are loaded.
*/
(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`.
*/
for (var property in jasmineInterface) {
global[property] = jasmineInterface[property];
}
}());

View File

@@ -0,0 +1,111 @@
/**
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
customize Jasmine for a project.
If a project is using Jasmine via the standalone distribution, this file can
be customized directly. If you only wish to configure the Jasmine env, you
can load another file that calls `jasmine.getEnv().configure({...})`
after `boot0.js` is loaded and before this file is loaded.
*/
(function() {
var env = jasmine.getEnv();
/**
* ## 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(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;
}
}());

64
lib/jasmine-core/boot0.js Normal file
View File

@@ -0,0 +1,64 @@
/*
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.
*/
/**
This file starts the process of "booting" Jasmine. It initializes Jasmine,
makes its globals available, and creates the env. This file should be loaded
after `jasmine.js` and `jasmine_html.js`, but before `boot1.js` or any project
source files or spec files are loaded.
*/
(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`.
*/
for (var property in jasmineInterface) {
global[property] = jasmineInterface[property];
}
}());

133
lib/jasmine-core/boot1.js Normal file
View File

@@ -0,0 +1,133 @@
/*
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.
*/
/**
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
customize Jasmine for a project.
If a project is using Jasmine via the standalone distribution, this file can
be customized directly. If you only wish to configure the Jasmine env, you
can load another file that calls `jasmine.getEnv().configure({...})`
after `boot0.js` is loaded and before this file is loaded.
*/
(function() {
var env = jasmine.getEnv();
/**
* ## 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(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,4 +1,33 @@
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
@@ -29,6 +58,11 @@ class Core(object):
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
@@ -57,4 +91,4 @@ class Core(object):
seen[marker] = 1
result.append(item)
return result
return result

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2020 Pivotal Labs
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
@@ -132,7 +132,7 @@ jasmineRequire.HtmlReporter = function(j$) {
if (result.status === 'failed') {
failures.push(failureDom(result));
}
addDeprecationWarnings(result);
addDeprecationWarnings(result, 'suite');
};
this.specStarted = function(result) {
@@ -168,7 +168,7 @@ jasmineRequire.HtmlReporter = function(j$) {
failures.push(failureDom(result));
}
addDeprecationWarnings(result);
addDeprecationWarnings(result, 'spec');
};
this.displaySpecInCorrectFormat = function(result) {
@@ -208,7 +208,10 @@ jasmineRequire.HtmlReporter = function(j$) {
' of ' +
totalSpecsDefined +
' specs - run all';
var skippedLink = addToExistingQueryString('spec', '');
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
var skippedLink =
(window.location.pathname || '') +
addToExistingQueryString('spec', '');
alert.appendChild(
createDom(
'span',
@@ -307,14 +310,27 @@ jasmineRequire.HtmlReporter = function(j$) {
addDeprecationWarnings(doneResult);
var warningBarClassName = 'jasmine-bar jasmine-warning';
for (i = 0; i < deprecationWarnings.length; i++) {
var warning = deprecationWarnings[i];
var context;
switch (deprecationWarnings[i].runnableType) {
case 'spec':
context = '(in spec: ' + deprecationWarnings[i].runnableName + ')';
break;
case 'suite':
context = '(in suite: ' + deprecationWarnings[i].runnableName + ')';
break;
default:
context = '';
}
alert.appendChild(
createDom(
'span',
{ className: warningBarClassName },
'DEPRECATION: ' + warning
{ className: 'jasmine-bar jasmine-warning' },
'DEPRECATION: ' + deprecationWarnings[i].message,
createDom('br'),
context
)
);
}
@@ -542,17 +558,20 @@ jasmineRequire.HtmlReporter = function(j$) {
);
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
failFastCheckbox.checked = config.failFast;
failFastCheckbox.checked = config.stopOnSpecFailure;
failFastCheckbox.onclick = function() {
navigateWithNewParam('failFast', !config.failFast);
navigateWithNewParam('failFast', !config.stopOnSpecFailure);
};
var throwCheckbox = optionsMenuDom.querySelector(
'#jasmine-throw-failures'
);
throwCheckbox.checked = config.oneFailurePerSpec;
throwCheckbox.checked = config.stopSpecOnExpectationFailure;
throwCheckbox.onclick = function() {
navigateWithNewParam('throwFailures', !config.oneFailurePerSpec);
navigateWithNewParam(
'oneFailurePerSpec',
!config.stopSpecOnExpectationFailure
);
};
var randomCheckbox = optionsMenuDom.querySelector(
@@ -622,15 +641,23 @@ jasmineRequire.HtmlReporter = function(j$) {
suite = suite.parent;
}
return addToExistingQueryString('spec', els.join(' '));
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
return (
(window.location.pathname || '') +
addToExistingQueryString('spec', els.join(' '))
);
}
function addDeprecationWarnings(result) {
function addDeprecationWarnings(result, runnableType) {
if (result && result.deprecationWarnings) {
for (var i = 0; i < result.deprecationWarnings.length; i++) {
var warning = result.deprecationWarnings[i].message;
if (!j$.util.arrayContains(warning)) {
deprecationWarnings.push(warning);
deprecationWarnings.push({
message: warning,
runnableName: result.fullName,
runnableType: runnableType
});
}
}
}
@@ -682,11 +709,19 @@ jasmineRequire.HtmlReporter = function(j$) {
}
function specHref(result) {
return addToExistingQueryString('spec', result.fullName);
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
return (
(window.location.pathname || '') +
addToExistingQueryString('spec', result.fullName)
);
}
function seedHref(seed) {
return addToExistingQueryString('seed', seed);
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
return (
(window.location.pathname || '') +
addToExistingQueryString('seed', seed)
);
}
function defaultQueryString(key, value) {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2020 Pivotal Labs
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

View File

@@ -4,6 +4,6 @@
#
module Jasmine
module Core
VERSION = "3.6.0"
VERSION = "3.10.1"
end
end

View File

@@ -1,37 +1,42 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "3.6.0",
"version": "3.10.1",
"repository": {
"type": "git",
"url": "https://github.com/jasmine/jasmine.git"
},
"keywords": [
"test",
"testing",
"jasmine",
"tdd",
"bdd"
],
"scripts": {
"posttest": "eslint \"src/**/*.js\" \"spec/**/*.js\" && prettier --check src/**/*.js spec/**/*.js",
"posttest": "eslint \"src/**/*.js\" \"spec/**/*.js\" && prettier --check \"src/**/*.js\" \"spec/**/*.js\"",
"test": "grunt --stack execSpecsInNode",
"cleanup": "prettier --write src/**/*.js spec/**/*.js",
"cleanup": "prettier --write \"src/**/*.js\" \"spec/**/*.js\"",
"build": "grunt buildDistribution",
"serve": "node spec/support/localJasmineBrowser.js",
"serve:performance": "node spec/support/localJasmineBrowser.js jasmine-browser-performance.json",
"ci": "node spec/support/ci.js",
"ci:performance": "node spec/support/ci.js jasmine-browser-performance.json"
},
"description": "Official packaging of Jasmine's core files for use by Node.js projects.",
"description": "Simple JavaScript testing framework for browsers and node.js",
"homepage": "https://jasmine.github.io",
"main": "./lib/jasmine-core.js",
"files": [
"MIT.LICENSE",
"README.md",
"images/*.{png,svg}",
"lib/**/*.{js,css}",
"package.json"
],
"devDependencies": {
"acorn": "^6.0.0",
"ejs": "^2.5.5",
"eslint": "^6.8.0",
"eslint-plugin-compat": "^3.8.0",
"express": "^4.16.4",
"fast-check": "^1.21.0",
"fast-glob": "^2.2.6",
"grunt": "^1.0.4",
"grunt-cli": "^1.3.2",
@@ -40,12 +45,11 @@
"grunt-css-url-embed": "^1.11.1",
"grunt-sass": "^3.0.2",
"jasmine": "^3.4.0",
"jasmine-browser-runner": "github:jasmine/jasmine-browser",
"jasmine-browser-runner": "github:jasmine/jasmine-browser#main",
"jsdom": "^15.0.0",
"load-grunt-tasks": "^4.0.0",
"node-sass": "^4.11.0",
"prettier": "1.17.1",
"selenium-webdriver": "^3.6.0",
"sass": "^1.32.12",
"shelljs": "^0.8.3",
"temp": "^0.9.0"
},

57
release_notes/3.10.0.md Normal file
View File

@@ -0,0 +1,57 @@
# Jasmine Core 3.10 Release Notes
## New features and bug fixes
* Added support for running Jasmine multiple times
* If the env is configured with `autoCleanClosures: false`, then it can be
executed repeatedly.
* Merges #1934 from @nicojs
* Fixes #1925
* Improved error message when an async expectation occurs after the spec
finishes
* Merges #1937 from @AndreWillomitzer
* Fixes #1854
* Reject timeout values that are too large for setTimeout
* See #1930
* Don't immediately move to the next queueable fn on async error
This allows assertion failures and other errors that occur after the async
error to be routed to the correct spec/suite.
* Added a stringContaining asymmetric equality tester
* Fixes #1923.
* The jasmine-core Ruby gem now prints a deprecation message when loaded unless
the SUPPRESS_JASMINE_DEPRECATION environment variable is set.
## Documentation updates
* Added discussion of max timeout value to jsdocs
* Merges #1931 from @trusktr
* Added missing @since annotations
* Improved jsdocs for asymmetric equality testers
* Added a deprecation notice to the jasmine-core Ruby gem's description
## Supported environments
jasmine-core 3.10.0 has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 10, 12, 14, 16 |
| Safari | 8-14 |
| Chrome | 94 |
| Firefox | 93, 78, 68 |
| Edge | 94 |
| Internet Explorer | 10, 11 |
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

12
release_notes/3.10.1.md Normal file
View File

@@ -0,0 +1,12 @@
# Jasmine Core 3.10.1 Release Notes
## Bugfixes
* Fixed missing pendingReason in pending spec results
* Fixes [#1939](https://github.com/jasmine/jasmine/issues/1939)
* Merges [#1940](https://github.com/jasmine/jasmine/pull/1940) from @jan-molak
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

80
release_notes/3.7.0.md Normal file
View File

@@ -0,0 +1,80 @@
# Jasmine Core 3.7 Release Notes
## Summary
This is a maintenance release of Jasmine with a number of new features and fixes.
## New features and bug fixes
* Allow custom object formatters to be added in beforeAll
- Fixes [#1876](http://github.com/jasmine/jasmine/issues/1876)
* Allow specs to disable Jasmine's global error handling by overwriting `onerror`.
- Merges [#1860](https://github.com/jasmine/jasmine/pull/1860) from @greghuc
* Fixed comparison between URL objects
- Fixes [#1866](http://github.com/jasmine/jasmine/issues/1866)
* Added support for stack traces created by `node --enable-source-maps`
with tools like the Typescript compiler.
- Merges [#1862](https://github.com/jasmine/jasmine/pull/1862) from @JannesMeyer
* Made properties added by createSpyObj() enumerable.
- Merges [#1859](https://github.com/jasmine/jasmine/pull/1859) from DCtheTall
- Fixes [#1837](http://github.com/jasmine/jasmine/issues/1837)
* Show the name of the spec/suite that caused a deprecation
* Warn if a spec or before/after function both takes a callback and returns a promise
* Don't overwrite MatchersUtil methods with ones that were added to
`Array.prototype`, esp. `contains`
- Fixes [#1849](http://github.com/jasmine/jasmine/issues/1849)
* Allow generator functions to be passed to `.and.callFake`
- Fixes [#1848](http://github.com/jasmine/jasmine/issues/1848)
## Documentation updates
* Fixed instructions for contributors to run Jasmine's ci script
* Updated supported Node versions in README
* Fixed script and CSS URLs in standalone example in README
- Merges [#1839](https://github.com/jasmine/jasmine/pull/1839) from @snowman
* Fixed typo in asyncMatcher toBePending comment
- Merges [#1847](https://github.com/jasmine/jasmine/pull/1847) from @SnailCoil
* Fixed link to custom object formatter tutorial
* Added jasmine.isSpy to the public interface
- Fixes [#1880](http://github.com/jasmine/jasmine/issues/1880)
## Internal notes
* Fixed intermittent test failures
* Added additional assertions to tests for toBeTruthy and toBeFalsy
- Merges [#1875](https://github.com/jasmine/jasmine/pull/1875) from @yasinkocak
* Pointed Travis badge at travis-ci.com, not .org
* Fixed file globs so that Prettier runs on all files
* Check for forgotten console and debugger statements
* Fixed code in Jasmine that will trigger deprecations in 3.99
* Use jasmine-browser from npm rather than from the main branch
- The current released version now works with IE, so we no longer need to
depend on main.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

8
release_notes/3.7.1.md Normal file
View File

@@ -0,0 +1,8 @@
# Jasmine Core 3.7.1 Release Notes
## Summary
This is a bug fix release of Jasmine. It's identical to 3.7.0 except that it
correctly reports its version number. Please see the
[3.7.0 release notes](https://github.com/jasmine/jasmine/blob/main/release_notes/3.7.0.md)
if you're upgrading directly from 3.6.0 or earlier.

132
release_notes/3.8.0.md Normal file
View File

@@ -0,0 +1,132 @@
# Jasmine Core 3.8 Release Notes
## Summary
This is a maintenance release of Jasmine with a number of new features and fixes.
## Python deprecation
The Jasmine packages for Python are deprecated. We intend to continue releasing
them through the end of the 3.x series, but after that they will be
discontinued. We recommend migrating to the following alternatives:
* The [jasmine-browser-runner](https://github.com/jasmine/jasmine-browser)
npm package to run specs in browsers, including headless Chrome and
Saucelabs. This is the most direct replacement for the `jasmine server`
and `jasmine ci` commands provided by the `jasmine` Python package.
* The [jasmine](https://github.com/jasmine/jasmine-npm) npm package (
`npm install jasmine`) to run specs under Node.js.
* The standalone distribution from the
[latest Jasmine release](https://github.com/jasmine/jasmine/releases) to
run specs in browsers with no additional tools.
* The [jasmine-core](https://github.com/jasmine/jasmine) npm package if all
you need is the Jasmine assets. This is the direct equivalent of the
jasmine-core Python package.
## New features and bug fixes
* Fixed spec filtering in Karma
* Merges [#1920](https://github.com/jasmine/jasmine/pull/1920) from @jlpstolwijk
* Fixes [#1906](https://github.com/jasmine/jasmine/issues/1906)
* Added expectAsync(...).already
* Causes async matchers to immediately fail if the promise is pending
* See https://jasmine.github.io/api/3.8/async-matchers.html#already
* Fixes [#1845](https://github.com/jasmine/jasmine/issues/1845)
* Include rejection details in failure messages for toBeResolved and toBeResolvedWith
* Fixed "stop spec on expectation failure" checkbox in standalone
* Added option for spyOnAllFunctions to include non-enumerable props
* Makes spyOnAllFunctions work on instance methods of ES6 classes
* Merges [#1909](https://github.com/jasmine/jasmine/pull/1909) from @Dari-k
* Fixes [#1897](https://github.com/jasmine/jasmine/issues/1897)
* Added Spy#calls#thisFor
* Provides the `this` value for a given spy call
* Merges [#1903](https://github.com/jasmine/jasmine/pull/1903) from @ajvincent
* Improved handling of unhandled promise rejections with no error in Node
* Fixes [#1759](https://github.com/jasmine/jasmine/issues/1759)
## Documentation updates
* Updated package description
* Updated contributing guide
* Added TypeScript typings and jasmine-browser-runner to issue template
* Removed constructors from jsdocs of classes that aren't user-constructable
* Fixed config.seed type in jsdocs
* Merges [#1892](https://github.com/jasmine/jasmine/pull/1892) from @UziTech
* Added jsdocs for the following:
* asymmetric equality testers
* Env#execute
* Env#allowRespy
* The public portion of Spec
* Spy.callData.returnValue
* Env#topSuite and Suite
* Added a jsdoc cross-reference from Configuration to its usage
* Added a note about correct usage of async matchers
* Added support for ArrayBuffers to matchersUtil.equals
* Merges [#1891](https://github.com/jasmine/jasmine/pull/1892) from @Finesse
* Merges [#1689](https://github.com/jasmine/jasmine/pull/1892) from @dankurka
* Fixes [#1687](https://github.com/jasmine/jasmine/issues/1687)
## Internal notes
* Fixed typo in spec name
* Merges [#1918](https://github.com/jasmine/jasmine/pull/1918) from @eltociear
* Specify files to include in the NPM package rather than files to exclude
* Added test coverage for MatchersUtil#equals with typed arrays
* Removed checks for typed array support in the test suite
* All supported browsers have all typed arrays except for Uint8ClampedArray,
BigInt64Array, and BigUint64Array.
* Fixed test failures on IE 10
* Test matrix updates
* Added Node 16
* Added Safari 14
* Added Firefox 78 (closest match to current ESR)
* Removed Safari 10-12 to speed up CI. The newer and older versions we test
provide a good measure of safety.
* Replaced node-sass dev dependency that isn't compatible with Node 16
* Removed unused dev dependencies
* Migrated CI from Travis to Circle
* Compensate for clock jitter in specs
## Supported environments
jasmine-core 3.8.0 has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 10, 12, 14, 16 |
| Safari | 8-14 |
| Chrome | 91 |
| Firefox | 89, 68, 78 |
| Edge | 91 |
| Internet Explorer | 10, 11 |
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

65
release_notes/3.9.0.md Normal file
View File

@@ -0,0 +1,65 @@
# Jasmine Core 3.9 Release Notes
## New features and bug fixes
* Fixed Trusted Types error in `j$.isError_` in Chromium-based browsers
* Merges [#1921](https://github.com/jasmine/jasmine/pull/1921) from @bjarkler
* Fixes [#1910](https://github.com/jasmine/jasmine/issues/1910)
* Fixes [#1653](https://github.com/jasmine/jasmine/issues/1653)
* Better reporting of unhandled promise rejections with truthy but non-`Error`
reasons on Node
* `Env#execute` returns a promise in environments that support promises
* Renamed `failFast` and `oneFailurePerSpec` config props to `stopOnSpecFailure`
and `stopSpecOnExpectationFailure`
The new names are more self-explanatory and consistent with jasmine-npm. The
old names are deprecated but will still work until the next major release.
* Split `boot.js` into two files to allow the env to be configured in between
This is mainly intended to support jasmine-browser-runner, which will load
a script that configures the env in between the two boot files (`boot0.js` and
`boot1.js`). The single-file `boot.js` will still be included until the next
major release.
## Ruby deprecation
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](https://github.com/jasmine/jasmine-browser)
npm package, which is the direct replacement for the `jasmine` gem.
If `jasmine-browser-runner` doesn't meet your needs, one of these might:
* The [jasmine](https://github.com/jasmine/jasmine-npm) npm package to run
specs in Node.js.
* The [standalone distribution](https://github.com/jasmine/jasmine#installation)
to run specs in browsers with no additional tools.
* The [jasmine-core](https://github.com/jasmine/jasmine) npm package if all
you need is the Jasmine assets. This is the direct equivalent of the
`jasmine-core` Ruby gem.
## Documentation updates
* Added API docs for `Suite#id` and `Spec#id`
* Marked `Env#hideDisabled` deprecated in jsdocs
------
## Supported environments
jasmine-core 3.9.0 has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 10, 12, 14, 16 |
| Safari | 8-14 |
| Chrome | 92 |
| Firefox | 91, 78, 68 |
| Edge | 92 |
| Internet Explorer | 10, 11 |
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

43
scripts/run-all-browsers Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/sh
run_browser() {
browser=$1
version=$2
description="$browser $version"
if [ $version = "latest" ]; then
version=""
fi
echo
echo
echo "Running $description"
echo
USE_SAUCE=true JASMINE_BROWSER=$browser SAUCE_BROWSER_VERSION=$version npm run ci
if [ $? -eq 0 ]; then
echo "PASS: $description" >> "$passfile"
else
echo "FAIL: $description" >> "$failfile"
fi
}
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
echo
cat "$passfile" "$failfile"
if [ -s "$failfile" ]; then
exit 1
fi

37
scripts/start-sauce-connect Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
if [ $# -gt 1 -o "$1" = "--help" ]; then
echo "Usage: $0 [pidfile]" 1>&2
exit
fi
if [ -z "$1" ]; then
pidfile=`mktemp`
else
pidfile="$1"
fi
outfile=`mktemp`
echo "Starting Sauce Connect"
if [ -z "$SAUCE_TUNNEL_IDENTIFIER" ]; then
sc -u "$SAUCE_USERNAME" -k "$SAUCE_ACCESS_KEY" -X 4445 --pidfile "$pidfile" 2>&1 | tee "$outfile" &
else
sc -u "$SAUCE_USERNAME" -k "$SAUCE_ACCESS_KEY" -X 4445 --pidfile "$pidfile" -i "$SAUCE_TUNNEL_IDENTIFIER" 2>&1 | tee "$outfile" &
fi
while ! fgrep "Sauce Connect is up, you may start your tests." "$outfile" > /dev/null; do
sleep 1
if ! ps -p $(cat "$pidfile") > /dev/null; then
echo "Sauce Connect exited"
exit 1
fi
done
if ! nc -z localhost 4445; then
echo "Can't connect to Sauce tunnel"
killall sc
exit 1
fi

33
scripts/stop-sauce-connect Executable file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
if [ -z "$1" ]; then
echo "Usage: $0 sauce-connect-pid" 1>&2
exit
fi
pid="$1"
echo "PID: $pid"
echo "Stopping Sauce Connect"
# Sauce Connect docs say that we can just kill -9 it if we don't care about
# failing any ongoing sessions. In practice, that sometimes works but usually
# leaks a tunnel so badly that you can't even stop it from the web UI.
# Instead of doing that, we give Sauce Connect some time to shut down
# gracefully and then give up.
kill -INT $pid
# Wait up to 2 minutes, then give up if it's still running
n=0
while [ $n -lt 120 ] && ps -p $pid > /dev/null; do
sleep 1
kill -INT $pid 2> /dev/null || true
n=$(($n + 1))
done
if ps -p $pid > /dev/null; then
echo "Could not shut down Sauce Connect"
fi
exit $exitcode

View File

@@ -4,15 +4,41 @@ 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=('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.'),
description=short_description,
long_description=long_description,
long_description_content_type='text/plain',
license='MIT',
classifiers=[
'Development Status :: 5 - Production/Stable',

View File

@@ -1,17 +1,20 @@
module.exports = {
"ignorePatterns": [
"support/ci.js",
"support/jasmine-browser.js"
],
ignorePatterns: ['support/ci.js', 'support/jasmine-browser.js'],
rules: {
// Relax rules for now to allow for the quirks of the test suite
// TODO: We should probably remove these & fix the resulting errors
"quotes": "off",
"semi": "off",
"key-spacing": "off",
"space-before-blocks": "off",
"no-unused-vars": "off",
"no-trailing-spaces": "off",
"block-spacing": "off",
quotes: 'off',
semi: 'off',
'key-spacing': 'off',
'space-before-blocks': 'off',
'no-unused-vars': 'off',
'no-trailing-spaces': 'off',
'block-spacing': 'off',
// Since linting is done at the end of the process and doesn't stop us
// from running tests, it makes sense to fail if debugger statements
// or console references are present.
'no-debugger': 'error',
'no-console': 'error'
}
}
};

View File

@@ -96,8 +96,8 @@ describe('AsyncExpectation', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = {
buildFailureMessage: function() {
return 'failure message';
pp: function(val) {
return val.toString();
}
},
addExpectationResult = jasmine.createSpy('addExpectationResult'),
@@ -114,7 +114,8 @@ describe('AsyncExpectation', function() {
expect(addExpectationResult).toHaveBeenCalledWith(
false,
jasmine.objectContaining({
message: 'Some context: failure message'
message:
'Some context: Expected a promise to be resolved but it was rejected with rejected.'
})
);
});
@@ -144,7 +145,8 @@ describe('AsyncExpectation', function() {
false,
jasmine.objectContaining({
message:
"Some context: Expected a promise to be resolved to 'a' but it was rejected."
"Some context: Expected a promise to be resolved to 'a' " +
"but it was rejected with 'b'."
})
);
});

View File

@@ -30,6 +30,20 @@ describe('CallTracker', function() {
expect(callTracker.argsFor(1)).toEqual([0, 'foo']);
});
it("tracks the 'this' object from each execution", function() {
var callTracker = new jasmineUnderTest.CallTracker();
var this0 = {},
this1 = {};
callTracker.track({ object: this0, args: [] });
callTracker.track({ object: this1, args: [] });
callTracker.track({ args: [] });
expect(callTracker.thisFor(0)).toBe(this0);
expect(callTracker.thisFor(1)).toBe(this1);
expect(callTracker.thisFor(2)).toBe(undefined);
});
it('returns any empty array when there was no call', function() {
var callTracker = new jasmineUnderTest.CallTracker();

View File

@@ -60,6 +60,93 @@ describe('Env', function() {
);
});
it('ignores configuration properties that are present but undefined', function() {
var initialConfig = {
random: true,
seed: '123',
failFast: true,
failSpecWithNoExpectations: true,
oneFailurePerSpec: true,
stopSpecOnExpectationFailure: true,
stopOnSpecFailure: true,
hideDisabled: true
};
env.configure(initialConfig);
env.configure({
random: undefined,
seed: undefined,
failFast: undefined,
failSpecWithNoExpectations: undefined,
oneFailurePerSpec: undefined,
stopSpecOnExpectationFailure: undefined,
stopOnSpecFailure: undefined,
hideDisabled: undefined
});
expect(env.configuration()).toEqual(
jasmine.objectContaining(initialConfig)
);
});
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({});
@@ -169,12 +256,30 @@ describe('Env', function() {
env.it('async', jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
it('throws an error when the timeout value is too large for setTimeout', function() {
expect(function() {
env.it('huge timeout', function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
});
describe('#xit', function() {
it('calls spec.exclude with "Temporarily disabled with xit"', function() {
var excludeSpy = jasmine.createSpy();
spyOn(env, 'it').and.returnValue({
exclude: excludeSpy
});
env.xit('foo', function() {});
expect(excludeSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
});
it('calls spec.pend with "Temporarily disabled with xit"', function() {
var pendSpy = jasmine.createSpy();
var realExclude = jasmineUnderTest.Spec.prototype.exclude;
spyOn(env, 'it').and.returnValue({
exclude: realExclude,
pend: pendSpy
});
env.xit('foo', function() {});
@@ -211,6 +316,12 @@ describe('Env', function() {
/fit expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
);
});
it('throws an error when the timeout value is too large for setTimeout', function() {
expect(function() {
env.fit('huge timeout', function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
});
describe('#beforeEach', function() {
@@ -228,6 +339,12 @@ describe('Env', function() {
env.beforeEach(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
it('throws an error when the timeout value is too large for setTimeout', function() {
expect(function() {
env.beforeEach(function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
});
describe('#beforeAll', function() {
@@ -245,6 +362,12 @@ describe('Env', function() {
env.beforeAll(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
it('throws an error when the timeout value is too large for setTimeout', function() {
expect(function() {
env.beforeAll(function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
});
describe('#afterEach', function() {
@@ -262,6 +385,12 @@ describe('Env', function() {
env.afterEach(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
it('throws an error when the timeout value is too large for setTimeout', function() {
expect(function() {
env.afterEach(function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
});
describe('#afterAll', function() {
@@ -279,6 +408,12 @@ describe('Env', function() {
env.afterAll(jasmine.getEnv().makeAsyncAwaitFunction());
}).not.toThrow();
});
it('throws an error when the timeout value is too large for setTimeout', function() {
expect(function() {
env.afterAll(function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
});
describe('when not constructed with suppressLoadErrors: true', function() {
@@ -334,20 +469,16 @@ describe('Env', function() {
expectationFactory('actual', specInstance);
});
env.addReporter({
jasmineDone: function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
}
env.execute(null, function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
});
env.execute();
});
it('creates an asyncExpectationFactory that uses the current custom equality testers and object formatters', function(done) {
@@ -371,19 +502,49 @@ describe('Env', function() {
asyncExpectationFactory('actual', specInstance);
});
env.addReporter({
jasmineDone: function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
}
env.execute(null, function() {
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
customObjectFormatter
]);
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
customTesters: [customEqualityTester],
pp: prettyPrinter
});
done();
});
});
describe('#execute', function() {
it('returns a promise when the environment supports promises', function() {
jasmine.getEnv().requirePromises();
expect(env.execute()).toBeInstanceOf(Promise);
});
env.execute();
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');
return env
.execute() // 1
.then(function() {
return env.execute(); // 2
})
.then(function() {
expect(env.topSuite().reset).toHaveBeenCalledOnceWith();
});
});
});
});

View File

@@ -86,6 +86,37 @@ describe('ExceptionFormatter', function() {
);
});
it('filters Jasmine stack frames from V8-style traces but leaves unmatched lines intact', function() {
var error = {
message: 'nope',
stack:
'C:\\__spec__\\core\\UtilSpec.ts:120\n' +
" new Error('nope');\n" +
' ^\n' +
'\n' +
'Error: nope\n' +
' at fn1 (C:\\__spec__\\core\\UtilSpec.js:115:19)\n' +
' -> C:\\__spec__\\core\\UtilSpec.ts:120:15\n' +
' at fn2 (C:\\__jasmine__\\lib\\jasmine-core\\jasmine.js:7533:40)\n' +
' at fn3 (C:\\__jasmine__\\lib\\jasmine-core\\jasmine.js:7575:25)\n' +
' at fn4 (node:internal/timers:462:21)\n'
};
var subject = new jasmineUnderTest.ExceptionFormatter({
jasmineFile: 'C:\\__jasmine__\\lib\\jasmine-core\\jasmine.js'
});
var result = subject.stack(error);
expect(result).toEqual(
'C:\\__spec__\\core\\UtilSpec.ts:120\n' +
" new Error('nope');\n" +
' ^\n' +
'Error: nope\n' +
' at fn1 (C:\\__spec__\\core\\UtilSpec.js:115:19)\n' +
' -> C:\\__spec__\\core\\UtilSpec.ts:120:15\n' +
' at <Jasmine>\n' +
' at fn4 (node:internal/timers:462:21)'
);
});
it('filters Jasmine stack frames from V8 style traces', function() {
var error = {
message: 'nope',

View File

@@ -29,8 +29,7 @@ describe('Exceptions:', function() {
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
env.execute(null, expectations);
});
it('should handle exceptions thrown directly in top-level describe blocks and continue', function(done) {
@@ -49,7 +48,6 @@ describe('Exceptions:', function() {
done();
};
env.addReporter({ jasmineDone: expectations });
env.execute();
env.execute(null, expectations);
});
});

View File

@@ -12,6 +12,23 @@ describe('GlobalErrors', function() {
expect(handler).toHaveBeenCalledWith('foo');
});
it('enables external interception of error by overriding global.onerror', function() {
var fakeGlobal = { onerror: null },
handler = jasmine.createSpy('errorHandler'),
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
fakeGlobal.onerror = hijackHandler;
fakeGlobal.onerror('foo');
expect(hijackHandler).toHaveBeenCalledWith('foo');
expect(handler).not.toHaveBeenCalled();
});
it('calls the global error handler with all parameters', function() {
var fakeGlobal = { onerror: null },
handler = jasmine.createSpy('errorHandler'),
@@ -58,7 +75,7 @@ describe('GlobalErrors', function() {
errors.pushListener(handler1);
errors.pushListener(handler2);
errors.popListener();
errors.popListener(handler2);
fakeGlobal.onerror('foo');
@@ -66,6 +83,13 @@ describe('GlobalErrors', function() {
expect(handler2).not.toHaveBeenCalled();
});
it('throws when no listener is passed to #popListener', function() {
var errors = new jasmineUnderTest.GlobalErrors({});
expect(function() {
errors.popListener();
}).toThrowError('popListener expects a listener');
});
it('uninstalls itself, putting back a previous callback', function() {
var originalCallback = jasmine.createSpy('error'),
fakeGlobal = { onerror: originalCallback },
@@ -98,7 +122,7 @@ describe('GlobalErrors', function() {
errors.uninstall();
});
it('reports uncaughtException in node.js', function() {
it('reports uncaught exceptions in node.js', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
@@ -146,52 +170,118 @@ describe('GlobalErrors', function() {
);
});
it('reports unhandledRejection in node.js', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
removeListener: jasmine.createSpy('process.removeListener'),
listeners: jasmine
.createSpy('process.listeners')
.and.returnValue(['foo']),
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
describe('Reporting unhandled promise rejections in node.js', function() {
it('reports rejections with `Error` reasons', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
removeListener: jasmine.createSpy('process.removeListener'),
listeners: jasmine
.createSpy('process.listeners')
.and.returnValue(['foo']),
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
'unhandledRejection',
jasmine.any(Function)
);
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith(
'unhandledRejection'
);
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith(
'unhandledRejection'
);
errors.install();
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
'unhandledRejection',
jasmine.any(Function)
);
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith(
'unhandledRejection'
);
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith(
'unhandledRejection'
);
errors.pushListener(handler);
errors.pushListener(handler);
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(new Error('bar'));
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(new Error('bar'));
expect(handler).toHaveBeenCalledWith(new Error('bar'));
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe(
'Unhandled promise rejection: Error: bar'
);
expect(handler).toHaveBeenCalledWith(new Error('bar'));
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe(
'Unhandled promise rejection: Error: bar'
);
errors.uninstall();
errors.uninstall();
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith(
'unhandledRejection',
addedListener
);
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
'unhandledRejection',
'foo'
);
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith(
'unhandledRejection',
addedListener
);
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
'unhandledRejection',
'foo'
);
});
it('reports rejections with non-`Error` reasons', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual(
'unhandledRejection'
);
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(17);
expect(handler).toHaveBeenCalledWith(
new Error(
'Unhandled promise rejection: 17\n' +
'(Tip: to get a useful stack trace, use ' +
'Promise.reject(new Error(...)) instead of Promise.reject(...).)'
)
);
});
it('reports rejections with no reason provided', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual(
'unhandledRejection'
);
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(undefined);
expect(handler).toHaveBeenCalledWith(
new Error(
'Unhandled promise rejection with no error or message\n' +
'(Tip: to get a useful stack trace, use ' +
'Promise.reject(new Error(...)) instead of Promise.reject().)'
)
);
});
});
describe('Reporting unhandled promise rejections in the browser', function() {
@@ -268,5 +358,64 @@ describe('GlobalErrors', function() {
})
);
});
describe('Enabling external interception of reported rejections by overriding global.onerror', function() {
it('overriding global.onerror intercepts rejections whose reason is a string', function() {
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
'addEventListener'
]),
handler = jasmine.createSpy('errorHandler'),
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
fakeGlobal.onerror = hijackHandler;
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
addedListener({ reason: 'nope' });
expect(hijackHandler).toHaveBeenCalledWith(
'Unhandled promise rejection: nope'
);
expect(handler).not.toHaveBeenCalled();
});
it('overriding global.onerror intercepts rejections whose reason is an Error', function() {
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
'addEventListener'
]),
handler = jasmine.createSpy('errorHandler'),
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
fakeGlobal.onerror = hijackHandler;
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
var reason;
try {
// Throwing ensures that we get a stack property in all browsers
throw new Error('bar');
} catch (e) {
reason = e;
}
addedListener({ reason: reason });
expect(hijackHandler).toHaveBeenCalledWith(
jasmine.objectContaining({
jasmineMessage: 'Unhandled promise rejection: Error: bar',
message: reason.message,
stack: reason.stack
})
);
expect(handler).not.toHaveBeenCalled();
});
});
});
});

View File

@@ -512,6 +512,50 @@ describe('QueueRunner', function() {
expect(onExceptionCallback).toHaveBeenCalledWith('foo');
expect(queueableFn2.fn).toHaveBeenCalled();
});
it('issues a deprecation if the function also takes a parameter', function() {
var queueableFn = {
fn: function(done) {
return new StubPromise();
}
},
deprecated = jasmine.createSpy('deprecated'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn],
deprecated: deprecated
}),
env = jasmineUnderTest.getEnv();
queueRunner.execute();
expect(deprecated).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. ' +
'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();
eval('var fn = async function(done){};');
var deprecated = jasmine.createSpy('deprecated'),
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [{ fn: fn }],
deprecated: deprecated
});
queueRunner.execute();
expect(deprecated).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 ' +
'(recommended) or remove the async keyword.'
);
});
});
it('passes the error instance to exception handlers in HTML browsers', function() {
@@ -625,9 +669,13 @@ describe('QueueRunner', function() {
jasmine.clock().uninstall();
});
it('skips to cleanup functions on the first exception', function() {
it('skips to cleanup functions once the fn completes after an unhandled exception', function() {
var errorListeners = [],
queueableFn = { fn: function(done) {} },
queueableFn = {
fn: function(done) {
queueableFnDone = done;
}
},
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') },
queueRunner = new jasmineUnderTest.QueueRunner({
@@ -642,10 +690,13 @@ describe('QueueRunner', function() {
queueableFns: [queueableFn, nextQueueableFn],
cleanupFns: [cleanupFn],
completeOnFirstError: true
});
}),
queueableFnDone;
queueRunner.execute();
errorListeners[errorListeners.length - 1](new Error('error'));
expect(cleanupFn.fn).not.toHaveBeenCalled();
queueableFnDone();
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
expect(cleanupFn.fn).toHaveBeenCalled();
});

View File

@@ -407,6 +407,123 @@ describe('SpyRegistry', function() {
expect(subject.toString).not.toBe('I am a spy');
expect(subject.hasOwnProperty).not.toBe('I am a spy');
});
describe('when includeNonEnumerable is true', function() {
it('does not override Object.prototype methods', function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({
createSpy: function() {
return 'I am a spy';
}
});
var subject = {
spied1: function() {}
};
spyRegistry.spyOnAllFunctions(subject, true);
expect(subject.spied1).toBe('I am a spy');
expect(subject.toString).not.toBe('I am a spy');
expect(subject.hasOwnProperty).not.toBe('I am a spy');
});
it('overrides non-enumerable properties', function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({
createSpy: function() {
return 'I am a spy';
}
});
var subject = {
spied1: function() {},
spied2: function() {}
};
Object.defineProperty(subject, 'spied2', {
enumerable: false,
writable: true,
configurable: true
});
spyRegistry.spyOnAllFunctions(subject, true);
expect(subject.spied1).toBe('I am a spy');
expect(subject.spied2).toBe('I am a spy');
});
it('should not spy on non-enumerable functions named constructor', function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({
createSpy: function() {
return 'I am a spy';
}
});
var subject = {
constructor: function() {}
};
Object.defineProperty(subject, 'constructor', {
enumerable: false,
writable: true,
configurable: true
});
spyRegistry.spyOnAllFunctions(subject, true);
expect(subject.constructor).not.toBe('I am a spy');
});
it('should spy on enumerable functions named constructor', function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({
createSpy: function() {
return 'I am a spy';
}
});
var subject = {
constructor: function() {}
};
spyRegistry.spyOnAllFunctions(subject, true);
expect(subject.constructor).toBe('I am a spy');
});
it('should not throw an exception if we try and access strict mode restricted properties', function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({
createSpy: function() {
return 'I am a spy';
}
});
var subject = function() {};
var fn = function() {
spyRegistry.spyOnAllFunctions(subject, true);
};
expect(fn).not.toThrow();
});
it('should not spy on properties which are more permissable further up the prototype chain', function() {
var spyRegistry = new jasmineUnderTest.SpyRegistry({
createSpy: function() {
return 'I am a spy';
}
});
var subjectParent = Object.defineProperty({}, 'sharedProp', {
value: function() {},
writable: true,
configurable: true
});
var subject = Object.create(subjectParent);
Object.defineProperty(subject, 'sharedProp', {
value: function() {}
});
var fn = function() {
spyRegistry.spyOnAllFunctions(subject, true);
};
expect(fn).not.toThrow();
expect(subject).not.toBe('I am a spy');
});
});
});
describe('#clearSpies', function() {

View File

@@ -183,14 +183,13 @@ describe('Spies', function() {
var spyObj = env.createSpyObj('base', ['method1'], ['prop1']);
expect(spyObj).toEqual({
method1: jasmine.any(Function)
method1: jasmine.any(Function),
prop1: undefined
});
var descriptor = Object.getOwnPropertyDescriptor(spyObj, 'prop1');
expect(descriptor.get.and.identity).toEqual('base.prop1.get');
expect(descriptor.set.and.identity).toEqual('base.prop1.set');
expect(spyObj.prop1).toBeUndefined();
});
it('creates an object with property names and return values if second object is passed', function() {
@@ -200,7 +199,9 @@ describe('Spies', function() {
});
expect(spyObj).toEqual({
method1: jasmine.any(Function)
method1: jasmine.any(Function),
prop1: 'foo',
prop2: 37
});
expect(spyObj.prop1).toEqual('foo');
@@ -212,7 +213,7 @@ describe('Spies', function() {
).toBe(1);
});
it('allows base name to be ommitted when assigning methods and properties', function() {
it('allows base name to be omitted when assigning methods and properties', function() {
var spyObj = env.createSpyObj({ m: 3 }, { p: 4 });
expect(spyObj.m()).toEqual(3);

View File

@@ -90,7 +90,7 @@ describe('SpyStrategy', function() {
expect(function() {
spyStrategy.exec();
}).toThrow({ code: 'ESRCH' });
}).toThrow(jasmine.objectContaining({ code: 'ESRCH' }));
expect(originalFn).not.toHaveBeenCalled();
});
@@ -334,6 +334,17 @@ describe('SpyStrategy', function() {
}).toThrowError(/^Argument passed to callFake should be a function, got/);
});
it('allows generator functions to be passed to callFake strategy', function() {
jasmine.getEnv().requireGeneratorFunctions();
var generator = jasmine.getEnv().makeGeneratorFunction('yield "ok";'),
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: function() {} });
spyStrategy.callFake(generator);
expect(spyStrategy.exec().next().value).toEqual('ok');
});
it('allows a return to plan stubbing after another strategy', function() {
var originalFn = jasmine.createSpy('original'),
fakeFn = jasmine.createSpy('fake').and.returnValue(67),

View File

@@ -142,4 +142,86 @@ describe('Suite', function() {
);
});
});
describe('attr.autoCleanClosures', function() {
function arrangeSuite(attrs) {
var suite = new jasmineUnderTest.Suite(attrs);
suite.beforeAll(function() {});
suite.beforeEach(function() {});
suite.afterEach(function() {});
suite.afterAll(function() {});
return suite;
}
it('should clean closures when "attr.autoCleanClosures" is missing', function() {
var suite = arrangeSuite({});
suite.cleanupBeforeAfter();
expect(suite.beforeAllFns[0].fn).toBe(null);
expect(suite.beforeFns[0].fn).toBe(null);
expect(suite.afterFns[0].fn).toBe(null);
expect(suite.afterAllFns[0].fn).toBe(null);
});
it('should clean closures when "attr.autoCleanClosures" is true', function() {
var suite = arrangeSuite({ autoCleanClosures: true });
suite.cleanupBeforeAfter();
expect(suite.beforeAllFns[0].fn).toBe(null);
expect(suite.beforeFns[0].fn).toBe(null);
expect(suite.afterFns[0].fn).toBe(null);
expect(suite.afterAllFns[0].fn).toBe(null);
});
it('should NOT clean closures when "attr.autoCleanClosures" is false', function() {
var suite = arrangeSuite({ autoCleanClosures: false });
suite.cleanupBeforeAfter();
expect(suite.beforeAllFns[0].fn).not.toBe(null);
expect(suite.beforeFns[0].fn).not.toBe(null);
expect(suite.afterFns[0].fn).not.toBe(null);
expect(suite.afterAllFns[0].fn).not.toBe(null);
});
});
describe('#reset', function() {
it('should reset the "pending" status', function() {
var suite = new jasmineUnderTest.Suite({});
suite.pend();
suite.reset();
expect(suite.getResult().status).toBe('passed');
});
it('should not reset the "pending" status when the suite was excluded', function() {
var suite = new jasmineUnderTest.Suite({});
suite.exclude();
suite.reset();
expect(suite.getResult().status).toBe('pending');
});
it('should also reset the children', function() {
var suite = new jasmineUnderTest.Suite({});
var child1 = jasmine.createSpyObj(['reset']);
var child2 = jasmine.createSpyObj(['reset']);
suite.addChild(child1);
suite.addChild(child2);
suite.reset();
expect(child1.reset).toHaveBeenCalled();
expect(child2.reset).toHaveBeenCalled();
});
it('should reset the failedExpectations', function() {
var suite = new jasmineUnderTest.Suite({
expectationResultFactory: function(error) {
return error;
}
});
suite.onException(new Error());
suite.reset();
var result = suite.getResult();
expect(result.status).toBe('passed');
expect(result.failedExpectations).toHaveSize(0);
});
});
});

View File

@@ -36,7 +36,6 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
it('provides properties of Array.prototype', function() {
var keys = [
'concat',
'constructor',
'every',
'filter',
'forEach',
@@ -55,8 +54,6 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
'some',
'sort',
'splice',
'toLocaleString',
'toString',
'unshift'
],
optionalKeys = [
@@ -69,7 +66,6 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
'flatMap',
'includes',
'keys',
'toSource',
'values'
],
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim({}, []),
@@ -98,4 +94,46 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
}
}
});
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

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

View File

@@ -1,29 +1,29 @@
describe("Anything", function() {
it("matches a string", function() {
describe('Anything', function() {
it('matches a string', function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch('foo')).toBe(true);
});
it("matches a number", function() {
it('matches a number', function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(42)).toBe(true);
});
it("matches an object", function() {
it('matches an object', function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch({ foo: 'bar' })).toBe(true);
});
it("matches an array", function() {
it('matches an array', function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch([1,2,3])).toBe(true);
expect(anything.asymmetricMatch([1, 2, 3])).toBe(true);
});
it("matches a Map", function() {
it('matches a Map', function() {
jasmine.getEnv().requireFunctioningMaps();
var anything = new jasmineUnderTest.Anything();
@@ -31,7 +31,7 @@ describe("Anything", function() {
expect(anything.asymmetricMatch(new Map())).toBe(true); // eslint-disable-line compat/compat
});
it("matches a Set", function() {
it('matches a Set', function() {
jasmine.getEnv().requireFunctioningSets();
var anything = new jasmineUnderTest.Anything();
@@ -39,15 +39,13 @@ describe("Anything", function() {
expect(anything.asymmetricMatch(new Set())).toBe(true); // eslint-disable-line compat/compat
});
it("matches a TypedArray", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
it('matches a TypedArray', function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.asymmetricMatch(new Uint32Array([]))).toBe(true); // eslint-disable-line compat/compat
});
it("matches a Symbol", function() {
it('matches a Symbol', function() {
jasmine.getEnv().requireFunctioningSymbols();
var anything = new jasmineUnderTest.Anything();
@@ -71,6 +69,6 @@ describe("Anything", function() {
it("jasmineToString's itself", function() {
var anything = new jasmineUnderTest.Anything();
expect(anything.jasmineToString()).toEqual("<jasmine.anything>");
expect(anything.jasmineToString()).toEqual('<jasmine.anything>');
});
});

View File

@@ -1,47 +1,47 @@
describe("ArrayContaining", function() {
it("matches any actual to an empty array", function() {
describe('ArrayContaining', function() {
it('matches any actual to an empty array', function() {
var containing = new jasmineUnderTest.ArrayContaining([]);
expect(containing.asymmetricMatch("foo")).toBe(true);
expect(containing.asymmetricMatch('foo')).toBe(true);
});
it("does not work when not passed an array", function() {
var containing = new jasmineUnderTest.ArrayContaining("foo");
it('does not work when not passed an array', function() {
var containing = new jasmineUnderTest.ArrayContaining('foo');
expect(function() {
containing.asymmetricMatch([]);
}).toThrowError(/not 'foo'/);
});
it("matches when the item is in the actual", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
it('matches when the item is in the actual', function() {
var containing = new jasmineUnderTest.ArrayContaining(['foo']);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(["foo"], matchersUtil)).toBe(true);
expect(containing.asymmetricMatch(['foo'], matchersUtil)).toBe(true);
});
it("matches when additional items are in the actual", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
it('matches when additional items are in the actual', function() {
var containing = new jasmineUnderTest.ArrayContaining(['foo']);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(["foo", "bar"], matchersUtil)).toBe(true);
expect(containing.asymmetricMatch(['foo', 'bar'], matchersUtil)).toBe(true);
});
it("does not match when the item is not in the actual", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
it('does not match when the item is not in the actual', function() {
var containing = new jasmineUnderTest.ArrayContaining(['foo']);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch(["bar"], matchersUtil)).toBe(false);
expect(containing.asymmetricMatch(['bar'], matchersUtil)).toBe(false);
});
it("does not match when the actual is not an array", function() {
var containing = new jasmineUnderTest.ArrayContaining(["foo"]);
it('does not match when the actual is not an array', function() {
var containing = new jasmineUnderTest.ArrayContaining(['foo']);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch("foo", matchersUtil)).toBe(false);
expect(containing.asymmetricMatch('foo', matchersUtil)).toBe(false);
});
it("jasmineToStrings itself", function() {
it('jasmineToStrings itself', function() {
var sample = [],
matcher = new jasmineUnderTest.ArrayContaining(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
@@ -52,17 +52,23 @@ describe("ArrayContaining", function() {
expect(pp).toHaveBeenCalledWith(sample);
});
it("uses custom equality testers", function() {
it('uses custom equality testers', function() {
var tester = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
if (
typeof a == 'string' &&
typeof b == 'string' &&
a.substr(0, 3) == 'foo' &&
b.substr(0, 3) == 'foo'
) {
return true;
}
};
var containing = new jasmineUnderTest.ArrayContaining(["fooVal"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
var containing = new jasmineUnderTest.ArrayContaining(['fooVal']);
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
expect(containing.asymmetricMatch(["fooBar"], matchersUtil)).toBe(true);
expect(containing.asymmetricMatch(['fooBar'], matchersUtil)).toBe(true);
});
});

View File

@@ -1,35 +1,37 @@
describe("ArrayWithExactContents", function() {
it("matches an array with the same items in a different order", function() {
describe('ArrayWithExactContents', function() {
it('matches an array with the same items in a different order', function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matcher.asymmetricMatch([2, 'a', /a/], matchersUtil)).toBe(true);
});
it("does not work when not passed an array", function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents("foo");
it('does not work when not passed an array', function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents('foo');
expect(function() {
matcher.asymmetricMatch([]);
}).toThrowError(/not 'foo'/);
});
it("does not match when an item is missing", function() {
it('does not match when an item is missing', function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a', 2, /a/]);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matcher.asymmetricMatch(['a', 2], matchersUtil)).toBe(false);
expect(matcher.asymmetricMatch(['a', 2, undefined], matchersUtil)).toBe(false);
expect(matcher.asymmetricMatch(['a', 2, undefined], matchersUtil)).toBe(
false
);
});
it("does not match when there is an extra item", function() {
it('does not match when there is an extra item', function() {
var matcher = new jasmineUnderTest.ArrayWithExactContents(['a']);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matcher.asymmetricMatch(['a', 2], matchersUtil)).toBe(false);
});
it("jasmineToStrings itself", function() {
it('jasmineToStrings itself', function() {
var sample = [],
matcher = new jasmineUnderTest.ArrayWithExactContents(sample),
pp = jasmine.createSpy('pp').and.returnValue('sample');
@@ -40,17 +42,23 @@ describe("ArrayWithExactContents", function() {
expect(pp).toHaveBeenCalledWith(sample);
});
it("uses custom equality testers", function() {
it('uses custom equality testers', function() {
var tester = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
if (
typeof a == 'string' &&
typeof b == 'string' &&
a.substr(0, 3) == 'foo' &&
b.substr(0, 3) == 'foo'
) {
return true;
}
};
var matcher = new jasmineUnderTest.ArrayWithExactContents(["fooVal"]);
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
var matcher = new jasmineUnderTest.ArrayWithExactContents(['fooVal']);
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
expect(matcher.asymmetricMatch(["fooBar"], matchersUtil)).toBe(true);
expect(matcher.asymmetricMatch(['fooBar'], matchersUtil)).toBe(true);
});
});

View File

@@ -1,27 +1,27 @@
describe("Empty", function () {
it("matches an empty object", function () {
describe('Empty', function() {
it('matches an empty object', function() {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch({})).toBe(true);
expect(empty.asymmetricMatch({undefined: false})).toBe(false);
expect(empty.asymmetricMatch({ undefined: false })).toBe(false);
});
it("matches an empty array", function () {
it('matches an empty array', function() {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch([])).toBe(true);
expect(empty.asymmetricMatch([1, 12, 3])).toBe(false);
});
it("matches an empty string", function () {
it('matches an empty string', function() {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch("")).toBe(true);
expect(empty.asymmetricMatch('')).toBe(true);
expect(empty.asymmetricMatch('')).toBe(true);
expect(empty.asymmetricMatch('12312')).toBe(false);
});
it("matches an empty map", function () {
it('matches an empty map', function() {
jasmine.getEnv().requireFunctioningMaps();
var empty = new jasmineUnderTest.Empty();
var fullMap = new Map(); // eslint-disable-line compat/compat
@@ -31,7 +31,7 @@ describe("Empty", function () {
expect(empty.asymmetricMatch(fullMap)).toBe(false);
});
it("matches an empty set", function () {
it('matches an empty set', function() {
jasmine.getEnv().requireFunctioningSets();
var empty = new jasmineUnderTest.Empty();
var fullSet = new Set(); // eslint-disable-line compat/compat
@@ -41,11 +41,10 @@ describe("Empty", function () {
expect(empty.asymmetricMatch(fullSet)).toBe(false);
});
it("matches an empty typed array", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
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([1, 2]))).toBe(false); // eslint-disable-line compat/compat
});
});

View File

@@ -1,38 +1,38 @@
describe("Falsy", function() {
it("is true for an empty string", function() {
var falsy = new jasmineUnderTest.Falsy();
describe('Falsy', function() {
it('is true for an empty string', function() {
var falsy = new jasmineUnderTest.Falsy();
expect(falsy.asymmetricMatch("")).toBe(true);
expect(falsy.asymmetricMatch('')).toBe(true);
expect(falsy.asymmetricMatch('asdasdad')).toBe(false);
});
expect(falsy.asymmetricMatch('')).toBe(true);
expect(falsy.asymmetricMatch('')).toBe(true);
expect(falsy.asymmetricMatch('asdasdad')).toBe(false);
});
it("is false for a number that is 0", function() {
var falsy = new jasmineUnderTest.Falsy(Number);
it('is false for a number that is 0', function() {
var falsy = new jasmineUnderTest.Falsy(Number);
expect(falsy.asymmetricMatch(1)).toBe(false);
expect(falsy.asymmetricMatch(0)).toBe(true);
expect(falsy.asymmetricMatch(-23)).toBe(false);
expect(falsy.asymmetricMatch(-3.1)).toBe(false);
});
expect(falsy.asymmetricMatch(1)).toBe(false);
expect(falsy.asymmetricMatch(0)).toBe(true);
expect(falsy.asymmetricMatch(-23)).toBe(false);
expect(falsy.asymmetricMatch(-3.1)).toBe(false);
});
it("is true for a null or undefined", function() {
var falsy = new jasmineUnderTest.Falsy(Function);
it('is true for a null or undefined', function() {
var falsy = new jasmineUnderTest.Falsy(Function);
expect(falsy.asymmetricMatch(null)).toBe(true);
expect(falsy.asymmetricMatch(undefined )).toBe(true);
});
expect(falsy.asymmetricMatch(null)).toBe(true);
expect(falsy.asymmetricMatch(undefined)).toBe(true);
});
it("is true for NaN", function() {
var falsy = new jasmineUnderTest.Falsy(Object);
it('is true for NaN', function() {
var falsy = new jasmineUnderTest.Falsy(Object);
expect(falsy.asymmetricMatch(NaN)).toBe(true);
});
expect(falsy.asymmetricMatch(NaN)).toBe(true);
});
it("is true for a false Boolean", function() {
var falsy = new jasmineUnderTest.Falsy(Boolean);
it('is true for a false Boolean', function() {
var falsy = new jasmineUnderTest.Falsy(Boolean);
expect(falsy.asymmetricMatch(false)).toBe(true);
expect(falsy.asymmetricMatch(true)).toBe(false);
});
expect(falsy.asymmetricMatch(false)).toBe(true);
expect(falsy.asymmetricMatch(true)).toBe(false);
});
});

View File

@@ -1,6 +1,7 @@
/* eslint-disable compat/compat */
describe('MapContaining', function() {
function MapI(iterable) { // for IE11
function MapI(iterable) {
// for IE11
var map = new Map();
iterable.forEach(function(kv) {
map.set(kv[0], kv[1]);
@@ -12,7 +13,6 @@ describe('MapContaining', function() {
jasmine.getEnv().requireFunctioningMaps();
});
it('matches any actual map to an empty map', function() {
var actualMap = new MapI([['foo', 'bar']]);
var containing = new jasmineUnderTest.MapContaining(new Map());
@@ -23,14 +23,11 @@ describe('MapContaining', function() {
it('matches when all the key/value pairs in sample have matches in actual', function() {
var actualMap = new MapI([
['foo', [1, 2, 3]],
[{'foo': 'bar'}, 'baz'],
['other', 'any'],
[{ foo: 'bar' }, 'baz'],
['other', 'any']
]);
var containingMap = new MapI([
[{'foo': 'bar'}, 'baz'],
['foo', [1, 2, 3]],
]);
var containingMap = new MapI([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2, 3]]]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -40,13 +37,10 @@ describe('MapContaining', function() {
it('does not match when a key is not in actual', function() {
var actualMap = new MapI([
['foo', [1, 2, 3]],
[{'foo': 'not a bar'}, 'baz'],
[{ foo: 'not a bar' }, 'baz']
]);
var containingMap = new MapI([
[{'foo': 'bar'}, 'baz'],
['foo', [1, 2, 3]],
]);
var containingMap = new MapI([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2, 3]]]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -54,15 +48,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 MapI([['foo', [1, 2, 3]], [{ foo: 'bar' }, 'baz']]);
var containingMap = new MapI([
[{'foo': 'bar'}, 'baz'],
['foo', [1, 2]],
]);
var containingMap = new MapI([[{ foo: 'bar' }, 'baz'], ['foo', [1, 2]]]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -73,18 +61,12 @@ describe('MapContaining', function() {
var actualMap = new MapI([
['foo1', 'not a bar'],
['foo2', 'bar'],
['baz', [1, 2, 3, 4]],
['baz', [1, 2, 3, 4]]
]);
var containingMap = new MapI([
[
jasmineUnderTest.stringMatching(/^foo\d/),
'bar'
],
[
'baz',
jasmineUnderTest.arrayContaining([2, 3])
],
[jasmineUnderTest.stringMatching(/^foo\d/), 'bar'],
['baz', jasmineUnderTest.arrayContaining([2, 3])]
]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -93,20 +75,11 @@ 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 MapI([['a-foo1', 'bar'], ['baz', [1, 2, 3, 4]]]);
var containingMap = new MapI([
[
jasmineUnderTest.stringMatching(/^foo\d/),
'bar'
],
[
'baz',
jasmineUnderTest.arrayContaining([2, 3])
],
[jasmineUnderTest.stringMatching(/^foo\d/), 'bar'],
['baz', jasmineUnderTest.arrayContaining([2, 3])]
]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -115,20 +88,11 @@ 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 MapI([['foo1', 'bar'], ['baz', [1, 2, 3, 4]]]);
var containingMap = new MapI([
[
jasmineUnderTest.stringMatching(/^foo\d/),
'bar'
],
[
'baz',
jasmineUnderTest.arrayContaining([4, 5])
],
[jasmineUnderTest.stringMatching(/^foo\d/), 'bar'],
['baz', jasmineUnderTest.arrayContaining([4, 5])]
]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -140,18 +104,12 @@ describe('MapContaining', function() {
var actualMap = new MapI([
['foo', new MapI([['foo1', 1], ['foo2', 2]])],
[new MapI([[1, 'bar1'], [2, 'bar2']]), 'bar'],
['other', 'any'],
['other', 'any']
]);
var containingMap = new MapI([
[
'foo',
new jasmineUnderTest.MapContaining(new MapI([['foo1', 1]]))
],
[
new jasmineUnderTest.MapContaining(new MapI([[2, 'bar2']])),
'bar'
],
['foo', new jasmineUnderTest.MapContaining(new MapI([['foo1', 1]]))],
[new jasmineUnderTest.MapContaining(new MapI([[2, 'bar2']])), 'bar']
]);
var containing = new jasmineUnderTest.MapContaining(containingMap);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -162,25 +120,41 @@ describe('MapContaining', function() {
it('uses custom equality testers', function() {
function tester(a, b) {
// treat all negative numbers as equal
return (typeof a == 'number' && typeof b == 'number') ? (a < 0 && b < 0) : a === b;
return typeof a == 'number' && typeof b == 'number'
? a < 0 && b < 0
: a === b;
}
var actualMap = new MapI([['foo', -1]]);
var containing = new jasmineUnderTest.MapContaining(new MapI([['foo', -2]]));
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
var containing = new jasmineUnderTest.MapContaining(
new MapI([['foo', -2]])
);
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
expect(containing.asymmetricMatch(actualMap, matchersUtil)).toBe(true);
});
it('does not match when actual is not a map', function() {
var containingMap = new MapI([['foo', 'bar']]);
expect(new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch('foo')).toBe(false);
expect(new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch(-1)).toBe(false);
expect(new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch({'foo': 'bar'})).toBe(false);
expect(
new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch('foo')
).toBe(false);
expect(
new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch(-1)
).toBe(false);
expect(
new jasmineUnderTest.MapContaining(containingMap).asymmetricMatch({
foo: 'bar'
})
).toBe(false);
});
it('throws an error when sample is not a map', function() {
expect(function() {
new jasmineUnderTest.MapContaining({'foo': 'bar'}).asymmetricMatch(new Map());
new jasmineUnderTest.MapContaining({ foo: 'bar' }).asymmetricMatch(
new Map()
);
}).toThrowError(/You must provide a map/);
});

View File

@@ -1,27 +1,27 @@
describe("NotEmpty", function () {
it("matches a non empty object", function () {
describe('NotEmpty', function() {
it('matches a non empty object', function() {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch({undefined: false})).toBe(true);
expect(notEmpty.asymmetricMatch({ undefined: false })).toBe(true);
expect(notEmpty.asymmetricMatch({})).toBe(false);
});
it("matches a non empty array", function () {
it('matches a non empty array', function() {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch([1, 12, 3])).toBe(true);
expect(notEmpty.asymmetricMatch([])).toBe(false);
});
it("matches a non empty string", function () {
it('matches a non empty string', function() {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch('12312')).toBe(true);
expect(notEmpty.asymmetricMatch("")).toBe(false);
expect(notEmpty.asymmetricMatch('')).toBe(false);
expect(notEmpty.asymmetricMatch('')).toBe(false);
});
it("matches a non empty map", 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
@@ -32,7 +32,7 @@ describe("NotEmpty", function () {
expect(notEmpty.asymmetricMatch(emptyMap)).toBe(false);
});
it("matches a non empty set", function () {
it('matches a non empty set', function() {
jasmine.getEnv().requireFunctioningSets();
var notEmpty = new jasmineUnderTest.NotEmpty();
var filledSet = new Set(); // eslint-disable-line compat/compat
@@ -43,11 +43,10 @@ describe("NotEmpty", function () {
expect(notEmpty.asymmetricMatch(emptySet)).toBe(false);
});
it("matches a non empty typed array", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
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([1, 2, 3]))).toBe(true); // eslint-disable-line compat/compat
expect(notEmpty.asymmetricMatch(new Int16Array())).toBe(false); // eslint-disable-line compat/compat
});
});

View File

@@ -1,47 +1,55 @@
describe("ObjectContaining", function() {
it("matches any object actual to an empty object", function() {
describe('ObjectContaining', function() {
it('matches any object actual to an empty object', function() {
var containing = new jasmineUnderTest.ObjectContaining({});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({foo: 1}, matchersUtil)).toBe(true);
expect(containing.asymmetricMatch({ foo: 1 }, matchersUtil)).toBe(true);
});
it("does not match when the actual is not an object", function() {
it('does not match when the actual is not an object', function() {
var containing = new jasmineUnderTest.ObjectContaining({});
[1, true, undefined, "a string"].forEach(function(actual) {
[1, true, undefined, 'a string'].forEach(function(actual) {
expect(containing.asymmetricMatch(actual)).toBe(false);
});
});
it("does not match an empty object actual", function() {
var containing = new jasmineUnderTest.ObjectContaining("foo");
it('does not match an empty object actual', function() {
var containing = new jasmineUnderTest.ObjectContaining('foo');
expect(function() {
containing.asymmetricMatch({})
}).toThrowError(/not 'foo'/)
containing.asymmetricMatch({});
}).toThrowError(/not 'foo'/);
});
it("matches when the key/value pair is present in the actual", function() {
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
it('matches when the key/value pair is present in the actual', function() {
var containing = new jasmineUnderTest.ObjectContaining({ foo: 'fooVal' });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"}, matchersUtil)).toBe(true);
expect(
containing.asymmetricMatch({ foo: 'fooVal', bar: 'barVal' }, matchersUtil)
).toBe(true);
});
it("does not match when the key/value pair is not present in the actual", function() {
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
it('does not match when the key/value pair is not present in the actual', function() {
var containing = new jasmineUnderTest.ObjectContaining({ foo: 'fooVal' });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({bar: "barVal", quux: "quuxVal"}, matchersUtil)).toBe(false);
expect(
containing.asymmetricMatch(
{ bar: 'barVal', quux: 'quuxVal' },
matchersUtil
)
).toBe(false);
});
it("does not match when the key is present but the value is different in the actual", function() {
var containing = new jasmineUnderTest.ObjectContaining({foo: "other"});
it('does not match when the key is present but the value is different in the actual', function() {
var containing = new jasmineUnderTest.ObjectContaining({ foo: 'other' });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({foo: "fooVal", bar: "barVal"}, matchersUtil)).toBe(false);
expect(
containing.asymmetricMatch({ foo: 'fooVal', bar: 'barVal' }, matchersUtil)
).toBe(false);
});
it("jasmineToString's itself", function() {
@@ -53,46 +61,55 @@ describe("ObjectContaining", function() {
'<jasmine.objectContaining(sample)>'
);
expect(pp).toHaveBeenCalledWith(sample);
});
it("matches recursively", function() {
var containing = new jasmineUnderTest.ObjectContaining({one: new jasmineUnderTest.ObjectContaining({two: {}})});
it('matches recursively', function() {
var containing = new jasmineUnderTest.ObjectContaining({
one: new jasmineUnderTest.ObjectContaining({ two: {} })
});
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({one: {two: {}}}, matchersUtil)).toBe(true);
expect(containing.asymmetricMatch({ one: { two: {} } }, matchersUtil)).toBe(
true
);
});
it("matches when key is present with undefined value", function() {
it('matches when key is present with undefined value', function() {
var containing = new jasmineUnderTest.ObjectContaining({ one: undefined });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({ one: undefined }, matchersUtil)).toBe(true);
expect(containing.asymmetricMatch({ one: undefined }, matchersUtil)).toBe(
true
);
});
it("does not match when key with undefined value is not present", function() {
it('does not match when key with undefined value is not present', function() {
var containing = new jasmineUnderTest.ObjectContaining({ one: undefined });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(containing.asymmetricMatch({}, matchersUtil)).toBe(false);
});
it("matches defined properties", function(){
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
it('matches defined properties', function() {
var containing = new jasmineUnderTest.ObjectContaining({ foo: 'fooVal' });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var definedPropertyObject = {};
Object.defineProperty(definedPropertyObject, "foo", {
get: function() { return "fooVal" }
Object.defineProperty(definedPropertyObject, 'foo', {
get: function() {
return 'fooVal';
}
});
expect(containing.asymmetricMatch(definedPropertyObject, matchersUtil)).toBe(true);
expect(
containing.asymmetricMatch(definedPropertyObject, matchersUtil)
).toBe(true);
});
it("matches prototype properties", function(){
var containing = new jasmineUnderTest.ObjectContaining({ foo: "fooVal" });
it('matches prototype properties', function() {
var containing = new jasmineUnderTest.ObjectContaining({ foo: 'fooVal' });
var matchersUtil = new jasmineUnderTest.MatchersUtil();
var prototypeObject = {foo: "fooVal"};
var prototypeObject = { foo: 'fooVal' };
var obj;
if (Object.create) {
@@ -107,23 +124,31 @@ describe("ObjectContaining", function() {
expect(containing.asymmetricMatch(obj, matchersUtil)).toBe(true);
});
it("uses custom equality testers", function() {
it('uses custom equality testers', function() {
var tester = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
if (
typeof a == 'string' &&
typeof b == 'string' &&
a.substr(0, 3) == 'foo' &&
b.substr(0, 3) == 'foo'
) {
return true;
}
};
var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
var containing = new jasmineUnderTest.ObjectContaining({ foo: 'fooVal' });
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
expect(containing.asymmetricMatch({foo: "fooBar"}, matchersUtil)).toBe(true);
expect(containing.asymmetricMatch({ foo: 'fooBar' }, matchersUtil)).toBe(
true
);
});
describe("valuesForDiff_", function() {
describe("when other is not an object", function() {
it("sets self to jasmineToString()", function () {
describe('valuesForDiff_', function() {
describe('when other is not an object', function() {
it('sets self to jasmineToString()', function() {
var containing = new jasmineUnderTest.ObjectContaining({}),
pp = jasmineUnderTest.makePrettyPrinter(),
result = containing.valuesForDiff_('a', pp);
@@ -135,27 +160,31 @@ describe("ObjectContaining", function() {
});
});
describe("when other is an object", function() {
it("includes keys that are present in both other and sample", function() {
var sample = {a: 1, b: 2},
other = {a: 3, b: 4},
describe('when other is an object', function() {
it('includes keys that are present in both other and sample', function() {
var sample = { a: 1, b: 2 },
other = { a: 3, b: 4 },
containing = new jasmineUnderTest.ObjectContaining(sample),
result = containing.valuesForDiff_(other);
expect(result.self).not.toBeInstanceOf(jasmineUnderTest.ObjectContaining);
expect(result.self).not.toBeInstanceOf(
jasmineUnderTest.ObjectContaining
);
expect(result).toEqual({
self: sample,
other: other
});
});
it("includes keys that are present only in sample", function() {
var sample = {a: 1, b: 2},
other = {a: 3},
it('includes keys that are present only in sample', function() {
var sample = { a: 1, b: 2 },
other = { a: 3 },
containing = new jasmineUnderTest.ObjectContaining(sample),
result = containing.valuesForDiff_(other);
expect(result.self).not.toBeInstanceOf(jasmineUnderTest.ObjectContaining);
expect(result.self).not.toBeInstanceOf(
jasmineUnderTest.ObjectContaining
);
expect(containing.valuesForDiff_(other)).toEqual({
self: sample,
other: {
@@ -165,13 +194,15 @@ describe("ObjectContaining", function() {
});
});
it("omits keys that are present only in other", function() {
var sample = {a: 1, b: 2},
other = {a: 3, b: 4, c: 5},
it('omits keys that are present only in other', function() {
var sample = { a: 1, b: 2 },
other = { a: 3, b: 4, c: 5 },
containing = new jasmineUnderTest.ObjectContaining(sample),
result = containing.valuesForDiff_(other);
expect(result.self).not.toBeInstanceOf(jasmineUnderTest.ObjectContaining);
expect(result.self).not.toBeInstanceOf(
jasmineUnderTest.ObjectContaining
);
expect(result).toEqual({
self: sample,
other: {

View File

@@ -1,6 +1,7 @@
/* eslint-disable compat/compat */
describe('SetContaining', function() {
function SetI(iterable) { // for IE11
function SetI(iterable) {
// for IE11
var set = new Set();
iterable.forEach(function(v) {
set.add(v);
@@ -12,7 +13,6 @@ describe('SetContaining', function() {
jasmine.getEnv().requireFunctioningSets();
});
it('matches any actual set to an empty set', function() {
var actualSet = new SetI(['foo', 'bar']);
var containing = new jasmineUnderTest.SetContaining(new Set());
@@ -21,13 +21,9 @@ describe('SetContaining', function() {
});
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 SetI([{ foo: 'bar' }, 'baz', [1, 2, 3]]);
var containingSet = new SetI([
[1, 2, 3], {'foo': 'bar'}
]);
var containingSet = new SetI([[1, 2, 3], { foo: 'bar' }]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -35,13 +31,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 SetI([{ foo: 'bar' }, 'baz', [1, 2, 3]]);
var containingSet = new SetI([
[1, 2], {'foo': 'bar'}
]);
var containingSet = new SetI([[1, 2], { foo: 'bar' }]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -49,13 +41,11 @@ 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 SetI([[1, 2, 3, 4], 'other', 'foo1']);
var containingSet = new SetI([
jasmineUnderTest.stringMatching(/^foo\d/),
jasmineUnderTest.arrayContaining([2, 3]),
jasmineUnderTest.arrayContaining([2, 3])
]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -64,13 +54,11 @@ 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 SetI(['a-foo1', [1, 2, 3, 4], 'other']);
var containingSet = new SetI([
jasmine.stringMatching(/^foo\d/),
jasmine.arrayContaining([2, 3]),
jasmine.arrayContaining([2, 3])
]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -79,12 +67,11 @@ describe('SetContaining', function() {
});
it('matches recursively', function() {
var actualSet = new SetI([
'foo', new SetI([1, 'bar', 2]), 'other'
]);
var actualSet = new SetI(['foo', new SetI([1, 'bar', 2]), 'other']);
var containingSet = new SetI([
new jasmineUnderTest.SetContaining(new SetI(['bar'])), 'foo'
new jasmineUnderTest.SetContaining(new SetI(['bar'])),
'foo'
]);
var containing = new jasmineUnderTest.SetContaining(containingSet);
var matchersUtil = new jasmineUnderTest.MatchersUtil();
@@ -95,25 +82,37 @@ describe('SetContaining', function() {
it('uses custom equality testers', function() {
function tester(a, b) {
// treat all negative numbers as equal
return (typeof a == 'number' && typeof b == 'number') ? (a < 0 && b < 0) : a === b;
return typeof a == 'number' && typeof b == 'number'
? a < 0 && b < 0
: a === b;
}
var actualSet = new SetI(['foo', -1]);
var containing = new jasmineUnderTest.SetContaining(new SetI([-2, 'foo']));
var matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: [tester]});
var matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: [tester]
});
expect(containing.asymmetricMatch(actualSet, matchersUtil)).toBe(true);
});
it('does not match when actual is not a set', function() {
var containingSet = new SetI(['foo']);
expect(new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch('foo')).toBe(false);
expect(new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch(1)).toBe(false);
expect(new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch(['foo'])).toBe(false);
expect(
new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch('foo')
).toBe(false);
expect(
new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch(1)
).toBe(false);
expect(
new jasmineUnderTest.SetContaining(containingSet).asymmetricMatch(['foo'])
).toBe(false);
});
it('throws an error when sample is not a set', function() {
expect(function() {
new jasmineUnderTest.SetContaining({'foo': 'bar'}).asymmetricMatch(new Set());
new jasmineUnderTest.SetContaining({ foo: 'bar' }).asymmetricMatch(
new Set()
);
}).toThrowError(/You must provide a set/);
});

View File

@@ -0,0 +1,27 @@
describe('StringContaining', function() {
it('searches for a provided substring when the expected is a String', function() {
var matcher = new jasmineUnderTest.StringContaining('foo');
expect(matcher.asymmetricMatch('barfoobaz')).toBe(true);
expect(matcher.asymmetricMatch('barbaz')).toBe(false);
});
it('raises an Error when the expected is not a String', function() {
expect(function() {
new jasmineUnderTest.StringContaining(/foo/);
}).toThrowError(/not a String/);
});
it('fails when the actual is not a String', function() {
var matcher = new jasmineUnderTest.StringContaining('x');
expect(matcher.asymmetricMatch(['x'])).toBe(false);
});
it("jasmineToString's itself", function() {
var matching = new jasmineUnderTest.StringContaining('foo');
expect(matching.jasmineToString()).toEqual(
'<jasmine.stringContaining("foo")>'
);
});
});

View File

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

View File

@@ -1,12 +1,12 @@
describe("Truthy", function () {
it("is true for a non empty string", function () {
describe('Truthy', function() {
it('is true for a non empty string', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch("foo")).toBe(true);
expect(truthy.asymmetricMatch("")).toBe(false);
expect(truthy.asymmetricMatch('foo')).toBe(true);
expect(truthy.asymmetricMatch('')).toBe(false);
});
it("is true for a number that is not 0", function () {
it('is true for a number that is not 0', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(1)).toBe(true);
@@ -15,49 +15,47 @@ describe("Truthy", function () {
expect(truthy.asymmetricMatch(-3.1)).toBe(true);
});
it("is true for a function", function () {
it('is true for a function', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(function () {
})).toBe(true);
expect(truthy.asymmetricMatch(function() {})).toBe(true);
});
it("is true for an Object", function () {
it('is true for an Object', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch({})).toBe(true);
});
it("is true for a truthful Boolean", function () {
it('is true for a truthful Boolean', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(true)).toBe(true);
expect(truthy.asymmetricMatch(false)).toBe(false);
});
it("is true for an empty object", function () {
it('is true for an empty object', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch({})).toBe(true);
});
it("is true for an empty array", function () {
it('is true for an empty array', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch([])).toBe(true);
});
it("is true for a date", function () {
it('is true for a date', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(new Date())).toBe(true);
});
it("is true for a infiniti", function () {
it('is true for a infiniti', function() {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(Infinity)).toBe(true);
expect(truthy.asymmetricMatch(-Infinity)).toBe(true);
});
});

View File

@@ -29,6 +29,43 @@ describe('base helpers', function() {
}
}, 100);
});
it('returns true for an Error subclass', function() {
function MyError() {}
MyError.prototype = new Error();
expect(jasmineUnderTest.isError_(new MyError())).toBe(true);
});
it('returns true for an un-thrown Error with no message in this environment', function() {
expect(jasmineUnderTest.isError_(new Error())).toBe(true);
});
it('returns true for an Error that originated from another frame', function() {
var iframe, error;
if (typeof window === 'undefined') {
pending('This test only runs in browsers.');
}
iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
try {
error = iframe.contentWindow.eval('new Error()');
expect(jasmineUnderTest.isError_(error)).toBe(true);
} finally {
document.body.removeChild(iframe);
}
});
it('returns false for a falsy value', function() {
expect(jasmineUnderTest.isError_(undefined)).toBe(false);
});
it('returns false for a non-Error object', function() {
expect(jasmineUnderTest.isError_({})).toBe(false);
});
});
describe('isAsymmetricEqualityTester_', function() {
@@ -62,4 +99,91 @@ describe('base helpers', function() {
expect(jasmineUnderTest.isSet({})).toBe(false);
});
});
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('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
);
});
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
);
});
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
);
});
});
describe('DEFAULT_TIMEOUT_INTERVAL setter', function() {
var max = 2147483647;
beforeEach(function() {
this.initialValue = jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL;
});
afterEach(function() {
jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL = this.initialValue;
});
it('accepts only values <= ' + max, function() {
expect(function() {
jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL = max + 1;
}).toThrowError(
'jasmine.DEFAULT_TIMEOUT_INTERVAL cannot be greater than ' + max
);
jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL = max;
expect(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL).toEqual(max);
});
it('is consistent with setTimeout in this environment', function(done) {
var f1 = jasmine.createSpy('setTimeout callback for ' + max),
f2 = jasmine.createSpy('setTimeout callback for ' + (max + 1)),
id;
// Suppress printing of TimeoutOverflowWarning in node
spyOn(console, 'error');
id = setTimeout(f1, max);
setTimeout(function() {
clearTimeout(id);
expect(f1).not.toHaveBeenCalled();
id = setTimeout(f2, max + 1);
setTimeout(function() {
clearTimeout(id);
expect(f2).toHaveBeenCalled();
done();
});
});
});
});
});

View File

@@ -1,12 +1,12 @@
describe('Asymmetric equality testers (Integration)', function () {
describe('Asymmetric equality testers (Integration)', function() {
function verifyPasses(expectations, setup) {
it('passes', function (done) {
it('passes', function(done) {
var env = new jasmineUnderTest.Env();
env.it('a spec', function () {
env.it('a spec', function() {
expectations(env);
});
var specExpectations = function (result) {
var specExpectations = function(result) {
expect(result.status).toEqual('passed');
expect(result.passedExpectations.length)
.withContext('Number of passed expectations')
@@ -14,115 +14,122 @@ describe('Asymmetric equality testers (Integration)', function () {
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(0);
expect(result.failedExpectations[0] && result.failedExpectations[0].message)
expect(
result.failedExpectations[0] && result.failedExpectations[0].message
)
.withContext('Failure message')
.toBeUndefined();
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
function verifyFails(expectations) {
it('fails', function (done) {
it('fails', function(done) {
var env = new jasmineUnderTest.Env();
env.it('a spec', function () {
env.it('a spec', function() {
expectations(env);
});
var specExpectations = function (result) {
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown error rather than a matcher failure')
.withContext(
'Failed with a thrown error rather than a matcher failure'
)
.not.toMatch(/^Error: /);
expect(result.failedExpectations[0].matcherName).withContext('Matcher name')
expect(result.failedExpectations[0].matcherName)
.withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
describe('any', function () {
verifyPasses(function (env) {
describe('any', function() {
verifyPasses(function(env) {
env.expect(5).toEqual(jasmineUnderTest.any(Number));
});
verifyFails(function (env) {
env.expect("five").toEqual(jasmineUnderTest.any(Number));
verifyFails(function(env) {
env.expect('five').toEqual(jasmineUnderTest.any(Number));
});
});
describe('anything', function () {
verifyPasses(function (env) {
describe('anything', function() {
verifyPasses(function(env) {
env.expect('').toEqual(jasmineUnderTest.anything());
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect(null).toEqual(jasmineUnderTest.anything());
});
});
describe('arrayContaining', function () {
verifyPasses(function (env) {
env.addCustomEqualityTester(function (a, b) {
describe('arrayContaining', function() {
verifyPasses(function(env) {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect([1, 2, 3]).toEqual(jasmineUnderTest.arrayContaining(["2"]));
env.expect([1, 2, 3]).toEqual(jasmineUnderTest.arrayContaining(['2']));
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect(null).toEqual(jasmineUnderTest.arrayContaining([2]));
});
});
describe('arrayWithExactContents', function () {
verifyPasses(function (env) {
env.addCustomEqualityTester(function (a, b) {
describe('arrayWithExactContents', function() {
verifyPasses(function(env) {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect([1, 2]).toEqual(jasmineUnderTest.arrayWithExactContents(["2", "1"]));
env
.expect([1, 2])
.toEqual(jasmineUnderTest.arrayWithExactContents(['2', '1']));
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect([]).toEqual(jasmineUnderTest.arrayWithExactContents([2]));
});
});
describe('empty', function () {
verifyPasses(function (env) {
describe('empty', function() {
verifyPasses(function(env) {
env.expect([]).toEqual(jasmineUnderTest.empty());
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect([1]).toEqual(jasmineUnderTest.empty());
});
});
describe('falsy', function () {
verifyPasses(function (env) {
describe('falsy', function() {
verifyPasses(function(env) {
env.expect(false).toEqual(jasmineUnderTest.falsy());
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect(true).toEqual(jasmineUnderTest.falsy());
});
});
describe('mapContaining', function () {
describe('mapContaining', function() {
if (jasmine.getEnv().hasFunctioningMaps()) {
verifyPasses(function (env) {
verifyPasses(function(env) {
var actual = new Map();
actual.set('a', "2");
actual.set('a', '2');
var expected = new Map();
expected.set('a', 2);
env.addCustomEqualityTester(function (a, b) {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
@@ -130,54 +137,62 @@ describe('Asymmetric equality testers (Integration)', function () {
});
} else {
it('passes', function() {
jasmine.getEnv().pending('Browser has incomplete or missing support for Maps');
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Maps');
});
}
if (jasmine.getEnv().hasFunctioningMaps()) {
verifyFails(function (env) {
env.expect('something').toEqual(jasmineUnderTest.mapContaining(new Map()));
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');
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Maps');
});
}
});
describe('notEmpty', function () {
verifyPasses(function (env) {
describe('notEmpty', function() {
verifyPasses(function(env) {
env.expect([1]).toEqual(jasmineUnderTest.notEmpty());
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect([]).toEqual(jasmineUnderTest.notEmpty());
});
});
describe('objectContaining', function () {
verifyPasses(function (env) {
env.addCustomEqualityTester(function (a, b) {
describe('objectContaining', function() {
verifyPasses(function(env) {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect({a: 1, b: 2}).toEqual(jasmineUnderTest.objectContaining({a: "1"}));
env
.expect({ a: 1, b: 2 })
.toEqual(jasmineUnderTest.objectContaining({ a: '1' }));
});
verifyFails(function (env) {
env.expect({}).toEqual(jasmineUnderTest.objectContaining({a: "1"}));
verifyFails(function(env) {
env.expect({}).toEqual(jasmineUnderTest.objectContaining({ a: '1' }));
});
});
describe('setContaining', function () {
describe('setContaining', function() {
if (jasmine.getEnv().hasFunctioningSets()) {
verifyPasses(function (env) {
verifyPasses(function(env) {
var actual = new Set();
actual.add("1");
actual.add('1');
var expected = new Set();
actual.add(1);
env.addCustomEqualityTester(function (a, b) {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
@@ -185,37 +200,53 @@ describe('Asymmetric equality testers (Integration)', function () {
});
} else {
it('pases', function() {
jasmine.getEnv().pending('Browser has incomplete or missing support for Sets');
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Sets');
});
}
if (jasmine.getEnv().hasFunctioningSets()) {
verifyFails(function (env) {
env.expect('something').toEqual(jasmineUnderTest.setContaining(new Set()));
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');
jasmine
.getEnv()
.pending('Browser has incomplete or missing support for Sets');
});
}
});
describe('stringMatching', function () {
verifyPasses(function (env) {
describe('stringMatching', function() {
verifyPasses(function(env) {
env.expect('foo').toEqual(jasmineUnderTest.stringMatching(/o/));
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect('bar').toEqual(jasmineUnderTest.stringMatching(/o/));
});
});
describe('truthy', function () {
verifyPasses(function (env) {
describe('stringContaining', function() {
verifyPasses(function(env) {
env.expect('foo').toEqual(jasmineUnderTest.stringContaining('o'));
});
verifyFails(function(env) {
env.expect('bar').toEqual(jasmineUnderTest.stringContaining('o'));
});
});
describe('truthy', function() {
verifyPasses(function(env) {
env.expect(true).toEqual(jasmineUnderTest.truthy());
});
verifyFails(function (env) {
verifyFails(function(env) {
env.expect(false).toEqual(jasmineUnderTest.truthy());
});
});

View File

@@ -4,7 +4,7 @@ describe('Custom Async Matchers (Integration)', function() {
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
env.configure({ random: false });
});
afterEach(function() {
@@ -17,7 +17,11 @@ describe('Custom Async Matchers (Integration)', function() {
env.it('spec using custom async matcher', function() {
env.addAsyncMatchers({
toBeReal: function() {
return { compare: function() { return Promise.resolve({ pass: true }); } };
return {
compare: function() {
return Promise.resolve({ pass: true });
}
};
}
});
@@ -28,8 +32,8 @@ describe('Custom Async Matchers (Integration)', function() {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it('uses the negative compare function for a negative comparison, if provided', function(done) {
@@ -39,8 +43,12 @@ describe('Custom Async Matchers (Integration)', function() {
env.addAsyncMatchers({
toBeReal: function() {
return {
compare: function() { return Promise.resolve({ pass: true }); },
negativeCompare: function() { return Promise.resolve({ pass: true }); }
compare: function() {
return Promise.resolve({ pass: true });
},
negativeCompare: function() {
return Promise.resolve({ pass: true });
}
};
}
});
@@ -52,8 +60,8 @@ describe('Custom Async Matchers (Integration)', function() {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it('generates messages with the same rules as built in matchers absent a custom message', function(done) {
@@ -74,30 +82,34 @@ describe('Custom Async Matchers (Integration)', function() {
});
var specExpectations = function(result) {
expect(result.failedExpectations[0].message).toEqual("Expected 'a' to be real.");
expect(result.failedExpectations[0].message).toEqual(
"Expected 'a' to be real."
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
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) {
it('passes the jasmine utility and current equality testers to the matcher factory', function(done) {
jasmine.getEnv().requirePromises();
var matcherFactory = function () {
var matcherFactory = function() {
return {
compare: function () {
return Promise.resolve({pass: true});
compare: function() {
return Promise.resolve({ pass: true });
}
};
},
matcherFactorySpy = jasmine.createSpy("matcherFactorySpy").and.callFake(matcherFactory),
customEqualityFn = function () {
matcherFactorySpy = jasmine
.createSpy('matcherFactorySpy')
.and.callFake(matcherFactory),
customEqualityFn = function() {
return true;
};
env.it("spec with expectation", function() {
env.it('spec with expectation', function() {
env.addCustomEqualityTester(customEqualityFn);
env.addAsyncMatchers({
toBeReal: matcherFactorySpy
@@ -113,39 +125,43 @@ describe('Custom Async Matchers (Integration)', function() {
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("provides custom equality testers to the matcher factory via matchersUtil", function(done) {
it('provides custom equality testers to the matcher factory via matchersUtil', function(done) {
jasmine.getEnv().requirePromises();
var matcherFactory = function (matchersUtil) {
var matcherFactory = function(matchersUtil) {
return {
compare: function (actual, expected) {
return Promise.resolve({pass: matchersUtil.equals(actual[0], expected)});
compare: function(actual, expected) {
return Promise.resolve({
pass: matchersUtil.equals(actual[0], expected)
});
}
};
},
customEqualityFn = jasmine.createSpy("customEqualityFn").and.callFake(function (a, b) {
return a.toString() === b;
});
customEqualityFn = jasmine
.createSpy('customEqualityFn')
.and.callFake(function(a, b) {
return a.toString() === b;
});
env.it("spec with expectation", function() {
env.it('spec with expectation', function() {
env.addCustomEqualityTester(customEqualityFn);
env.addAsyncMatchers({
toBeArrayWithFirstElement: matcherFactory
});
return env.expectAsync([1, 2]).toBeArrayWithFirstElement("1");
return env.expectAsync([1, 2]).toBeArrayWithFirstElement('1');
});
var specExpectations = function(result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, "1");
expect(customEqualityFn).toHaveBeenCalledWith(1, '1');
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
});

View File

@@ -1,52 +1,65 @@
describe("Custom Matchers (Integration)", function () {
describe('Custom Matchers (Integration)', function() {
var env;
var fakeTimer;
beforeEach(function () {
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
env.configure({ random: false });
});
afterEach(function() {
env.cleanup_();
});
it("allows adding more matchers local to a spec", function (done) {
env.it('spec defining a custom matcher', function () {
it('allows adding more matchers local to a spec', function(done) {
env.it('spec defining a custom matcher', function() {
env.addMatchers({
matcherForSpec: function () {
matcherForSpec: function() {
return {
compare: function (actual, expected) {
return {pass: false, message: "matcherForSpec: actual: " + actual + "; expected: " + expected};
compare: function(actual, expected) {
return {
pass: false,
message:
'matcherForSpec: actual: ' +
actual +
'; expected: ' +
expected
};
}
}
};
}
});
env.expect("zzz").matcherForSpec("yyy");
env.expect('zzz').matcherForSpec('yyy');
});
env.it("spec without custom matcher defined", function() {
expect(env.expect("zzz").matcherForSpec).toBeUndefined();
env.it('spec without custom matcher defined', function() {
expect(env.expect('zzz').matcherForSpec).toBeUndefined();
});
var specDoneSpy = jasmine.createSpy("specDoneSpy");
var specDoneSpy = jasmine.createSpy('specDoneSpy');
var expectations = function() {
var firstSpecResult = specDoneSpy.calls.first().args[0];
expect(firstSpecResult.status).toEqual("failed");
expect(firstSpecResult.failedExpectations[0].message).toEqual("matcherForSpec: actual: zzz; expected: yyy");
expect(firstSpecResult.status).toEqual('failed');
expect(firstSpecResult.failedExpectations[0].message).toEqual(
'matcherForSpec: actual: zzz; expected: yyy'
);
done();
};
env.addReporter({ specDone:specDoneSpy, jasmineDone: expectations});
env.addReporter({ specDone: specDoneSpy });
env.execute();
env.execute(null, expectations);
});
it("passes the spec if the custom matcher passes", function(done) {
env.it("spec using custom matcher", function() {
it('passes the spec if the custom matcher passes', function(done) {
env.it('spec using custom matcher', function() {
env.addMatchers({
toBeReal: function() {
return { compare: function() { return { pass: true }; } };
return {
compare: function() {
return { pass: true };
}
};
}
});
@@ -57,66 +70,80 @@ describe("Custom Matchers (Integration)", function () {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers", function(done) {
env.it("spec using custom equality matcher", function() {
it('passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers', function(done) {
env.it('spec using custom equality matcher', function() {
var customEqualityFn = function(a, b) {
// All "foo*" strings match each other.
if (typeof a == "string" && typeof b == "string" &&
a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
if (
typeof a == 'string' &&
typeof b == 'string' &&
a.substr(0, 3) == 'foo' &&
b.substr(0, 3) == 'foo'
) {
return true;
}
};
env.addCustomEqualityTester(customEqualityFn);
env.expect({foo: 'fooValue'}).toEqual(jasmineUnderTest.objectContaining({foo: 'fooBar'}));
env.expect(['fooValue', 'things']).toEqual(jasmineUnderTest.arrayContaining(['fooBar']));
env.expect(['fooValue']).toEqual(jasmineUnderTest.arrayWithExactContents(['fooBar']));
env
.expect({ foo: 'fooValue' })
.toEqual(jasmineUnderTest.objectContaining({ foo: 'fooBar' }));
env
.expect(['fooValue', 'things'])
.toEqual(jasmineUnderTest.arrayContaining(['fooBar']));
env
.expect(['fooValue'])
.toEqual(jasmineUnderTest.arrayWithExactContents(['fooBar']));
});
var specExpectations = function(result) {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("supports asymmetric equality testers that take a list of custom equality testers", function(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() {
env.it('spec using custom asymmetric equality tester', function() {
var customEqualityFn = function(a, b) {
if (a === 2 && b === "two") {
if (a === 2 && b === 'two') {
return true;
}
};
var arrayWithFirstElement = function(sample) {
return {
asymmetricMatch: function (actual, customEqualityTesters) {
return jasmineUnderTest.matchersUtil.equals(sample, actual[0], customEqualityTesters);
asymmetricMatch: function(actual, customEqualityTesters) {
return jasmineUnderTest.matchersUtil.equals(
sample,
actual[0],
customEqualityTesters
);
}
};
};
env.addCustomEqualityTester(customEqualityFn);
env.expect(["two"]).toEqual(arrayWithFirstElement(2));
env.expect(['two']).toEqual(arrayWithFirstElement(2));
});
var specExpectations = function(result) {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
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() {
it('displays an appropriate failure message if a custom equality matcher fails', function(done) {
env.it('spec using custom equality matcher', function() {
var customEqualityFn = function(a, b) {
// "foo" is not equal to anything
if (a === 'foo' || b === 'foo') {
@@ -125,7 +152,7 @@ describe("Custom Matchers (Integration)", function () {
};
env.addCustomEqualityTester(customEqualityFn);
env.expect({foo: 'foo'}).toEqual({foo: 'foo'});
env.expect({ foo: 'foo' }).toEqual({ foo: 'foo' });
});
var specExpectations = function(result) {
@@ -135,17 +162,21 @@ describe("Custom Matchers (Integration)", function () {
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("uses the negative compare function for a negative comparison, if provided", function(done) {
env.it("spec with custom negative comparison matcher", function() {
it('uses the negative compare function for a negative comparison, if provided', function(done) {
env.it('spec with custom negative comparison matcher', function() {
env.addMatchers({
toBeReal: function() {
return {
compare: function() { return { pass: true }; },
negativeCompare: function() { return { pass: true }; }
compare: function() {
return { pass: true };
},
negativeCompare: function() {
return { pass: true };
}
};
}
});
@@ -157,11 +188,11 @@ describe("Custom Matchers (Integration)", function () {
expect(result.status).toEqual('passed');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("generates messages with the same rules as built in matchers absent a custom message", function(done) {
it('generates messages with the same rules as built in matchers absent a custom message', function(done) {
env.it('spec with an expectation', function() {
env.addMatchers({
toBeReal: function() {
@@ -169,25 +200,29 @@ describe("Custom Matchers (Integration)", function () {
compare: function() {
return { pass: false };
}
}
};
}
});
env.expect("a").toBeReal();
env.expect('a').toBeReal();
});
var specExpectations = function(result) {
expect(result.failedExpectations[0].message).toEqual("Expected 'a' to be real.");
expect(result.failedExpectations[0].message).toEqual(
"Expected 'a' to be real."
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("passes the expected and actual arguments to the comparison function", function(done) {
var argumentSpy = jasmine.createSpy("argument spy").and.returnValue({ pass: true });
it('passes the expected and actual arguments to the comparison function', function(done) {
var argumentSpy = jasmine
.createSpy('argument spy')
.and.returnValue({ pass: true });
env.it('spec with an expectation', function () {
env.it('spec with an expectation', function() {
env.addMatchers({
toBeReal: function() {
return { compare: argumentSpy };
@@ -195,28 +230,37 @@ describe("Custom Matchers (Integration)", function () {
});
env.expect(true).toBeReal();
env.expect(true).toBeReal("arg");
env.expect(true).toBeReal("arg1", "arg2");
env.expect(true).toBeReal('arg');
env.expect(true).toBeReal('arg1', 'arg2');
});
var specExpectations = function() {
expect(argumentSpy).toHaveBeenCalledWith(true);
expect(argumentSpy).toHaveBeenCalledWith(true, "arg");
expect(argumentSpy).toHaveBeenCalledWith(true, "arg1", "arg2");
expect(argumentSpy).toHaveBeenCalledWith(true, 'arg');
expect(argumentSpy).toHaveBeenCalledWith(true, 'arg1', 'arg2');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
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() { return { compare: function() { return {pass: true}; }}; },
matcherFactorySpy = jasmine.createSpy("matcherFactorySpy").and.callFake(matcherFactory),
customEqualityFn = function() { return true; };
it('passes the jasmine utility and current equality testers to the matcher factory', function(done) {
var matcherFactory = function() {
return {
compare: function() {
return { pass: true };
}
};
},
matcherFactorySpy = jasmine
.createSpy('matcherFactorySpy')
.and.callFake(matcherFactory),
customEqualityFn = function() {
return true;
};
env.it("spec with expectation", function() {
env.it('spec with expectation', function() {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeReal: matcherFactorySpy
@@ -232,37 +276,39 @@ describe("Custom Matchers (Integration)", function () {
);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
it("provides custom equality testers to the matcher factory via matchersUtil", function (done) {
var matcherFactory = function (matchersUtil) {
it('provides custom equality testers to the matcher factory via matchersUtil', function(done) {
var matcherFactory = function(matchersUtil) {
return {
compare: function (actual, expected) {
return {pass: matchersUtil.equals(actual[0], expected)};
compare: function(actual, expected) {
return { pass: matchersUtil.equals(actual[0], expected) };
}
};
},
customEqualityFn = jasmine.createSpy("customEqualityFn").and.callFake(function (a, b) {
return a.toString() === b;
});
customEqualityFn = jasmine
.createSpy('customEqualityFn')
.and.callFake(function(a, b) {
return a.toString() === b;
});
env.it("spec with expectation", function () {
env.it('spec with expectation', function() {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeArrayWithFirstElement: matcherFactory
});
env.expect([1, 2]).toBeArrayWithFirstElement("1");
env.expect([1, 2]).toBeArrayWithFirstElement('1');
});
var specExpectations = function (result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, "1");
var specExpectations = function(result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, '1');
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
});

View File

@@ -1,14 +1,16 @@
describe("Custom object formatters", function() {
describe('Custom object formatters', function() {
var env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
env.configure({ random: false });
});
it("scopes custom object formatters to a spec", function(done) {
it('scopes custom object formatters to a spec', function(done) {
env.it('a spec with custom pretty-printer', function() {
env.addCustomObjectFormatter(function(obj) { return 'custom(' + obj + ')'; });
env.addCustomObjectFormatter(function(obj) {
return 'custom(' + obj + ')';
});
env.expect(42).toBeUndefined();
});
@@ -21,23 +23,29 @@ describe("Custom object formatters", function() {
specResults.push(result);
};
var expectations = function() {
expect(specResults[0].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
expect(specResults[1].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
expect(specResults[0].failedExpectations[0].message).toEqual(
'Expected custom(42) to be undefined.'
);
expect(specResults[1].failedExpectations[0].message).toEqual(
'Expected 42 to be undefined.'
);
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.addReporter({ specDone: specDone });
env.execute();
env.execute(null, expectations);
});
it("scopes custom object formatters to a suite", function(done) {
it('scopes custom object formatters to a suite', function(done) {
env.it('a spec without custom pretty-printer', function() {
env.expect(42).toBeUndefined();
});
env.describe('with custom pretty-printer', function() {
env.beforeEach(function() {
env.addCustomObjectFormatter(function(obj) { return 'custom(' + obj + ')'; });
env.beforeAll(function() {
env.addCustomObjectFormatter(function(obj) {
return 'custom(' + obj + ')';
});
});
env.it('a spec', function() {
@@ -50,18 +58,24 @@ describe("Custom object formatters", function() {
specResults.push(result);
};
var expectations = function() {
expect(specResults[0].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
expect(specResults[1].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
expect(specResults[0].failedExpectations[0].message).toEqual(
'Expected 42 to be undefined.'
);
expect(specResults[1].failedExpectations[0].message).toEqual(
'Expected custom(42) to be undefined.'
);
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.addReporter({ specDone: specDone });
env.execute();
env.execute(null, expectations);
});
it("throws an exception if you try to add a custom object formatter outside a runable", function() {
it('throws an exception if you try to add a custom object formatter outside a runable', function() {
expect(function() {
env.addCustomObjectFormatter(function() {});
}).toThrowError('Custom object formatters must be added in a before function or a spec')
}).toThrowError(
'Custom object formatters must be added in a before function or a spec'
);
});
});

View File

@@ -3,7 +3,7 @@ describe('Custom Spy Strategies (Integration)', function() {
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
env.configure({ random: false });
});
afterEach(function() {
@@ -11,10 +11,9 @@ describe('Custom Spy Strategies (Integration)', function() {
});
it('allows adding more strategies local to a suite', function(done) {
var plan = jasmine.createSpy('custom strategy plan')
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
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() {
@@ -33,20 +32,20 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('allows adding more strategies local to a spec', function(done) {
var plan = jasmine.createSpy('custom strategy plan')
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
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);
@@ -60,26 +59,28 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('allows using custom strategies on a per-argument basis', function(done) {
var plan = jasmine.createSpy('custom strategy plan')
.and.returnValue(42);
var strategy = jasmine.createSpy('custom strategy')
.and.returnValue(plan);
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);
var spy = env.createSpy('something')
var spy = env
.createSpy('something')
.and.returnValue('no args return')
.withArgs(1, 2, 3).and.frobnicate(17);
.withArgs(1, 2, 3)
.and.frobnicate(17);
expect(spy()).toEqual('no args return');
expect(plan).not.toHaveBeenCalled();
@@ -91,13 +92,14 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(env.createSpy('something').and.frobnicate).toBeUndefined();
});
function jasmineDone(result) {
function expectations() {
var result = jasmineDone.calls.argsFor(0)[0];
expect(result.overallStatus).toEqual('passed');
done();
}
env.addReporter({ jasmineDone: jasmineDone });
env.execute();
env.execute(null, expectations);
});
it('allows multiple custom strategies to be used', function(done) {
@@ -105,7 +107,8 @@ describe('Custom Spy Strategies (Integration)', function() {
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');
specDone = jasmine.createSpy('specDone'),
jasmineDone = jasmine.createSpy('jasmineDone');
env.beforeEach(function() {
env.addSpyStrategy('frobnicate', strategy1);
@@ -130,13 +133,14 @@ describe('Custom Spy Strategies (Integration)', function() {
expect(plan2).toHaveBeenCalled();
});
function jasmineDone(result) {
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();
env.execute(null, expectations);
});
});

View File

@@ -3,7 +3,7 @@ describe('Default Spy Strategy (Integration)', function() {
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
env.configure({ random: false });
});
afterEach(function() {
@@ -13,7 +13,7 @@ describe('Default Spy Strategy (Integration)', function() {
it('allows defining a default spy strategy', function(done) {
env.describe('suite with default strategy', function() {
env.beforeEach(function() {
env.setDefaultSpyStrategy(function (and) {
env.setDefaultSpyStrategy(function(and) {
and.returnValue(42);
});
});
@@ -29,21 +29,27 @@ describe('Default Spy Strategy (Integration)', function() {
expect(spy()).toBeUndefined();
});
function jasmineDone(result) {
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();
env.execute(null, expectations);
});
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', function(done) {
env.it('spec', function() {
var a = env.createSpy('a');
env.setDefaultSpyStrategy(function (and) { and.returnValue(42); });
env.setDefaultSpyStrategy(function(and) {
and.returnValue(42);
});
var b = env.createSpy('b');
env.setDefaultSpyStrategy(function (and) { and.stub(); });
env.setDefaultSpyStrategy(function(and) {
and.stub();
});
var c = env.createSpy('c');
env.setDefaultSpyStrategy();
var d = env.createSpy('d');
@@ -61,12 +67,14 @@ describe('Default Spy Strategy (Integration)', function() {
expect(d.and.isConfigured()).toBe(false);
});
function jasmineDone(result) {
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();
env.execute(null, expectations);
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -23,13 +23,15 @@ describe('Matchers (Integration)', function() {
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(0);
expect(result.failedExpectations[0] && result.failedExpectations[0].message)
expect(
result.failedExpectations[0] && result.failedExpectations[0].message
)
.withContext('Failure message')
.toBeUndefined();
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -45,38 +47,44 @@ describe('Matchers (Integration)', function() {
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown error rather than a matcher failure')
.withContext(
'Failed with a thrown error rather than a matcher failure'
)
.not.toMatch(/^Error: /);
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown type error rather than a matcher failure')
.withContext(
'Failed with a thrown type error rather than a matcher failure'
)
.not.toMatch(/^TypeError: /);
expect(result.failedExpectations[0].matcherName).withContext('Matcher name')
expect(result.failedExpectations[0].matcherName)
.withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
function verifyFailsWithCustomObjectFormatters(config) {
it('uses custom object formatters', function(done) {
env.it('a spec', function () {
env.it('a spec', function() {
env.addCustomObjectFormatter(config.formatter);
config.expectations(env);
});
var specExpectations = function (result) {
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.toEqual(config.expectedMessage);
expect(result.failedExpectations[0].message).toEqual(
config.expectedMessage
);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -96,13 +104,15 @@ describe('Matchers (Integration)', function() {
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(0);
expect(result.failedExpectations[0] && result.failedExpectations[0].message)
expect(
result.failedExpectations[0] && result.failedExpectations[0].message
)
.withContext('Failure message')
.toBeUndefined();
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -120,14 +130,17 @@ describe('Matchers (Integration)', function() {
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown error rather than a matcher failure')
.withContext(
'Failed with a thrown error rather than a matcher failure'
)
.not.toMatch(/^Error: /);
expect(result.failedExpectations[0].matcherName).withContext('Matcher name')
expect(result.failedExpectations[0].matcherName)
.withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
@@ -135,26 +148,26 @@ describe('Matchers (Integration)', function() {
it('uses custom object formatters', function(done) {
var env = new jasmineUnderTest.Env();
jasmine.getEnv().requirePromises();
env.it('a spec', function () {
env.it('a spec', function() {
env.addCustomObjectFormatter(config.formatter);
return config.expectations(env);
});
var specExpectations = function (result) {
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message)
.toEqual(config.expectedMessage);
expect(result.failedExpectations[0].message).toEqual(
config.expectedMessage
);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
}
describe('nothing', function() {
verifyPasses(function(env) {
env.expect().nothing();
@@ -330,16 +343,18 @@ describe('Matchers (Integration)', function() {
env.expect(1).toBePositiveInfinity();
},
expectedMessage: 'Expected |1| to be Infinity.'
})
});
});
describe('toBeResolved', function() {
verifyPassesAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeResolved(); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeResolved();
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.reject()).toBeResolved(); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject()).toBeResolved();
});
});
@@ -348,11 +363,13 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
return env.expectAsync(Promise.resolve('5')).toBeResolvedTo(5); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve('5')).toBeResolvedTo(5);
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar'); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar');
});
verifyFailsWithCustomObjectFormattersAsync({
@@ -360,20 +377,24 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y'); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y');
},
expectedMessage: 'Expected a promise to be resolved to |y| ' +
expectedMessage:
'Expected a promise to be resolved to |y| ' +
'but it was resolved to |x|.'
});
});
describe('toBeRejected', function() {
verifyPassesAsync(function(env) {
return env.expectAsync(Promise.reject('nope')).toBeRejected(); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject('nope')).toBeRejected();
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejected(); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeRejected();
});
});
@@ -382,11 +403,13 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
return env.expectAsync(Promise.reject('5')).toBeRejectedWith(5); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject('5')).toBeRejectedWith(5);
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope'); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope');
});
verifyFailsWithCustomObjectFormattersAsync({
@@ -394,20 +417,28 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y'); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y');
},
expectedMessage: 'Expected a promise to be rejected with |y| ' +
expectedMessage:
'Expected a promise to be rejected with |y| ' +
'but it was rejected with |x|.'
});
});
describe('toBeRejectedWithError', function() {
verifyPassesAsync(function(env) {
return env.expectAsync(Promise.reject(new Error())).toBeRejectedWithError(Error); // eslint-disable-line compat/compat
return (
env
// eslint-disable-next-line compat/compat
.expectAsync(Promise.reject(new Error()))
.toBeRejectedWithError(Error)
);
});
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error); // eslint-disable-line compat/compat
// eslint-disable-next-line compat/compat
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error);
});
verifyFailsWithCustomObjectFormattersAsync({
@@ -415,9 +446,15 @@ describe('Matchers (Integration)', function() {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('foo')).toBeRejectedWithError('foo'); // eslint-disable-line compat/compat
return (
env
// eslint-disable-next-line compat/compat
.expectAsync(Promise.reject('foo'))
.toBeRejectedWithError('foo')
);
},
expectedMessage: 'Expected a promise to be rejected with Error: |foo| ' +
expectedMessage:
'Expected a promise to be rejected with Error: |foo| ' +
'but it was rejected with |foo|.'
});
});
@@ -486,7 +523,7 @@ describe('Matchers (Integration)', function() {
}
},
expectations: function(env) {
env.expect([{foo: 4}]).toEqual([{foo: 5}]);
env.expect([{ foo: 4 }]).toEqual([{ foo: 5 }]);
},
expectedMessage: 'Expected $[0].foo = four to equal five.'
});
@@ -494,11 +531,11 @@ describe('Matchers (Integration)', function() {
describe('toHaveSize', function() {
verifyPasses(function(env) {
env.expect(['a','b']).toHaveSize(2);
env.expect(['a', 'b']).toHaveSize(2);
});
verifyFails(function(env) {
env.expect(['a','b']).toHaveSize(1);
env.expect(['a', 'b']).toHaveSize(1);
});
});
@@ -517,14 +554,16 @@ describe('Matchers (Integration)', function() {
describe('toHaveBeenCalledBefore', function() {
verifyPasses(function(env) {
var a = env.createSpy('a'), b = env.createSpy('b');
var a = env.createSpy('a'),
b = env.createSpy('b');
a();
b();
env.expect(a).toHaveBeenCalledBefore(b);
});
verifyFails(function(env) {
var a = env.createSpy('a'), b = env.createSpy('b');
var a = env.createSpy('a'),
b = env.createSpy('b');
b();
a();
env.expect(a).toHaveBeenCalledBefore(b);
@@ -567,7 +606,8 @@ describe('Matchers (Integration)', function() {
var spy = env.createSpy('foo');
env.expect(spy).toHaveBeenCalledWith('x');
},
expectedMessage: 'Expected spy foo to have been called with:\n' +
expectedMessage:
'Expected spy foo to have been called with:\n' +
' |x|\n' +
'but it was never called.'
});
@@ -622,7 +662,11 @@ describe('Matchers (Integration)', function() {
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect(function() { throw '5'; }).toThrow(5);
env
.expect(function() {
throw '5';
})
.toThrow(5);
});
verifyFails(function(env) {
@@ -635,9 +679,11 @@ describe('Matchers (Integration)', function() {
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw 'x'
}).not.toThrow();
env
.expect(function() {
throw 'x';
})
.not.toThrow();
},
expectedMessage: 'Expected function not to throw, but it threw |x|.'
});
@@ -645,11 +691,15 @@ describe('Matchers (Integration)', function() {
describe('toThrowError', function() {
verifyPasses(function(env) {
env.expect(function() { throw new Error(); }).toThrowError();
env
.expect(function() {
throw new Error();
})
.toThrowError();
});
verifyFails(function(env) {
env.expect(function() { }).toThrowError();
env.expect(function() {}).toThrowError();
});
verifyFailsWithCustomObjectFormatters({
@@ -658,9 +708,11 @@ describe('Matchers (Integration)', function() {
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw 'x'
}).toThrowError();
env
.expect(function() {
throw 'x';
})
.toThrowError();
},
expectedMessage: 'Expected function to throw an Error, but it threw |x|.'
});
@@ -672,11 +724,15 @@ describe('Matchers (Integration)', function() {
}
verifyPasses(function(env) {
env.expect(throws).toThrowMatching(function() { return true; });
env.expect(throws).toThrowMatching(function() {
return true;
});
});
verifyFails(function(env) {
env.expect(throws).toThrowMatching(function() { return false; });
env.expect(throws).toThrowMatching(function() {
return false;
});
});
verifyFailsWithCustomObjectFormatters({
@@ -685,14 +741,102 @@ describe('Matchers (Integration)', function() {
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw new Error('nope')
}).toThrowMatching(function() {
return false;
});
env
.expect(function() {
throw new Error('nope');
})
.toThrowMatching(function() {
return false;
});
},
expectedMessage: 'Expected function to throw an exception matching ' +
expectedMessage:
'Expected function to throw an exception matching ' +
'a predicate, but it threw Error with message |nope|.'
});
});
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();
});
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message).toEqual(
'Expected [object Promise] to be rejected.'
);
expect(result.failedExpectations[0].matcherName)
.withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
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()
);
});
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message).toEqual(
'Expected a promise to be resolved but it was ' +
'rejected with Error: nope.'
);
expect(result.failedExpectations[0].matcherName)
.withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
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() {
return env.expectAsync(promise).already.toBeResolved();
});
var specExpectations = function(result) {
expect(result.status).toEqual('failed');
expect(result.failedExpectations.length)
.withContext('Number of failed expectations')
.toEqual(1);
expect(result.failedExpectations[0].message).toEqual(
'Expected a promise to be settled ' +
'(via expectAsync(...).already) but it was pending.'
);
expect(result.failedExpectations[0].matcherName)
.withContext('Matcher name')
.not.toEqual('');
};
env.addReporter({ specDone: specExpectations });
env.execute(null, done);
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,132 +1,159 @@
describe("DiffBuilder", function () {
it("records the actual and expected objects", function () {
describe('DiffBuilder', function() {
it('records the actual and expected objects', function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({x: 'actual'}, {x: 'expected'});
diffBuilder.setRoots({ x: 'actual' }, { x: 'expected' });
diffBuilder.recordMismatch();
expect(diffBuilder.getMessage()).toEqual("Expected Object({ x: 'actual' }) to equal Object({ x: 'expected' }).");
expect(diffBuilder.getMessage()).toEqual(
"Expected Object({ x: 'actual' }) to equal Object({ x: 'expected' })."
);
});
it("prints the path at which the difference was found", function () {
it('prints the path at which the difference was found', function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({foo: {x: 'actual'}}, {foo: {x: 'expected'}});
diffBuilder.setRoots({ foo: { x: 'actual' } }, { foo: { x: 'expected' } });
diffBuilder.withPath('foo', function () {
diffBuilder.withPath('foo', function() {
diffBuilder.recordMismatch();
});
expect(diffBuilder.getMessage()).toEqual("Expected $.foo = Object({ x: 'actual' }) to equal Object({ x: 'expected' }).");
expect(diffBuilder.getMessage()).toEqual(
"Expected $.foo = Object({ x: 'actual' }) to equal Object({ x: 'expected' })."
);
});
it("prints multiple messages, separated by newlines", function () {
it('prints multiple messages, separated by newlines', function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({foo: 1, bar: 3}, {foo: 2, bar: 4});
diffBuilder.setRoots({ foo: 1, bar: 3 }, { foo: 2, bar: 4 });
diffBuilder.withPath('foo', function () {
diffBuilder.withPath('foo', function() {
diffBuilder.recordMismatch();
});
diffBuilder.withPath('bar', function () {
diffBuilder.withPath('bar', function() {
diffBuilder.recordMismatch();
});
var message =
"Expected $.foo = 1 to equal 2.\n" +
"Expected $.bar = 3 to equal 4.";
'Expected $.foo = 1 to equal 2.\n' + 'Expected $.bar = 3 to equal 4.';
expect(diffBuilder.getMessage()).toEqual(message);
});
it("allows customization of the message", function () {
it('allows customization of the message', function() {
var diffBuilder = jasmineUnderTest.DiffBuilder();
diffBuilder.setRoots({x: 'bar'}, {x: 'foo'});
diffBuilder.setRoots({ x: 'bar' }, { x: 'foo' });
function darthVaderFormatter(actual, expected, path) {
return "I find your lack of " + expected + " disturbing. (was " + actual + ", at " + path + ")"
return (
'I find your lack of ' +
expected +
' disturbing. (was ' +
actual +
', at ' +
path +
')'
);
}
diffBuilder.withPath('x', function () {
diffBuilder.withPath('x', function() {
diffBuilder.recordMismatch(darthVaderFormatter);
});
expect(diffBuilder.getMessage()).toEqual("I find your lack of foo disturbing. (was bar, at $.x)");
expect(diffBuilder.getMessage()).toEqual(
'I find your lack of foo disturbing. (was bar, at $.x)'
);
});
it("uses the injected pretty-printer", function () {
var prettyPrinter = function (val) {
it('uses the injected pretty-printer', function() {
var prettyPrinter = function(val) {
return '|' + val + '|';
},
diffBuilder = jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
prettyPrinter.customFormat_ = function () {
};
diffBuilder = jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});
prettyPrinter.customFormat_ = function() {};
diffBuilder.setRoots({foo: 'actual'}, {foo: 'expected'});
diffBuilder.withPath('foo', function () {
diffBuilder.setRoots({ foo: 'actual' }, { foo: 'expected' });
diffBuilder.withPath('foo', function() {
diffBuilder.recordMismatch();
});
expect(diffBuilder.getMessage()).toEqual("Expected $.foo = |actual| to equal |expected|.");
expect(diffBuilder.getMessage()).toEqual(
'Expected $.foo = |actual| to equal |expected|.'
);
});
it("passes the injected pretty-printer to the diff formatter", function () {
it('passes the injected pretty-printer to the diff formatter', function() {
var diffFormatter = jasmine.createSpy('diffFormatter'),
prettyPrinter = function () {
},
diffBuilder = jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
prettyPrinter.customFormat_ = function () {
};
prettyPrinter = function() {},
diffBuilder = jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});
prettyPrinter.customFormat_ = function() {};
diffBuilder.setRoots({x: 'bar'}, {x: 'foo'});
diffBuilder.withPath('x', function () {
diffBuilder.setRoots({ x: 'bar' }, { x: 'foo' });
diffBuilder.withPath('x', function() {
diffBuilder.recordMismatch(diffFormatter);
});
diffBuilder.getMessage();
expect(diffFormatter).toHaveBeenCalledWith('bar', 'foo', jasmine.anything(), prettyPrinter);
expect(diffFormatter).toHaveBeenCalledWith(
'bar',
'foo',
jasmine.anything(),
prettyPrinter
);
});
it("uses custom object formatters on leaf nodes", function() {
it('uses custom object formatters on leaf nodes', function() {
var formatter = function(x) {
if (typeof x === 'number') {
return '[number:' + x + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});
diffBuilder.setRoots(5, 4);
diffBuilder.recordMismatch();
expect(diffBuilder.getMessage()).toEqual('Expected [number:5] to equal [number:4].');
expect(diffBuilder.getMessage()).toEqual(
'Expected [number:5] to equal [number:4].'
);
});
it("uses custom object formatters on non leaf nodes", function () {
var formatter = function (x) {
it('uses custom object formatters on non leaf nodes', function() {
var formatter = function(x) {
if (x.hasOwnProperty('a')) {
return '[thing with a=' + x.a + ', b=' + JSON.stringify(x.b) + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter});
var expectedMsg = 'Expected $[0].foo = [thing with a=1, b={"x":42}] to equal [thing with a=1, b={"x":43}].\n' +
var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});
var expectedMsg =
'Expected $[0].foo = [thing with a=1, b={"x":42}] to equal [thing with a=1, b={"x":43}].\n' +
"Expected $[0].bar = 'yes' to equal 'no'.";
diffBuilder.setRoots(
[{foo: {a: 1, b: {x: 42}}, bar: 'yes'}],
[{foo: {a: 1, b: {x: 43}}, bar: 'no'}]
[{ foo: { a: 1, b: { x: 42 } }, bar: 'yes' }],
[{ foo: { a: 1, b: { x: 43 } }, bar: 'no' }]
);
diffBuilder.withPath(0, function () {
diffBuilder.withPath('foo', function () {
diffBuilder.withPath('b', function () {
diffBuilder.withPath('x', function () {
diffBuilder.withPath(0, function() {
diffBuilder.withPath('foo', function() {
diffBuilder.withPath('b', function() {
diffBuilder.withPath('x', function() {
diffBuilder.recordMismatch();
});
});
});
diffBuilder.withPath('bar', function () {
diffBuilder.withPath('bar', function() {
diffBuilder.recordMismatch();
});
});
@@ -136,14 +163,16 @@ describe("DiffBuilder", function () {
it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ at the root', function() {
var prettyPrinter = jasmineUnderTest.makePrettyPrinter([]),
diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter}),
expectedMsg = 'Expected $.foo = 1 to equal 2.\n' +
"Expected $.baz = undefined to equal 3.";
diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
}),
expectedMsg =
'Expected $.foo = 1 to equal 2.\n' +
'Expected $.baz = undefined to equal 3.';
diffBuilder.setRoots(
{foo: 1, bar: 2},
jasmine.objectContaining({foo: 2, baz: 3})
{ foo: 1, bar: 2 },
jasmine.objectContaining({ foo: 2, baz: 3 })
);
diffBuilder.withPath('foo', function() {
@@ -158,21 +187,23 @@ describe("DiffBuilder", function () {
it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ below the root', function() {
var prettyPrinter = jasmineUnderTest.makePrettyPrinter([]),
diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter}),
expectedMsg = 'Expected $.x.foo = 1 to equal 2.\n' +
"Expected $.x.baz = undefined to equal 3.";
diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
}),
expectedMsg =
'Expected $.x.foo = 1 to equal 2.\n' +
'Expected $.x.baz = undefined to equal 3.';
diffBuilder.setRoots(
{x: {foo: 1, bar: 2}},
{x: jasmine.objectContaining({foo: 2, baz: 3})}
{ x: { foo: 1, bar: 2 } },
{ x: jasmine.objectContaining({ foo: 2, baz: 3 }) }
);
diffBuilder.withPath('x', function() {
diffBuilder.withPath('foo', function () {
diffBuilder.withPath('foo', function() {
diffBuilder.recordMismatch();
});
diffBuilder.withPath('baz', function () {
diffBuilder.withPath('baz', function() {
diffBuilder.recordMismatch();
});
});

View File

@@ -1,15 +1,15 @@
describe('MismatchTree', function () {
describe('#add', function () {
describe('When the path is empty', function () {
it('flags the root node as mismatched', function () {
describe('MismatchTree', function() {
describe('#add', function() {
describe('When the path is empty', function() {
it('flags the root node as mismatched', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath([]));
expect(tree.isMismatch).toBe(true);
});
});
describe('When the path is not empty', function () {
it('flags the node as mismatched', function () {
describe('When the path is not empty', function() {
it('flags the node as mismatched', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
@@ -17,7 +17,7 @@ describe('MismatchTree', function () {
expect(tree.child('a').child('b').isMismatch).toBe(true);
});
it('does not flag ancestors as mismatched', function () {
it('does not flag ancestors as mismatched', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
@@ -27,7 +27,7 @@ describe('MismatchTree', function () {
});
});
it('stores the formatter on only the target node', function () {
it('stores the formatter on only the target node', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']), formatter);
@@ -37,7 +37,7 @@ describe('MismatchTree', function () {
expect(tree.child('a').child('b').formatter).toBe(formatter);
});
it('stores the path to the node', function () {
it('stores the path to the node', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']), formatter);
@@ -46,8 +46,8 @@ describe('MismatchTree', function () {
});
});
describe('#traverse', function () {
it('calls the callback for all nodes that are or contain mismatches', function () {
describe('#traverse', function() {
it('calls the callback for all nodes that are or contain mismatches', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']), formatter);
tree.add(new jasmineUnderTest.ObjectPath(['c']));
@@ -56,20 +56,28 @@ describe('MismatchTree', function () {
tree.traverse(visit);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath([]), false, undefined
new jasmineUnderTest.ObjectPath([]),
false,
undefined
);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath(['a']), false, undefined
new jasmineUnderTest.ObjectPath(['a']),
false,
undefined
);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath(['a', 'b']), true, formatter
new jasmineUnderTest.ObjectPath(['a', 'b']),
true,
formatter
);
expect(visit).toHaveBeenCalledWith(
new jasmineUnderTest.ObjectPath(['c']), true, undefined
new jasmineUnderTest.ObjectPath(['c']),
true,
undefined
);
});
it('does not call the callback if there are no mismatches', function () {
it('does not call the callback if there are no mismatches', function() {
var tree = new jasmineUnderTest.MismatchTree();
var visit = jasmine.createSpy('visit');
@@ -78,12 +86,12 @@ describe('MismatchTree', function () {
expect(visit).not.toHaveBeenCalled();
});
it('visits parents before children', function () {
it('visits parents before children', function() {
var tree = new jasmineUnderTest.MismatchTree();
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
var visited = [];
tree.traverse(function (path) {
tree.traverse(function(path) {
visited.push(path);
return true;
});
@@ -101,7 +109,7 @@ describe('MismatchTree', function () {
tree.add(new jasmineUnderTest.ObjectPath([1]));
var visited = [];
tree.traverse(function (path) {
tree.traverse(function(path) {
visited.push(path);
return true;
});
@@ -118,7 +126,7 @@ describe('MismatchTree', function () {
tree.add(new jasmineUnderTest.ObjectPath(['a', 'b']));
var visited = [];
tree.traverse(function (path) {
tree.traverse(function(path) {
visited.push(path);
return path.depth() === 0;
});
@@ -130,7 +138,5 @@ describe('MismatchTree', function () {
});
});
function formatter() {
}
function formatter() {}
});

View File

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

View File

@@ -8,7 +8,7 @@ describe('toBePending', function() {
actual = new Promise(function() {});
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
@@ -20,7 +20,7 @@ describe('toBePending', function() {
actual = Promise.resolve();
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: false}));
expect(result).toEqual(jasmine.objectContaining({ pass: false }));
});
});
@@ -32,21 +32,19 @@ describe('toBePending', function() {
actual = Promise.reject(new Error('promise was rejected'));
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: false}));
expect(result).toEqual(jasmine.objectContaining({ pass: false }));
});
});
it('fails if actual is not a promise', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = 'not a promise';
matcher = jasmineUnderTest.asyncMatchers.toBePending(matchersUtil),
actual = 'not a promise';
function f() {
return matcher.compare(actual);
}
expect(f).toThrowError(
'Expected toBePending to be called on a promise.'
);
expect(f).toThrowError('Expected toBePending to be called on a promise.');
});
});

View File

@@ -8,7 +8,7 @@ describe('toBeRejected', function() {
actual = Promise.reject('AsyncExpectationSpec rejection');
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
@@ -20,7 +20,7 @@ describe('toBeRejected', function() {
actual = Promise.resolve();
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: false}));
expect(result).toEqual(jasmine.objectContaining({ pass: false }));
});
});
@@ -33,8 +33,6 @@ describe('toBeRejected', function() {
return matcher.compare(actual);
}
expect(f).toThrowError(
'Expected toBeRejected to be called on a promise.'
);
expect(f).toThrowError('Expected toBeRejected to be called on a promise.');
});
});

View File

@@ -1,174 +1,253 @@
/* eslint-disable compat/compat */
describe('#toBeRejectedWithError', function () {
it('passes when Error type matches', function () {
describe('#toBeRejectedWithError', function() {
it('passes when Error type matches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new TypeError('foo'));
return matcher.compare(actual, TypeError).then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with TypeError, but it was.'
}));
return matcher.compare(actual, TypeError).then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
'Expected a promise not to be rejected with TypeError, but it was.'
})
);
});
});
it('passes when Error type and message matches', function () {
it('passes when Error type and message matches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new TypeError('foo'));
return matcher.compare(actual, TypeError, 'foo').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with TypeError: \'foo\', but it was.'
}));
return matcher.compare(actual, TypeError, 'foo').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
"Expected a promise not to be rejected with TypeError: 'foo', but it was."
})
);
});
});
it('passes when Error matches and is exactly Error', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error());
return matcher.compare(actual, Error).then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with Error, but it was.'
}));
return matcher.compare(actual, Error).then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
'Expected a promise not to be rejected with Error, but it was.'
})
);
});
});
it('passes when Error message matches a string', function () {
it('passes when Error message matches a string', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, 'foo').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with Error: \'foo\', but it was.'
}));
return matcher.compare(actual, 'foo').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
"Expected a promise not to be rejected with Error: 'foo', but it was."
})
);
});
});
it('passes when Error message matches a RegExp', function () {
it('passes when Error message matches a RegExp', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, /foo/).then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with Error: /foo/, but it was.'
}));
return matcher.compare(actual, /foo/).then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
'Expected a promise not to be rejected with Error: /foo/, but it was.'
})
);
});
});
it('passes when Error message is empty', function () {
it('passes when Error message is empty', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error());
return matcher.compare(actual, '').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with Error: \'\', but it was.'
}));
return matcher.compare(actual, '').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
"Expected a promise not to be rejected with Error: '', but it was."
})
);
});
});
it('passes when no arguments', function () {
it('passes when no arguments', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error());
return matcher.compare(actual, void 0).then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with Error, but it was.'
}));
return matcher.compare(actual, void 0).then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message:
'Expected a promise not to be rejected with Error, but it was.'
})
);
});
});
it('fails when resolved', function () {
it('fails when resolved', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.resolve(new Error('foo'));
return matcher.compare(actual, 'foo').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: 'Expected a promise to be rejected but it was resolved.'
}));
return matcher.compare(actual, 'foo').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message: 'Expected a promise to be rejected but it was resolved.'
})
);
});
});
it('fails when rejected with non Error type', function () {
it('fails when rejected with non Error type', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject('foo');
return matcher.compare(actual, 'foo').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: 'Expected a promise to be rejected with Error: \'foo\' but it was rejected with \'foo\'.'
}));
return matcher.compare(actual, 'foo').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message:
"Expected a promise to be rejected with Error: 'foo' but it was rejected with 'foo'."
})
);
});
});
it('fails when Error type mismatches', function () {
it('fails when Error type mismatches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, TypeError, 'foo').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: 'Expected a promise to be rejected with TypeError: \'foo\' but it was rejected with type Error.'
}));
return matcher.compare(actual, TypeError, 'foo').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message:
"Expected a promise to be rejected with TypeError: 'foo' but it was rejected with type Error."
})
);
});
});
it('fails when Error message mismatches', function () {
it('fails when Error message mismatches', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = Promise.reject(new Error('foo'));
return matcher.compare(actual, 'bar').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: 'Expected a promise to be rejected with Error: \'bar\' but it was rejected with Error: foo.'
}));
return matcher.compare(actual, 'bar').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message:
"Expected a promise to be rejected with Error: 'bar' but it was rejected with Error: foo."
})
);
});
});
it('fails if actual is not a promise', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(matchersUtil),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWithError(
matchersUtil
),
actual = 'not a promise';
function f() {

View File

@@ -1,74 +1,91 @@
/* eslint-disable compat/compat */
describe('#toBeRejectedWith', function () {
it('should return true if the promise is rejected with the expected value', function () {
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'});
actual = Promise.reject({ error: 'PEBCAK' });
return matcher.compare(actual, {error: 'PEBCAK'}).then(function (result) {
return matcher.compare(actual, { error: 'PEBCAK' }).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
it('should fail if the promise resolves', 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();
return matcher.compare(actual, '').then(function (result) {
return matcher.compare(actual, '').then(function(result) {
expect(result).toEqual(jasmine.objectContaining({ pass: false }));
});
});
it('should fail if the promise is rejected with a different value', 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()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject('A Bad Apple');
return matcher.compare(actual, 'Some Cool Thing').then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: "Expected a promise to be rejected with 'Some Cool Thing' but it was rejected with 'A Bad Apple'.",
}));
return matcher.compare(actual, 'Some Cool Thing').then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message:
"Expected a promise to be rejected with 'Some Cool Thing' but it was rejected with 'A Bad Apple'."
})
);
});
});
it('should build its error correctly when negated', function () {
it('should build its error correctly when negated', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject(true);
return matcher.compare(actual, true).then(function (result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with true.'
}));
return matcher.compare(actual, true).then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be rejected with true.'
})
);
});
});
it('should support custom equality testers', function () {
it('should support custom equality testers', function() {
jasmine.getEnv().requirePromises();
var customEqualityTesters = [function() { return true; }],
matchersUtil = new jasmineUnderTest.MatchersUtil({customTesters: customEqualityTesters}),
var customEqualityTesters = [
function() {
return true;
}
],
matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: customEqualityTesters
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = Promise.reject('actual');
return matcher.compare(actual, 'expected').then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
it('fails if actual is not a promise', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeRejectedWith(matchersUtil),
actual = 'not a promise';

View File

@@ -8,19 +8,26 @@ describe('toBeResolved', function() {
actual = Promise.resolve();
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
it('fails if the actual is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter([])
}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolved(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec rejection');
actual = Promise.reject(new Error('AsyncExpectationSpec rejection'));
return matcher.compare(actual).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: false}));
expect(result).toEqual({
pass: false,
message:
'Expected a promise to be resolved but it was rejected ' +
'with Error: AsyncExpectationSpec rejection.'
});
});
});
@@ -33,8 +40,6 @@ describe('toBeResolved', function() {
return matcher.compare(actual);
}
expect(f).toThrowError(
'Expected toBeResolved to be called on a promise.'
);
expect(f).toThrowError('Expected toBeResolved to be called on a promise.');
});
});

View File

@@ -5,62 +5,81 @@ describe('#toBeResolvedTo', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve({foo: 42});
actual = Promise.resolve({ foo: 42 });
return matcher.compare(actual, {foo: 42}).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
return matcher.compare(actual, { foo: 42 }).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
it('fails if the promise is rejected', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.reject('AsyncExpectationSpec error');
actual = Promise.reject(new Error('AsyncExpectationSpec error'));
return matcher.compare(actual, '').then(function(result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: "Expected a promise to be resolved to '' but it was rejected.",
}));
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message:
"Expected a promise to be resolved to '' but it was rejected " +
'with Error: AsyncExpectationSpec error.'
})
);
});
});
it('fails if the promise is resolved to a different value', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve({foo: 17});
actual = Promise.resolve({ foo: 17 });
return matcher.compare(actual, {foo: 42}).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({
pass: false,
message: 'Expected a promise to be resolved to Object({ foo: 42 }) but it was resolved to Object({ foo: 17 }).',
}));
return matcher.compare(actual, { foo: 42 }).then(function(result) {
expect(result).toEqual(
jasmine.objectContaining({
pass: false,
message:
'Expected a promise to be resolved to Object({ foo: 42 }) but it was resolved to Object({ foo: 17 }).'
})
);
});
});
it('builds its message correctly when negated', function() {
jasmine.getEnv().requirePromises();
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = Promise.resolve(true);
return matcher.compare(actual, true).then(function(result) {
expect(result).toEqual(jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be resolved to true.'
}));
expect(result).toEqual(
jasmine.objectContaining({
pass: true,
message: 'Expected a promise not to be resolved to true.'
})
);
});
});
it('supports custom equality testers', function() {
jasmine.getEnv().requirePromises();
var customEqualityTesters = [function() { return true; }],
var customEqualityTesters = [
function() {
return true;
}
],
matchersUtil = new jasmineUnderTest.MatchersUtil({
customTesters: customEqualityTesters,
pp: jasmineUnderTest.makePrettyPrinter()
@@ -69,12 +88,14 @@ describe('#toBeResolvedTo', function() {
actual = Promise.resolve('actual');
return matcher.compare(actual, 'expected').then(function(result) {
expect(result).toEqual(jasmine.objectContaining({pass: true}));
expect(result).toEqual(jasmine.objectContaining({ pass: true }));
});
});
it('fails if actual is not a promise', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.asyncMatchers.toBeResolvedTo(matchersUtil),
actual = 'not a promise';

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
describe("toBeCloseTo", function() {
it("passes when within two decimal places by default", function() {
describe('toBeCloseTo', function() {
it('passes when within two decimal places by default', function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
@@ -13,7 +13,7 @@ describe("toBeCloseTo", function() {
expect(result.pass).toBe(true);
});
it("fails when not within two decimal places by default", function() {
it('fails when not within two decimal places by default', function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
@@ -24,7 +24,7 @@ describe("toBeCloseTo", function() {
expect(result.pass).toBe(false);
});
it("accepts an optional precision argument", function() {
it('accepts an optional precision argument', function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
@@ -47,23 +47,29 @@ describe("toBeCloseTo", function() {
expect(result.pass).toBe(true);
});
it("fails when one of the arguments is null", function() {
it('fails when one of the arguments is null', function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo();
expect(function() {
matcher.compare(null, null);
}).toThrowError('Cannot use toBeCloseTo with null. Arguments evaluated to: expect(null).toBeCloseTo(null).');
}).toThrowError(
'Cannot use toBeCloseTo with null. Arguments evaluated to: expect(null).toBeCloseTo(null).'
);
expect(function() {
matcher.compare(0, null);
}).toThrowError('Cannot use toBeCloseTo with null. Arguments evaluated to: expect(0).toBeCloseTo(null).');
}).toThrowError(
'Cannot use toBeCloseTo with null. Arguments evaluated to: expect(0).toBeCloseTo(null).'
);
expect(function() {
matcher.compare(null, 0);
}).toThrowError('Cannot use toBeCloseTo with null. Arguments evaluated to: expect(null).toBeCloseTo(0).');
}).toThrowError(
'Cannot use toBeCloseTo with null. Arguments evaluated to: expect(null).toBeCloseTo(0).'
);
});
it("rounds expected values", function() {
it('rounds expected values', function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
@@ -91,15 +97,15 @@ describe("toBeCloseTo", function() {
expect(result.pass).toBe(true);
});
it("handles edge cases with rounding", function () {
it('handles edge cases with rounding', function() {
var matcher = jasmineUnderTest.matchers.toBeCloseTo(),
result;
// these cases resulted in false negatives in version of V8
// these cases resulted in false negatives in version of V8
// included in Node.js 12 and Chrome 74 (and Edge Chromium)
result = matcher.compare(4.030904708957288, 4.0309, 5);
expect(result.pass).toBe(true);
result = matcher.compare(4.82665525779431,4.82666, 5);
result = matcher.compare(4.82665525779431, 4.82666, 5);
expect(result.pass).toBe(true);
result = matcher.compare(-2.82665525779431, -2.82666, 5);
expect(result.pass).toBe(true);

View File

@@ -1,18 +1,17 @@
describe("toBeDefined", function() {
it("matches for defined values", function() {
describe('toBeDefined', function() {
it('matches for defined values', function() {
var matcher = jasmineUnderTest.matchers.toBeDefined(),
result;
result = matcher.compare('foo');
expect(result.pass).toBe(true);
});
it("fails when matching undefined values", function() {
it('fails when matching undefined values', function() {
var matcher = jasmineUnderTest.matchers.toBeDefined(),
result;
result = matcher.compare(void 0);
expect(result.pass).toBe(false);
})
});
});

View File

@@ -1,5 +1,5 @@
describe("toBeFalse", function() {
it("passes for false", function() {
describe('toBeFalse', function() {
it('passes for false', function() {
var matcher = jasmineUnderTest.matchers.toBeFalse(),
result;
@@ -7,7 +7,7 @@ describe("toBeFalse", function() {
expect(result.pass).toBe(true);
});
it("fails for non-false", function() {
it('fails for non-false', function() {
var matcher = jasmineUnderTest.matchers.toBeFalse(),
result;
@@ -15,7 +15,7 @@ describe("toBeFalse", function() {
expect(result.pass).toBe(false);
});
it("fails for falsy", function() {
it('fails for falsy', function() {
var matcher = jasmineUnderTest.matchers.toBeFalse(),
result;

View File

@@ -1,4 +1,4 @@
describe("toBeFalsy", function() {
describe('toBeFalsy', function() {
it("passes for 'falsy' values", function() {
var matcher = jasmineUnderTest.matchers.toBeFalsy(),
result;
@@ -15,6 +15,9 @@ describe("toBeFalsy", function() {
result = matcher.compare(null);
expect(result.pass).toBe(true);
result = matcher.compare(undefined);
expect(result.pass).toBe(true);
result = matcher.compare(void 0);
expect(result.pass).toBe(true);
});
@@ -29,10 +32,16 @@ describe("toBeFalsy", function() {
result = matcher.compare(1);
expect(result.pass).toBe(false);
result = matcher.compare("foo");
result = matcher.compare('foo');
expect(result.pass).toBe(false);
result = matcher.compare({});
expect(result.pass).toBe(false);
result = matcher.compare([]);
expect(result.pass).toBe(false);
result = matcher.compare(function() {});
expect(result.pass).toBe(false);
});
});

View File

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

View File

@@ -1,5 +1,5 @@
describe("toBeGreaterThan", function() {
it("passes when actual > expected", function() {
describe('toBeGreaterThan', function() {
it('passes when actual > expected', function() {
var matcher = jasmineUnderTest.matchers.toBeGreaterThan(),
result;
@@ -7,7 +7,7 @@ describe("toBeGreaterThan", function() {
expect(result.pass).toBe(true);
});
it("fails when actual <= expected", function() {
it('fails when actual <= expected', function() {
var matcher = jasmineUnderTest.matchers.toBeGreaterThan(),
result;

View File

@@ -92,13 +92,14 @@ describe('toBeInstanceOf', function() {
describe('when expecting Function', function() {
it('passes for a function', function() {
var fn = function() { };
var fn = function() {};
var matcher = jasmineUnderTest.matchers.toBeInstanceOf();
var result = matcher.compare(fn, Function);
expect(result).toEqual({
pass: true,
message: 'Expected instance of Function not to be an instance of Function'
message:
'Expected instance of Function not to be an instance of Function'
});
});
@@ -111,13 +112,14 @@ describe('toBeInstanceOf', function() {
var result = matcher.compare(fn, Function);
expect(result).toEqual({
pass: true,
message: 'Expected instance of AsyncFunction not to be an instance of Function'
message:
'Expected instance of AsyncFunction not to be an instance of Function'
});
});
});
describe('when expecting Object', function() {
function Animal() { }
function Animal() {}
it('passes for any object', function() {
var matcher = jasmineUnderTest.matchers.toBeInstanceOf();
@@ -164,14 +166,15 @@ describe('toBeInstanceOf', function() {
var result = matcher.compare(object, Object);
expect(result).toEqual({
pass: true,
message: 'Expected instance of null({ }) not to be an instance of Object'
message:
'Expected instance of null({ }) not to be an instance of Object'
});
});
});
describe('when expecting a user-defined class', function() {
// Base class
function Animal() { }
function Animal() {}
// Subclasses, defined using syntax that is as old as possible
function Dog() {
@@ -218,8 +221,10 @@ describe('toBeInstanceOf', function() {
var matcher = jasmineUnderTest.matchers.toBeInstanceOf();
expect(function() {
matcher.compare({}, 'Error');
}).toThrowError('<toBeInstanceOf> : Expected value is not a constructor function\n' +
'Usage: expect(value).toBeInstanceOf(<ConstructorFunction>)');
}).toThrowError(
'<toBeInstanceOf> : Expected value is not a constructor function\n' +
'Usage: expect(value).toBeInstanceOf(<ConstructorFunction>)'
);
});
it('raises an error if missing an expected value', function() {
@@ -228,7 +233,9 @@ describe('toBeInstanceOf', function() {
});
expect(function() {
matcher.compare({}, undefined);
}).toThrowError('<toBeInstanceOf> : Expected value is not a constructor function\n' +
'Usage: expect(value).toBeInstanceOf(<ConstructorFunction>)');
}).toThrowError(
'<toBeInstanceOf> : Expected value is not a constructor function\n' +
'Usage: expect(value).toBeInstanceOf(<ConstructorFunction>)'
);
});
});

View File

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

View File

@@ -1,5 +1,5 @@
describe("toBeLessThan", function() {
it("passes when actual < expected", function() {
describe('toBeLessThan', function() {
it('passes when actual < expected', function() {
var matcher = jasmineUnderTest.matchers.toBeLessThan(),
result;
@@ -7,7 +7,7 @@ describe("toBeLessThan", function() {
expect(result.pass).toBe(true);
});
it("fails when actual <= expected", function() {
it('fails when actual <= expected', function() {
var matcher = jasmineUnderTest.matchers.toBeLessThan(),
result;

View File

@@ -1,14 +1,14 @@
describe("toBeNaN", function() {
it("passes for NaN with a custom .not fail", function() {
describe('toBeNaN', function() {
it('passes for NaN with a custom .not fail', function() {
var matcher = jasmineUnderTest.matchers.toBeNaN(),
result;
result = matcher.compare(Number.NaN);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected actual not to be NaN.");
expect(result.message).toEqual('Expected actual not to be NaN.');
});
it("fails for anything not a NaN", function() {
it('fails for anything not a NaN', function() {
var matcher = jasmineUnderTest.matchers.toBeNaN(),
result;
@@ -28,12 +28,12 @@ describe("toBeNaN", function() {
expect(result.pass).toBe(false);
});
it("has a custom message on failure", function() {
it('has a custom message on failure', function() {
var matcher = jasmineUnderTest.matchers.toBeNaN({
pp: jasmineUnderTest.makePrettyPrinter()
}),
result = matcher.compare(0);
expect(result.message()).toEqual("Expected 0 to be NaN.");
expect(result.message()).toEqual('Expected 0 to be NaN.');
});
});

View File

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

View File

@@ -1,5 +1,5 @@
describe("toBeNull", function() {
it("passes for null", function() {
describe('toBeNull', function() {
it('passes for null', function() {
var matcher = jasmineUnderTest.matchers.toBeNull(),
result;
@@ -7,7 +7,7 @@ describe("toBeNull", function() {
expect(result.pass).toBe(true);
});
it("fails for non-null", function() {
it('fails for non-null', function() {
var matcher = jasmineUnderTest.matchers.toBeNull(),
result;

View File

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

View File

@@ -1,5 +1,5 @@
describe("toBe", function() {
it("passes with no message when actual === expected", function() {
describe('toBe', function() {
it('passes with no message when actual === expected', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result;
@@ -8,29 +8,37 @@ describe("toBe", function() {
expect(result.pass).toBe(true);
});
it("passes with a custom message when expected is an array", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
it('passes with a custom message when expected is an array', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result,
array = [1];
result = matcher.compare(array, array);
expect(result.pass).toBe(true);
expect(result.message).toBe("Expected [ 1 ] not to be [ 1 ]. Tip: To check for deep equality, use .toEqual() instead of .toBe().")
expect(result.message).toBe(
'Expected [ 1 ] not to be [ 1 ]. Tip: To check for deep equality, use .toEqual() instead of .toBe().'
);
});
it("passes with a custom message when expected is an object", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
it('passes with a custom message when expected is an object', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result,
obj = {foo: "bar"};
obj = { foo: 'bar' };
result = matcher.compare(obj, obj);
expect(result.pass).toBe(true);
expect(result.message).toBe("Expected Object({ foo: 'bar' }) not to be Object({ foo: 'bar' }). Tip: To check for deep equality, use .toEqual() instead of .toBe().")
expect(result.message).toBe(
"Expected Object({ foo: 'bar' }) not to be Object({ foo: 'bar' }). Tip: To check for deep equality, use .toEqual() instead of .toBe()."
);
});
it("fails with no message when actual !== expected", function() {
it('fails with no message when actual !== expected', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil(),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result;
@@ -40,35 +48,47 @@ describe("toBe", function() {
expect(result.message).toBeUndefined();
});
it("fails with a custom message when expected is an array", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
it('fails with a custom message when expected is an array', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result;
result = matcher.compare([1], [1]);
expect(result.pass).toBe(false);
expect(result.message).toBe("Expected [ 1 ] to be [ 1 ]. Tip: To check for deep equality, use .toEqual() instead of .toBe().")
expect(result.message).toBe(
'Expected [ 1 ] to be [ 1 ]. Tip: To check for deep equality, use .toEqual() instead of .toBe().'
);
});
it("fails with a custom message when expected is an object", function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({pp: jasmineUnderTest.makePrettyPrinter()}),
it('fails with a custom message when expected is an object', function() {
var matchersUtil = new jasmineUnderTest.MatchersUtil({
pp: jasmineUnderTest.makePrettyPrinter()
}),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result;
result = matcher.compare({foo: "bar"}, {foo: "bar"});
result = matcher.compare({ foo: 'bar' }, { foo: 'bar' });
expect(result.pass).toBe(false);
expect(result.message).toBe("Expected Object({ foo: 'bar' }) to be Object({ foo: 'bar' }). Tip: To check for deep equality, use .toEqual() instead of .toBe().")
expect(result.message).toBe(
"Expected Object({ foo: 'bar' }) to be Object({ foo: 'bar' }). Tip: To check for deep equality, use .toEqual() instead of .toBe()."
);
});
it("works with custom object formatters when expected is an object", function() {
var formatter = function(x) { return '<' + x.foo + '>'; },
it('works with custom object formatters when expected is an object', function() {
var formatter = function(x) {
return '<' + x.foo + '>';
},
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]),
matchersUtil = new jasmineUnderTest.MatchersUtil({pp: prettyPrinter}),
matchersUtil = new jasmineUnderTest.MatchersUtil({ pp: prettyPrinter }),
matcher = jasmineUnderTest.matchers.toBe(matchersUtil),
result;
result = matcher.compare({foo: "bar"}, {foo: "bar"});
result = matcher.compare({ foo: 'bar' }, { foo: 'bar' });
expect(result.pass).toBe(false);
expect(result.message).toBe("Expected <bar> to be <bar>. Tip: To check for deep equality, use .toEqual() instead of .toBe().")
expect(result.message).toBe(
'Expected <bar> to be <bar>. Tip: To check for deep equality, use .toEqual() instead of .toBe().'
);
});
});

View File

@@ -1,5 +1,5 @@
describe("toBeTrue", function() {
it("passes for true", function() {
describe('toBeTrue', function() {
it('passes for true', function() {
var matcher = jasmineUnderTest.matchers.toBeTrue(),
result;
@@ -7,7 +7,7 @@ describe("toBeTrue", function() {
expect(result.pass).toBe(true);
});
it("fails for non-true", function() {
it('fails for non-true', function() {
var matcher = jasmineUnderTest.matchers.toBeTrue(),
result;

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