vitest-auto-spy 4.5.1 → 4.6.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.
package/AGENTS.md CHANGED
@@ -1134,6 +1134,17 @@ import { setSpyEngine } from 'vitest-auto-spy/setup';
1134
1134
  setSpyEngine('runner'); // every double built afterwards is `vi.fn()` per method, as before 4.1
1135
1135
  ```
1136
1136
 
1137
+ **On Vitest 5 the registry story changes, and this library follows it.** Vitest 5 keeps registered
1138
+ mocks behind `WeakRef`s and its `clearAllMocks()` visits only the ones *called* since the last
1139
+ sweep — so a spy that is not a `vi.fn()` has to make itself reachable to that sweep deliberately. It
1140
+ does, which is why `vi.clearAllMocks()`, `vi.resetAllMocks()` and the `clearMocks: true` default
1141
+ (new in Vitest 5) clear these doubles exactly as they clear the runner's own. Nothing in a spec
1142
+ changes, and the peer range still starts at 2.1 — one install spans Vitest 2.1 through 5.x.
1143
+
1144
+ What Vitest 5 does break is the runner's own doing, not this library's: with `clearMocks` on by
1145
+ default, a test asserting on a call that an **earlier** test or a `beforeAll` recorded now reads
1146
+ zero. Count it in a plain variable rather than in the spy, or set `clearMocks: false`.
1147
+
1137
1148
  `getSpyEngine()` reports the current one, `'auto-spy'` is the default, and doubles already built keep
1138
1149
  the engine they were built with. The switch is Vitest-only: on Bun and `node:test` the runner's own
1139
1150
  matchers recognise only the runner's own mocks, so those adapters keep using them.
@@ -2470,6 +2481,8 @@ packages, which a subpath export can never be.
2470
2481
  | `done.fail is not a function` | Vitest passes a `TestContext`, not jasmine's `done`; the line usually sits in an `error` callback nobody awaits, so the run stays **green** | assert on the failure — `await expect(firstValueFrom(src$)).rejects.toMatchObject({ … })`, or `expect.fail(message)` |
2471
2482
  | a `.withContext('…')` message that never appears in the failure output | Vitest's chai layer has an `@internal` `withContext(flags)`; handed a string it walks the character indices, sets nonsense flags and returns `this` | `expect(actual, 'message').toBe(expected)` — the second argument of `expect` is the label. Nothing throws, so nothing warns (§20) |
2472
2483
  | `requested method(s) not found on the class prototype` | typo, or an instance-field callable | fix the name, or move it to `instanceMethodsToSpyOn` |
2484
+ | `All declarations of 'Matchers' must have identical type parameters` | a custom matcher declares `interface Matchers<T = any>` (the Vitest 4 shape) while Vitest 5 declares `Matchers<R, T>` | declare it on `Chai.Assertion` instead — that interface has no type parameters in either major, so one declaration merges on both (§10) |
2485
+ | `toHaveBeenCalledTimes` reads `0` for a call an earlier test made, after moving to Vitest 5 | `clearMocks` defaults to `true` on Vitest 5, so `vi.clearAllMocks()` runs before every test | count the calls in a plain variable instead of reading the spy, or set `clearMocks: false` (§10) |
2473
2486
  | `was configured with 'mustBeCalledWith'` | the code called the spy with other arguments | that is the assertion firing — fix the code, or relax to `calledWith` |
2474
2487
  | `extendWithAutoSpies needs Vitest 4.1 or newer` | the `test` handed in has only the object-form `extend` (Vitest ≤ 4.0); the builder form the helper is written against arrived in 4.1 | upgrade Vitest, or keep `provideAutoSpy` + `injectSpy` in a `beforeEach` until then |
2475
2488
  | `advanceTimers() requires fake timers` | no fake timers installed | `setupFakeTimers()` or `vi.useFakeTimers()` first |
package/README.md CHANGED
@@ -211,7 +211,7 @@ npm i -D vitest-auto-spy
211
211
  | Tool | Minimum |
212
212
  | ---------- | --------------------------------------------------------------------------------- |
213
213
  | Node.js | ≥ 18 for the library — in practice, whatever your runner needs |
214
- | Vitest | ≥ 2.1 (required peer) |
214
+ | Vitest | ≥ 2.1 (required peer) — one install covers 2.1 through 5.x |
215
215
  | Bun | ≥ 1.4 for `vitest-auto-spy/bun-angular`; any recent Bun for `vitest-auto-spy/bun` |
216
216
  | TypeScript | ≥ 4.7 for the typed helpers (plain JS works too, just untyped) |
217
217
 
@@ -221,6 +221,22 @@ The runtime helpers themselves still run on older Vitest (the library polyfills
221
221
  `bun:test` and `node:test` regardless), but the types no longer line up there, so the range stops
222
222
  claiming it.
223
223
 
224
+ **Vitest 5 needs nothing from you.** The same install covers it — no second major of this package,
225
+ no version-split types, no `@next` tag, no change to an import. Two changes in Vitest 5 would
226
+ otherwise have broken quietly, and both are handled here: its `clearAllMocks()` now visits only the
227
+ mocks that were called, so a spy engine that is not `vi.fn()` had to make itself reachable to the
228
+ sweep; and the `Matchers` interface grew a second type parameter, so the bundled matchers declare
229
+ themselves on Chai's `Assertion` instead and keep typing on 4 and 5 alike. The one thing Vitest 5
230
+ can still break is its own doing: `clearMocks` is on by default there, so a spec asserting on a call
231
+ recorded by an *earlier* test now reads zero. Record it in a counter, not in the spy.
232
+
233
+ Measured 2026-09-06 on 40 spec files, 800 tests, 400 spied methods per file, v8 coverage on,
234
+ Node v24.19.0, median of five runs: the same suite takes **1383 ms on Vitest 4.1.11 and 1276 ms on
235
+ Vitest 5.0.0** — **−7.7 %** for changing nothing but the runner. The spy engine this library has
236
+ shipped since 4.1 is worth another **−6.1 % on Vitest 4 and −8.1 % on Vitest 5** against building
237
+ every method with the runner's own `vi.fn()` (`setSpyEngine('runner')`). End to end, the slowest
238
+ pairing to the fastest is 1473 ms → 1276 ms, **−13.4 %**.
239
+
224
240
  Node **≥ 18** is the library's own floor and it holds — the published output is ES2022 and every
225
241
  entry runs on 18. What moves the real minimum is the runner: **Vitest 4 cannot start on Node 18 at
226
242
  all**, because Vite 7 calls `crypto.hash` (added in Node 20.12) and the run dies with
package/dist/angular.d.ts CHANGED
@@ -378,10 +378,12 @@ declare function createDirectiveHost<Props extends object = Record<never, never>
378
378
  * it in a bundled test build.
379
379
  */
380
380
 
381
- declare module 'vitest' {
382
- interface Matchers<T = any> {
383
- /** Assert that `directive` is applied somewhere in this fixture (optionally, on `selector`). */
384
- toHaveDirectiveApplied(directive: Type<unknown>, selector?: string): T;
381
+ declare global {
382
+ namespace Chai {
383
+ interface Assertion {
384
+ /** Assert that `directive` is applied somewhere in this fixture (optionally, on `selector`). */
385
+ toHaveDirectiveApplied(directive: Type<unknown>, selector?: string): void;
386
+ }
385
387
  }
386
388
  }
387
389
  /**
@@ -559,14 +561,16 @@ interface ResourceLike<TValue = unknown> {
559
561
  value(): TValue;
560
562
  error?(): Error | undefined;
561
563
  }
562
- declare module 'vitest' {
563
- interface Matchers<T = any> {
564
- /** The resource is still in flight — `status()` is `'loading'` or `'reloading'`. */
565
- toBeLoading(): T;
566
- /** The resource has resolved *and* its value deep-equals the expected one. */
567
- toHaveResourceValue(expected: unknown): T;
568
- /** The resource has failed; with an argument, its error message matches too. */
569
- toHaveResourceError(expected?: RegExp | string): T;
564
+ declare global {
565
+ namespace Chai {
566
+ interface Assertion {
567
+ /** The resource is still in flight — `status()` is `'loading'` or `'reloading'`. */
568
+ toBeLoading(): void;
569
+ /** The resource has resolved *and* its value deep-equals the expected one. */
570
+ toHaveResourceValue(expected: unknown): void;
571
+ /** The resource has failed; with an argument, its error message matches too. */
572
+ toHaveResourceError(expected?: RegExp | string): void;
573
+ }
570
574
  }
571
575
  }
572
576
  /**
@@ -591,10 +595,12 @@ declare function registerResourceMatchers(): void;
591
595
 
592
596
  /** Anything readable like a signal: `signal()`, `computed()`, `input()`, or a plain getter. */
593
597
  type SignalLike<T> = () => T;
594
- declare module 'vitest' {
595
- interface Matchers<T = any> {
596
- /** Read the signal under test and deep-compare its current value. */
597
- toHaveSignalValue(expected: unknown): T;
598
+ declare global {
599
+ namespace Chai {
600
+ interface Assertion {
601
+ /** Read the signal under test and deep-compare its current value. */
602
+ toHaveSignalValue(expected: unknown): void;
603
+ }
598
604
  }
599
605
  }
600
606
  /**
package/dist/angular.js CHANGED
@@ -387,6 +387,7 @@ sweepSentinel.mockReset = function resetAllMocksSweep() {
387
387
  resetAllFastSpies();
388
388
  return sweepSentinel;
389
389
  };
390
+ sweepSentinel();
390
391
  var vitestMockAdapter = guardAccessorSpies({
391
392
  createMockFn(implementation, name) {
392
393
  return createFastSpy(implementation, name) ;
@@ -1167,6 +1168,18 @@ function readStoredAccessor(store, key, receiver) {
1167
1168
  }
1168
1169
  return accessor.get?.call(receiver);
1169
1170
  }
1171
+ function storeWriteTraps(store) {
1172
+ return {
1173
+ set(_target, key, value, receiver) {
1174
+ if (!writeStoredAccessor(store, key, value, receiver)) {
1175
+ writeStoredValue(store, key, value);
1176
+ }
1177
+ return true;
1178
+ },
1179
+ defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1180
+ deleteProperty: (_target, key) => dropStoredProp(store, key)
1181
+ };
1182
+ }
1170
1183
  var NOT_STORED = /* @__PURE__ */ Symbol("vitest-auto-spy.notStored");
1171
1184
  var PROTOCOL_KEYS = /* @__PURE__ */ new Set(["schedule", "lift", "@@observable", "getReader"]);
1172
1185
  function isProtocolKey(key) {
@@ -1274,14 +1287,7 @@ function createAutoMockHandler(seed, unstubbed) {
1274
1287
  const store = createProxyPropStore(seed);
1275
1288
  return {
1276
1289
  get: (_target, key, receiver) => readKey(store, key, receiver, unstubbed),
1277
- set(_target, key, value, receiver) {
1278
- if (!writeStoredAccessor(store, key, value, receiver)) {
1279
- writeStoredValue(store, key, value);
1280
- }
1281
- return true;
1282
- },
1283
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1284
- deleteProperty: (_target, key) => dropStoredProp(store, key),
1290
+ ...storeWriteTraps(store),
1285
1291
  has(_target, key) {
1286
1292
  return key === AUTO_SPY_MARK || key === DISPOSE || hasStoredProp(store, key);
1287
1293
  },
@@ -1,12 +1,12 @@
1
1
  import { flushEffects } from './chunk-5BPM3BLI.js';
2
2
  export { flushEffects, stable } from './chunk-5BPM3BLI.js';
3
3
  import './chunk-Y4YG7UOK.js';
4
- import { createSpyForToken } from './chunk-Z4VRMCW2.js';
4
+ import { createSpyForToken } from './chunk-4OANQSWG.js';
5
5
  import './chunk-NQXXUJPS.js';
6
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-GAY6LNAM.js';
6
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-3GK5IJTV.js';
7
7
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-D5LDT3W4.js';
8
- import { createSpyFromClass } from './chunk-FYFF67EN.js';
9
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-FYFF67EN.js';
8
+ import { createSpyFromClass } from './chunk-4VNMT3ZU.js';
9
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4VNMT3ZU.js';
10
10
  export { createFunctionSpy, errorHandler } from './chunk-FFKN6QKI.js';
11
11
  import './chunk-PC3FAZT3.js';
12
12
  import { isAutoSpyLike } from './chunk-XRVVZXOM.js';
package/dist/bun.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import './chunk-Y4YG7UOK.js';
2
2
  import './chunk-NQXXUJPS.js';
3
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-GAY6LNAM.js';
3
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-3GK5IJTV.js';
4
4
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-D5LDT3W4.js';
5
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-FYFF67EN.js';
5
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4VNMT3ZU.js';
6
6
  export { createFunctionSpy, errorHandler } from './chunk-FFKN6QKI.js';
7
7
  import './chunk-PC3FAZT3.js';
8
8
  import './chunk-XRVVZXOM.js';
@@ -1,5 +1,5 @@
1
1
  import { redefineFailure, mockValueProp, mockAccessorsProp } from './chunk-D5LDT3W4.js';
2
- import { resolveConfiguration, mergeMethodNames, getCallableMemberNames, applyReturns, createSpyFromClass, resolveAccessors, createAccessorsSpies, createProxyPropStore, describeStoredProp, dropStoredProp, storeDefinedProp, writeStoredAccessor, writeStoredValue, readStoredAccessor, NOT_STORED, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-FYFF67EN.js';
2
+ import { resolveConfiguration, mergeMethodNames, getCallableMemberNames, applyReturns, createSpyFromClass, resolveAccessors, createAccessorsSpies, createProxyPropStore, storeWriteTraps, describeStoredProp, readStoredAccessor, NOT_STORED, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-4VNMT3ZU.js';
3
3
  import { defineHelper, serializeValue, resolveUnstubbedGuard, createFunctionSpy } from './chunk-FFKN6QKI.js';
4
4
  import { DISPOSE } from './chunk-PC3FAZT3.js';
5
5
  import { DEEP_CHILDREN } from './chunk-XRVVZXOM.js';
@@ -183,16 +183,9 @@ function createDeepNode(name, overrides, selfReturning) {
183
183
  const { store } = state;
184
184
  const handler = {
185
185
  get: (target, key, receiver) => readNodeMember(state, target, key, receiver),
186
- set(_target, key, value, receiver) {
187
- if (!writeStoredAccessor(store, key, value, receiver)) {
188
- writeStoredValue(store, key, value);
189
- }
190
- return true;
191
- },
192
- // The three traps that make `mockValueProp` / `mockReadonlyProp` / `mockAccessorsProp` reach a
193
- // node at all — see `proxy-props.ts` for why their absence was silent rather than loud.
194
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
195
- deleteProperty: (_target, key) => dropStoredProp(store, key),
186
+ // The traps that make `mockValueProp` / `mockReadonlyProp` / `mockAccessorsProp` reach a node at
187
+ // all — see `proxy-props.ts` for why their absence was silent rather than loud.
188
+ ...storeWriteTraps(store),
196
189
  getOwnPropertyDescriptor(target, key) {
197
190
  return describeStoredProp(store, key) ?? Reflect.getOwnPropertyDescriptor(target, key);
198
191
  },
@@ -1,4 +1,4 @@
1
- import { createSpyFromClass, createAutoMock } from './chunk-FYFF67EN.js';
1
+ import { createSpyFromClass, createAutoMock } from './chunk-4VNMT3ZU.js';
2
2
  import { withDocs, DOCS_LINKS } from './chunk-B45HLBA4.js';
3
3
 
4
4
  // src/lib/track-injections.ts
@@ -127,6 +127,18 @@ function readStoredAccessor(store, key, receiver) {
127
127
  }
128
128
  return accessor.get?.call(receiver);
129
129
  }
130
+ function storeWriteTraps(store) {
131
+ return {
132
+ set(_target, key, value, receiver) {
133
+ if (!writeStoredAccessor(store, key, value, receiver)) {
134
+ writeStoredValue(store, key, value);
135
+ }
136
+ return true;
137
+ },
138
+ defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
139
+ deleteProperty: (_target, key) => dropStoredProp(store, key)
140
+ };
141
+ }
130
142
  var NOT_STORED = /* @__PURE__ */ Symbol("vitest-auto-spy.notStored");
131
143
  var PROTOCOL_KEYS = /* @__PURE__ */ new Set(["schedule", "lift", "@@observable", "getReader"]);
132
144
  function isProtocolKey(key) {
@@ -179,14 +191,7 @@ function createAutoMockHandler(seed, unstubbed) {
179
191
  const store = createProxyPropStore(seed);
180
192
  return {
181
193
  get: (_target, key, receiver) => readKey(store, key, receiver, unstubbed),
182
- set(_target, key, value, receiver) {
183
- if (!writeStoredAccessor(store, key, value, receiver)) {
184
- writeStoredValue(store, key, value);
185
- }
186
- return true;
187
- },
188
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
189
- deleteProperty: (_target, key) => dropStoredProp(store, key),
194
+ ...storeWriteTraps(store),
190
195
  has(_target, key) {
191
196
  return key === AUTO_SPY_MARK || key === DISPOSE || hasStoredProp(store, key);
192
197
  },
@@ -602,4 +607,4 @@ function hasNothingToRead(ObjectClass, accessors, config) {
602
607
  config.onlyMethodsToSpyOn.length === 0;
603
608
  }
604
609
 
605
- export { NOT_STORED, applyReturns, autoMocked, clearAutoSpy, createAccessorsSpies, createAutoMock, createProxyPropStore, createSpyFromClass, describeStoredProp, disposeAutoSpy, dropStoredProp, getCallableMemberNames, isDeletedProp, isProtocolKey, mergeMethodNames, readStoredAccessor, resetAutoSpy, resolveAccessors, resolveConfiguration, storeDefinedProp, writeStoredAccessor, writeStoredValue };
610
+ export { NOT_STORED, applyReturns, autoMocked, clearAutoSpy, createAccessorsSpies, createAutoMock, createProxyPropStore, createSpyFromClass, describeStoredProp, disposeAutoSpy, getCallableMemberNames, isDeletedProp, isProtocolKey, mergeMethodNames, readStoredAccessor, resetAutoSpy, resolveAccessors, resolveConfiguration, storeWriteTraps };
@@ -1,4 +1,4 @@
1
- import { vitestMockAdapter } from './chunk-KYAJCFUA.js';
1
+ import { vitestMockAdapter } from './chunk-7NI7XB6R.js';
2
2
  import { registerMockAdapter } from './shared-state.js';
3
3
 
4
4
  function useVitestAdapter() {
@@ -356,6 +356,7 @@ sweepSentinel.mockReset = function resetAllMocksSweep() {
356
356
  resetAllFastSpies();
357
357
  return sweepSentinel;
358
358
  };
359
+ sweepSentinel();
359
360
  var engine = "auto-spy";
360
361
  function setSpyEngine(next) {
361
362
  engine = next;
package/dist/cli.js CHANGED
@@ -2149,10 +2149,10 @@ function canMatchBundleChunk(pattern) {
2149
2149
  const extension = segment.slice(segment.lastIndexOf(".") + 1);
2150
2150
  return extension === "*" || /^[cm]?js$/.test(extension) || /^{[^}]*\b[cm]?js\b[^}]*}$/.test(extension);
2151
2151
  }
2152
- function collectTargetScope(value, into) {
2152
+ function forEachUnitTestOptions(value, onOptions) {
2153
2153
  if (Array.isArray(value)) {
2154
2154
  for (const item of value) {
2155
- collectTargetScope(item, into);
2155
+ forEachUnitTestOptions(item, onOptions);
2156
2156
  }
2157
2157
  return;
2158
2158
  }
@@ -2161,50 +2161,37 @@ function collectTargetScope(value, into) {
2161
2161
  }
2162
2162
  const options = value["options"];
2163
2163
  if ((value["builder"] === UNIT_TEST_BUILDER || value["executor"] === UNIT_TEST_BUILDER) && isRecord(options)) {
2164
- for (const key of ["coverageInclude", "coverageExclude"]) {
2165
- const list = options[key];
2166
- if (Array.isArray(list)) {
2167
- into.patterns += list.length;
2168
- }
2169
- }
2164
+ onOptions(options);
2170
2165
  }
2171
2166
  for (const nested of Object.values(value)) {
2172
- collectTargetScope(nested, into);
2167
+ forEachUnitTestOptions(nested, onOptions);
2173
2168
  }
2174
2169
  }
2175
- function targetScopeSize(profile) {
2176
- const total = { patterns: 0 };
2170
+ function forEachWorkspaceUnitTest(profile, onOptions) {
2177
2171
  for (const file of profile.files.filter((candidate) => WORKSPACE_FILE.test(candidate))) {
2178
- collectTargetScope(parseJsonc(readTextFile(join(profile.cwd, file)) ?? ""), total);
2172
+ forEachUnitTestOptions(parseJsonc(readTextFile(join(profile.cwd, file)) ?? ""), onOptions);
2179
2173
  }
2180
- return total.patterns;
2181
2174
  }
2182
- function collectRunnerConfigs(value, into) {
2183
- if (Array.isArray(value)) {
2184
- for (const item of value) {
2185
- collectRunnerConfigs(item, into);
2186
- }
2187
- return;
2188
- }
2189
- if (!isRecord(value)) {
2190
- return;
2191
- }
2192
- const options = value["options"];
2193
- if ((value["builder"] === UNIT_TEST_BUILDER || value["executor"] === UNIT_TEST_BUILDER) && isRecord(options)) {
2194
- const runnerConfig = options["runnerConfig"];
2195
- if (typeof runnerConfig === "string") {
2196
- into.add(runnerConfig.replace(/^\.\//, ""));
2175
+ function targetScopeSize(profile) {
2176
+ let patterns = 0;
2177
+ forEachWorkspaceUnitTest(profile, (options) => {
2178
+ for (const key of ["coverageInclude", "coverageExclude"]) {
2179
+ const list = options[key];
2180
+ if (Array.isArray(list)) {
2181
+ patterns += list.length;
2182
+ }
2197
2183
  }
2198
- }
2199
- for (const nested of Object.values(value)) {
2200
- collectRunnerConfigs(nested, into);
2201
- }
2184
+ });
2185
+ return patterns;
2202
2186
  }
2203
2187
  function unitTestRunnerConfigs(profile) {
2204
2188
  const found = /* @__PURE__ */ new Set();
2205
- for (const file of profile.files.filter((candidate) => WORKSPACE_FILE.test(candidate))) {
2206
- collectRunnerConfigs(parseJsonc(readTextFile(join(profile.cwd, file)) ?? ""), found);
2207
- }
2189
+ forEachWorkspaceUnitTest(profile, (options) => {
2190
+ const runnerConfig = options["runnerConfig"];
2191
+ if (typeof runnerConfig === "string") {
2192
+ found.add(runnerConfig.replace(/^\.\//, ""));
2193
+ }
2194
+ });
2208
2195
  return [...found];
2209
2196
  }
2210
2197
  function installedMajor(cwd, packageName) {
@@ -2356,7 +2343,7 @@ function checkForeignPragma(graph) {
2356
2343
  }
2357
2344
 
2358
2345
  // src/cli/checks/export-map.generated.ts
2359
- var EXPORT_MAP_VERSION = "4.5.0";
2346
+ var EXPORT_MAP_VERSION = "4.5.1";
2360
2347
  var ENTRY_SPECIFIERS = "vitest-auto-spy vitest-auto-spy/bun vitest-auto-spy/bun-angular vitest-auto-spy/node vitest-auto-spy/rxjs vitest-auto-spy/console vitest-auto-spy/dom-stubs vitest-auto-spy/diagnostics vitest-auto-spy/jasmine vitest-auto-spy/jasmine-compat vitest-auto-spy/observer-spy vitest-auto-spy/angular vitest-auto-spy/angular-http vitest-auto-spy/nestjs vitest-auto-spy/react vitest-auto-spy/vue vitest-auto-spy/svelte vitest-auto-spy/setup vitest-auto-spy/zone vitest-auto-spy/eslint-plugin";
2361
2348
  var EXPORTED_BY = {
2362
2349
  AccessorImplementations: "0 1 2 3 11 14 15 16",
@@ -2840,6 +2827,19 @@ function tableApplies(cwd) {
2840
2827
  const theirs = installed === void 0 ? void 0 : majorOf(installed);
2841
2828
  return theirs === void 0 || theirs === majorOf(EXPORT_MAP_VERSION);
2842
2829
  }
2830
+ function scanSources(profile, graph, visit) {
2831
+ if (!tableApplies(profile.cwd)) {
2832
+ return [];
2833
+ }
2834
+ const findings = [];
2835
+ const report2 = (finding) => {
2836
+ findings.push(finding);
2837
+ };
2838
+ for (const [file, text] of graph.texts) {
2839
+ visit(file, text, report2);
2840
+ }
2841
+ return findings;
2842
+ }
2843
2843
 
2844
2844
  // src/cli/checks/helper-entry.ts
2845
2845
  function candidates(owners, preferred) {
@@ -2856,20 +2856,15 @@ function findingFor(file, entry, name, owners) {
2856
2856
  };
2857
2857
  }
2858
2858
  function checkHelperEntry(profile, graph) {
2859
- if (!tableApplies(profile.cwd)) {
2860
- return [];
2861
- }
2862
- const findings = [];
2863
- for (const [file, text] of graph.texts) {
2859
+ return scanSources(profile, graph, (file, text, report2) => {
2864
2860
  for (const { entry, name } of findEntryImports(text)) {
2865
2861
  const exported = entryExports(entry);
2866
2862
  const owners = candidates(ownersOf(name), profile.entry);
2867
2863
  if (exported !== void 0 && !exported.has(name) && owners.length > 0) {
2868
- findings.push(findingFor(file, entry, name, owners));
2864
+ report2(findingFor(file, entry, name, owners));
2869
2865
  }
2870
2866
  }
2871
- }
2872
- return findings;
2867
+ });
2873
2868
  }
2874
2869
  var JASMINE_PACKAGES = ["@hirez_io/observer-spy", "@types/jasmine", "jasmine-auto-spies", "jasmine-core"];
2875
2870
  var KARMA_PACKAGE = /^karma/;
@@ -3152,13 +3147,9 @@ function findUnawaitedCalls(source, locals) {
3152
3147
  return found;
3153
3148
  }
3154
3149
  function checkUnawaitedHelper(profile, graph) {
3155
- if (!tableApplies(profile.cwd)) {
3156
- return [];
3157
- }
3158
- const findings = [];
3159
- for (const [file, text] of graph.texts) {
3150
+ return scanSources(profile, graph, (file, text, report2) => {
3160
3151
  for (const local of new Set(findUnawaitedCalls(text, awaitableLocals(text)))) {
3161
- findings.push({
3152
+ report2({
3162
3153
  check: "no-unawaited-helper",
3163
3154
  severity: "error",
3164
3155
  file,
@@ -3166,8 +3157,7 @@ function checkUnawaitedHelper(profile, graph) {
3166
3157
  fix: "Await it. Unawaited, it settles after the test has already ended, so the assertion inside it can only report into a later test \u2014 or nowhere at all."
3167
3158
  });
3168
3159
  }
3169
- }
3170
- return findings;
3160
+ });
3171
3161
  }
3172
3162
 
3173
3163
  // src/cli/doctor.ts
package/dist/console.js CHANGED
@@ -1,4 +1,4 @@
1
- import { vitestMockAdapter } from './chunk-KYAJCFUA.js';
1
+ import { vitestMockAdapter } from './chunk-7NI7XB6R.js';
2
2
  import './chunk-YHDBRBGU.js';
3
3
  import { createFunctionSpy } from './chunk-FFKN6QKI.js';
4
4
  import './chunk-PC3FAZT3.js';
package/dist/dom-stubs.js CHANGED
@@ -380,6 +380,7 @@ sweepSentinel.mockReset = function resetAllMocksSweep() {
380
380
  resetAllFastSpies();
381
381
  return sweepSentinel;
382
382
  };
383
+ sweepSentinel();
383
384
  var vitestMockAdapter = guardAccessorSpies({
384
385
  createMockFn(implementation, name) {
385
386
  return createFastSpy(implementation, name) ;
@@ -338,13 +338,15 @@ function templatePolicy(context) {
338
338
  }
339
339
  var RENDER_MESSAGES = {
340
340
  keepTemplate: '`keepTemplate: true` puts the real template back, and this project set `{ templates: "never" }`. Drop it \u2014 or, when the component genuinely reads its own template through `viewChild` or content projection, silence this line, because the alternative is a spec that cannot reach the component at all.',
341
+ templatesNever: 'This project set `{ templates: "never" }`, and this line renders a template \u2014 under that policy markup is e2e\'s business whether or not the spec reads it back, so the report says nothing about what this file does with it. `renderShallow(X)` brings the same component up through the same `TestBed` with the children dropped and the template blank, and leaves inputs, signals, lifecycle hooks and DI exactly where they were; `fixture` is still a real `ComponentFixture`. What it buys is measured in `bench-angular/`: **0.24\xD7** the per-test cycle at 100 children and **0.05\xD7** at 400, and nothing at zero. Two costs to decide rather than discover: a spec that asserts on markup goes red, which is the move to e2e the policy is asking for, and coverage falls by whatever only the template reached \u2014 a `computed` nothing else reads, a handler bound only in the markup. When the component reads its own template through `viewChild`, content projection or a `@defer` block, the answer is `{ keepTemplate: true }`, which still drops the children.',
341
342
  preferRenderShallow: "`TestBed.createComponent` pays for compiling the template and instantiating the whole child subtree, and nothing in this file reads either \u2014 no `nativeElement`, no `debugElement`, no `By.css`, no `querySelector`. `renderShallow(X)` brings the same component up through the same `TestBed` with the children dropped and the template blank, and leaves inputs, signals, lifecycle hooks and DI exactly where they were; `fixture` is still a real `ComponentFixture`. What it buys is measured in `bench-angular/`: **0.24\xD7** the per-test cycle at 100 children and **0.05\xD7** at 400 \u2014 but at **zero** children the two are level (measurements straddle 1.0, and it is the noisiest row in the benchmark), so a leaf component gains nothing and this report is worth ignoring there. Reach for `{ keepTemplate: true }` when the component reads its own template through `viewChild` or content projection, which this rule cannot see from the spec."
342
343
  };
343
344
  function buildsDirectiveHarness(source) {
344
345
  return source.includes("createDirectiveHost");
345
346
  }
347
+ var DOCUMENT_DELEGATION = /\b(\w+)\s*:\s*document\s*\.\s*\1\b/g;
346
348
  function readsRenderedTemplate(source) {
347
- return TEMPLATE_READS.some((member) => source.includes(member));
349
+ return TEMPLATE_READS.some((member) => source.replace(DOCUMENT_DELEGATION, "").includes(member));
348
350
  }
349
351
  function renderShallowSuggestion(context, node) {
350
352
  const [component, ...extra] = node.arguments;
@@ -1667,13 +1669,13 @@ var preferRenderShallow = defineRule({
1667
1669
  create: (context) => ({
1668
1670
  'CallExpression[callee.object.name="TestBed"][callee.property.name="createComponent"]': (node) => {
1669
1671
  const source = context.sourceCode.getText();
1670
- if (templatePolicy(context) === "as-needed" ? readsRenderedTemplate(source) : buildsDirectiveHarness(source)) {
1672
+ const policy = templatePolicy(context);
1673
+ if (policy === "as-needed" ? readsRenderedTemplate(source) : buildsDirectiveHarness(source)) {
1671
1674
  return;
1672
1675
  }
1676
+ const messageId = policy === "never" ? "templatesNever" : "preferRenderShallow";
1673
1677
  const suggestion = renderShallowSuggestion(context, node);
1674
- context.report(
1675
- suggestion ? { node, messageId: "preferRenderShallow", suggest: [suggestion] } : { node, messageId: "preferRenderShallow" }
1676
- );
1678
+ context.report(suggestion ? { node, messageId, suggest: [suggestion] } : { node, messageId });
1677
1679
  },
1678
1680
  'Property[key.name="keepTemplate"][value.value=true]': (node) => {
1679
1681
  if (templatePolicy(context) === "never") {
package/dist/index.js CHANGED
@@ -384,6 +384,7 @@ sweepSentinel.mockReset = function resetAllMocksSweep() {
384
384
  resetAllFastSpies();
385
385
  return sweepSentinel;
386
386
  };
387
+ sweepSentinel();
387
388
  var vitestMockAdapter = guardAccessorSpies({
388
389
  createMockFn(implementation, name) {
389
390
  return createFastSpy(implementation, name) ;
@@ -1176,6 +1177,18 @@ function readStoredAccessor(store, key, receiver) {
1176
1177
  }
1177
1178
  return accessor.get?.call(receiver);
1178
1179
  }
1180
+ function storeWriteTraps(store) {
1181
+ return {
1182
+ set(_target, key, value, receiver) {
1183
+ if (!writeStoredAccessor(store, key, value, receiver)) {
1184
+ writeStoredValue(store, key, value);
1185
+ }
1186
+ return true;
1187
+ },
1188
+ defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1189
+ deleteProperty: (_target, key) => dropStoredProp(store, key)
1190
+ };
1191
+ }
1179
1192
  var NOT_STORED = /* @__PURE__ */ Symbol("vitest-auto-spy.notStored");
1180
1193
  var PROTOCOL_KEYS = /* @__PURE__ */ new Set(["schedule", "lift", "@@observable", "getReader"]);
1181
1194
  function isProtocolKey(key) {
@@ -1290,14 +1303,7 @@ function createAutoMockHandler(seed, unstubbed) {
1290
1303
  const store = createProxyPropStore(seed);
1291
1304
  return {
1292
1305
  get: (_target, key, receiver) => readKey(store, key, receiver, unstubbed),
1293
- set(_target, key, value, receiver) {
1294
- if (!writeStoredAccessor(store, key, value, receiver)) {
1295
- writeStoredValue(store, key, value);
1296
- }
1297
- return true;
1298
- },
1299
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1300
- deleteProperty: (_target, key) => dropStoredProp(store, key),
1306
+ ...storeWriteTraps(store),
1301
1307
  has(_target, key) {
1302
1308
  return key === AUTO_SPY_MARK || key === DISPOSE || hasStoredProp(store, key);
1303
1309
  },
@@ -1980,16 +1986,9 @@ function createDeepNode(name, overrides, selfReturning) {
1980
1986
  const { store } = state;
1981
1987
  const handler = {
1982
1988
  get: (target, key, receiver) => readNodeMember(state, target, key, receiver),
1983
- set(_target, key, value, receiver) {
1984
- if (!writeStoredAccessor(store, key, value, receiver)) {
1985
- writeStoredValue(store, key, value);
1986
- }
1987
- return true;
1988
- },
1989
- // The three traps that make `mockValueProp` / `mockReadonlyProp` / `mockAccessorsProp` reach a
1990
- // node at all — see `proxy-props.ts` for why their absence was silent rather than loud.
1991
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1992
- deleteProperty: (_target, key) => dropStoredProp(store, key),
1989
+ // The traps that make `mockValueProp` / `mockReadonlyProp` / `mockAccessorsProp` reach a node at
1990
+ // all — see `proxy-props.ts` for why their absence was silent rather than loud.
1991
+ ...storeWriteTraps(store),
1993
1992
  getOwnPropertyDescriptor(target, key) {
1994
1993
  return describeStoredProp(store, key) ?? Reflect.getOwnPropertyDescriptor(target, key);
1995
1994
  },
package/dist/jasmine.d.ts CHANGED
@@ -80,25 +80,29 @@ type NameList<Names extends string> = Names[] | Record<Names, unknown>;
80
80
  declare function createSpyObj<Names extends string, Props extends string = never>(baseName: string, methodNames: NameList<Names>, propertyNames?: NameList<Props>): SpyObj<Names, Props>;
81
81
  declare function createSpyObj<Names extends string, Props extends string = never>(methodNames: NameList<Names>, propertyNames?: NameList<Props>): SpyObj<Names, Props>;
82
82
 
83
- declare module 'vitest' {
84
- interface Matchers<T = any> {
85
- /** See {@link AsymmetricMatchersContaining.jasmineTruthy}. */
86
- jasmineTruthy(): T;
87
- /** See {@link AsymmetricMatchersContaining.jasmineFalsy}. */
88
- jasmineFalsy(): T;
89
- /** See {@link AsymmetricMatchersContaining.jasmineEmpty}. */
90
- jasmineEmpty(): T;
91
- /** See {@link AsymmetricMatchersContaining.jasmineNotEmpty}. */
92
- jasmineNotEmpty(): T;
93
- /** See {@link AsymmetricMatchersContaining.jasmineIs}. */
94
- jasmineIs(sample: unknown): T;
95
- /** See {@link AsymmetricMatchersContaining.jasmineMapContaining}. */
96
- jasmineMapContaining(sample: Map<unknown, unknown>): T;
97
- /** See {@link AsymmetricMatchersContaining.jasmineSetContaining}. */
98
- jasmineSetContaining(sample: Set<unknown>): T;
99
- /** See {@link AsymmetricMatchersContaining.jasmineArrayWithExactContents}. */
100
- jasmineArrayWithExactContents(sample: unknown[]): T;
83
+ declare global {
84
+ namespace Chai {
85
+ interface Assertion {
86
+ /** See {@link AsymmetricMatchersContaining.jasmineTruthy}. */
87
+ jasmineTruthy(): void;
88
+ /** See {@link AsymmetricMatchersContaining.jasmineFalsy}. */
89
+ jasmineFalsy(): void;
90
+ /** See {@link AsymmetricMatchersContaining.jasmineEmpty}. */
91
+ jasmineEmpty(): void;
92
+ /** See {@link AsymmetricMatchersContaining.jasmineNotEmpty}. */
93
+ jasmineNotEmpty(): void;
94
+ /** See {@link AsymmetricMatchersContaining.jasmineIs}. */
95
+ jasmineIs(sample: unknown): void;
96
+ /** See {@link AsymmetricMatchersContaining.jasmineMapContaining}. */
97
+ jasmineMapContaining(sample: Map<unknown, unknown>): void;
98
+ /** See {@link AsymmetricMatchersContaining.jasmineSetContaining}. */
99
+ jasmineSetContaining(sample: Set<unknown>): void;
100
+ /** See {@link AsymmetricMatchersContaining.jasmineArrayWithExactContents}. */
101
+ jasmineArrayWithExactContents(sample: unknown[]): void;
102
+ }
101
103
  }
104
+ }
105
+ declare module 'vitest' {
102
106
  interface AsymmetricMatchersContaining {
103
107
  /** jasmine's `jasmine.truthy()` — any value that is loosely true. */
104
108
  jasmineTruthy(): unknown;
package/dist/jasmine.js CHANGED
@@ -1,9 +1,9 @@
1
- import { useVitestAdapter } from './chunk-EMASXQDZ.js';
1
+ import { useVitestAdapter } from './chunk-557TSVD5.js';
2
2
  import { enableJasmineCompat } from './chunk-MAKQSO2R.js';
3
3
  export { enableJasmineCompat } from './chunk-MAKQSO2R.js';
4
- import './chunk-KYAJCFUA.js';
4
+ import './chunk-7NI7XB6R.js';
5
5
  import './chunk-YHDBRBGU.js';
6
- import { createSpyFromClass } from './chunk-FYFF67EN.js';
6
+ import { createSpyFromClass } from './chunk-4VNMT3ZU.js';
7
7
  import { createFunctionSpy } from './chunk-FFKN6QKI.js';
8
8
  import './chunk-PC3FAZT3.js';
9
9
  import './chunk-XRVVZXOM.js';
package/dist/nestjs.js CHANGED
@@ -1,8 +1,8 @@
1
- import { createSpyForToken } from './chunk-Z4VRMCW2.js';
2
- export { trackInjections } from './chunk-Z4VRMCW2.js';
3
- import { vitestMockAdapter } from './chunk-KYAJCFUA.js';
1
+ import { createSpyForToken } from './chunk-4OANQSWG.js';
2
+ export { trackInjections } from './chunk-4OANQSWG.js';
3
+ import { vitestMockAdapter } from './chunk-7NI7XB6R.js';
4
4
  import './chunk-YHDBRBGU.js';
5
- import { createSpyFromClass } from './chunk-FYFF67EN.js';
5
+ import { createSpyFromClass } from './chunk-4VNMT3ZU.js';
6
6
  import './chunk-FFKN6QKI.js';
7
7
  import './chunk-PC3FAZT3.js';
8
8
  import './chunk-XRVVZXOM.js';
package/dist/node.cjs CHANGED
@@ -1097,6 +1097,18 @@ function readStoredAccessor(store, key, receiver) {
1097
1097
  }
1098
1098
  return accessor.get?.call(receiver);
1099
1099
  }
1100
+ function storeWriteTraps(store) {
1101
+ return {
1102
+ set(_target, key, value, receiver) {
1103
+ if (!writeStoredAccessor(store, key, value, receiver)) {
1104
+ writeStoredValue(store, key, value);
1105
+ }
1106
+ return true;
1107
+ },
1108
+ defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1109
+ deleteProperty: (_target, key) => dropStoredProp(store, key)
1110
+ };
1111
+ }
1100
1112
  var NOT_STORED = /* @__PURE__ */ Symbol("vitest-auto-spy.notStored");
1101
1113
  var PROTOCOL_KEYS = /* @__PURE__ */ new Set(["schedule", "lift", "@@observable", "getReader"]);
1102
1114
  function isProtocolKey(key) {
@@ -1213,14 +1225,7 @@ function createAutoMockHandler(seed, unstubbed) {
1213
1225
  const store = createProxyPropStore(seed);
1214
1226
  return {
1215
1227
  get: (_target, key, receiver) => readKey(store, key, receiver, unstubbed),
1216
- set(_target, key, value, receiver) {
1217
- if (!writeStoredAccessor(store, key, value, receiver)) {
1218
- writeStoredValue(store, key, value);
1219
- }
1220
- return true;
1221
- },
1222
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1223
- deleteProperty: (_target, key) => dropStoredProp(store, key),
1228
+ ...storeWriteTraps(store),
1224
1229
  has(_target, key) {
1225
1230
  return key === AUTO_SPY_MARK || key === DISPOSE || hasStoredProp(store, key);
1226
1231
  },
@@ -1878,16 +1883,9 @@ function createDeepNode(name, overrides, selfReturning) {
1878
1883
  const { store } = state;
1879
1884
  const handler = {
1880
1885
  get: (target, key, receiver) => readNodeMember(state, target, key, receiver),
1881
- set(_target, key, value, receiver) {
1882
- if (!writeStoredAccessor(store, key, value, receiver)) {
1883
- writeStoredValue(store, key, value);
1884
- }
1885
- return true;
1886
- },
1887
- // The three traps that make `mockValueProp` / `mockReadonlyProp` / `mockAccessorsProp` reach a
1888
- // node at all — see `proxy-props.ts` for why their absence was silent rather than loud.
1889
- defineProperty: (_target, key, descriptor) => storeDefinedProp(store, key, descriptor),
1890
- deleteProperty: (_target, key) => dropStoredProp(store, key),
1886
+ // The traps that make `mockValueProp` / `mockReadonlyProp` / `mockAccessorsProp` reach a node at
1887
+ // all — see `proxy-props.ts` for why their absence was silent rather than loud.
1888
+ ...storeWriteTraps(store),
1891
1889
  getOwnPropertyDescriptor(target, key) {
1892
1890
  return describeStoredProp(store, key) ?? Reflect.getOwnPropertyDescriptor(target, key);
1893
1891
  },
package/dist/node.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRedefineMockAdapter } from './chunk-NQXXUJPS.js';
2
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-GAY6LNAM.js';
2
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-3GK5IJTV.js';
3
3
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-D5LDT3W4.js';
4
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-FYFF67EN.js';
4
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4VNMT3ZU.js';
5
5
  export { createFunctionSpy, errorHandler } from './chunk-FFKN6QKI.js';
6
6
  import './chunk-PC3FAZT3.js';
7
7
  import './chunk-XRVVZXOM.js';
package/dist/react.js CHANGED
@@ -1,8 +1,8 @@
1
- import { vitestMockAdapter } from './chunk-KYAJCFUA.js';
1
+ import { vitestMockAdapter } from './chunk-7NI7XB6R.js';
2
2
  import './chunk-YHDBRBGU.js';
3
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-GAY6LNAM.js';
3
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-3GK5IJTV.js';
4
4
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-D5LDT3W4.js';
5
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-FYFF67EN.js';
5
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4VNMT3ZU.js';
6
6
  export { createFunctionSpy, errorHandler } from './chunk-FFKN6QKI.js';
7
7
  import './chunk-PC3FAZT3.js';
8
8
  import './chunk-XRVVZXOM.js';
package/dist/setup.d.ts CHANGED
@@ -592,10 +592,12 @@ interface CountingClockOptions {
592
592
  */
593
593
  declare function useCountingClock(options?: CountingClockOptions): CountingClock;
594
594
 
595
- declare module 'vitest' {
596
- interface Matchers<T = any> {
597
- /** Assert that this element is `document.activeElement`. */
598
- toHaveFocus(): T;
595
+ declare global {
596
+ namespace Chai {
597
+ interface Assertion {
598
+ /** Assert that this element is `document.activeElement`. */
599
+ toHaveFocus(): void;
600
+ }
599
601
  }
600
602
  }
601
603
  /**
package/dist/setup.js CHANGED
@@ -1,5 +1,5 @@
1
- import { useVitestAdapter } from './chunk-EMASXQDZ.js';
2
- export { getSpyEngine, setSpyEngine } from './chunk-KYAJCFUA.js';
1
+ import { useVitestAdapter } from './chunk-557TSVD5.js';
2
+ export { getSpyEngine, setSpyEngine } from './chunk-7NI7XB6R.js';
3
3
  import { SWEEP_SENTINEL } from './chunk-YHDBRBGU.js';
4
4
  import { mockValueProp, countMockedProps, restoreMockedProps } from './chunk-D5LDT3W4.js';
5
5
  import { defineHelper, setDefaultStrictMode } from './chunk-FFKN6QKI.js';
package/dist/svelte.js CHANGED
@@ -1,8 +1,8 @@
1
- import { vitestMockAdapter } from './chunk-KYAJCFUA.js';
1
+ import { vitestMockAdapter } from './chunk-7NI7XB6R.js';
2
2
  import './chunk-YHDBRBGU.js';
3
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-GAY6LNAM.js';
3
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-3GK5IJTV.js';
4
4
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-D5LDT3W4.js';
5
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-FYFF67EN.js';
5
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4VNMT3ZU.js';
6
6
  export { createFunctionSpy, errorHandler } from './chunk-FFKN6QKI.js';
7
7
  import './chunk-PC3FAZT3.js';
8
8
  import './chunk-XRVVZXOM.js';
package/dist/vue.js CHANGED
@@ -1,9 +1,9 @@
1
- import { vitestMockAdapter } from './chunk-KYAJCFUA.js';
1
+ import { vitestMockAdapter } from './chunk-7NI7XB6R.js';
2
2
  import './chunk-YHDBRBGU.js';
3
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-GAY6LNAM.js';
3
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-3GK5IJTV.js';
4
4
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-D5LDT3W4.js';
5
- import { createSpyFromClass } from './chunk-FYFF67EN.js';
6
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-FYFF67EN.js';
5
+ import { createSpyFromClass } from './chunk-4VNMT3ZU.js';
6
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4VNMT3ZU.js';
7
7
  export { createFunctionSpy, errorHandler } from './chunk-FFKN6QKI.js';
8
8
  import './chunk-PC3FAZT3.js';
9
9
  import './chunk-XRVVZXOM.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-auto-spy",
3
- "version": "4.5.1",
3
+ "version": "4.6.0",
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 and jasmine-auto-spies.",
5
5
  "keywords": [
6
6
  "auto-mock",
@@ -289,18 +289,17 @@
289
289
  "devDependencies": {
290
290
  "@analogjs/vite-plugin-angular": "^2.2.0",
291
291
  "@analogjs/vitest-angular": "^2.2.0",
292
- "@angular/build": "^21.2.16",
293
- "@angular/common": "^21.2.17",
294
- "@angular/compiler": "^21.2.17",
295
- "@angular/compiler-cli": "^21.2.17",
296
- "@angular/core": "^21.0.0",
297
- "@angular/platform-browser": "^21.2.17",
298
- "@angular/platform-browser-dynamic": "^21.2.17",
292
+ "@angular/build": "^22.1.7",
293
+ "@angular/common": "^22.1.5",
294
+ "@angular/compiler": "^22.1.5",
295
+ "@angular/compiler-cli": "^22.1.5",
296
+ "@angular/core": "^22.1.5",
297
+ "@angular/platform-browser": "^22.1.5",
299
298
  "@eslint-community/eslint-plugin-eslint-comments": "^4.7.2",
300
- "@happy-dom/global-registrator": "^20.11.6",
301
- "@trivago/prettier-plugin-sort-imports": "^4.3.0",
299
+ "@happy-dom/global-registrator": "^20.14.0",
300
+ "@trivago/prettier-plugin-sort-imports": "^6.0.2",
302
301
  "@types/jsdom": "^30.0.0",
303
- "@types/node": "^20.19.43",
302
+ "@types/node": "^24.13.3",
304
303
  "@typescript-eslint/eslint-plugin": "^8.61.0",
305
304
  "@typescript-eslint/parser": "^8.61.0",
306
305
  "@vitest/coverage-v8": "^4.1.9",
@@ -308,15 +307,15 @@
308
307
  "eslint-plugin-import": "^2.32.0",
309
308
  "eslint-plugin-optimize-regex": "^1.2.1",
310
309
  "eslint-plugin-rxjs": "^5.0.3",
311
- "js-yaml": "^4.2.0",
312
- "jscpd": "^4.2.5",
313
- "jsdom": "^29.1.1",
310
+ "js-yaml": "^5.4.1",
311
+ "jscpd": "^5.1.2",
312
+ "jsdom": "^30.0.1",
314
313
  "prettier": "^3.8.4",
315
314
  "prettier-plugin-sort-json": "^4.2.0",
316
315
  "reflect-metadata": "^0.2.2",
317
316
  "rxjs": "^7.8.0",
318
317
  "tsup": "^8.3.0",
319
- "typescript": "^5.6.0",
318
+ "typescript": "^6.0.3",
320
319
  "vitest": "^4.1.9",
321
320
  "zone.js": "^0.16.2"
322
321
  }