vitest-auto-spy 3.13.0 → 3.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -0
- package/README.md +19 -1
- package/dist/angular.js +63 -13
- package/dist/bun-angular.js +7 -7
- package/dist/bun.js +4 -4
- package/dist/{chunk-IKH4OTMV.js → chunk-C3IZLTSJ.js} +3 -3
- package/dist/{chunk-JV5XRAS4.js → chunk-CEVEKNJZ.js} +2 -2
- package/dist/{chunk-7YTPHYP7.js → chunk-PCP6A6PD.js} +1 -1
- package/dist/{chunk-R4EWAG7Y.js → chunk-WVW4XRL5.js} +1 -1
- package/dist/{chunk-3AWKPZCE.js → chunk-ZY7KPBJJ.js} +63 -13
- package/dist/console.js +1 -1
- package/dist/index.js +63 -13
- package/dist/nestjs.js +3 -3
- package/dist/node.cjs +63 -13
- package/dist/node.js +4 -4
- package/dist/react.js +4 -4
- package/dist/setup.js +2 -2
- package/dist/shared-state.js +3 -0
- package/dist/svelte.js +4 -4
- package/dist/vue.js +5 -5
- package/package.json +1 -1
- package/skills/vitest-auto-spy/SKILL.md +8 -0
package/AGENTS.md
CHANGED
|
@@ -358,6 +358,8 @@ users.getName.calledWith(1).mockReturnValue('Ada');
|
|
|
358
358
|
users.getName.mustBeCalledWith(1).mockReturnValue('Ada');
|
|
359
359
|
// asymmetric matchers work in both
|
|
360
360
|
users.save.calledWith(expect.objectContaining({ id: 1 })).mockReturnValue(true);
|
|
361
|
+
// re-registering the same arguments replaces the answer — matcher arguments included
|
|
362
|
+
users.save.calledWith(expect.objectContaining({ id: 1 })).mockReturnValue(false);
|
|
361
363
|
|
|
362
364
|
// promises
|
|
363
365
|
users.load.resolveWith({ id: 1 });
|
|
@@ -374,6 +376,13 @@ feed.items$.throwWith('FAKE ERROR');
|
|
|
374
376
|
const subject = feed.items$.returnSubject(); // ReplaySubject, for anything the helpers miss
|
|
375
377
|
```
|
|
376
378
|
|
|
379
|
+
An exact argument list is matched before the asymmetric configs, and those are tried in
|
|
380
|
+
registration order — a narrow config written first keeps its calls. Two matchers count as the same
|
|
381
|
+
argument when they accept the same values (same matcher class, sample and inversion), which is what
|
|
382
|
+
makes a second `calledWith(1, expect.anything())` an override rather than a second config sitting
|
|
383
|
+
behind the first. A hand-rolled `{ asymmetricMatch }` object is compared by identity instead: its
|
|
384
|
+
verdict is a closure, so only re-registering that same instance overrides.
|
|
385
|
+
|
|
377
386
|
`mock.settledResults` is native on Vitest and polyfilled on Bun / `node:test`, so it is identical on
|
|
378
387
|
all three. Entries are `{ type: 'fulfilled' | 'incomplete' | 'rejected', value }`.
|
|
379
388
|
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ identical API, with **RxJS** spies and **Angular / NestJS / React / Vue·Pinia /
|
|
|
16
16
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
17
17
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
18
18
|
[](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
|
|
19
|
-
[](#install)
|
|
20
20
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
21
21
|
[](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
|
|
22
22
|
[](./LICENSE)
|
|
@@ -1231,6 +1231,24 @@ Wanted: getName(1)
|
|
|
1231
1231
|
Actual: getName(2)
|
|
1232
1232
|
```
|
|
1233
1233
|
|
|
1234
|
+
### Matching order, and re-configuring the same arguments
|
|
1235
|
+
|
|
1236
|
+
An exact argument list is matched first; the asymmetric configs (`expect.any(Number)`,
|
|
1237
|
+
`expect.objectContaining({ … })`, …) are then tried in the order they were registered, so a narrow
|
|
1238
|
+
config placed before a wide one keeps its calls. Registering the **same** argument list again
|
|
1239
|
+
replaces the answer it gave before — matcher arguments included:
|
|
1240
|
+
|
|
1241
|
+
```ts
|
|
1242
|
+
myService.getName.calledWith(expect.anything()).mockReturnValue('first');
|
|
1243
|
+
myService.getName.calledWith(expect.anything()).mockReturnValue('second');
|
|
1244
|
+
expect(myService.getName(1)).toBe('second');
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
Each `expect.anything()` is a new object, so the two are compared by what they accept rather than by
|
|
1248
|
+
identity — same matcher class, same sample, same inversion. A hand-rolled `{ asymmetricMatch }`
|
|
1249
|
+
object is the exception: its verdict lives in a closure nothing can read, so two of them are always
|
|
1250
|
+
two configs and only the very same instance, re-registered, overrides.
|
|
1251
|
+
|
|
1234
1252
|
## Promise-returning methods
|
|
1235
1253
|
|
|
1236
1254
|
```ts
|
package/dist/angular.js
CHANGED
|
@@ -102,6 +102,9 @@ function serializeShape(value, context) {
|
|
|
102
102
|
if (value instanceof Date) {
|
|
103
103
|
return `new Date(${value.getTime()})`;
|
|
104
104
|
}
|
|
105
|
+
if (value instanceof RegExp) {
|
|
106
|
+
return String(value);
|
|
107
|
+
}
|
|
105
108
|
if (value instanceof Map) {
|
|
106
109
|
return serializeMap(value, context);
|
|
107
110
|
}
|
|
@@ -172,6 +175,22 @@ function isAsymmetricMatcher(value) {
|
|
|
172
175
|
function hasAsymmetricMatcher(args) {
|
|
173
176
|
return args.some(isAsymmetricMatcher);
|
|
174
177
|
}
|
|
178
|
+
var ASYMMETRIC_MATCHER_BRAND = /* @__PURE__ */ Symbol.for("jest.asymmetricMatcher");
|
|
179
|
+
function isSameMatcher(configArg, candidateArg) {
|
|
180
|
+
if (configArg === candidateArg) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
if (!isAsymmetricMatcher(candidateArg) || !isBrandedMatcher(configArg) || !isBrandedMatcher(candidateArg)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
if (Object.getPrototypeOf(configArg) !== Object.getPrototypeOf(candidateArg)) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
return serializeValue(configArg) === serializeValue(candidateArg);
|
|
190
|
+
}
|
|
191
|
+
function isBrandedMatcher(matcher) {
|
|
192
|
+
return matcher.$$typeof === ASYMMETRIC_MATCHER_BRAND;
|
|
193
|
+
}
|
|
175
194
|
var ArgsMap = class {
|
|
176
195
|
// Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
|
|
177
196
|
// plain own property, never walking or polluting the object prototype chain.
|
|
@@ -186,19 +205,7 @@ var ArgsMap = class {
|
|
|
186
205
|
#arities = /* @__PURE__ */ new Set();
|
|
187
206
|
set(key, value) {
|
|
188
207
|
if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
|
|
189
|
-
|
|
190
|
-
const described = [];
|
|
191
|
-
for (const arg of key) {
|
|
192
|
-
if (isAsymmetricMatcher(arg)) {
|
|
193
|
-
serialized.push(void 0);
|
|
194
|
-
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
195
|
-
} else {
|
|
196
|
-
const rendered = this.#serialize([arg]);
|
|
197
|
-
serialized.push(rendered);
|
|
198
|
-
described.push(rendered.slice(1, -1));
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
this.#matcherConfigs.push({ args: key, serialized, described, value });
|
|
208
|
+
this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
|
|
202
209
|
return;
|
|
203
210
|
}
|
|
204
211
|
if (Array.isArray(key)) {
|
|
@@ -228,6 +235,49 @@ var ArgsMap = class {
|
|
|
228
235
|
const asymmetric = this.#matcherConfigs.map((config) => `[${config.described.join(",")}]`);
|
|
229
236
|
return [...Object.keys(this.#map), ...asymmetric];
|
|
230
237
|
}
|
|
238
|
+
/** Render one asymmetric config once, at registration time. See {@link MatcherConfig}. */
|
|
239
|
+
#buildMatcherConfig(key, value) {
|
|
240
|
+
const serialized = [];
|
|
241
|
+
const described = [];
|
|
242
|
+
for (const arg of key) {
|
|
243
|
+
if (isAsymmetricMatcher(arg)) {
|
|
244
|
+
serialized.push(void 0);
|
|
245
|
+
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
246
|
+
} else {
|
|
247
|
+
const rendered = this.#serialize([arg]);
|
|
248
|
+
serialized.push(rendered);
|
|
249
|
+
described.push(rendered.slice(1, -1));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return { args: key, serialized, described, value };
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Register an asymmetric config, replacing an equivalent one in place.
|
|
256
|
+
*
|
|
257
|
+
* Re-registering args is how a test overrides an earlier answer, and on the exact map that falls
|
|
258
|
+
* out for free — the second `set` writes the same key. The matcher list has to do it by hand:
|
|
259
|
+
* lookup takes the first predicate that matches, so an appended duplicate would sit behind the
|
|
260
|
+
* config it was meant to replace and never be reached, and a `beforeEach` that reconfigures the
|
|
261
|
+
* same spy would grow the list on every test. Replacing in place also keeps the registration
|
|
262
|
+
* order that decides which of two *overlapping* configs wins.
|
|
263
|
+
*/
|
|
264
|
+
#setMatcherConfig(config) {
|
|
265
|
+
const index = this.#matcherConfigs.findIndex((existing) => this.#sameConfigArgs(existing, config));
|
|
266
|
+
if (index === -1) {
|
|
267
|
+
this.#matcherConfigs.push(config);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.#matcherConfigs[index] = config;
|
|
271
|
+
}
|
|
272
|
+
/** Whether two configs were registered for the same argument list, matcher positions included. */
|
|
273
|
+
#sameConfigArgs(existing, candidate) {
|
|
274
|
+
if (existing.args.length !== candidate.args.length) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
return existing.args.every(
|
|
278
|
+
(arg, index) => isAsymmetricMatcher(arg) ? isSameMatcher(arg, candidate.args[index]) : existing.serialized[index] === candidate.serialized[index]
|
|
279
|
+
);
|
|
280
|
+
}
|
|
231
281
|
// Keys are always argument arrays; `serializeValue` renders them to a stable,
|
|
232
282
|
// total string (single-quoted strings, bracketed arrays, distinct `undefined`
|
|
233
283
|
// / function / symbol / BigInt / Date renderings, circular-ref safe). Arrays of
|
package/dist/bun-angular.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import './chunk-Y4YG7UOK.js';
|
|
2
|
-
import { createSpyForToken } from './chunk-
|
|
2
|
+
import { createSpyForToken } from './chunk-CEVEKNJZ.js';
|
|
3
3
|
import './chunk-NQXXUJPS.js';
|
|
4
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
5
|
-
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-
|
|
6
|
-
import { createSpyFromClass } from './chunk-
|
|
7
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
8
|
-
import { withDocs, DOCS_LINKS, isAutoSpyLike } from './chunk-
|
|
9
|
-
export { createFunctionSpy, errorHandler } from './chunk-
|
|
4
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-C3IZLTSJ.js';
|
|
5
|
+
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
6
|
+
import { createSpyFromClass } from './chunk-PCP6A6PD.js';
|
|
7
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-PCP6A6PD.js';
|
|
8
|
+
import { withDocs, DOCS_LINKS, isAutoSpyLike } from './chunk-ZY7KPBJJ.js';
|
|
9
|
+
export { createFunctionSpy, errorHandler } from './chunk-ZY7KPBJJ.js';
|
|
10
10
|
import './chunk-J5O72UHX.js';
|
|
11
11
|
import '@angular/compiler';
|
|
12
12
|
import { NgModule, provideZonelessChangeDetection, Injector, runInInjectionContext, NO_ERRORS_SCHEMA, ApplicationRef, ɵSIGNAL as _SIGNAL } from '@angular/core';
|
package/dist/bun.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import './chunk-Y4YG7UOK.js';
|
|
2
2
|
import './chunk-NQXXUJPS.js';
|
|
3
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
4
|
-
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-
|
|
5
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
6
|
-
export { createFunctionSpy, errorHandler } from './chunk-
|
|
3
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-C3IZLTSJ.js';
|
|
4
|
+
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
5
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-PCP6A6PD.js';
|
|
6
|
+
export { createFunctionSpy, errorHandler } from './chunk-ZY7KPBJJ.js';
|
|
7
7
|
import './chunk-J5O72UHX.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { mockValueProp, mockReadonlyPropGetter } from './chunk-
|
|
2
|
-
import { createSpyFromClass, createProxyPropStore, describeStoredProp, dropStoredProp, storeDefinedProp, writeStoredAccessor, writeStoredValue, readStoredAccessor, NOT_STORED, DISPOSE, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-
|
|
3
|
-
import { defineHelper, withDocs, DOCS_LINKS, serializeValue, createFunctionSpy, DEEP_CHILDREN } from './chunk-
|
|
1
|
+
import { mockValueProp, mockReadonlyPropGetter } from './chunk-WVW4XRL5.js';
|
|
2
|
+
import { createSpyFromClass, createProxyPropStore, describeStoredProp, dropStoredProp, storeDefinedProp, writeStoredAccessor, writeStoredValue, readStoredAccessor, NOT_STORED, DISPOSE, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-PCP6A6PD.js';
|
|
3
|
+
import { defineHelper, withDocs, DOCS_LINKS, serializeValue, createFunctionSpy, DEEP_CHILDREN } from './chunk-ZY7KPBJJ.js';
|
|
4
4
|
import { getMockAdapter } from './shared-state.js';
|
|
5
5
|
export { describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, getPackageCopies, setEmissionTimeout } from './shared-state.js';
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createSpyFromClass, createAutoMock } from './chunk-
|
|
2
|
-
import { withDocs, DOCS_LINKS } from './chunk-
|
|
1
|
+
import { createSpyFromClass, createAutoMock } from './chunk-PCP6A6PD.js';
|
|
2
|
+
import { withDocs, DOCS_LINKS } from './chunk-ZY7KPBJJ.js';
|
|
3
3
|
|
|
4
4
|
// src/lib/track-injections.ts
|
|
5
5
|
function createSpyForToken(token) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runClearHook, runConfigReset, resolveUnstubbedGuard, withDocs, DOCS_LINKS, AUTO_SPY_MARK, createFunctionSpy, isMarkedMock, readDeepChildren, markAsMock } from './chunk-
|
|
1
|
+
import { runClearHook, runConfigReset, resolveUnstubbedGuard, withDocs, DOCS_LINKS, AUTO_SPY_MARK, createFunctionSpy, isMarkedMock, readDeepChildren, markAsMock } from './chunk-ZY7KPBJJ.js';
|
|
2
2
|
import { getMockAdapter, requireObservableSupport } from './shared-state.js';
|
|
3
3
|
|
|
4
4
|
// src/lib/dispose-symbol.ts
|
|
@@ -81,6 +81,9 @@ function serializeShape(value, context) {
|
|
|
81
81
|
if (value instanceof Date) {
|
|
82
82
|
return `new Date(${value.getTime()})`;
|
|
83
83
|
}
|
|
84
|
+
if (value instanceof RegExp) {
|
|
85
|
+
return String(value);
|
|
86
|
+
}
|
|
84
87
|
if (value instanceof Map) {
|
|
85
88
|
return serializeMap(value, context);
|
|
86
89
|
}
|
|
@@ -187,6 +190,22 @@ function isAsymmetricMatcher(value) {
|
|
|
187
190
|
function hasAsymmetricMatcher(args) {
|
|
188
191
|
return args.some(isAsymmetricMatcher);
|
|
189
192
|
}
|
|
193
|
+
var ASYMMETRIC_MATCHER_BRAND = /* @__PURE__ */ Symbol.for("jest.asymmetricMatcher");
|
|
194
|
+
function isSameMatcher(configArg, candidateArg) {
|
|
195
|
+
if (configArg === candidateArg) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
if (!isAsymmetricMatcher(candidateArg) || !isBrandedMatcher(configArg) || !isBrandedMatcher(candidateArg)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
if (Object.getPrototypeOf(configArg) !== Object.getPrototypeOf(candidateArg)) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
return serializeValue(configArg) === serializeValue(candidateArg);
|
|
205
|
+
}
|
|
206
|
+
function isBrandedMatcher(matcher) {
|
|
207
|
+
return matcher.$$typeof === ASYMMETRIC_MATCHER_BRAND;
|
|
208
|
+
}
|
|
190
209
|
var ArgsMap = class {
|
|
191
210
|
// Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
|
|
192
211
|
// plain own property, never walking or polluting the object prototype chain.
|
|
@@ -201,19 +220,7 @@ var ArgsMap = class {
|
|
|
201
220
|
#arities = /* @__PURE__ */ new Set();
|
|
202
221
|
set(key, value) {
|
|
203
222
|
if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
|
|
204
|
-
|
|
205
|
-
const described = [];
|
|
206
|
-
for (const arg of key) {
|
|
207
|
-
if (isAsymmetricMatcher(arg)) {
|
|
208
|
-
serialized.push(void 0);
|
|
209
|
-
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
210
|
-
} else {
|
|
211
|
-
const rendered = this.#serialize([arg]);
|
|
212
|
-
serialized.push(rendered);
|
|
213
|
-
described.push(rendered.slice(1, -1));
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
this.#matcherConfigs.push({ args: key, serialized, described, value });
|
|
223
|
+
this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
|
|
217
224
|
return;
|
|
218
225
|
}
|
|
219
226
|
if (Array.isArray(key)) {
|
|
@@ -243,6 +250,49 @@ var ArgsMap = class {
|
|
|
243
250
|
const asymmetric = this.#matcherConfigs.map((config) => `[${config.described.join(",")}]`);
|
|
244
251
|
return [...Object.keys(this.#map), ...asymmetric];
|
|
245
252
|
}
|
|
253
|
+
/** Render one asymmetric config once, at registration time. See {@link MatcherConfig}. */
|
|
254
|
+
#buildMatcherConfig(key, value) {
|
|
255
|
+
const serialized = [];
|
|
256
|
+
const described = [];
|
|
257
|
+
for (const arg of key) {
|
|
258
|
+
if (isAsymmetricMatcher(arg)) {
|
|
259
|
+
serialized.push(void 0);
|
|
260
|
+
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
261
|
+
} else {
|
|
262
|
+
const rendered = this.#serialize([arg]);
|
|
263
|
+
serialized.push(rendered);
|
|
264
|
+
described.push(rendered.slice(1, -1));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return { args: key, serialized, described, value };
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Register an asymmetric config, replacing an equivalent one in place.
|
|
271
|
+
*
|
|
272
|
+
* Re-registering args is how a test overrides an earlier answer, and on the exact map that falls
|
|
273
|
+
* out for free — the second `set` writes the same key. The matcher list has to do it by hand:
|
|
274
|
+
* lookup takes the first predicate that matches, so an appended duplicate would sit behind the
|
|
275
|
+
* config it was meant to replace and never be reached, and a `beforeEach` that reconfigures the
|
|
276
|
+
* same spy would grow the list on every test. Replacing in place also keeps the registration
|
|
277
|
+
* order that decides which of two *overlapping* configs wins.
|
|
278
|
+
*/
|
|
279
|
+
#setMatcherConfig(config) {
|
|
280
|
+
const index = this.#matcherConfigs.findIndex((existing) => this.#sameConfigArgs(existing, config));
|
|
281
|
+
if (index === -1) {
|
|
282
|
+
this.#matcherConfigs.push(config);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
this.#matcherConfigs[index] = config;
|
|
286
|
+
}
|
|
287
|
+
/** Whether two configs were registered for the same argument list, matcher positions included. */
|
|
288
|
+
#sameConfigArgs(existing, candidate) {
|
|
289
|
+
if (existing.args.length !== candidate.args.length) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
return existing.args.every(
|
|
293
|
+
(arg, index) => isAsymmetricMatcher(arg) ? isSameMatcher(arg, candidate.args[index]) : existing.serialized[index] === candidate.serialized[index]
|
|
294
|
+
);
|
|
295
|
+
}
|
|
246
296
|
// Keys are always argument arrays; `serializeValue` renders them to a stable,
|
|
247
297
|
// total string (single-quoted strings, bracketed arrays, distinct `undefined`
|
|
248
298
|
// / function / symbol / BigInt / Date renderings, circular-ref safe). Arrays of
|
package/dist/console.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
|
|
2
|
-
import { createFunctionSpy } from './chunk-
|
|
2
|
+
import { createFunctionSpy } from './chunk-ZY7KPBJJ.js';
|
|
3
3
|
import './chunk-J5O72UHX.js';
|
|
4
4
|
import { hasMockAdapter, registerMockAdapter, getMockAdapter } from './shared-state.js';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -164,6 +164,9 @@ function serializeShape(value, context) {
|
|
|
164
164
|
if (value instanceof Date) {
|
|
165
165
|
return `new Date(${value.getTime()})`;
|
|
166
166
|
}
|
|
167
|
+
if (value instanceof RegExp) {
|
|
168
|
+
return String(value);
|
|
169
|
+
}
|
|
167
170
|
if (value instanceof Map) {
|
|
168
171
|
return serializeMap(value, context);
|
|
169
172
|
}
|
|
@@ -234,6 +237,22 @@ function isAsymmetricMatcher(value) {
|
|
|
234
237
|
function hasAsymmetricMatcher(args) {
|
|
235
238
|
return args.some(isAsymmetricMatcher);
|
|
236
239
|
}
|
|
240
|
+
var ASYMMETRIC_MATCHER_BRAND = /* @__PURE__ */ Symbol.for("jest.asymmetricMatcher");
|
|
241
|
+
function isSameMatcher(configArg, candidateArg) {
|
|
242
|
+
if (configArg === candidateArg) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
if (!isAsymmetricMatcher(candidateArg) || !isBrandedMatcher(configArg) || !isBrandedMatcher(candidateArg)) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (Object.getPrototypeOf(configArg) !== Object.getPrototypeOf(candidateArg)) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
return serializeValue(configArg) === serializeValue(candidateArg);
|
|
252
|
+
}
|
|
253
|
+
function isBrandedMatcher(matcher) {
|
|
254
|
+
return matcher.$$typeof === ASYMMETRIC_MATCHER_BRAND;
|
|
255
|
+
}
|
|
237
256
|
var ArgsMap = class {
|
|
238
257
|
// Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
|
|
239
258
|
// plain own property, never walking or polluting the object prototype chain.
|
|
@@ -248,19 +267,7 @@ var ArgsMap = class {
|
|
|
248
267
|
#arities = /* @__PURE__ */ new Set();
|
|
249
268
|
set(key, value) {
|
|
250
269
|
if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
|
|
251
|
-
|
|
252
|
-
const described = [];
|
|
253
|
-
for (const arg of key) {
|
|
254
|
-
if (isAsymmetricMatcher(arg)) {
|
|
255
|
-
serialized.push(void 0);
|
|
256
|
-
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
257
|
-
} else {
|
|
258
|
-
const rendered = this.#serialize([arg]);
|
|
259
|
-
serialized.push(rendered);
|
|
260
|
-
described.push(rendered.slice(1, -1));
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
this.#matcherConfigs.push({ args: key, serialized, described, value });
|
|
270
|
+
this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
|
|
264
271
|
return;
|
|
265
272
|
}
|
|
266
273
|
if (Array.isArray(key)) {
|
|
@@ -290,6 +297,49 @@ var ArgsMap = class {
|
|
|
290
297
|
const asymmetric = this.#matcherConfigs.map((config) => `[${config.described.join(",")}]`);
|
|
291
298
|
return [...Object.keys(this.#map), ...asymmetric];
|
|
292
299
|
}
|
|
300
|
+
/** Render one asymmetric config once, at registration time. See {@link MatcherConfig}. */
|
|
301
|
+
#buildMatcherConfig(key, value) {
|
|
302
|
+
const serialized = [];
|
|
303
|
+
const described = [];
|
|
304
|
+
for (const arg of key) {
|
|
305
|
+
if (isAsymmetricMatcher(arg)) {
|
|
306
|
+
serialized.push(void 0);
|
|
307
|
+
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
308
|
+
} else {
|
|
309
|
+
const rendered = this.#serialize([arg]);
|
|
310
|
+
serialized.push(rendered);
|
|
311
|
+
described.push(rendered.slice(1, -1));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return { args: key, serialized, described, value };
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Register an asymmetric config, replacing an equivalent one in place.
|
|
318
|
+
*
|
|
319
|
+
* Re-registering args is how a test overrides an earlier answer, and on the exact map that falls
|
|
320
|
+
* out for free — the second `set` writes the same key. The matcher list has to do it by hand:
|
|
321
|
+
* lookup takes the first predicate that matches, so an appended duplicate would sit behind the
|
|
322
|
+
* config it was meant to replace and never be reached, and a `beforeEach` that reconfigures the
|
|
323
|
+
* same spy would grow the list on every test. Replacing in place also keeps the registration
|
|
324
|
+
* order that decides which of two *overlapping* configs wins.
|
|
325
|
+
*/
|
|
326
|
+
#setMatcherConfig(config) {
|
|
327
|
+
const index = this.#matcherConfigs.findIndex((existing) => this.#sameConfigArgs(existing, config));
|
|
328
|
+
if (index === -1) {
|
|
329
|
+
this.#matcherConfigs.push(config);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
this.#matcherConfigs[index] = config;
|
|
333
|
+
}
|
|
334
|
+
/** Whether two configs were registered for the same argument list, matcher positions included. */
|
|
335
|
+
#sameConfigArgs(existing, candidate) {
|
|
336
|
+
if (existing.args.length !== candidate.args.length) {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
return existing.args.every(
|
|
340
|
+
(arg, index) => isAsymmetricMatcher(arg) ? isSameMatcher(arg, candidate.args[index]) : existing.serialized[index] === candidate.serialized[index]
|
|
341
|
+
);
|
|
342
|
+
}
|
|
293
343
|
// Keys are always argument arrays; `serializeValue` renders them to a stable,
|
|
294
344
|
// total string (single-quoted strings, bracketed arrays, distinct `undefined`
|
|
295
345
|
// / function / symbol / BigInt / Date renderings, circular-ref safe). Arrays of
|
package/dist/nestjs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { trackInjections } from './chunk-
|
|
1
|
+
export { trackInjections } from './chunk-CEVEKNJZ.js';
|
|
2
2
|
import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
|
|
3
|
-
import { createSpyFromClass } from './chunk-
|
|
4
|
-
import './chunk-
|
|
3
|
+
import { createSpyFromClass } from './chunk-PCP6A6PD.js';
|
|
4
|
+
import './chunk-ZY7KPBJJ.js';
|
|
5
5
|
import './chunk-J5O72UHX.js';
|
|
6
6
|
import { registerMockAdapter } from './shared-state.js';
|
|
7
7
|
|
package/dist/node.cjs
CHANGED
|
@@ -322,6 +322,9 @@ function serializeShape(value, context) {
|
|
|
322
322
|
if (value instanceof Date) {
|
|
323
323
|
return `new Date(${value.getTime()})`;
|
|
324
324
|
}
|
|
325
|
+
if (value instanceof RegExp) {
|
|
326
|
+
return String(value);
|
|
327
|
+
}
|
|
325
328
|
if (value instanceof Map) {
|
|
326
329
|
return serializeMap(value, context);
|
|
327
330
|
}
|
|
@@ -392,6 +395,22 @@ function isAsymmetricMatcher(value) {
|
|
|
392
395
|
function hasAsymmetricMatcher(args) {
|
|
393
396
|
return args.some(isAsymmetricMatcher);
|
|
394
397
|
}
|
|
398
|
+
var ASYMMETRIC_MATCHER_BRAND = /* @__PURE__ */ Symbol.for("jest.asymmetricMatcher");
|
|
399
|
+
function isSameMatcher(configArg, candidateArg) {
|
|
400
|
+
if (configArg === candidateArg) {
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
if (!isAsymmetricMatcher(candidateArg) || !isBrandedMatcher(configArg) || !isBrandedMatcher(candidateArg)) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
if (Object.getPrototypeOf(configArg) !== Object.getPrototypeOf(candidateArg)) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
return serializeValue(configArg) === serializeValue(candidateArg);
|
|
410
|
+
}
|
|
411
|
+
function isBrandedMatcher(matcher) {
|
|
412
|
+
return matcher.$$typeof === ASYMMETRIC_MATCHER_BRAND;
|
|
413
|
+
}
|
|
395
414
|
var ArgsMap = class {
|
|
396
415
|
// Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
|
|
397
416
|
// plain own property, never walking or polluting the object prototype chain.
|
|
@@ -406,19 +425,7 @@ var ArgsMap = class {
|
|
|
406
425
|
#arities = /* @__PURE__ */ new Set();
|
|
407
426
|
set(key, value) {
|
|
408
427
|
if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
|
|
409
|
-
|
|
410
|
-
const described = [];
|
|
411
|
-
for (const arg of key) {
|
|
412
|
-
if (isAsymmetricMatcher(arg)) {
|
|
413
|
-
serialized.push(void 0);
|
|
414
|
-
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
415
|
-
} else {
|
|
416
|
-
const rendered = this.#serialize([arg]);
|
|
417
|
-
serialized.push(rendered);
|
|
418
|
-
described.push(rendered.slice(1, -1));
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
this.#matcherConfigs.push({ args: key, serialized, described, value });
|
|
428
|
+
this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
|
|
422
429
|
return;
|
|
423
430
|
}
|
|
424
431
|
if (Array.isArray(key)) {
|
|
@@ -448,6 +455,49 @@ var ArgsMap = class {
|
|
|
448
455
|
const asymmetric = this.#matcherConfigs.map((config) => `[${config.described.join(",")}]`);
|
|
449
456
|
return [...Object.keys(this.#map), ...asymmetric];
|
|
450
457
|
}
|
|
458
|
+
/** Render one asymmetric config once, at registration time. See {@link MatcherConfig}. */
|
|
459
|
+
#buildMatcherConfig(key, value) {
|
|
460
|
+
const serialized = [];
|
|
461
|
+
const described = [];
|
|
462
|
+
for (const arg of key) {
|
|
463
|
+
if (isAsymmetricMatcher(arg)) {
|
|
464
|
+
serialized.push(void 0);
|
|
465
|
+
described.push(arg.toAsymmetricMatcher?.() ?? String(arg));
|
|
466
|
+
} else {
|
|
467
|
+
const rendered = this.#serialize([arg]);
|
|
468
|
+
serialized.push(rendered);
|
|
469
|
+
described.push(rendered.slice(1, -1));
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
return { args: key, serialized, described, value };
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Register an asymmetric config, replacing an equivalent one in place.
|
|
476
|
+
*
|
|
477
|
+
* Re-registering args is how a test overrides an earlier answer, and on the exact map that falls
|
|
478
|
+
* out for free — the second `set` writes the same key. The matcher list has to do it by hand:
|
|
479
|
+
* lookup takes the first predicate that matches, so an appended duplicate would sit behind the
|
|
480
|
+
* config it was meant to replace and never be reached, and a `beforeEach` that reconfigures the
|
|
481
|
+
* same spy would grow the list on every test. Replacing in place also keeps the registration
|
|
482
|
+
* order that decides which of two *overlapping* configs wins.
|
|
483
|
+
*/
|
|
484
|
+
#setMatcherConfig(config) {
|
|
485
|
+
const index = this.#matcherConfigs.findIndex((existing) => this.#sameConfigArgs(existing, config));
|
|
486
|
+
if (index === -1) {
|
|
487
|
+
this.#matcherConfigs.push(config);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
this.#matcherConfigs[index] = config;
|
|
491
|
+
}
|
|
492
|
+
/** Whether two configs were registered for the same argument list, matcher positions included. */
|
|
493
|
+
#sameConfigArgs(existing, candidate) {
|
|
494
|
+
if (existing.args.length !== candidate.args.length) {
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
return existing.args.every(
|
|
498
|
+
(arg, index) => isAsymmetricMatcher(arg) ? isSameMatcher(arg, candidate.args[index]) : existing.serialized[index] === candidate.serialized[index]
|
|
499
|
+
);
|
|
500
|
+
}
|
|
451
501
|
// Keys are always argument arrays; `serializeValue` renders them to a stable,
|
|
452
502
|
// total string (single-quoted strings, bracketed arrays, distinct `undefined`
|
|
453
503
|
// / function / symbol / BigInt / Date renderings, circular-ref safe). Arrays of
|
package/dist/node.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRedefineMockAdapter } from './chunk-NQXXUJPS.js';
|
|
2
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
3
|
-
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-
|
|
4
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
5
|
-
export { createFunctionSpy, errorHandler } from './chunk-
|
|
2
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-C3IZLTSJ.js';
|
|
3
|
+
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
4
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-PCP6A6PD.js';
|
|
5
|
+
export { createFunctionSpy, errorHandler } from './chunk-ZY7KPBJJ.js';
|
|
6
6
|
import './chunk-J5O72UHX.js';
|
|
7
7
|
import { mock } from 'node:test';
|
|
8
8
|
import { registerMockAdapter, guardAccessorSpies } from './shared-state.js';
|
package/dist/react.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
|
|
2
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
3
|
-
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-
|
|
4
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
5
|
-
export { createFunctionSpy, errorHandler } from './chunk-
|
|
2
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-C3IZLTSJ.js';
|
|
3
|
+
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
4
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-PCP6A6PD.js';
|
|
5
|
+
export { createFunctionSpy, errorHandler } from './chunk-ZY7KPBJJ.js';
|
|
6
6
|
import './chunk-J5O72UHX.js';
|
|
7
7
|
import { registerMockAdapter } from './shared-state.js';
|
|
8
8
|
|
package/dist/setup.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
|
|
2
|
-
import { mockValueProp, countMockedProps, restoreMockedProps } from './chunk-
|
|
3
|
-
import { withDocs, DOCS_LINKS, setDefaultStrictMode } from './chunk-
|
|
2
|
+
import { mockValueProp, countMockedProps, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
3
|
+
import { withDocs, DOCS_LINKS, setDefaultStrictMode } from './chunk-ZY7KPBJJ.js';
|
|
4
4
|
import './chunk-J5O72UHX.js';
|
|
5
5
|
import { registerMockAdapter, describeDuplicateCopies } from './shared-state.js';
|
|
6
6
|
export { describeDuplicateCopies, getPackageCopies } from './shared-state.js';
|
package/dist/shared-state.js
CHANGED
|
@@ -18,6 +18,9 @@ function serializeShape(value, context) {
|
|
|
18
18
|
if (value instanceof Date) {
|
|
19
19
|
return `new Date(${value.getTime()})`;
|
|
20
20
|
}
|
|
21
|
+
if (value instanceof RegExp) {
|
|
22
|
+
return String(value);
|
|
23
|
+
}
|
|
21
24
|
if (value instanceof Map) {
|
|
22
25
|
return serializeMap(value, context);
|
|
23
26
|
}
|
package/dist/svelte.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
|
|
2
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
3
|
-
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-
|
|
4
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
5
|
-
export { createFunctionSpy, errorHandler } from './chunk-
|
|
2
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-C3IZLTSJ.js';
|
|
3
|
+
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
4
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-PCP6A6PD.js';
|
|
5
|
+
export { createFunctionSpy, errorHandler } from './chunk-ZY7KPBJJ.js';
|
|
6
6
|
import './chunk-J5O72UHX.js';
|
|
7
7
|
import { registerMockAdapter } from './shared-state.js';
|
|
8
8
|
|
package/dist/vue.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
|
|
2
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
3
|
-
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-
|
|
4
|
-
import { createSpyFromClass } from './chunk-
|
|
5
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
6
|
-
export { createFunctionSpy, errorHandler } from './chunk-
|
|
2
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-C3IZLTSJ.js';
|
|
3
|
+
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-WVW4XRL5.js';
|
|
4
|
+
import { createSpyFromClass } from './chunk-PCP6A6PD.js';
|
|
5
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-PCP6A6PD.js';
|
|
6
|
+
export { createFunctionSpy, errorHandler } from './chunk-ZY7KPBJJ.js';
|
|
7
7
|
import './chunk-J5O72UHX.js';
|
|
8
8
|
import { registerMockAdapter } from './shared-state.js';
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-auto-spy",
|
|
3
|
-
"version": "3.13.
|
|
3
|
+
"version": "3.13.1",
|
|
4
4
|
"description": "Auto-generate fully-typed test spies from a class — across Vitest, Bun and node:test, with Angular/NestJS/React/Vue/Svelte recipes. Drop-in replacement for jest-auto-spies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"auto-mock",
|
|
@@ -209,6 +209,14 @@ it('loads', async () => {
|
|
|
209
209
|
- **Never assert a resource with `expect(r.value()).toEqual(...)` alone** — an unresolved resource
|
|
210
210
|
still holds its _default_, so that passes while proving nothing. `toHaveResourceValue(v)` after
|
|
211
211
|
`registerResourceMatchers()` fails unless the resource actually resolved.
|
|
212
|
+
- **`calledWith` matches exact arguments first, then the matcher configs in registration order** —
|
|
213
|
+
so put the narrow `expect.any(Number)` before the wide `expect.anything()` when both can match.
|
|
214
|
+
Re-registering the same arguments replaces the previous answer, matcher arguments included: two
|
|
215
|
+
`calledWith(1, expect.anything())` lines are an override, not two configs.
|
|
216
|
+
- **On Bun (`bun:test`), an asymmetric matcher inside `calledWith` matches nothing** — Bun's
|
|
217
|
+
`expect.any()` / `expect.objectContaining()` are native objects carrying no `asymmetricMatch`, so
|
|
218
|
+
the config is kept as an ordinary argument and the call falls through to `undefined` instead of
|
|
219
|
+
failing. Dispatch on exact arguments there, or use `mockImplementation`.
|
|
212
220
|
- **Never put `captureArg()` in `calledWith`** — it matches every value, so it configures a return
|
|
213
221
|
for every call. It belongs in `toHaveBeenCalledWith`; the types enforce this.
|
|
214
222
|
- **Never `vi.mock('@angular/core')`** (or any relative path) under the Angular unit-test builder —
|