vitest-auto-spy 3.3.0 → 3.4.0
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.
Potentially problematic release.
This version of vitest-auto-spy might be problematic. Click here for more details.
- package/AGENTS.md +28 -0
- package/README.md +11 -0
- package/dist/setup.d.ts +76 -1
- package/dist/setup.js +90 -13
- package/package.json +1 -1
- package/skills/vitest-auto-spy/SKILL.md +1 -0
package/AGENTS.md
CHANGED
|
@@ -456,6 +456,34 @@ undo), `flushStrayRejections()` (takes what was captured and starts again from e
|
|
|
456
456
|
`countStrayRejections()`. The `no-floating-assertion` lint rule catches the commonest shape before
|
|
457
457
|
it ever runs (§16).
|
|
458
458
|
|
|
459
|
+
**The one that gets slower the longer the run goes on:** every `vi.fn()` and `vi.spyOn()` is added
|
|
460
|
+
to one `Set` inside `@vitest/spy`, because that is what `vi.clearAllMocks()` walks, and nothing takes
|
|
461
|
+
anything out of it again. With `isolate: false` the set is created once per worker and only grows:
|
|
462
|
+
`clearMocks: true` then walks every mock of every file already run **before every single test**, and
|
|
463
|
+
the worker holds all of them at once — their recorded arguments included, and through those whole
|
|
464
|
+
component trees.
|
|
465
|
+
|
|
466
|
+
```ts
|
|
467
|
+
setupAutoSpy({ pruneMockRegistry: true }); // keep only the mocks that outlive a file
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
The part to understand before turning it on is what must **not** be pruned. Dropping a mock from that
|
|
471
|
+
set means `clearMocks` can no longer see it, so its calls accumulate silently — harmless for a mock
|
|
472
|
+
that dies with its file, a bug for the module-level `vi.fn()` in a shared `*.mock.ts` that six spec
|
|
473
|
+
files import. The first file to import it creates it; drop it when that file ends and the file that
|
|
474
|
+
happens to run **second** fails on calls its predecessor made, which reads as flakiness because which
|
|
475
|
+
file is first is the runner's choice. So the split is drawn where it is observable: what is already in
|
|
476
|
+
the registry when a file's hooks start was created while the module graph was being evaluated and is
|
|
477
|
+
kept; everything added after that belongs to the file and goes when it ends. One case lands on the
|
|
478
|
+
wrong side — a module first loaded by a dynamic `import()` inside a test — and says so explicitly:
|
|
479
|
+
|
|
480
|
+
```ts
|
|
481
|
+
export const navigation = { setFocus: keepMockRegistered(vi.fn()) };
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
`trackMockRegistry()` installs the pair of hooks on its own, `pruneMockRegistry()` is the one-shot
|
|
485
|
+
sweep (it returns how many went) and `getMockRegistrySize()` reports what is left.
|
|
486
|
+
|
|
459
487
|
Two more switches, both about the environment rather than the spies:
|
|
460
488
|
|
|
461
489
|
```ts
|
package/README.md
CHANGED
|
@@ -1295,6 +1295,7 @@ single-purpose utility you can pick up independently — they all ride on the sa
|
|
|
1295
1295
|
| `installPerTest(install)` | `/setup` | Re-install a stub before every test of the block — a `describe`-level stub is restored away after the first |
|
|
1296
1296
|
| `setupAngularTestEnv(opts)` | `/angular` | Zone and zoneless spec files in one worker, switching platforms per file |
|
|
1297
1297
|
| `restoreTimerGlobals()` | `/setup` | Put back timer globals that uninstalling the fakes deleted rather than restored |
|
|
1298
|
+
| `trackMockRegistry()` / `keepMockRegistered(mock)` | `/setup` | Keep @vitest/spy's mock registry to the mocks that outlive a file; mark one the split would miss ([details](#test-run-hygiene)) |
|
|
1298
1299
|
| `errorHandler` | core | The `mustBeCalledWith` argument-mismatch reporter — swap it to customize failure output |
|
|
1299
1300
|
|
|
1300
1301
|
A taste of the DI pair — provide the spy, inject it back fully typed:
|
|
@@ -1426,6 +1427,15 @@ expensive to diagnose when it is missing. The first three are on by default:
|
|
|
1426
1427
|
migrated Angular monorepo — 1688 spec files, 11 587 tests, green, exit 0 — was hiding six defects
|
|
1427
1428
|
of exactly that shape, two of them assertions that were simply false and one a `TypeError` thrown
|
|
1428
1429
|
by production code.
|
|
1430
|
+
8. **The mock registry, which nothing empties.** Opt-in. Every `vi.fn()` and `vi.spyOn()` is added to
|
|
1431
|
+
one `Set` inside `@vitest/spy` so that `vi.clearAllMocks()` has something to walk, and no API takes
|
|
1432
|
+
anything out of it again. With `isolate: false` that set is created once per worker and only
|
|
1433
|
+
grows, so `clearMocks: true` walks every mock of every file already run before each test, and the
|
|
1434
|
+
worker holds all of them at once — with their recorded arguments, and through those whole
|
|
1435
|
+
component trees. Pruning it is easy to get wrong in one specific way: drop the module-level
|
|
1436
|
+
`vi.fn()` that six spec files import from a shared `*.mock.ts` and nothing clears it any more, so
|
|
1437
|
+
its calls accumulate and the file that happens to run second fails on calls its predecessor made.
|
|
1438
|
+
`pruneMockRegistry` keeps what a file inherited and drops only what it added.
|
|
1429
1439
|
|
|
1430
1440
|
| Option | Default | Notes |
|
|
1431
1441
|
| --------------------- | --------- | ----------------------------------------------------------------------------- |
|
|
@@ -1438,6 +1448,7 @@ expensive to diagnose when it is missing. The first three are on by default:
|
|
|
1438
1448
|
| `guardGlobals` | `'off'` | Report a test that redefines a global property as non-configurable |
|
|
1439
1449
|
| `globalFakeTimers` | `false` | Fake timers for every test **and between them** — Jest's `enableGlobally` |
|
|
1440
1450
|
| `restoreTimerGlobals` | `true` | Put back timer globals that uninstalling the fakes deleted |
|
|
1451
|
+
| `pruneMockRegistry` | `false` | Keep @vitest/spy's ever-growing mock registry to the mocks that outlive a file |
|
|
1441
1452
|
|
|
1442
1453
|
`restoreMocks` is off by default because it also drops `vi.spyOn` stubs a suite installed in
|
|
1443
1454
|
`beforeAll`; it is the knob to reach for when the run shares one environment across files.
|
package/dist/setup.d.ts
CHANGED
|
@@ -270,6 +270,18 @@ interface SetupAutoSpyOptions {
|
|
|
270
270
|
* installed on purpose. See {@link restoreTimerGlobals}.
|
|
271
271
|
*/
|
|
272
272
|
restoreTimerGlobals?: boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Keep `@vitest/spy`'s registry of every mock ever created down to the mocks that outlive a file.
|
|
275
|
+
* Default `false`, because it reaches into a set the runner does not expose.
|
|
276
|
+
*
|
|
277
|
+
* The registry exists so `vi.clearAllMocks()` has something to walk. With `isolate: false` it is
|
|
278
|
+
* created once per worker and only grows: `clearMocks: true` then walks every mock of every file
|
|
279
|
+
* already run before each test, and the heap holds all of them — with their recorded arguments,
|
|
280
|
+
* and through those whole component trees. Turning this on prunes what each file added once the
|
|
281
|
+
* file is over, and keeps what the file inherited. See {@link trackMockRegistry}, and
|
|
282
|
+
* {@link keepMockRegistered} for the one case the split gets wrong on its own.
|
|
283
|
+
*/
|
|
284
|
+
pruneMockRegistry?: boolean;
|
|
273
285
|
/**
|
|
274
286
|
* Clear the `vitest-auto-spy/console` spies after every test. Default `true`.
|
|
275
287
|
*
|
|
@@ -415,6 +427,69 @@ declare module 'vitest' {
|
|
|
415
427
|
*/
|
|
416
428
|
declare function registerFocusMatchers(): void;
|
|
417
429
|
|
|
430
|
+
/**
|
|
431
|
+
* Capture `@vitest/spy`'s mock registry, or return `undefined` if this runner does not expose one
|
|
432
|
+
* the probe can confirm.
|
|
433
|
+
*
|
|
434
|
+
* Called once per worker: a second call hands back the first result, including a failed one.
|
|
435
|
+
*
|
|
436
|
+
* The capture clears every mock's recorded calls as a side effect, because `vi.clearAllMocks()` is
|
|
437
|
+
* what makes the set iterate. That is why {@link trackMockRegistry} does it in `beforeAll`, where
|
|
438
|
+
* no test has recorded anything yet.
|
|
439
|
+
*/
|
|
440
|
+
declare function captureMockRegistry(): Set<unknown> | undefined;
|
|
441
|
+
/**
|
|
442
|
+
* Mark `mock` as one that outlives the file it was created in, so pruning never drops it.
|
|
443
|
+
*
|
|
444
|
+
* Needed only for a mock created inside a test or a hook and then shared with later files — a
|
|
445
|
+
* module loaded by a dynamic `import()` in a test, or a fixture cached in a module-level variable
|
|
446
|
+
* on first use. A `vi.fn()` at the top level of a module is kept without being told.
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```ts
|
|
450
|
+
* // fixtures/navigation.mock.ts — imported by six spec files
|
|
451
|
+
* export const navigation = { setFocus: keepMockRegistered(vi.fn()) };
|
|
452
|
+
* ```
|
|
453
|
+
*/
|
|
454
|
+
declare function keepMockRegistered<T>(mock: T): T;
|
|
455
|
+
/**
|
|
456
|
+
* Mark everything currently in the registry as long-lived.
|
|
457
|
+
*
|
|
458
|
+
* Run at the start of a file, this is the whole classification: what exists now was created while
|
|
459
|
+
* the modules were being evaluated, and everything added afterwards belongs to this file.
|
|
460
|
+
*/
|
|
461
|
+
declare function keepRegisteredMocks(): void;
|
|
462
|
+
/**
|
|
463
|
+
* Drop every mock that is not marked long-lived from the registry, and report how many went.
|
|
464
|
+
*
|
|
465
|
+
* Safe to call without a capture, and safe to call twice — the second call finds nothing to do.
|
|
466
|
+
*/
|
|
467
|
+
declare function pruneMockRegistry(): number;
|
|
468
|
+
/**
|
|
469
|
+
* Keep the registry to the mocks that outlive a file: capture it, mark what each file inherits, and
|
|
470
|
+
* prune what the file added once it is over.
|
|
471
|
+
*
|
|
472
|
+
* ```ts
|
|
473
|
+
* // vitest.setup.ts
|
|
474
|
+
* import { trackMockRegistry } from 'vitest-auto-spy/setup';
|
|
475
|
+
*
|
|
476
|
+
* trackMockRegistry();
|
|
477
|
+
* ```
|
|
478
|
+
*
|
|
479
|
+
* This is what `setupAutoSpy({ pruneMockRegistry: true })` installs; call it directly to have it
|
|
480
|
+
* without the rest.
|
|
481
|
+
*/
|
|
482
|
+
declare function trackMockRegistry(): void;
|
|
483
|
+
/** How many mocks the registry holds, or `undefined` if it was never captured. For diagnostics. */
|
|
484
|
+
declare function getMockRegistrySize(): number | undefined;
|
|
485
|
+
/**
|
|
486
|
+
* Forget the capture and every long-lived mark.
|
|
487
|
+
*
|
|
488
|
+
* A worker never needs this — the registry it captured is the one it keeps. This module's own spec
|
|
489
|
+
* does, because it has to exercise both a successful and a failed capture in one process.
|
|
490
|
+
*/
|
|
491
|
+
declare function resetMockRegistryTracking(): void;
|
|
492
|
+
|
|
418
493
|
/**
|
|
419
494
|
* The callback half of a scheduler call, spelled out so a wrapper can pass it along and — for a
|
|
420
495
|
* one-shot scheduler — call it itself.
|
|
@@ -561,4 +636,4 @@ declare const BLOCKED_FETCH_MESSAGE = "[vitest-auto-spy] fetch is stubbed in uni
|
|
|
561
636
|
*/
|
|
562
637
|
declare function blockNetwork(): void;
|
|
563
638
|
|
|
564
|
-
export { BLOCKED_FETCH_MESSAGE, type CountingClock, type CountingClockOptions, type DuplicateCopiesReaction, type FakeTimersConfig, type GlobalPatchReaction, type PerTestHandle, type RejectionHost, type SchedulerHost, type SetupAutoSpyOptions, type StopTrackingRejections, type StopTrackingTimers, type StrayRejection, type SystemTime, advanceTimers, blockNetwork, cancelStrayTimers, countStrayRejections, countStrayTimers, flushStrayRejections, getWatchedTimerGlobals, guardGlobalPatches, installPerTest, mockNow, mockSystemTime, registerFocusMatchers, restoreTimerGlobals, setupAutoSpy, setupFakeTimers, trackStrayRejections, trackStrayTimers, useCountingClock, withSystemTime };
|
|
639
|
+
export { BLOCKED_FETCH_MESSAGE, type CountingClock, type CountingClockOptions, type DuplicateCopiesReaction, type FakeTimersConfig, type GlobalPatchReaction, type PerTestHandle, type RejectionHost, type SchedulerHost, type SetupAutoSpyOptions, type StopTrackingRejections, type StopTrackingTimers, type StrayRejection, type SystemTime, advanceTimers, blockNetwork, cancelStrayTimers, captureMockRegistry, countStrayRejections, countStrayTimers, flushStrayRejections, getMockRegistrySize, getWatchedTimerGlobals, guardGlobalPatches, installPerTest, keepMockRegistered, keepRegisteredMocks, mockNow, mockSystemTime, pruneMockRegistry, registerFocusMatchers, resetMockRegistryTracking, restoreTimerGlobals, setupAutoSpy, setupFakeTimers, trackMockRegistry, trackStrayRejections, trackStrayTimers, useCountingClock, withSystemTime };
|
package/dist/setup.js
CHANGED
|
@@ -136,6 +136,80 @@ function guardGlobalPatches(reaction) {
|
|
|
136
136
|
checkSealedAdditions(watched, reaction);
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
|
+
var registry;
|
|
140
|
+
var captureAttempted = false;
|
|
141
|
+
var longLived = /* @__PURE__ */ new WeakSet();
|
|
142
|
+
function isWeakKey(value) {
|
|
143
|
+
return typeof value === "function" || typeof value === "object" && value !== null;
|
|
144
|
+
}
|
|
145
|
+
function captureMockRegistry() {
|
|
146
|
+
if (captureAttempted) {
|
|
147
|
+
return registry;
|
|
148
|
+
}
|
|
149
|
+
captureAttempted = true;
|
|
150
|
+
const probe = vi.fn();
|
|
151
|
+
const originalForEach = Set.prototype.forEach;
|
|
152
|
+
let captured;
|
|
153
|
+
const remember = (set) => {
|
|
154
|
+
captured ??= set;
|
|
155
|
+
};
|
|
156
|
+
Set.prototype.forEach = function patchedForEach(...args) {
|
|
157
|
+
remember(this);
|
|
158
|
+
originalForEach.apply(this, args);
|
|
159
|
+
};
|
|
160
|
+
try {
|
|
161
|
+
vi.clearAllMocks();
|
|
162
|
+
} finally {
|
|
163
|
+
Set.prototype.forEach = originalForEach;
|
|
164
|
+
}
|
|
165
|
+
if (!captured?.has(probe)) {
|
|
166
|
+
return void 0;
|
|
167
|
+
}
|
|
168
|
+
captured.delete(probe);
|
|
169
|
+
registry = captured;
|
|
170
|
+
return registry;
|
|
171
|
+
}
|
|
172
|
+
function keepMockRegistered(mock) {
|
|
173
|
+
if (isWeakKey(mock)) {
|
|
174
|
+
longLived.add(mock);
|
|
175
|
+
}
|
|
176
|
+
return mock;
|
|
177
|
+
}
|
|
178
|
+
function keepRegisteredMocks() {
|
|
179
|
+
registry?.forEach((mock) => {
|
|
180
|
+
keepMockRegistered(mock);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function pruneMockRegistry() {
|
|
184
|
+
if (!registry) {
|
|
185
|
+
return 0;
|
|
186
|
+
}
|
|
187
|
+
let pruned = 0;
|
|
188
|
+
for (const mock of registry) {
|
|
189
|
+
if (!isWeakKey(mock) || !longLived.has(mock)) {
|
|
190
|
+
registry.delete(mock);
|
|
191
|
+
pruned += 1;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return pruned;
|
|
195
|
+
}
|
|
196
|
+
function trackMockRegistry() {
|
|
197
|
+
beforeAll(() => {
|
|
198
|
+
captureMockRegistry();
|
|
199
|
+
keepRegisteredMocks();
|
|
200
|
+
});
|
|
201
|
+
afterAll(() => {
|
|
202
|
+
pruneMockRegistry();
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function getMockRegistrySize() {
|
|
206
|
+
return registry?.size;
|
|
207
|
+
}
|
|
208
|
+
function resetMockRegistryTracking() {
|
|
209
|
+
registry = void 0;
|
|
210
|
+
captureAttempted = false;
|
|
211
|
+
longLived = /* @__PURE__ */ new WeakSet();
|
|
212
|
+
}
|
|
139
213
|
|
|
140
214
|
// src/lib/network-stub.ts
|
|
141
215
|
var BLOCKED_FETCH_MESSAGE = "[vitest-auto-spy] fetch is stubbed in unit tests";
|
|
@@ -154,7 +228,7 @@ function describeTarget(input) {
|
|
|
154
228
|
}
|
|
155
229
|
var HANDLER_SLOT = "unhandledPromiseRejectionHandler";
|
|
156
230
|
var MISSING_ZONE = "trackStrayRejections() found no zone.js on the host (`Zone.__symbol__` is not there), so there is no handler slot to claim. This module never imports zone.js \u2014 a zoneless project must not pull it in \u2014 which means the consumer loads it first: `import 'zone.js';` at the top of the setup file, or, under `@angular/build:unit-test`, the builder's own entry point does it. It throws rather than quietly doing nothing on purpose: without zone.js the global `Promise` is the platform one, whose unhandled rejections Vitest already reports and fails the run for, so a silent no-op here would read as \"the check is on\" while nothing was ever checked. Drop the option instead.";
|
|
157
|
-
function
|
|
231
|
+
function registry2() {
|
|
158
232
|
return globalThis.__vitestAutoSpyTrackedRejections__ ??= /* @__PURE__ */ new Map();
|
|
159
233
|
}
|
|
160
234
|
function defaultHost() {
|
|
@@ -182,7 +256,7 @@ function describeRejection(error) {
|
|
|
182
256
|
return { reason, assertion: isAssertionFailure(reason), testName: expect.getState().currentTestName ?? "" };
|
|
183
257
|
}
|
|
184
258
|
function trackStrayRejections(host = defaultHost()) {
|
|
185
|
-
const tracked =
|
|
259
|
+
const tracked = registry2().get(host);
|
|
186
260
|
if (tracked) {
|
|
187
261
|
return tracked.stop;
|
|
188
262
|
}
|
|
@@ -202,25 +276,25 @@ function trackStrayRejections(host = defaultHost()) {
|
|
|
202
276
|
} else {
|
|
203
277
|
Reflect.deleteProperty(zone, slot);
|
|
204
278
|
}
|
|
205
|
-
|
|
279
|
+
registry2().delete(host);
|
|
206
280
|
};
|
|
207
|
-
|
|
281
|
+
registry2().set(host, { captured, stop });
|
|
208
282
|
return stop;
|
|
209
283
|
}
|
|
210
284
|
function countStrayRejections(host = defaultHost()) {
|
|
211
|
-
const tracked =
|
|
285
|
+
const tracked = registry2().get(host);
|
|
212
286
|
if (!tracked) {
|
|
213
287
|
throw new Error(withDocs("countStrayRejections() needs trackStrayRejections() to have run first.", DOCS_LINKS.setup));
|
|
214
288
|
}
|
|
215
289
|
return tracked.captured.length;
|
|
216
290
|
}
|
|
217
291
|
function flushStrayRejections(host = defaultHost()) {
|
|
218
|
-
const tracked =
|
|
292
|
+
const tracked = registry2().get(host);
|
|
219
293
|
return tracked ? tracked.captured.splice(0) : [];
|
|
220
294
|
}
|
|
221
295
|
|
|
222
296
|
// src/lib/stray-timers.ts
|
|
223
|
-
function
|
|
297
|
+
function registry3() {
|
|
224
298
|
return globalThis.__vitestAutoSpyTrackedSchedulers__ ??= /* @__PURE__ */ new Map();
|
|
225
299
|
}
|
|
226
300
|
function defaultHost2() {
|
|
@@ -278,7 +352,7 @@ function wrapFrameScheduler(host, frames) {
|
|
|
278
352
|
};
|
|
279
353
|
}
|
|
280
354
|
function trackStrayTimers(host = defaultHost2()) {
|
|
281
|
-
const tracked =
|
|
355
|
+
const tracked = registry3().get(host);
|
|
282
356
|
if (tracked) {
|
|
283
357
|
return tracked.stop;
|
|
284
358
|
}
|
|
@@ -294,13 +368,13 @@ function trackStrayTimers(host = defaultHost2()) {
|
|
|
294
368
|
const stop = () => {
|
|
295
369
|
cancelStrayTimers(host);
|
|
296
370
|
undo.forEach((restore) => restore());
|
|
297
|
-
|
|
371
|
+
registry3().delete(host);
|
|
298
372
|
};
|
|
299
|
-
|
|
373
|
+
registry3().set(host, { handles, frames, stop });
|
|
300
374
|
return stop;
|
|
301
375
|
}
|
|
302
376
|
function cancelStrayTimers(host = defaultHost2()) {
|
|
303
|
-
const tracked =
|
|
377
|
+
const tracked = registry3().get(host);
|
|
304
378
|
if (!tracked) {
|
|
305
379
|
return 0;
|
|
306
380
|
}
|
|
@@ -318,7 +392,7 @@ function cancelStrayTimers(host = defaultHost2()) {
|
|
|
318
392
|
return cancelled;
|
|
319
393
|
}
|
|
320
394
|
function countStrayTimers(host = defaultHost2()) {
|
|
321
|
-
const tracked =
|
|
395
|
+
const tracked = registry3().get(host);
|
|
322
396
|
if (!tracked) {
|
|
323
397
|
throw new Error(withDocs("countStrayTimers() needs trackStrayTimers() to have run first.", DOCS_LINKS.setup));
|
|
324
398
|
}
|
|
@@ -408,6 +482,9 @@ function setupAutoSpy(options = {}) {
|
|
|
408
482
|
cancelStrayTimers();
|
|
409
483
|
});
|
|
410
484
|
}
|
|
485
|
+
if (options.pruneMockRegistry ?? false) {
|
|
486
|
+
trackMockRegistry();
|
|
487
|
+
}
|
|
411
488
|
if (options.globalFakeTimers) {
|
|
412
489
|
setupFakeTimers(options.globalFakeTimers === true ? void 0 : options.globalFakeTimers, { betweenTests: true });
|
|
413
490
|
}
|
|
@@ -552,4 +629,4 @@ function registerFocusMatchers() {
|
|
|
552
629
|
// src/setup.ts
|
|
553
630
|
useVitestAdapter();
|
|
554
631
|
|
|
555
|
-
export { BLOCKED_FETCH_MESSAGE, advanceTimers, blockNetwork, cancelStrayTimers, countStrayRejections, countStrayTimers, flushStrayRejections, getWatchedTimerGlobals, guardGlobalPatches, installPerTest, mockNow, mockSystemTime, registerFocusMatchers, restoreTimerGlobals, setupAutoSpy, setupFakeTimers, trackStrayRejections, trackStrayTimers, useCountingClock, withSystemTime };
|
|
632
|
+
export { BLOCKED_FETCH_MESSAGE, advanceTimers, blockNetwork, cancelStrayTimers, captureMockRegistry, countStrayRejections, countStrayTimers, flushStrayRejections, getMockRegistrySize, getWatchedTimerGlobals, guardGlobalPatches, installPerTest, keepMockRegistered, keepRegisteredMocks, mockNow, mockSystemTime, pruneMockRegistry, registerFocusMatchers, resetMockRegistryTracking, restoreTimerGlobals, setupAutoSpy, setupFakeTimers, trackMockRegistry, trackStrayRejections, trackStrayTimers, useCountingClock, withSystemTime };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-auto-spy",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Auto-generate fully-typed test spies from a class — across Vitest, Bun and node:test, with NestJS/React/Vue/Svelte/Angular recipes. Drop-in replacement for jest-auto-spies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"auto-mock",
|
|
@@ -104,6 +104,7 @@ it('loads', async () => {
|
|
|
104
104
|
| a green run exiting 1 with `AbortError` under happy-dom | `setupAutoSpy({ blockNetwork: true })` |
|
|
105
105
|
| timers or frames from a previous file failing this one | `setupAutoSpy({ strayTimers: true })` |
|
|
106
106
|
| an assertion error in stderr, every test green and the run at 0 | `setupAutoSpy({ strayRejections: true })` — zone.js swallowed it |
|
|
107
|
+
| a run getting slower the longer it goes, on `isolate: false` | `setupAutoSpy({ pruneMockRegistry: true })` — the mock registry |
|
|
107
108
|
| `Cannot read properties of undefined (reading 'now')` | `restoreTimerGlobals` — on by default |
|
|
108
109
|
| a spy handed to an API typed against the real class | `asInstance()` / `asSpy()` |
|
|
109
110
|
| the code under test does `new X()` (a global, a vendor SDK) | `mockConstructor(factory)` / `stubConstructor(obj, key, factory)` |
|