Merge branch 'main' into 7.0

This commit is contained in:
Steve Gravrock
2026-02-16 07:28:22 -08:00
16 changed files with 669 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
Copyright (c) 2008-2019 Pivotal Labs
Copyright (c) 2008-2025 The Jasmine developers
Copyright (c) 2008-2026 The Jasmine developers
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -60,5 +60,5 @@ To find out what environments work with a particular Jasmine release, see the [r
* Sheel Choksi
Copyright (c) 2008-2019 Pivotal Labs<br>
Copyright (c) 2008-2025 The Jasmine developers<br>
Copyright (c) 2008-2026 The Jasmine developers<br>
This software is licensed under the [MIT License](https://github.com/jasmine/jasmine/blob/main/LICENSE).

View File

@@ -44,6 +44,9 @@ const getJasmineRequireObj = (function() {
return jasmineRequire;
}
const loadedAsBrowserEsm =
globalThis.document && !globalThis.document.currentScript;
getJasmineRequire().core = function(jRequire) {
const private$ = {};
const j$ = {};
@@ -136,8 +139,7 @@ const getJasmineRequireObj = (function() {
private$
);
private$.loadedAsBrowserEsm =
globalThis.document && !globalThis.document.currentScript;
private$.loadedAsBrowserEsm = loadedAsBrowserEsm;
return { jasmine: j$, private: private$ };
};
@@ -218,7 +220,7 @@ getJasmineRequireObj().base = function(j$, private$, jasmineGlobal) {
* Maximum number of characters to display when pretty printing objects.
* Characters past this number will be ellipised.
* @name jasmine.MAX_PRETTY_PRINT_CHARS
* @default 100
* @default 1000
* @since 2.9.0
*/
j$.MAX_PRETTY_PRINT_CHARS = 1000;
@@ -3836,7 +3838,8 @@ getJasmineRequireObj().ExceptionFormatter = function(j$, private$) {
'lineNumber',
'column',
'description',
'jasmineMessage'
'jasmineMessage',
'errors'
];
function ExceptionFormatter(options) {
@@ -3902,6 +3905,19 @@ getJasmineRequireObj().ExceptionFormatter = function(j$, private$) {
lines = lines.concat(substack);
}
if (Array.isArray(error.errors)) {
for (let i = 0; i < error.errors.length; i++) {
if (error.errors[i] instanceof Error) {
lines.push('');
const substack = this.stack_(error.errors[i], {
messageHandling: 'require'
});
substack[0] = 'Error ' + (i + 1) + ': ' + substack[0];
lines = lines.concat(substack.map(x => ' ' + x));
}
}
}
return lines;
};
@@ -8792,7 +8808,6 @@ getJasmineRequireObj().reporterEvents = function(j$, private$) {
* {@link ReporterCapabilities} will apply.
* @name Reporter#reporterCapabilities
* @type ReporterCapabilities | undefined
* @optional
* @since 5.0
*/
/**
@@ -8859,7 +8874,6 @@ getJasmineRequireObj().reporterEvents = function(j$, private$) {
/**
* `specStarted` is invoked when an `it` starts to run (including associated `beforeEach` functions)
* @function
* @optional
* @name Reporter#specStarted
* @param {SpecStartedEvent} result Information about the individual {@link it} being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
@@ -8906,6 +8920,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of the group
* @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
*/
@@ -8921,6 +8936,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of the group
* @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
*/
@@ -8937,6 +8953,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of the group
* @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
*/
@@ -8955,6 +8972,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of what this spec is checking
* @param {implementationCallback} [testFunction] Function that contains the code of your test. If not provided the test will be `pending`.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.
@@ -8972,6 +8990,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of what this spec is checking.
* @param {implementationCallback} [testFunction] Function that contains the code of your test. Will not be executed.
*/
@@ -8987,6 +9006,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of what this spec is checking.
* @param {implementationCallback} testFunction Function that contains the code of your test.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.
@@ -9002,6 +9022,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to setup your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeEach.
* @see async
@@ -9016,6 +9037,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to teardown your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterEach.
* @see async
@@ -9032,6 +9054,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to setup your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeAll.
* @see async
@@ -9048,6 +9071,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to teardown your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterAll.
* @see async
@@ -9061,6 +9085,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name getSpecProperty
* @since 5.10.0
* @function
* @global
* @overwritable
* @param {String} key The name of the property
* @returns {*} The value of the property
*/
@@ -9073,6 +9099,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name setSpecProperty
* @since 3.6.0
* @function
* @global
* @overwritable
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
@@ -9085,6 +9113,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name setSuiteProperty
* @since 3.6.0
* @function
* @global
* @overwritable
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
@@ -9098,6 +9128,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {matchers}
*/
@@ -9114,6 +9145,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 3.3.0
* @function
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {async-matchers}
* @example
@@ -9140,8 +9172,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name throwUnlessAsync
* @since 5.1.0
* @function
* @param actual
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {matchers}
*/
@@ -9164,8 +9196,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name throwUnless
* @since 5.1.0
* @function
* @param actual
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {matchers}
*/
@@ -9179,6 +9211,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.0.0
* @function
* @global
* @overwritable
* @param {String} [message] - Reason the spec is pending.
*/
pending: function() {
@@ -9191,6 +9224,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {String|Error} [error] - Reason for the failure.
*/
fail: function() {
@@ -9203,6 +9237,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {Object} obj - The object upon which to install the {@link Spy}.
* @param {String} methodName - The name of the method to replace with a {@link Spy}.
* @returns {Spy}
@@ -9217,6 +9252,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.6.0
* @function
* @global
* @overwritable
* @param {Object} obj - The object upon which to install the {@link Spy}
* @param {String} propertyName - The name of the property to replace with a {@link Spy}.
* @param {String} [accessType=get] - The access type (get|set) of the property to {@link Spy} on.
@@ -9232,6 +9268,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 3.2.1
* @function
* @global
* @overwritable
* @param {Object} obj - The object upon which to install the {@link Spy}s
* @param {boolean} includeNonEnumerable - Whether or not to add spies to non-enumerable properties
* @returns {Object} the spied object
@@ -12206,7 +12243,7 @@ getJasmineRequireObj().UserContext = function(j$, private$) {
};
getJasmineRequireObj().version = function() {
return '6.0.0-alpha.2';
return '6.0.1';
};
(function() {

View File

@@ -1,7 +1,7 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "6.0.0-alpha.2",
"version": "6.0.1",
"repository": {
"type": "git",
"url": "https://github.com/jasmine/jasmine.git"
@@ -46,10 +46,10 @@
"ejs": "^3.1.10",
"eslint": "^9.24.0",
"eslint-plugin-compat": "^6.0.2",
"glob": "^10.2.3",
"glob": "^13.0.0",
"globals": "^16.0.0",
"jasmine": "file:../jasmine-npm",
"jasmine-browser-runner": "github:jasmine/jasmine-browser-runner#4.0",
"jasmine-browser-runner": "github:jasmine/jasmine-browser-runner",
"jsdom": "^26.0.0",
"prettier": "1.17.1",
"sass": "^1.58.3"

44
release_notes/5.13.0.md Normal file
View File

@@ -0,0 +1,44 @@
# Jasmine Core 5.13.0 Release Notes
## Changes to supported environments
Safari 26 is now supported on a best-effort basis.
Due to the limited availability of Safari 18 and later on free CI services,
Safari support in future jasmine-core versions will be limited to:
* Best-effort support for the latest Safari version available on GitHub Actions,
which may change at any time.
* Best-effort support for Safari 16 and 17 for as long as it remains practical.
## New Features
* New `extraItStackFrames` and `extraDescribeStackFrames` config options to fix
the filename properties of reporter events in configurations that wrap
`it`/`describe`, such as zone.js. The `filename` properties of reporter events
are no longer deprecated.
* `jasmine.allOf` asymmetric equality tester
* Merges [#2087](https://github.com/jasmine/jasmine/issues/2083) from @jonahd-g
* Fixes [#2083](https://github.com/jasmine/jasmine/pull/2087)
## Supported environments
This version has been tested in the following environments.
| Environment | Supported versions |
|-------------|--------------------------------|
| Node | 18.20.5**, 20, 22, 24 |
| Safari** | 16, 17, 26.1 |
| Chrome | 142* |
| Firefox | 102**, 115**, 128**, 140, 145* |
| Edge | 142* |
\* Evergreen browser. Each version of Jasmine is tested against the latest
version available at release time.<br>
\** Supported on a best-effort basis. Support for these versions may be dropped
if it becomes impractical, and bugs affecting only these versions may not be
treated as release blockers.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

@@ -0,0 +1,74 @@
# Jasmine Core 6.0.0-beta.0 Release Notes
This is a pre-release, intended to offer a preview of upcoming changes and to
solicit feedback.
## A Note About Pre-Release Compatibility
There may be additional breaking changes in future 6.0 pre-releases or in the
final 6.0 release. That's allowed by the semver specification, but users are
sometimes unpleasantly surprised by it.
NPM's implementation of carat version ranges assumes that subsequent
pre-releases and final releases are fully compatible with earlier pre-releases.
If your package.json contains `"jasmine-core": "^6.0.0-beta.0`,
NPM might install any later 6.x version even though there is no guarantee of
compatibility. If that isn't ok, you should specify an exact pre-release version:
`"jasmine-core": "6.0.0-beta.0`.
## Breaking changes
* boot1.js no longer adds jsApiReporter to the env.
* HtmlReporterV2 initialization and boot1.js have been simplified. If you
maintain your own boot file, update it to match the boot1.js included in this
package.
## New features
* Statically exposed pretty printer as jasmine.pp().
## Bug fixes
* Fixed HtmlReporterV2 progress bar when running a subset of specs.
## Deprecations
* jsApiReporter is deprecated.
* Detect monkey patching and emit a deprecation warning.
## Documentation improvements
* Documented the set of possible spec statuses.
## Internal improvements
* Replaced isArray helper with native Array.isArray
## Supported environments
This version has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------------------|
| Node | 20, 22, 24 |
| Safari | 16**, 17**, 26.1** |
| Chrome | 142* |
| Firefox | 102**, 115**, 128**, 140, 145* |
| Edge | 142* |
\* Evergreen browser. Each version of Jasmine is tested against the latest
version available at release time.<br>
\** Supported on a best-effort basis. Support for these versions may be dropped
if it becomes impractical, and bugs affecting only these versions may not be
treated as release blockers.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

@@ -0,0 +1,47 @@
# Jasmine Core 6.0.0-beta.1 Release Notes
This is a pre-release, intended to offer a preview of upcoming changes and to
solicit feedback.
A corresponding release of the `jasmine` package is not planned because the
change in this release only affects browser users.
## A Note About Pre-Release Compatibility
There may be additional breaking changes in future 6.0 pre-releases or in the
final 6.0 release. That's allowed by the semver specification, but users are
sometimes unpleasantly surprised by it.
NPM's implementation of carat version ranges assumes that subsequent
pre-releases and final releases are fully compatible with earlier pre-releases.
If your package.json contains `"jasmine-core": "^6.0.0-beta.1`,
NPM might install any later 6.x version even though there is no guarantee of
compatibility. If that isn't ok, you should specify an exact pre-release version:
`"jasmine-core": "6.0.0-beta.1`.
## Bug Fixes
* Revert to using window.onload in boot1.js. This fixes top level await in
jasmine-browser-runner.
## Supported environments
This version has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------------------|
| Node | 20, 22, 24 |
| Safari** | 16, 17, 26.1 |
| Chrome | 143* |
| Firefox | 102**, 115**, 128**, 140, 145* |
| Edge | 142* |
\* Evergreen browser. Each version of Jasmine is tested against the latest
version available at release time.<br>
\** Supported on a best-effort basis. Support for these versions may be dropped
if it becomes impractical, and bugs affecting only these versions may not be
treated as release blockers.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

190
release_notes/6.0.0.md Normal file
View File

@@ -0,0 +1,190 @@
# Jasmine Core 6.0.0 Release Notes
## Summary
This is a major release that includes breaking changes as well as significant
new features. Many of the breaking changes and deprecations in this release are
intended to improve the stability of the Jasmine ecosystem by making the
distinction between public and private APIs more obvious, reducing exposure of
jasmine-core's internal state, removing ambiguities from the reporter API, and
warning about monkey patching.
6.x is intended to ba a relatively short-lived, transitional series. It is
compatible with the current versions of karma-jasmine and other legacy Angular
tools but emits deprecation warnings when used with them. 7.0 will drop
compatibility with those tools. If you use Karma in a non-Angular context,
consider migrating to a maintained alternative such as jasmine-browser-runner or
web-test-runner. If you use Angular, please direct any questions about support
for future versions of Jasmine to the Angular team.
Please see the [migration guide](https://jasmine.github.io/upgrade-guides/6.0)
for more information. If you use Jasmine via the `jasmine` package, please see
[its release notes](https://github.com/jasmine/jasmine-npm/blob/main/release_notes/6.0.0.md)
as well.
## Changes to supported environments
* Node 18 is no longer supported.
## Breaking changes
### General
* Private APIs have been removed from the `jasmine` namespace.
The purpose of this change is to reduce the risk of users inadvertently
depending on private APIs. Anything not covered by
[the documentation](https://jasmine.github.io/pages/docs_home.html) remains
private regardless of namespacing. Private APIs may be changed or removed in
any release. This change is being made in a major release as a courtesy to
users of libraries that depend on private APIs.
### Changes that affect spec writing
* Global error spies always receive a single argument. Previously, the browser
error event was passed as the second argument.
* If a spy is invoked via `.call(null, ...)` or `.apply(null, ...)`, the spy's
`this` argument will be `null`. Previously it was `globalThis`.
* Mock clock timing functions cannot be spied on. Previously this "worked" but
prevented the mock clock from uninstalling itself.
* The mock clock no longer supports the eval forms of `setTimeout` and
`setInterval`.
* Keys passed to `setSpecProperty`/`setSuiteProperty` must be strings. Values
must be both structured-cloneable and JSON-serializable.
### Changes that affect configuration
* HTML reporters cache configuration throughout each run. Configuration changes
made while specs are running will not affect reporter behavior.
* If an execution order is passed to `Env#execute`, it must not enter any suite
more than once.
* The argument passed to spec filters is a
[spec metadata](https://jasmine.github.io/api/6.0/Spec.html)
instance, not the internal spec object.
* The default value of the `forbidDuplicateNames` config option has been
changed to true.
### Changes that affect reporters
This release includes changes that are intended to streamline and clarify the
reporter interface, prevent sharing of mutable state, and prevent bugs involving
non-serializable objects. These changes should be compatible with most existing
reporters but could break reporters that manage their internal state in unusual
ways.
* Meaningless properties such as `status` and `failedExpectations` are omitted
from the events passed to [suiteStarted](https://jasmine.github.io/api/6.0/global.html#SuiteStartedEvent)
and [specStarted](https://jasmine.github.io/api/6.0/global.html#SpecStartedEvent).
* Reporter events are deep-cloned before being passed to each reporter. This
protects reporters against later mutation by jasmine-core or other reporters.
* The `expected` and `actual` properties of
[passed and failed expectations](https://jasmine.github.io/api/6.0/global.html#ExpectationResult)
have been removed.
* The [order](https://jasmine.github.io/api/6.0/global.html#Order)
property of the`jasmineStarted` and `jasmineDone` reporter events no longer
includes undocumented properties.
* boot1.js no longer adds `jsApiReporter` to the env.
### Changes that affect browser boot files
* The `createElement` and `createTextNode` options of the legacy `HtmlReporter`
are ignored. `HtmlReporter` now unconditionally uses `document.createElement`
and `document.createTextNode`.
### Changes to Node boot functions
* [boot](https://jasmine.github.io/api/6.0/module-jasmine-core.html#.boot)
defaults to creating a new core instance each time it's called. This restores
the pre-5.0 default behavior.
* [noGlobals](https://jasmine.github.io/api/6.0/module-jasmine-core.html#.noGlobals)
no longer takes a parameter. It always returns the same object when called
repeatedly.
## New features
* A new `HtmlReporterV2` with several improvements over the old `HtmlReporter`:
* Clicking a spec/suite link does exact filtering rather than a substring
match.
* The old dots are replaced with a progress bar. This improves usability with
large suites and fixes an accessibility problem.
* Details of failed specs are displayed as soon as each spec finishes.
* A Performance tab shows metrics and a list of the slowest specs.
* Initialization and wire-up in boot files are much simpler.
If you're using jasmine-browser-runner or copying boot1.js from the standalone
distribution, you'll automatically get the new reporter. If you maintain your
own boot files, you'll get the old reporter unless you update your boot files
to match the one that's in this package.
The new reporter produces `spec` query string parameters that are different
from those created by the old reporter. If you use other software that
interprets the `spec` parameter, such as karma-jasmine, you won't be able to
adopt `HtmlReporterV2` unlesss that other software is updated.
* Larger body font size in HTML reporters
* `globalThis` is used to determine the global object during initialization
This makes jasmine-core more tolerant of buggy bundlers or loaders that
cause `this` to be undefined in the global context.
* Experimental [`safariYieldStrategy: "time"`](https://jasmine.github.io/api/6.0/Configuration.html#safariYieldStrategy)
config option, which may make Jasmine run significantly faster in Safari and
similar browsers. So far, this option has not been tested on a wide variety of
workloads. Feedback is appreciated.
* Statically exposed pretty printer as `jasmine.pp()`.
## Deprecations
* Common monkey patching patterns are detected and result in a deprecation
warning. Code that overwrites anything provided by jasmine-core (other than
globals like `it`/`expect`/etc or configuration properties like
`jasmine.DEFAULT_TIMEOUT_INTERVAL`) may be broken by any jasmine-core release.
* Warn if jasmine-core is loaded as an ES module in a browser.
This is an untested and unsupported configuration that has been known to cause
problems.
* `HtmlReporter` and `HtmlSpecFilter` are deprecated in favor of `HtmlReporterV2`.
* `jsApiReporter` is deprecated.
## Documentation improvements
* Improved API reference documentation for APIs that are used from browser boot
files.
* Documented the set of possible spec statuses.
* Documented that globals are overwriteable.
## Internal improvements
* Encapsulated suite and spec result and status management.
* Adopted strict mode throughout the codebase.
* Decomposed `HtmlReporter` into components and converted to ES6 classes.
* Made global error handling more uniform between browsers and Node.
* Removed code to support browsers that don't have `MessageChannel`. Jasmine
hasn't run in any such browsers since 2.x.
* Replaced `isArray` helper with native `Array.isArray`.
## Supported environments
This version has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------------------|
| Node | 20, 22, 24 |
| Safari** | 16, 17, 26.2 |
| Chrome | 143* |
| Firefox | 102**, 115**, 128**, 140, 147* |
| Edge | 143* |
\* Evergreen browser. Each version of Jasmine is tested against the latest
version available at release time.<br>
\** Supported on a best-effort basis. Support for these versions may be dropped
if it becomes impractical, and bugs affecting only these versions may not be
treated as release blockers.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

29
release_notes/6.0.1.md Normal file
View File

@@ -0,0 +1,29 @@
# Jasmine Core 6.0.1 Release Notes
## Bug fixes
* Don't emit a deprecation warning when `jasmineRequire.core` is called from an
ES module
## Supported environments
This version has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------------------|
| Node | 20, 22, 24 |
| Safari** | 16, 17, 26.2 |
| Chrome | 143* |
| Firefox | 102**, 115**, 128**, 140, 147* |
| Edge | 143* |
\* Evergreen browser. Each version of Jasmine is tested against the latest
version available at release time.<br>
\** Supported on a best-effort basis. Support for these versions may be dropped
if it becomes impractical, and bugs affecting only these versions may not be
treated as release blockers.
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

@@ -352,5 +352,184 @@ describe('ExceptionFormatter', function() {
}).not.toThrowError();
});
});
describe('when the error has an errors array (AggregateError)', function() {
it('includes all aggregated errors in the stack trace', function() {
const subject = new privateUnderTest.ExceptionFormatter();
const error1 = (function fn1() {
return new Error('first error');
})();
const error2 = (function fn2() {
return new Error('second error');
})();
const aggregateError = (function fn3() {
return new Error('Multiple errors occurred');
})();
aggregateError.errors = [error1, error2];
const lines = subject.stack(aggregateError).split('\n');
// TODO: be consistent across environments about whether the message is
// included in the stack trace
if (lines[0] === 'Error: Multiple errors occurred') {
lines.shift();
}
// Exclude lines that vary from environment to environment
const filteredLines = lines.filter(
x =>
!x.includes('/jasmine.js:') &&
// Some Node 20 and 22 minors when running in parallel
!x.includes('process.processTicksAndRejections')
);
for (let i = 0; i < filteredLines.length; i++) {
jasmine.debugLog(`Line ${i} after filtering: ${filteredLines[i]}`);
}
// Inexact matching because stack frame formatting varies from runtime
// to runtime
const expectedPatterns = [
// Overall error
/fn3.*ExceptionFormatterSpec\.js/,
/ExceptionFormatterSpec\.js/,
/^$/,
// First nested error
/^ Error 1: Error: first error$/,
/^ .*fn1.*ExceptionFormatterSpec\.js/,
/^ .*ExceptionFormatterSpec\.js/,
/^$/,
// Second nested error
/^ .*Error 2: Error: second error$/,
/^ .*fn2.*ExceptionFormatterSpec\.js/,
/^ .*ExceptionFormatterSpec\.js/
];
expect(filteredLines).toEqual(
expectedPatterns.map(p => jasmine.stringMatching(p))
);
});
it('handles empty errors array', function() {
const subject = new privateUnderTest.ExceptionFormatter();
const aggregateError = new Error('No errors');
aggregateError.errors = [];
expect(function() {
subject.stack(aggregateError);
}).not.toThrowError();
});
it('handles nested AggregateError', function() {
const subject = new privateUnderTest.ExceptionFormatter();
const innerError1 = new Error('inner error 1');
const innerError2 = new Error('inner error 2');
const innerAggregate = new Error('Inner aggregate');
innerAggregate.errors = [innerError1, innerError2];
const outerError = new Error('outer error');
const outerAggregate = new Error('Outer aggregate');
outerAggregate.errors = [innerAggregate, outerError];
const lines = subject.stack(outerAggregate).split('\n');
const innerAggMsgIx = lines.findIndex(line =>
line.includes('Error 1: Error: Inner aggregate')
);
expect(innerAggMsgIx).toBeGreaterThan(-1);
const innerError1MsgIx = lines.findIndex(line =>
line.includes('Error 1: Error: inner error 1')
);
expect(innerError1MsgIx).toBeGreaterThan(innerAggMsgIx);
const innerError2MsgIx = lines.findIndex(line =>
line.includes('Error 2: Error: inner error 2')
);
expect(innerError2MsgIx).toBeGreaterThan(innerError1MsgIx);
const outerErrorMsgIx = lines.findIndex(line =>
line.includes('Error 2: Error: outer error')
);
expect(outerErrorMsgIx).toBeGreaterThan(innerError2MsgIx);
});
it('handles AggregateError containing error with cause', function() {
const subject = new privateUnderTest.ExceptionFormatter();
const rootCause = new Error('root cause');
const errorWithCause = new Error('error with cause', {
cause: rootCause
});
const aggregateError = new Error('Aggregate with cause chain');
aggregateError.errors = [errorWithCause];
const lines = subject.stack(aggregateError).split('\n');
const error1MsgIx = lines.findIndex(line =>
line.includes('Error 1: Error: error with cause')
);
expect(error1MsgIx).toBeGreaterThan(-1);
const causeMsgIx = lines.findIndex(line =>
line.includes('Caused by: Error: root cause')
);
expect(causeMsgIx).toBeGreaterThan(error1MsgIx);
});
it('skips non-Error items in errors array', function() {
const subject = new privateUnderTest.ExceptionFormatter();
const error1 = new Error('real error');
const aggregateError = new Error('Mixed array');
aggregateError.errors = [
error1,
'string error',
{ message: 'object error' },
null,
undefined,
42
];
const lines = subject.stack(aggregateError).split('\n');
const error1MsgIx = lines.findIndex(line =>
line.includes('Error 1: Error: real error')
);
expect(error1MsgIx).toBeGreaterThan(-1);
const hasStringError = lines.some(line =>
line.includes('string error')
);
expect(hasStringError).toBe(false);
const hasObjectError = lines.some(line =>
line.includes('object error')
);
expect(hasObjectError).toBe(false);
});
it('works with native AggregateError constructor', function() {
const subject = new privateUnderTest.ExceptionFormatter();
const error1 = new Error('first error');
const error2 = new Error('second error');
const aggregateError = new AggregateError(
[error1, error2],
'Multiple errors'
);
const lines = subject.stack(aggregateError).split('\n');
const error1MsgIx = lines.findIndex(line =>
line.includes('Error 1: Error: first error')
);
expect(error1MsgIx).toBeGreaterThan(-1);
const error2MsgIx = lines.findIndex(line =>
line.includes('Error 2: Error: second error')
);
expect(error2MsgIx).toBeGreaterThan(error1MsgIx);
});
});
});
});

View File

@@ -768,7 +768,16 @@ describe('matchersUtil', function() {
a2[0] = 1;
const diffBuilder = new privateUnderTest.DiffBuilder();
expect(matchersUtil.equals(a1, a2, diffBuilder)).toBe(false);
jasmine.debugLog('Diff: ' + diffBuilder.getMessage());
jasmine.debugLog(
'a1 keys: ' + jasmine.pp(privateUnderTest.MatchersUtil.keys(a1))
);
jasmine.debugLog(
'a2 keys: ' + jasmine.pp(privateUnderTest.MatchersUtil.keys(a2))
);
jasmine.debugLog('a1 length:' + a1.length);
jasmine.debugLog('a2 length:' + a2.length);
jasmine.debugLog('a1[0]: ' + a1[0]);
jasmine.debugLog('a2[0]: ' + a2[0]);
}
);

View File

@@ -11,7 +11,8 @@ getJasmineRequireObj().ExceptionFormatter = function(j$, private$) {
'lineNumber',
'column',
'description',
'jasmineMessage'
'jasmineMessage',
'errors'
];
function ExceptionFormatter(options) {
@@ -77,6 +78,19 @@ getJasmineRequireObj().ExceptionFormatter = function(j$, private$) {
lines = lines.concat(substack);
}
if (Array.isArray(error.errors)) {
for (let i = 0; i < error.errors.length; i++) {
if (error.errors[i] instanceof Error) {
lines.push('');
const substack = this.stack_(error.errors[i], {
messageHandling: 'require'
});
substack[0] = 'Error ' + (i + 1) + ': ' + substack[0];
lines = lines.concat(substack.map(x => ' ' + x));
}
}
}
return lines;
};

View File

@@ -22,7 +22,7 @@ getJasmineRequireObj().base = function(j$, private$, jasmineGlobal) {
* Maximum number of characters to display when pretty printing objects.
* Characters past this number will be ellipised.
* @name jasmine.MAX_PRETTY_PRINT_CHARS
* @default 100
* @default 1000
* @since 2.9.0
*/
j$.MAX_PRETTY_PRINT_CHARS = 1000;

View File

@@ -7,7 +7,6 @@ getJasmineRequireObj().reporterEvents = function(j$, private$) {
* {@link ReporterCapabilities} will apply.
* @name Reporter#reporterCapabilities
* @type ReporterCapabilities | undefined
* @optional
* @since 5.0
*/
/**
@@ -74,7 +73,6 @@ getJasmineRequireObj().reporterEvents = function(j$, private$) {
/**
* `specStarted` is invoked when an `it` starts to run (including associated `beforeEach` functions)
* @function
* @optional
* @name Reporter#specStarted
* @param {SpecStartedEvent} result Information about the individual {@link it} being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.

View File

@@ -19,6 +19,9 @@ const getJasmineRequireObj = (function() {
return jasmineRequire;
}
const loadedAsBrowserEsm =
globalThis.document && !globalThis.document.currentScript;
getJasmineRequire().core = function(jRequire) {
const private$ = {};
const j$ = {};
@@ -111,8 +114,7 @@ const getJasmineRequireObj = (function() {
private$
);
private$.loadedAsBrowserEsm =
globalThis.document && !globalThis.document.currentScript;
private$.loadedAsBrowserEsm = loadedAsBrowserEsm;
return { jasmine: j$, private: private$ };
};

View File

@@ -20,6 +20,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of the group
* @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
*/
@@ -35,6 +36,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of the group
* @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
*/
@@ -51,6 +53,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of the group
* @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
*/
@@ -69,6 +72,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of what this spec is checking
* @param {implementationCallback} [testFunction] Function that contains the code of your test. If not provided the test will be `pending`.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.
@@ -86,6 +90,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of what this spec is checking.
* @param {implementationCallback} [testFunction] Function that contains the code of your test. Will not be executed.
*/
@@ -101,6 +106,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {String} description Textual description of what this spec is checking.
* @param {implementationCallback} testFunction Function that contains the code of your test.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.
@@ -116,6 +122,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to setup your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeEach.
* @see async
@@ -130,6 +137,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to teardown your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterEach.
* @see async
@@ -146,6 +154,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to setup your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeAll.
* @see async
@@ -162,6 +171,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {implementationCallback} [function] Function that contains the code to teardown your specs.
* @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterAll.
* @see async
@@ -175,6 +185,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name getSpecProperty
* @since 5.10.0
* @function
* @global
* @overwritable
* @param {String} key The name of the property
* @returns {*} The value of the property
*/
@@ -187,6 +199,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name setSpecProperty
* @since 3.6.0
* @function
* @global
* @overwritable
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
@@ -199,6 +213,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name setSuiteProperty
* @since 3.6.0
* @function
* @global
* @overwritable
* @param {String} key The name of the property
* @param {*} value The value of the property
*/
@@ -212,6 +228,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {matchers}
*/
@@ -228,6 +245,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 3.3.0
* @function
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {async-matchers}
* @example
@@ -254,8 +272,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name throwUnlessAsync
* @since 5.1.0
* @function
* @param actual
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {matchers}
*/
@@ -278,8 +296,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @name throwUnless
* @since 5.1.0
* @function
* @param actual
* @global
* @overwritable
* @param {Object} actual - Actual computed value to test expectations against.
* @return {matchers}
*/
@@ -293,6 +311,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.0.0
* @function
* @global
* @overwritable
* @param {String} [message] - Reason the spec is pending.
*/
pending: function() {
@@ -305,6 +324,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.1.0
* @function
* @global
* @overwritable
* @param {String|Error} [error] - Reason for the failure.
*/
fail: function() {
@@ -317,6 +337,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 1.3.0
* @function
* @global
* @overwritable
* @param {Object} obj - The object upon which to install the {@link Spy}.
* @param {String} methodName - The name of the method to replace with a {@link Spy}.
* @returns {Spy}
@@ -331,6 +352,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 2.6.0
* @function
* @global
* @overwritable
* @param {Object} obj - The object upon which to install the {@link Spy}
* @param {String} propertyName - The name of the property to replace with a {@link Spy}.
* @param {String} [accessType=get] - The access type (get|set) of the property to {@link Spy} on.
@@ -346,6 +368,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @since 3.2.1
* @function
* @global
* @overwritable
* @param {Object} obj - The object upon which to install the {@link Spy}s
* @param {boolean} includeNonEnumerable - Whether or not to add spies to non-enumerable properties
* @returns {Object} the spied object