Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4be08b657 | ||
|
|
50ef882a1a | ||
|
|
c1cd5c6291 | ||
|
|
63ed2b3948 | ||
|
|
0183acc682 | ||
|
|
e15819c0dd | ||
|
|
f694194b2b | ||
|
|
94c00886a6 | ||
|
|
f5915d7963 | ||
|
|
15587f3ce3 | ||
|
|
3ecddc2555 | ||
|
|
6a7c0e6368 | ||
|
|
84daa0f5dc | ||
|
|
c6b3e947e9 |
@@ -4,6 +4,10 @@
|
||||
version: 2.1
|
||||
|
||||
executors:
|
||||
node24:
|
||||
docker:
|
||||
- image: cimg/node:24.0.0
|
||||
working_directory: ~/workspace
|
||||
node22:
|
||||
docker:
|
||||
- image: cimg/node:22.0.0
|
||||
@@ -100,6 +104,9 @@ workflows:
|
||||
|
||||
push:
|
||||
jobs:
|
||||
- build:
|
||||
executor: node24
|
||||
name: build_node_24
|
||||
- build:
|
||||
executor: node22
|
||||
name: build_node_22
|
||||
@@ -125,10 +132,10 @@ workflows:
|
||||
requires:
|
||||
- build_node_18
|
||||
- test_parallel:
|
||||
executor: node18
|
||||
name: test_parallel_node_18
|
||||
executor: node24
|
||||
name: test_parallel_node_24
|
||||
requires:
|
||||
- build_node_18
|
||||
- build_node_24
|
||||
- test_parallel:
|
||||
executor: node22
|
||||
name: test_parallel_node_22
|
||||
@@ -139,6 +146,11 @@ workflows:
|
||||
name: test_parallel_node_20
|
||||
requires:
|
||||
- build_node_20
|
||||
- test_parallel:
|
||||
executor: node18
|
||||
name: test_parallel_node_18
|
||||
requires:
|
||||
- build_node_18
|
||||
- test_browsers:
|
||||
requires:
|
||||
- build_node_18
|
||||
|
||||
@@ -29,7 +29,7 @@ Microsoft Edge) as well as Node.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|----------------------------|
|
||||
| Node | 18, 20, 22 |
|
||||
| Node | 18, 20, 22, 24 |
|
||||
| Safari | 15*, 16*, 17* |
|
||||
| Chrome | Evergreen |
|
||||
| Firefox | Evergreen, 102*, 115*, 128 |
|
||||
|
||||
@@ -2803,7 +2803,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
|
||||
this.track = function(context) {
|
||||
if (opts.cloneArgs) {
|
||||
context.args = j$.util.cloneArgs(context.args);
|
||||
context.args = opts.argsCloner(context.args);
|
||||
}
|
||||
calls.push(context);
|
||||
};
|
||||
@@ -2911,13 +2911,15 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Set this spy to do a shallow clone of arguments passed to each invocation.
|
||||
* Set this spy to do a clone of arguments passed to each invocation.
|
||||
* @name Spy#calls#saveArgumentsByValue
|
||||
* @since 2.5.0
|
||||
* @param {Function} [argsCloner] A function to use to clone the arguments. Defaults to a shallow cloning function.
|
||||
* @function
|
||||
*/
|
||||
this.saveArgumentsByValue = function() {
|
||||
this.saveArgumentsByValue = function(argsCloner = j$.util.cloneArgs) {
|
||||
opts.cloneArgs = true;
|
||||
opts.argsCloner = argsCloner;
|
||||
};
|
||||
|
||||
this.unverifiedCount = function() {
|
||||
@@ -3125,6 +3127,10 @@ getJasmineRequireObj().Clock = function() {
|
||||
* @function
|
||||
*/
|
||||
this.uninstall = function() {
|
||||
// Ensure auto ticking loop is aborted when clock is uninstalled
|
||||
if (tickMode.mode === 'auto') {
|
||||
tickMode = { mode: 'manual', counter: tickMode.counter + 1 };
|
||||
}
|
||||
delayedFunctionScheduler = null;
|
||||
mockDate.uninstall();
|
||||
replace(global, realTimingFunctions);
|
||||
@@ -3278,6 +3284,12 @@ callbacks to execute _before_ running the next one.
|
||||
//
|
||||
// @return {!Promise<undefined>}
|
||||
async function newMacrotask() {
|
||||
if (NODE_JS) {
|
||||
// setImmediate is generally faster than setTimeout in Node
|
||||
// https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#setimmediate-vs-settimeout
|
||||
return new Promise(resolve => void setImmediate(resolve));
|
||||
}
|
||||
|
||||
// MessageChannel ensures that setTimeout is not throttled to 4ms.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
|
||||
// https://stackblitz.com/edit/stackblitz-starters-qtlpcc
|
||||
@@ -4871,7 +4883,10 @@ getJasmineRequireObj().DiffBuilder = function(j$) {
|
||||
);
|
||||
|
||||
if (useCustom) {
|
||||
messages.push(wrapPrettyPrinted(actualCustom, expectedCustom, path));
|
||||
const prettyActual = actualCustom || this.prettyPrinter_(actual);
|
||||
const prettyExpected =
|
||||
expectedCustom || this.prettyPrinter_(expected);
|
||||
messages.push(wrapPrettyPrinted(prettyActual, prettyExpected, path));
|
||||
return false; // don't recurse further
|
||||
}
|
||||
|
||||
@@ -7748,7 +7763,11 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
} else if (value instanceof RegExp) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
if (value.name) {
|
||||
this.emitScalar(`Function '${value.name}'`);
|
||||
} else {
|
||||
this.emitScalar('Function');
|
||||
}
|
||||
} else if (j$.isDomNode(value)) {
|
||||
if (value.tagName) {
|
||||
this.emitDomElement(value);
|
||||
@@ -9664,7 +9683,7 @@ getJasmineRequireObj().Spy = function(j$) {
|
||||
"Spy '" +
|
||||
strategyArgs.name +
|
||||
"' received a call with arguments " +
|
||||
j$.basicPrettyPrinter_(Array.prototype.slice.call(args)) +
|
||||
matchersUtil.pp(Array.prototype.slice.call(args)) +
|
||||
' but all configured strategies specify other arguments.'
|
||||
);
|
||||
} else {
|
||||
@@ -11391,5 +11410,5 @@ getJasmineRequireObj().UserContext = function(j$) {
|
||||
};
|
||||
|
||||
getJasmineRequireObj().version = function() {
|
||||
return '5.7.0';
|
||||
return '5.8.0';
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "5.7.0",
|
||||
"version": "5.8.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
to automatically tick the clock asynchronously
|
||||
* Merges #2042 from @atscott and @stephenfarrar
|
||||
* Fixes #1725
|
||||
* Fixes #1932
|
||||
|
||||
* Expose [spec path](https://jasmine.github.io/api/5.7/Spec.html#getPath) as an
|
||||
array of names in addition to the existing concatenated name
|
||||
@@ -54,10 +53,9 @@ This version has been tested in the following environments.
|
||||
|
||||
\* Evergreen browser. Each version of Jasmine is tested against the latest
|
||||
version available at release time.<br>
|
||||
\** Environments that are past end of life are supported on a best-effort basis.
|
||||
They may be dropped in a future minor release of Jasmine if continued support
|
||||
becomes impractical.
|
||||
|
||||
\** 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.
|
||||
|
||||
------
|
||||
|
||||
|
||||
28
release_notes/5.7.1.md
Normal file
28
release_notes/5.7.1.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Jasmine Core 5.7.1 Release Notes
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Ensure that uninstalling the clock also stops auto tick
|
||||
* Merges #2057 from @atscott
|
||||
|
||||
## Supported environments
|
||||
|
||||
This version has been tested in the following environments.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|-------------------------|
|
||||
| Node | 18**, 20, 22 |
|
||||
| Safari | 15**, 16**, 17** |
|
||||
| Chrome | 136* |
|
||||
| Firefox | 102**, 115**, 128, 138* |
|
||||
| Edge | 135* |
|
||||
|
||||
\* 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)_
|
||||
44
release_notes/5.8.0.md
Normal file
44
release_notes/5.8.0.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Jasmine Core 5.8.0 Release Notes
|
||||
|
||||
## New Features
|
||||
|
||||
* Allow passing a function to `saveArgumentsByValue` to customize how arguments
|
||||
are saved
|
||||
* Merges [#2062](https://github.com/jasmine/jasmine/pull/2062) from @evanwaslh
|
||||
* Fixes [#1886](https://github.com/jasmine/jasmine/issues/1886)
|
||||
* Use custom object formatters in spy strategy mismatch errors
|
||||
* Include function names in pretty printer output
|
||||
* Improve performance of autoTick in Node
|
||||
* Merges [#2058](https://github.com/jasmine/jasmine/pull/2058) from @atscott
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* Fix diff building when only one side has a custom object formatter
|
||||
* Fixes [#2061](https://github.com/jasmine/jasmine/issues/2061)
|
||||
|
||||
## Documentation improvements
|
||||
|
||||
* Added Node 24 to supported environments
|
||||
|
||||
## Supported environments
|
||||
|
||||
This version has been tested in the following environments.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|-------------------------|
|
||||
| Node | 18**, 20, 22, 24 |
|
||||
| Safari | 15**, 16**, 17** |
|
||||
| Chrome | 137* |
|
||||
| Firefox | 102**, 115**, 128, 139* |
|
||||
| Edge | 137* |
|
||||
|
||||
\* 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)_
|
||||
@@ -134,6 +134,42 @@ describe('CallTracker', function() {
|
||||
expect(callTracker.mostRecent().args[1]).toEqual(arrayArg);
|
||||
});
|
||||
|
||||
it('allows object arguments to be deep cloned', function() {
|
||||
const callTracker = new jasmineUnderTest.CallTracker();
|
||||
callTracker.saveArgumentsByValue(args => JSON.parse(JSON.stringify(args)));
|
||||
|
||||
const objectArg = { foo: { bar: { baz: ['qux'] } } },
|
||||
arrayArg = ['foo', 'bar'];
|
||||
|
||||
callTracker.track({
|
||||
object: {},
|
||||
args: [objectArg, arrayArg, false, undefined, null, NaN, '', 0, 1.0]
|
||||
});
|
||||
|
||||
objectArg.foo.bar.baz.push('quux');
|
||||
|
||||
expect(callTracker.mostRecent().args[0]).not.toBe(objectArg);
|
||||
expect(callTracker.mostRecent().args[0]).not.toEqual(objectArg);
|
||||
expect(callTracker.mostRecent().args[0]).toEqual({
|
||||
foo: { bar: { baz: ['qux'] } }
|
||||
});
|
||||
expect(callTracker.mostRecent().args[1]).not.toBe(arrayArg);
|
||||
expect(callTracker.mostRecent().args[1]).toEqual(arrayArg);
|
||||
});
|
||||
|
||||
it('can take any function to transform arguments when saving by value', function() {
|
||||
const callTracker = new jasmineUnderTest.CallTracker();
|
||||
callTracker.saveArgumentsByValue(JSON.stringify);
|
||||
|
||||
const objectArg = { foo: { bar: { baz: ['qux'] } } },
|
||||
arrayArg = ['foo', 'bar'],
|
||||
args = [objectArg, arrayArg, false, undefined, null, NaN, '', 0, 1.0];
|
||||
|
||||
callTracker.track({ object: {}, args });
|
||||
|
||||
expect(callTracker.mostRecent().args).toEqual(JSON.stringify(args));
|
||||
});
|
||||
|
||||
it('saves primitive arguments by value', function() {
|
||||
const callTracker = new jasmineUnderTest.CallTracker(),
|
||||
args = [undefined, null, false, '', /\s/, 0, 1.2, NaN];
|
||||
|
||||
@@ -699,22 +699,39 @@ describe('Clock (acceptance)', function() {
|
||||
tick: function() {},
|
||||
uninstall: function() {}
|
||||
};
|
||||
// window setTimeout to window to make firefox happy
|
||||
const _setTimeout =
|
||||
typeof window !== 'undefined' ? setTimeout.bind(window) : setTimeout;
|
||||
// passing a fake global allows us to preserve the real timing functions for use in tests
|
||||
const _global = { setTimeout: _setTimeout, setInterval: setInterval };
|
||||
clock = new jasmineUnderTest.Clock(
|
||||
// We use the real window for global or firefox is displeased when we try to call a real setTimeout on an object "that doesn't implement window".
|
||||
typeof window !== 'undefined' ? window : { setTimeout: setTimeout },
|
||||
_global,
|
||||
function() {
|
||||
return delayedFunctionScheduler;
|
||||
},
|
||||
mockDate
|
||||
);
|
||||
clock.install();
|
||||
clock.autoTick();
|
||||
clock.install().autoTick();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
clock.uninstall();
|
||||
});
|
||||
|
||||
it('flushes microtask queue between macrotasks', async () => {
|
||||
const log = [];
|
||||
await new Promise(r => clock.setTimeout(r, 10)).then(() => {
|
||||
log.push(1);
|
||||
Promise.resolve().then(() => log.push(2));
|
||||
Promise.resolve().then(() => log.push(3));
|
||||
});
|
||||
await new Promise(r => clock.setTimeout(r, 10)).then(() => {
|
||||
log.push(4);
|
||||
Promise.resolve().then(() => log.push(5));
|
||||
});
|
||||
expect(log).toEqual([1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('can run setTimeouts/setIntervals asynchronously', function() {
|
||||
const recurring = jasmine.createSpy('recurring'),
|
||||
fn1 = jasmine.createSpy('fn1'),
|
||||
@@ -776,6 +793,26 @@ describe('Clock (acceptance)', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('aborts auto ticking when uninstalled, even if installed again synchonrously', async () => {
|
||||
clock.uninstall();
|
||||
clock.install();
|
||||
|
||||
let resolved = false;
|
||||
const promise = new Promise(resolve => {
|
||||
clock.setTimeout(resolve, 1);
|
||||
}).then(() => {
|
||||
resolved = true;
|
||||
});
|
||||
|
||||
// wait some real time and verify that the clock did not flush the timer above automatically
|
||||
await new Promise(resolve => setTimeout(resolve, 2));
|
||||
expect(resolved).toBe(false);
|
||||
|
||||
// enabling auto tick again will flush the timer
|
||||
clock.autoTick();
|
||||
await expectAsync(promise).toBeResolved();
|
||||
});
|
||||
|
||||
it('speeds up the execution of the timers in all browsers', async () => {
|
||||
const startTimeMs = performance.now() / 1000;
|
||||
await new Promise(resolve => clock.setTimeout(resolve, 5000));
|
||||
|
||||
@@ -164,7 +164,7 @@ describe('PrettyPrinter', function() {
|
||||
"Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })"
|
||||
);
|
||||
expect(pp({ foo: function() {}, bar: [1, 2, 3] })).toEqual(
|
||||
'Object({ foo: Function, bar: [ 1, 2, 3 ] })'
|
||||
"Object({ foo: Function 'foo', bar: [ 1, 2, 3 ] })"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -450,7 +450,7 @@ describe('PrettyPrinter', function() {
|
||||
};
|
||||
|
||||
expect(pp(objFromOtherContext)).toEqual(
|
||||
"Object({ foo: 'bar', toString: Function })"
|
||||
"Object({ foo: 'bar', toString: Function 'toString' })"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -477,6 +477,17 @@ describe('PrettyPrinter', function() {
|
||||
expect(pp(a)).toEqual('<anonymous>({ })');
|
||||
});
|
||||
|
||||
it('stringifies functions with names', function() {
|
||||
const pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(foo)).toEqual("Function 'foo'");
|
||||
function foo() {}
|
||||
});
|
||||
|
||||
it('stringifies functions without names', function() {
|
||||
const pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(function() {})).toEqual('Function');
|
||||
});
|
||||
|
||||
it('should handle objects with null prototype', function() {
|
||||
const pp = jasmineUnderTest.makePrettyPrinter();
|
||||
const obj = Object.create(null);
|
||||
|
||||
@@ -3855,6 +3855,35 @@ describe('Env integration', function() {
|
||||
expect(failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('uses custom object formatters in spy strategy argument mismatch errors', async function() {
|
||||
env.it('a spec', function() {
|
||||
env.addCustomObjectFormatter(function(value) {
|
||||
if (typeof value === 'string') {
|
||||
return 'custom:' + value;
|
||||
}
|
||||
});
|
||||
const spy = env
|
||||
.createSpy('foo')
|
||||
.withArgs('x')
|
||||
.and.returnValue('');
|
||||
spy('y');
|
||||
});
|
||||
|
||||
let failedExpectations;
|
||||
env.addReporter({
|
||||
specDone: r => (failedExpectations = r.failedExpectations)
|
||||
});
|
||||
|
||||
await env.execute();
|
||||
expect(failedExpectations).toEqual([
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringContaining(
|
||||
'received a call with arguments [ custom:y ]'
|
||||
)
|
||||
})
|
||||
]);
|
||||
});
|
||||
|
||||
describe('#spyOnGlobalErrorsAsync', function() {
|
||||
const leftInstalledMessage =
|
||||
'Global error spy was not uninstalled. ' +
|
||||
|
||||
@@ -161,6 +161,63 @@ describe('DiffBuilder', function() {
|
||||
expect(diffBuilder.getMessage()).toEqual(expectedMsg);
|
||||
});
|
||||
|
||||
it('handles cases where only the expected has a custom object formatter', function() {
|
||||
const formatter = function(x) {
|
||||
if (typeof x === 'number') {
|
||||
return '[number:' + x + ']';
|
||||
}
|
||||
};
|
||||
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder({
|
||||
prettyPrinter: prettyPrinter
|
||||
});
|
||||
|
||||
diffBuilder.setRoots('five', 4);
|
||||
diffBuilder.recordMismatch();
|
||||
|
||||
expect(diffBuilder.getMessage()).toEqual(
|
||||
"Expected 'five' to equal [number:4]."
|
||||
);
|
||||
});
|
||||
|
||||
it('handles cases where only the actual has a custom object formatter', function() {
|
||||
const formatter = function(x) {
|
||||
if (typeof x === 'number') {
|
||||
return '[number:' + x + ']';
|
||||
}
|
||||
};
|
||||
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder({
|
||||
prettyPrinter: prettyPrinter
|
||||
});
|
||||
|
||||
diffBuilder.setRoots(5, 'four');
|
||||
diffBuilder.recordMismatch();
|
||||
|
||||
expect(diffBuilder.getMessage()).toEqual(
|
||||
"Expected [number:5] to equal 'four'."
|
||||
);
|
||||
});
|
||||
|
||||
it('handles complex cases where only one side has a custom object formatter', function() {
|
||||
const formatter = function(x) {
|
||||
if (typeof x === 'number') {
|
||||
return '[number:' + x + ']';
|
||||
}
|
||||
};
|
||||
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder({
|
||||
prettyPrinter: prettyPrinter
|
||||
});
|
||||
|
||||
diffBuilder.setRoots(5, { foo: 'bar', fnord: { graults: ['wombat'] } });
|
||||
diffBuilder.recordMismatch();
|
||||
|
||||
expect(diffBuilder.getMessage()).toEqual(
|
||||
"Expected [number:5] to equal Object({ foo: 'bar', fnord: Object({ graults: [ 'wombat' ] }) })."
|
||||
);
|
||||
});
|
||||
|
||||
it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ at the root', function() {
|
||||
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([]),
|
||||
diffBuilder = new jasmineUnderTest.DiffBuilder({
|
||||
|
||||
@@ -458,9 +458,9 @@ describe('toEqual', function() {
|
||||
});
|
||||
|
||||
it('reports mismatches between Functions', function() {
|
||||
const actual = { x: function() {} },
|
||||
expected = { x: function() {} },
|
||||
message = 'Expected $.x = Function to equal Function.';
|
||||
const actual = { x: function() {} };
|
||||
const expected = { x: function() {} };
|
||||
const message = "Expected $.x = Function 'x' to equal Function 'x'.";
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
|
||||
this.track = function(context) {
|
||||
if (opts.cloneArgs) {
|
||||
context.args = j$.util.cloneArgs(context.args);
|
||||
context.args = opts.argsCloner(context.args);
|
||||
}
|
||||
calls.push(context);
|
||||
};
|
||||
@@ -117,13 +117,15 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Set this spy to do a shallow clone of arguments passed to each invocation.
|
||||
* Set this spy to do a clone of arguments passed to each invocation.
|
||||
* @name Spy#calls#saveArgumentsByValue
|
||||
* @since 2.5.0
|
||||
* @param {Function} [argsCloner] A function to use to clone the arguments. Defaults to a shallow cloning function.
|
||||
* @function
|
||||
*/
|
||||
this.saveArgumentsByValue = function() {
|
||||
this.saveArgumentsByValue = function(argsCloner = j$.util.cloneArgs) {
|
||||
opts.cloneArgs = true;
|
||||
opts.argsCloner = argsCloner;
|
||||
};
|
||||
|
||||
this.unverifiedCount = function() {
|
||||
|
||||
@@ -69,6 +69,10 @@ getJasmineRequireObj().Clock = function() {
|
||||
* @function
|
||||
*/
|
||||
this.uninstall = function() {
|
||||
// Ensure auto ticking loop is aborted when clock is uninstalled
|
||||
if (tickMode.mode === 'auto') {
|
||||
tickMode = { mode: 'manual', counter: tickMode.counter + 1 };
|
||||
}
|
||||
delayedFunctionScheduler = null;
|
||||
mockDate.uninstall();
|
||||
replace(global, realTimingFunctions);
|
||||
@@ -222,6 +226,12 @@ callbacks to execute _before_ running the next one.
|
||||
//
|
||||
// @return {!Promise<undefined>}
|
||||
async function newMacrotask() {
|
||||
if (NODE_JS) {
|
||||
// setImmediate is generally faster than setTimeout in Node
|
||||
// https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#setimmediate-vs-settimeout
|
||||
return new Promise(resolve => void setImmediate(resolve));
|
||||
}
|
||||
|
||||
// MessageChannel ensures that setTimeout is not throttled to 4ms.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
|
||||
// https://stackblitz.com/edit/stackblitz-starters-qtlpcc
|
||||
|
||||
@@ -35,7 +35,11 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
} else if (value instanceof RegExp) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
if (value.name) {
|
||||
this.emitScalar(`Function '${value.name}'`);
|
||||
} else {
|
||||
this.emitScalar('Function');
|
||||
}
|
||||
} else if (j$.isDomNode(value)) {
|
||||
if (value.tagName) {
|
||||
this.emitDomElement(value);
|
||||
|
||||
@@ -161,7 +161,7 @@ getJasmineRequireObj().Spy = function(j$) {
|
||||
"Spy '" +
|
||||
strategyArgs.name +
|
||||
"' received a call with arguments " +
|
||||
j$.basicPrettyPrinter_(Array.prototype.slice.call(args)) +
|
||||
matchersUtil.pp(Array.prototype.slice.call(args)) +
|
||||
' but all configured strategies specify other arguments.'
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -37,7 +37,10 @@ getJasmineRequireObj().DiffBuilder = function(j$) {
|
||||
);
|
||||
|
||||
if (useCustom) {
|
||||
messages.push(wrapPrettyPrinted(actualCustom, expectedCustom, path));
|
||||
const prettyActual = actualCustom || this.prettyPrinter_(actual);
|
||||
const prettyExpected =
|
||||
expectedCustom || this.prettyPrinter_(expected);
|
||||
messages.push(wrapPrettyPrinted(prettyActual, prettyExpected, path));
|
||||
return false; // don't recurse further
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user