vitest-auto-spy 5.0.0 → 5.1.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.
Files changed (53) hide show
  1. package/AGENTS.md +37 -6
  2. package/README.md +15 -6
  3. package/dist/angular.d.ts +5 -5
  4. package/dist/angular.js +38 -26
  5. package/dist/bun-angular.d.ts +4 -4
  6. package/dist/bun-angular.js +5 -5
  7. package/dist/bun.d.ts +15 -4
  8. package/dist/bun.js +3 -3
  9. package/dist/{chunk-7U6CKTXA.js → chunk-5WEFPNUG.js} +1 -1
  10. package/dist/{chunk-VZP5MG5N.js → chunk-CUVQUISO.js} +11 -56
  11. package/dist/{chunk-5UF3IVFC.js → chunk-CWHCYCCQ.js} +1 -1
  12. package/dist/{chunk-E7HYS4K4.js → chunk-Q74KQJWG.js} +36 -26
  13. package/dist/chunk-RQGMLVRO.js +51 -0
  14. package/dist/{chunk-GNBP7CNT.js → chunk-VX5DDHAS.js} +1 -1
  15. package/dist/{chunk-KJREOXX6.js → chunk-YZOB2KRF.js} +2 -2
  16. package/dist/cli.js +310 -300
  17. package/dist/console.d.ts +1 -1
  18. package/dist/console.js +3 -2
  19. package/dist/diagnostics.js +5 -211
  20. package/dist/dom-stubs.d.ts +1 -1
  21. package/dist/dom-stubs.js +2 -0
  22. package/dist/eslint-plugin.cjs +12 -4
  23. package/dist/eslint-plugin.d.cts +4 -0
  24. package/dist/eslint-plugin.d.ts +4 -0
  25. package/dist/{expect-emission-Dy5CvsF2.d.ts → expect-emission-BfCKHEzi.d.ts} +1 -1
  26. package/dist/index.d.ts +3 -3
  27. package/dist/index.js +38 -26
  28. package/dist/jasmine-compat.d.ts +1 -1
  29. package/dist/jasmine.d.ts +2 -2
  30. package/dist/jasmine.js +5 -4
  31. package/dist/nestjs.d.ts +2 -2
  32. package/dist/nestjs.js +6 -5
  33. package/dist/node.cjs +37 -27
  34. package/dist/node.d.ts +3 -3
  35. package/dist/node.js +3 -3
  36. package/dist/{prop-mock-Dp2ZMFqj.d.ts → prop-mock-DkSaUWiQ.d.ts} +1 -1
  37. package/dist/react.d.ts +3 -3
  38. package/dist/react.js +5 -4
  39. package/dist/rstest.d.ts +6 -0
  40. package/dist/rstest.js +66 -0
  41. package/dist/rxjs.d.ts +2 -2
  42. package/dist/setup.d.ts +10 -9
  43. package/dist/setup.js +4 -3
  44. package/dist/shared-state.js +1 -1
  45. package/dist/svelte.d.ts +3 -3
  46. package/dist/svelte.js +5 -4
  47. package/dist/{track-injections-CAqxzlhV.d.ts → track-injections-CiYfR36E.d.ts} +1 -1
  48. package/dist/{types-CQLPjw8z.d.ts → types-CroX5c53.d.ts} +60 -13
  49. package/dist/vue.d.ts +4 -4
  50. package/dist/vue.js +6 -5
  51. package/dist/{zoneless-BFq3ve6Q.d.ts → zoneless-C9ruGqto.d.ts} +23 -3
  52. package/package.json +15 -3
  53. package/skills/vitest-auto-spy/SKILL.md +13 -5
package/AGENTS.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # vitest-auto-spy — instructions for AI coding agents
2
2
 
3
3
  You are looking at the agent-facing reference for **`vitest-auto-spy`**: typed test spies generated
4
- from a class, a type, or nothing at all, on Vitest / `bun:test` / `node:test`.
4
+ from a class, a type, or nothing at all, on Vitest / `bun:test` / `node:test` / Rstest.
5
5
 
6
6
  This file is written for an agent **using** the library in someone's test suite. It is shipped
7
7
  inside the npm package, so it is readable with no network:
@@ -43,6 +43,7 @@ adapter installed and spies fail at runtime.
43
43
  | `bun test` | `vitest-auto-spy/bun` |
44
44
  | `bun test` + Angular | `vitest-auto-spy/bun-angular` |
45
45
  | `node --test` | `vitest-auto-spy/node` |
46
+ | `rstest run` | `vitest-auto-spy/rstest` |
46
47
  | Angular + Vitest | `vitest-auto-spy/angular` |
47
48
  | NestJS | `vitest-auto-spy/nestjs` |
48
49
  | React | `vitest-auto-spy/react` |
@@ -1139,10 +1140,16 @@ Everything a spec can observe is the same, and the suite pins it by putting the
1139
1140
  Vitest applies through those two functions.
1140
1141
 
1141
1142
  **The one difference.** `mock.invocationCallOrder` counts on this library's own scale, so
1142
- `expect(a).toHaveBeenCalledBefore(b)` is exact between two auto-spies and meaningless between an
1143
- auto-spy and a hand-written `vi.fn()` — the two counters never met. Nothing else in the library or in
1144
- Vitest reads that field. If a suite needs the comparison, switch the whole run back to the runner's
1145
- factory:
1143
+ `expect(a).toHaveBeenCalledBefore(b)` is exact between two auto-spies and **wrong** between an
1144
+ auto-spy and a hand-written `vi.fn()` — not an error, an answer, computed from two counters that
1145
+ never met. `@vitest/spy` keeps its own in a module-private variable it neither exports nor lets
1146
+ anything advance, so the scales cannot be reconciled after the fact; they drift apart by however many
1147
+ calls of each kind the run has already made. Measured in a converted suite: a double reporting
1148
+ `[164, 165, 167, 168, 169]` beside a `vi.fn()` reporting `[28]` for its single call in the same test,
1149
+ under an assertion that had been passing — because `jest-auto-spies` built both halves with
1150
+ `jest.fn()`, which did share one counter. Three earlier calls of one family are enough to invert the
1151
+ verdict. Nothing else in the library or in Vitest reads that field. If a suite needs the comparison,
1152
+ compare two doubles of the same family, or switch the whole run back to the runner's factory:
1146
1153
 
1147
1154
  ```ts
1148
1155
  // vitest.setup.ts
@@ -2273,6 +2280,25 @@ and costs +206 B per mock against +65 B for naming at creation, measured over 20
2273
2280
  mock in `node:test`'s reporter output on its own. Full account:
2274
2281
  <https://asdalexey.github.io/vitest-auto-spy/runtimes/node#spy-names>.
2275
2282
 
2283
+ ### Rstest
2284
+
2285
+ `vitest-auto-spy/rstest` drives the same core through `rstest.fn()` / `rstest.spyOn()`. Rstest
2286
+ implements the Jest/Vitest mock surface, so **none of the `node:test` differences above apply**:
2287
+ `spy.method.mock.calls[0]` is a bare argument array, the `mockReturnValue` family is native, and
2288
+ `gettersToSpyOn` / `settersToSpyOn` go through `rstest.spyOn(obj, 'prop', 'get' | 'set')` rather than
2289
+ the redefinition fallback. `rstest.clearAllMocks()`, `rstest.resetAllMocks()` and the
2290
+ `clearMocks: true` / `resetMocks: true` config keys reach spies built by `createSpyFromClass` — the
2291
+ entry plants one sentinel mock for it, and there is nothing to enable.
2292
+
2293
+ Two things are not there. `vitest-auto-spy/setup` is wired to Vitest's hooks, so `setupAutoSpy()` and
2294
+ the fake-timer helpers are Vitest-only — on Rstest, import `vitest-auto-spy/rstest` once in the setup
2295
+ file, which is the part a setup file is for. `trackNodeMocks()` is `node:test`-only and is not needed:
2296
+ Rstest drops its mock registry between files, like Vitest and Bun.
2297
+
2298
+ Rstest is 0.x. Vitest stays the zero-config default; reach for this entry when the suite already runs
2299
+ on Rstest, which is typically an Rspack project reusing its bundler config for tests. Full account:
2300
+ <https://asdalexey.github.io/vitest-auto-spy/runtimes/rstest>.
2301
+
2276
2302
  ---
2277
2303
 
2278
2304
  ## 14. `fakeAsync` needs `vitest-auto-spy/zone`
@@ -2363,6 +2389,10 @@ export default [
2363
2389
  ];
2364
2390
  ```
2365
2391
 
2392
+ `autoSpy.configs.typeErrors` is a second flat config holding the subset whose findings are compile
2393
+ errors — `prefer-as-spy` (`TS2352`) and `no-mocked-for-spy` (`TS2322`). Spread its `rules` after a
2394
+ blanket downgrade so those keep their severity; do not copy the two names into a consumer's config.
2395
+
2366
2396
  | Rule | Level | Fix | Flags |
2367
2397
  | --------------------------------- | ------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
2368
2398
  | `no-expect-in-subscribe` | `error` | suggest | `expect()` inside `subscribe()` → `expectEmission` / `firstValueFrom` |
@@ -2585,7 +2615,8 @@ packages, which a subpath export can never be.
2585
2615
  | `TS2540: Cannot assign to 'X' because it is a read-only property` | a `readonly` field of an object under test | `mockValueProp(obj, 'X', value)` — on a class **getter**, `mockReadonlyProp` |
2586
2616
  | `TypeError: Cannot read properties of undefined (reading 'mockReturnValue')` | the member is an **instance field**, not on the prototype — `Router.currentNavigation` since Angular 20 | `provideAutoSpy(Router, { instanceMethodsToSpyOn: ['currentNavigation'] })` (§5) |
2587
2617
  | `throwWith` reaching the success branch first, with the previous test's value | the spy's `ReplaySubject(1)` outlived the test that filled it | upgrade; and `resetAutoSpy(spy)` in `beforeEach` when the TestBed is built in `beforeAll` |
2588
- | `TS2540` on a `Spy<T>` / `createAutoMock` member, which the runtime writes fine | `Spy<T>` is homomorphic, so it keeps the `readonly` of an abstract getter | `Mutable<Spy<T>>` for direct assignment, or `mockValueProp` for a patch that is undone |
2618
+ | `TS2540` on a `Spy<T>` / `createAutoMock` member, which the runtime writes fine | `Spy<T>` is homomorphic and keeps the `readonly` of the source member — deliberately: on a member replaced by a **spied accessor** the assignment reaches the setter spy and the getter still answers `undefined`, so the type error is the loud version of a silent no-op | `mockValueProp(spy, 'X', value)` — it defines rather than assigns, so it works in both cases; `Mutable<Spy<T>>` is the opt-in for plain data members, and `Reflect.set` is **not** a way round it |
2619
+ | `TS2345` from `mockReturnValue` / `mockImplementation` / `mockResolvedValue` on a double that used to compile | the mock surface is `MockInstance<Method>`, so the stub is now checked against the method's own return type | stub with what the method returns; if the double is meant to answer something else, the method's type or the spec's expectation is wrong |
2589
2620
  | `delete mock.optionalMethod` leaving the member present and truthy | the Proxy had no `deleteProperty` trap before 3.5.0 | upgrade; before that, `mock.optionalMethod = undefined` |
2590
2621
  | half a double's methods reaching the real implementation after `Object.assign` | `ownKeys` on a type-driven Proxy lists only the keys already read | `createSpyFromClass(X)` — a real object, with enumerable method keys |
2591
2622
  | `let s: MockInstance<() => unknown>` not matching anything | `MockInstance<F>` is invariant in `F`; Jest's `SpyInstance` was not | `MockInstance<T['method']>`, or better `injectSpy(X).method` |
package/README.md CHANGED
@@ -8,7 +8,7 @@ The only auto-spy library that reads a **class** and gives a **fully-typed** spy
8
8
  with **return-type-aware** helpers — `resolveWith` / `rejectWith` for `Promise`s, `nextWith` /
9
9
  `throwWith` for RxJS `Observable`s, and `calledWith` / `mustBeCalledWith` for argument matching. Or
10
10
  skip the class entirely and mock straight from a **type or interface** with `createAutoMock<T>()` and
11
- recursive `mockDeep<T>()`. Runs on **Vitest**, **Bun** (`bun:test`) and **`node:test`** behind one
11
+ recursive `mockDeep<T>()`. Runs on **Vitest**, **Bun** (`bun:test`), **`node:test`** and **Rstest** behind one
12
12
  identical API, with **RxJS** spies and **Angular / NestJS / React / Vue·Pinia / Svelte** recipes
13
13
  ([availability](#availability)). A drop-in replacement for
14
14
  [`jest-auto-spies`](https://www.npmjs.com/package/jest-auto-spies) — same API, and roughly 1.5x
@@ -86,7 +86,7 @@ faster at suite scale ([benchmarks](#benchmarks)) — and for
86
86
  - 🤖 Built for AI agents too — one `npx vitest-auto-spy init` writes the pointer into the files your agents actually read and specialises it for this repository, backed by an offline [`AGENTS.md`](#using-this-library-with-an-ai-agent) inside the package, a [per-agent map](#which-file-your-agent-reads) for **Claude Code**, **OpenAI Codex**, **GLM/z.ai**, **Cursor**, **Copilot**, **Gemini CLI** and the rest, `llms.txt` on the docs site, a Claude Code skill, and errors that name their own fix
87
87
  - 🟢 100% test coverage, **zero runtime dependencies** (in-tree arg serializer, no `javascript-stringify`)
88
88
 
89
- ## New in 5.0
89
+ ## New in 5
90
90
 
91
91
  A major that changes **no helper, no option and no runtime behaviour**. What it changes is what the
92
92
  package claims to run on, because both old peer ranges were claims the code could not keep — the
@@ -103,7 +103,7 @@ full list, with what to do about each, is in
103
103
  For almost everyone the whole upgrade is a version number: every Angular still supported by Angular
104
104
  satisfies the new floor, and only a project pinning `rxjs@7.0` or `7.1` on purpose has to move.
105
105
 
106
- ## New in 4.0
106
+ ## New in 4
107
107
 
108
108
  A major with **one job**: take out of your project the weight this library was making it carry.
109
109
  Nothing was removed or renamed and no runtime behaviour changed — the whole cost is two import
@@ -719,7 +719,7 @@ the time. It works in any client that _is_ Claude Code — the z.ai and Kimi set
719
719
 
720
720
  ## Availability
721
721
 
722
- > **All entry points are published.** The **Vitest / Bun / `node:test`** runtimes, the **RxJS** layer,
722
+ > **All entry points are published.** The **Vitest / Bun / `node:test` / Rstest** runtimes, the **RxJS** layer,
723
723
  > and the **Angular / NestJS / React / Vue·Pinia / Svelte** recipes all ship as importable entry points —
724
724
  > one identical API across every runner and framework.
725
725
 
@@ -727,6 +727,7 @@ the time. It works in any client that _is_ Claude Code — the z.ai and Kimi set
727
727
  | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
728
728
  | `vitest-auto-spy` · `vitest-auto-spy/rxjs` · `vitest-auto-spy/angular` | ✅ **Published** |
729
729
  | `vitest-auto-spy/bun` · `vitest-auto-spy/bun-angular` · `vitest-auto-spy/node` | ✅ **Published** |
730
+ | `vitest-auto-spy/rstest` | ✅ **Published** |
730
731
  | `vitest-auto-spy/nestjs` · `/react` · `/vue` · `/svelte` · `/console` | `provideAutoSpy`, `injectSpy` for `Test.createTestingModule`; `createNestUnit` builds the unit from its DI metadata with every unprovided token auto-spied, `expose` for sociable collaborators |
731
732
  | `vitest-auto-spy/setup` · `vitest-auto-spy/zone` · `vitest-auto-spy/eslint-plugin` | ✅ **Published** |
732
733
  | `vitest-auto-spy/jasmine` · `/jasmine-compat` · `/observer-spy` | ✅ **Published** |
@@ -1154,6 +1155,7 @@ Node / Bun / React / Vue project pulls **neither rxjs nor Angular into its runti
1154
1155
  | `vitest-auto-spy/bun` | the same core, driven by Bun's `bun:test` mocks | `bun:test` | ✅ |
1155
1156
  | `vitest-auto-spy/bun-angular` | Angular's `TestBed` under `bun test` — DOM, JIT `templateUrl` resolution and a zoneless environment, from one preload | `bun:test`, `@angular/core`, `@angular/platform-browser` | ✅ |
1156
1157
  | `vitest-auto-spy/node` | the same core, driven by `node:test`'s `mock.fn()`, plus `trackNodeMocks()` — a private `MockTracker` so dropped spies are actually freed | `node:test` | ✅ |
1158
+ | `vitest-auto-spy/rstest` | the same core, driven by Rstest's `rstest.fn()` / `rstest.spyOn()` | `@rstest/core` | ✅ |
1157
1159
  | `vitest-auto-spy/nestjs` | `provideAutoSpy`, `injectSpy` for `Test.createTestingModule` | — (your `@nestjs/*`) | ✅ |
1158
1160
  | `vitest-auto-spy/react` | the core, with a natural import for React Testing Library suites | — (your `react`) | ✅ |
1159
1161
  | `vitest-auto-spy/vue` | `provideAutoSpy` for `global.provide` + Pinia store spying | — (your `vue`/`pinia`) | ✅ |
@@ -1202,18 +1204,19 @@ import 'vitest-auto-spy/rxjs';
1202
1204
 
1203
1205
  The core is runner-agnostic behind a `MockAdapter`: pick the entry that matches your test
1204
1206
  runner — the public API (`createSpyFromClass`, `calledWith`, `resolveWith`, `nextWith`, …) is
1205
- identical across all three.
1207
+ identical across all four.
1206
1208
 
1207
1209
  ```ts
1208
1210
  import { createSpyFromClass } from 'vitest-auto-spy'; // Vitest (default, zero-config)
1209
1211
  import { createSpyFromClass } from 'vitest-auto-spy/bun'; // Bun — bun:test
1210
1212
  import { createSpyFromClass } from 'vitest-auto-spy/node'; // node:test
1213
+ import { createSpyFromClass } from 'vitest-auto-spy/rstest'; // Rstest
1211
1214
  ```
1212
1215
 
1213
1216
  Angular's `TestBed` runs on Bun too — see [Angular on Bun](#angular-on-bun-buntest) below.
1214
1217
 
1215
1218
  > Only the auto-spy helpers are normalised across runtimes; **native** mock methods stay the
1216
- > runner's own — `mockReturnValue` on Vitest/Bun, `spy.method.mock.mockImplementation` on
1219
+ > runner's own — `mockReturnValue` on Vitest/Bun/Rstest, `spy.method.mock.mockImplementation` on
1217
1220
  > `node:test`. Each entry registers its adapter on import, so import the one matching your runner.
1218
1221
 
1219
1222
  > Using an observable spy (`observablePropsToSpyOn`, `nextWith`, …) without importing
@@ -3017,6 +3020,11 @@ export default [
3017
3020
  ];
3018
3021
  ```
3019
3022
 
3023
+ A second config, `autoSpy.configs.typeErrors`, holds the subset whose findings are compile errors
3024
+ (`prefer-as-spy` is `TS2352`, `no-mocked-for-spy` is `TS2322`). Spread it **after** a blanket
3025
+ downgrade so those keep their severity — the recipe is a spread rather than rule names copied into
3026
+ your config, where they would go stale silently.
3027
+
3020
3028
  The full dial — landing it on a large existing suite without a red CI, the three rules that can
3021
3029
  report on correct code, and `setupModules` — is on the docs site:
3022
3030
  [ESLint plugin → Tuning it for your project](https://asdalexey.github.io/vitest-auto-spy/utilities/eslint-plugin#tuning-it-for-your-project).
@@ -3218,6 +3226,7 @@ names are unfindable from these messages otherwise — no `TS2739` text contains
3218
3226
  | `TS2322: Type 'Spy<X>' is not assignable to type 'Mocked<X>' …` | the variable was declared `Mocked<T>` | declare it `Spy<T>` |
3219
3227
  | `'AddPromiseSpyMethods<unknown>' is missing … from type 'WithMockReturnValue<…>'` | a generic class inferred as `Service<any>` | `asSpy<Service>(…)` / `injectSpy<Service>(…)` |
3220
3228
  | `TS2345` / `TS2554` **on a call to a spied method** (wrong arguments) | the arguments the real method rejects — the double's call signature is the method's own; it used to accept anything | fix the call; don't re-widen the spy |
3229
+ | `TS2345` **inside `mockReturnValue` / `mockImplementation` / `mockResolvedValue`** | the stub is not what the method returns — the mock surface is `MockInstance<Method>`, so it is checked | fix the stub; a deliberate mismatch is a type bug |
3221
3230
  | `TS2739 … 'Spy<X>' is missing …` **on a line with `injectSpy`** | the provider handed back the real object | `provideAutoSpy(X)`, or an honest `TestBed.inject` |
3222
3231
 
3223
3232
  Two notes that cost real time when they are missing.
package/dist/angular.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export { l as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, m as provideAutoSpyForToken, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-BFq3ve6Q.js';
1
+ export { l as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, m as provideAutoSpyForToken, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-C9ruGqto.js';
2
2
  import { InjectionToken, Provider, Type, Signal, WritableSignal } from '@angular/core';
3
3
  import { TestAPI } from 'vitest';
4
- import { C as ClassType, S as Spy, k as ClassSpyConfiguration, o as OnlyMethodKeysOf, g as AddSpyMethodsByReturnTypes } from './types-CQLPjw8z.js';
5
- export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-CAqxzlhV.js';
6
- export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-Dp2ZMFqj.js';
7
- export { C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-Dy5CvsF2.js';
4
+ import { C as ClassType, S as Spy, k as ClassSpyConfiguration, o as OnlyMethodKeysOf, g as AddSpyMethodsByReturnTypes } from './types-CroX5c53.js';
5
+ export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-CiYfR36E.js';
6
+ export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-DkSaUWiQ.js';
7
+ export { C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BfCKHEzi.js';
8
8
  import '@angular/core/testing';
9
9
 
10
10
  /**
package/dist/angular.js CHANGED
@@ -374,6 +374,8 @@ function createFastSpy(implementation, name) {
374
374
  spy[STATE] = void 0;
375
375
  return spy;
376
376
  }
377
+
378
+ // src/lib/vitest-adapter.ts
377
379
  function asVitestMock(mock) {
378
380
  return mock;
379
381
  }
@@ -564,33 +566,43 @@ function isSameMatcher(configArg, candidateArg) {
564
566
  function isBrandedMatcher(matcher) {
565
567
  return matcher.$$typeof === ASYMMETRIC_MATCHER_BRAND;
566
568
  }
569
+ var ARGS_MAP_BRAND = /* @__PURE__ */ Symbol.for("vitest-auto-spy.args-map");
570
+ var _a;
571
+ _a = ARGS_MAP_BRAND;
567
572
  var ArgsMap = class {
568
- // Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
569
- // plain own property, never walking or polluting the object prototype chain.
570
- #map = /* @__PURE__ */ Object.create(null);
571
- #matcherConfigs = [];
572
- // Argument counts present in the exact map. A call with a count nobody configured cannot be in
573
- // that map — two arg lists of different lengths never serialize to the same string — so the
574
- // serialization can be skipped outright. That matters because the map is consulted on *every*
575
- // invocation of a spy that has any `calledWith` config: without this, `service.load(component)`
576
- // on a spy configured with `calledWith(1)` walks and stringifies the whole component graph to
577
- // build a key that provably cannot match, and throws it away one line later.
578
- #arities = /* @__PURE__ */ new Set();
579
- /**
580
- * The configs of exactly one primitive argument, keyed by the argument itself.
581
- *
582
- * `calledWith(1)` / `calledWith('id')` is what nearly every spec writes, and it is looked up on
583
- * **every call** of that spy. Through the string map that costs a rendered key per call — an array
584
- * from `map`, a string per argument, a joined string, then a hash — for a lookup that a `Map` can
585
- * do on the value with no allocation at all. The configs live in both maps: the string map still
586
- * owns `configured()` and the arity set, so nothing about the failure messages or the miss check
587
- * changes.
588
- *
589
- * Only shapes where the two agree go in here. A symbol renders by description, so two distinct
590
- * symbols that share one are the same key in the string map and different keys in a `Map`; `-0`
591
- * renders apart from `0` and is the same key under `SameValueZero`. Both stay on the string path.
592
- */
593
- #exactSinglePrimitive = /* @__PURE__ */ new Map();
573
+ constructor() {
574
+ this[_a] = true;
575
+ // Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
576
+ // plain own property, never walking or polluting the object prototype chain.
577
+ this.#map = /* @__PURE__ */ Object.create(null);
578
+ this.#matcherConfigs = [];
579
+ // Argument counts present in the exact map. A call with a count nobody configured cannot be in
580
+ // that map — two arg lists of different lengths never serialize to the same string — so the
581
+ // serialization can be skipped outright. That matters because the map is consulted on *every*
582
+ // invocation of a spy that has any `calledWith` config: without this, `service.load(component)`
583
+ // on a spy configured with `calledWith(1)` walks and stringifies the whole component graph to
584
+ // build a key that provably cannot match, and throws it away one line later.
585
+ this.#arities = /* @__PURE__ */ new Set();
586
+ /**
587
+ * The configs of exactly one primitive argument, keyed by the argument itself.
588
+ *
589
+ * `calledWith(1)` / `calledWith('id')` is what nearly every spec writes, and it is looked up on
590
+ * **every call** of that spy. Through the string map that costs a rendered key per call — an array
591
+ * from `map`, a string per argument, a joined string, then a hash — for a lookup that a `Map` can
592
+ * do on the value with no allocation at all. The configs live in both maps: the string map still
593
+ * owns `configured()` and the arity set, so nothing about the failure messages or the miss check
594
+ * changes.
595
+ *
596
+ * Only shapes where the two agree go in here. A symbol renders by description, so two distinct
597
+ * symbols that share one are the same key in the string map and different keys in a `Map`; `-0`
598
+ * renders apart from `0` and is the same key under `SameValueZero`. Both stay on the string path.
599
+ */
600
+ this.#exactSinglePrimitive = /* @__PURE__ */ new Map();
601
+ }
602
+ #map;
603
+ #matcherConfigs;
604
+ #arities;
605
+ #exactSinglePrimitive;
594
606
  set(key, value) {
595
607
  if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
596
608
  this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
@@ -1,9 +1,9 @@
1
- export { A as AccessorKeysOf, a as AddAccessorsSpies, b as AddCalledWithObservable, c as AddCalledWithPromise, d as AddCalledWithSpyMethods, e as AddObservableSpyMethods, f as AddPromiseSpyMethods, g as AddSpyMethodsByReturnTypes, h as AddThrowHelper, i as AddVoidReturnHelpers, j as AutoSpyRxjsTypes, k as ClassSpyConfiguration, C as ClassType, l as CompleteValueConfig, D as DeepMockProxy, m as DeepPartial, E as ErrorValueConfig, F as Func, M as MethodReturns, n as Mutable, N as NextValueConfig, O as ObservableLike, o as OnlyMethodKeysOf, p as OnlyObservablePropsOf, q as OnlyPropsOf, r as Overload, s as Overloads, P as PropStubValue, S as Spy, t as SpyDisposable, u as SpyOptions, v as StrictSpyConfiguration, w as SubjectLike, x as SubjectOf, U as UnstubbedCall, y as UnstubbedCallHandler, V as ValueConfig, z as ValueConfigPerCall, W as WithMockReturnValue } from './types-CQLPjw8z.js';
1
+ export { A as AccessorKeysOf, a as AddAccessorsSpies, b as AddCalledWithObservable, c as AddCalledWithPromise, d as AddCalledWithSpyMethods, e as AddObservableSpyMethods, f as AddPromiseSpyMethods, g as AddSpyMethodsByReturnTypes, h as AddThrowHelper, i as AddVoidReturnHelpers, j as AutoSpyRxjsTypes, k as ClassSpyConfiguration, C as ClassType, l as CompleteValueConfig, D as DeepMockProxy, m as DeepPartial, E as ErrorValueConfig, F as Func, M as MethodReturns, n as Mutable, N as NextValueConfig, O as ObservableLike, o as OnlyMethodKeysOf, p as OnlyObservablePropsOf, q as OnlyPropsOf, r as Overload, s as Overloads, P as PropStubValue, S as Spy, t as SpyDisposable, u as SpyOptions, v as StrictSpyConfiguration, w as SubjectLike, x as SubjectOf, U as UnstubbedCall, y as UnstubbedCallHandler, V as ValueConfig, z as ValueConfigPerCall, W as WithMockReturnValue } from './types-CroX5c53.js';
2
2
  export { ArgCaptor, AsInstances, AssertMockedOptions, ConstructorMock, ConstructorSpy, FixtureFactory, FlushUntilOptions, MockDeepOptions, ModuleNamespace, ModuleNamespaceOptions, asInstance, asInstances, asSpy, assertMocked, captureArg, clearAutoSpy, createFixture, createFixtureFactory, createFunctionSpy, createMock, createSpyClass, createSpyFromClass, createSpyFromInstance, errorHandler, flushEventLoop, flushEventLoopUntil, mockConstructor, mockDeep, moduleNamespace, narrow, resetAutoSpy, restoreSpiedInstance, settleDynamicImport, stubConstructor, withOverrides } from './bun.js';
3
- export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-Dy5CvsF2.js';
4
- export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-Dp2ZMFqj.js';
3
+ export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BfCKHEzi.js';
4
+ export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-DkSaUWiQ.js';
5
5
  export { d as describeDuplicateCopies, g as getPackageCopies } from './package-identity-B1pqa-Sh.js';
6
- export { A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-BFq3ve6Q.js';
6
+ export { A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-C9ruGqto.js';
7
7
  import 'vitest';
8
8
  import '@angular/core';
9
9
  import '@angular/core/testing';
@@ -1,13 +1,13 @@
1
1
  import { flushEffects } from './chunk-ALFMIDWW.js';
2
2
  export { flushEffects, stable } from './chunk-ALFMIDWW.js';
3
3
  import './chunk-Y4YG7UOK.js';
4
- import { createSpyForToken } from './chunk-5UF3IVFC.js';
4
+ import { createSpyForToken } from './chunk-CWHCYCCQ.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-KJREOXX6.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-YZOB2KRF.js';
7
7
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-ZLF2YBXV.js';
8
- import { createSpyFromClass } from './chunk-GNBP7CNT.js';
9
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-GNBP7CNT.js';
10
- export { createFunctionSpy, errorHandler } from './chunk-E7HYS4K4.js';
8
+ import { createSpyFromClass } from './chunk-VX5DDHAS.js';
9
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-VX5DDHAS.js';
10
+ export { createFunctionSpy, errorHandler } from './chunk-Q74KQJWG.js';
11
11
  import './chunk-PC3FAZT3.js';
12
12
  import { isAutoSpyLike } from './chunk-XRVVZXOM.js';
13
13
  import { withDocs, DOCS_LINKS } from './chunk-B45HLBA4.js';
package/dist/bun.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { u as SpyOptions, C as ClassType, k as ClassSpyConfiguration, o as OnlyMethodKeysOf, S as Spy, m as DeepPartial, D as DeepMockProxy, F as Func, y as UnstubbedCallHandler, g as AddSpyMethodsByReturnTypes } from './types-CQLPjw8z.js';
2
- export { A as AccessorKeysOf, a as AddAccessorsSpies, b as AddCalledWithObservable, c as AddCalledWithPromise, d as AddCalledWithSpyMethods, e as AddObservableSpyMethods, f as AddPromiseSpyMethods, h as AddThrowHelper, i as AddVoidReturnHelpers, j as AutoSpyRxjsTypes, l as CompleteValueConfig, E as ErrorValueConfig, M as MethodReturns, n as Mutable, N as NextValueConfig, O as ObservableLike, p as OnlyObservablePropsOf, q as OnlyPropsOf, r as Overload, s as Overloads, P as PropStubValue, t as SpyDisposable, v as StrictSpyConfiguration, w as SubjectLike, x as SubjectOf, U as UnstubbedCall, V as ValueConfig, z as ValueConfigPerCall, W as WithMockReturnValue } from './types-CQLPjw8z.js';
3
- export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-Dy5CvsF2.js';
4
- export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-Dp2ZMFqj.js';
1
+ import { u as SpyOptions, C as ClassType, k as ClassSpyConfiguration, o as OnlyMethodKeysOf, S as Spy, m as DeepPartial, D as DeepMockProxy, F as Func, y as UnstubbedCallHandler, g as AddSpyMethodsByReturnTypes } from './types-CroX5c53.js';
2
+ export { A as AccessorKeysOf, a as AddAccessorsSpies, b as AddCalledWithObservable, c as AddCalledWithPromise, d as AddCalledWithSpyMethods, e as AddObservableSpyMethods, f as AddPromiseSpyMethods, h as AddThrowHelper, i as AddVoidReturnHelpers, j as AutoSpyRxjsTypes, l as CompleteValueConfig, E as ErrorValueConfig, M as MethodReturns, n as Mutable, N as NextValueConfig, O as ObservableLike, p as OnlyObservablePropsOf, q as OnlyPropsOf, r as Overload, s as Overloads, P as PropStubValue, t as SpyDisposable, v as StrictSpyConfiguration, w as SubjectLike, x as SubjectOf, U as UnstubbedCall, V as ValueConfig, z as ValueConfigPerCall, W as WithMockReturnValue } from './types-CroX5c53.js';
3
+ export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BfCKHEzi.js';
4
+ export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-DkSaUWiQ.js';
5
5
  export { d as describeDuplicateCopies, g as getPackageCopies } from './package-identity-B1pqa-Sh.js';
6
6
  import { Mock } from 'vitest';
7
7
 
@@ -384,8 +384,19 @@ interface ConfiguredEntry {
384
384
  /** Whether an actual call's arguments hit this config. */
385
385
  matches(actualArgs: unknown[]): boolean;
386
386
  }
387
+ /**
388
+ * Identity that survives being bundled twice.
389
+ *
390
+ * tsup inlines a copy of this class into every entry point that reaches it, so a double built by
391
+ * `vitest-auto-spy` and read by `vitest-auto-spy/diagnostics` carries two different `ArgsMap`
392
+ * constructors and `instanceof` answers false. That is how `explainSpy` reported `nothing
393
+ * configured` for every configured double in the published package while every source-level spec
394
+ * passed: the specs import one copy. A registry symbol is the same value in both.
395
+ */
396
+ declare const ARGS_MAP_BRAND: unique symbol;
387
397
  declare class ArgsMap {
388
398
  #private;
399
+ readonly [ARGS_MAP_BRAND] = true;
389
400
  set(key: unknown, value: unknown): void;
390
401
  get(key: unknown): unknown;
391
402
  /**
package/dist/bun.js CHANGED
@@ -1,9 +1,9 @@
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-KJREOXX6.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-YZOB2KRF.js';
4
4
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-ZLF2YBXV.js';
5
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-GNBP7CNT.js';
6
- export { createFunctionSpy, errorHandler } from './chunk-E7HYS4K4.js';
5
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-VX5DDHAS.js';
6
+ export { createFunctionSpy, errorHandler } from './chunk-Q74KQJWG.js';
7
7
  import './chunk-PC3FAZT3.js';
8
8
  import './chunk-XRVVZXOM.js';
9
9
  import './chunk-B45HLBA4.js';
@@ -1,4 +1,4 @@
1
- import { vitestMockAdapter } from './chunk-VZP5MG5N.js';
1
+ import { vitestMockAdapter } from './chunk-RQGMLVRO.js';
2
2
  import { registerMockAdapter } from './shared-state.js';
3
3
 
4
4
  function useVitestAdapter() {
@@ -1,8 +1,14 @@
1
- import { SWEEP_SENTINEL } from './chunk-YHDBRBGU.js';
2
- import { FAST_SPY_BRAND, isThenable } from './chunk-E7HYS4K4.js';
1
+ import { FAST_SPY_BRAND, isThenable } from './chunk-Q74KQJWG.js';
3
2
  import { DISPOSE } from './chunk-PC3FAZT3.js';
4
- import { vi } from 'vitest';
5
- import { guardAccessorSpies } from './shared-state.js';
3
+
4
+ // src/lib/spy-engine.ts
5
+ var engine = "auto-spy";
6
+ function setSpyEngine(next) {
7
+ engine = next;
8
+ }
9
+ function getSpyEngine() {
10
+ return engine;
11
+ }
6
12
 
7
13
  // src/lib/fast-spy.ts
8
14
  var clearEpoch = 0;
@@ -343,56 +349,5 @@ function createFastSpy(implementation, name) {
343
349
  spy[STATE] = void 0;
344
350
  return spy;
345
351
  }
346
- function asVitestMock(mock) {
347
- return mock;
348
- }
349
- var sweepSentinel = vi.fn();
350
- Object.defineProperty(sweepSentinel, SWEEP_SENTINEL, { value: true, enumerable: false, configurable: true });
351
- sweepSentinel.mockClear = function clearAllMocksSweep() {
352
- clearAllFastSpies();
353
- return sweepSentinel;
354
- };
355
- sweepSentinel.mockReset = function resetAllMocksSweep() {
356
- resetAllFastSpies();
357
- return sweepSentinel;
358
- };
359
- sweepSentinel();
360
- var engine = "auto-spy";
361
- function setSpyEngine(next) {
362
- engine = next;
363
- }
364
- function getSpyEngine() {
365
- return engine;
366
- }
367
- function createRunnerMockFn(implementation, name) {
368
- const mock = implementation ? vi.fn(implementation) : vi.fn();
369
- if (name !== void 0) {
370
- mock.mockName(name);
371
- }
372
- return mock;
373
- }
374
- var vitestMockAdapter = guardAccessorSpies({
375
- createMockFn(implementation, name) {
376
- return engine === "auto-spy" ? createFastSpy(implementation, name) : createRunnerMockFn(implementation, name);
377
- },
378
- spyOnGetter(target, property) {
379
- return vi.spyOn(target, property, "get");
380
- },
381
- spyOnSetter(target, property) {
382
- return vi.spyOn(target, property, "set");
383
- },
384
- getCalls(mock) {
385
- return asVitestMock(mock).mock.calls;
386
- },
387
- reset(mock) {
388
- asVitestMock(mock).mockReset();
389
- },
390
- clear(mock) {
391
- asVitestMock(mock).mockClear();
392
- },
393
- restoreImplementation(mock, implementation) {
394
- asVitestMock(mock).mockImplementation(implementation);
395
- }
396
- });
397
352
 
398
- export { getSpyEngine, setSpyEngine, vitestMockAdapter };
353
+ export { clearAllFastSpies, createFastSpy, getSpyEngine, resetAllFastSpies, setSpyEngine };
@@ -1,4 +1,4 @@
1
- import { createSpyFromClass, createAutoMock } from './chunk-GNBP7CNT.js';
1
+ import { createSpyFromClass, createAutoMock } from './chunk-VX5DDHAS.js';
2
2
  import { withDocs, DOCS_LINKS } from './chunk-B45HLBA4.js';
3
3
 
4
4
  // src/lib/track-injections.ts
@@ -181,33 +181,43 @@ function isSameMatcher(configArg, candidateArg) {
181
181
  function isBrandedMatcher(matcher) {
182
182
  return matcher.$$typeof === ASYMMETRIC_MATCHER_BRAND;
183
183
  }
184
+ var ARGS_MAP_BRAND = /* @__PURE__ */ Symbol.for("vitest-auto-spy.args-map");
185
+ var _a;
186
+ _a = ARGS_MAP_BRAND;
184
187
  var ArgsMap = class {
185
- // Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
186
- // plain own property, never walking or polluting the object prototype chain.
187
- #map = /* @__PURE__ */ Object.create(null);
188
- #matcherConfigs = [];
189
- // Argument counts present in the exact map. A call with a count nobody configured cannot be in
190
- // that map — two arg lists of different lengths never serialize to the same string — so the
191
- // serialization can be skipped outright. That matters because the map is consulted on *every*
192
- // invocation of a spy that has any `calledWith` config: without this, `service.load(component)`
193
- // on a spy configured with `calledWith(1)` walks and stringifies the whole component graph to
194
- // build a key that provably cannot match, and throws it away one line later.
195
- #arities = /* @__PURE__ */ new Set();
196
- /**
197
- * The configs of exactly one primitive argument, keyed by the argument itself.
198
- *
199
- * `calledWith(1)` / `calledWith('id')` is what nearly every spec writes, and it is looked up on
200
- * **every call** of that spy. Through the string map that costs a rendered key per call — an array
201
- * from `map`, a string per argument, a joined string, then a hash — for a lookup that a `Map` can
202
- * do on the value with no allocation at all. The configs live in both maps: the string map still
203
- * owns `configured()` and the arity set, so nothing about the failure messages or the miss check
204
- * changes.
205
- *
206
- * Only shapes where the two agree go in here. A symbol renders by description, so two distinct
207
- * symbols that share one are the same key in the string map and different keys in a `Map`; `-0`
208
- * renders apart from `0` and is the same key under `SameValueZero`. Both stay on the string path.
209
- */
210
- #exactSinglePrimitive = /* @__PURE__ */ new Map();
188
+ constructor() {
189
+ this[_a] = true;
190
+ // Prototype-less so a `'__proto__'` (or `'constructor'`) serialized key is a
191
+ // plain own property, never walking or polluting the object prototype chain.
192
+ this.#map = /* @__PURE__ */ Object.create(null);
193
+ this.#matcherConfigs = [];
194
+ // Argument counts present in the exact map. A call with a count nobody configured cannot be in
195
+ // that map — two arg lists of different lengths never serialize to the same string — so the
196
+ // serialization can be skipped outright. That matters because the map is consulted on *every*
197
+ // invocation of a spy that has any `calledWith` config: without this, `service.load(component)`
198
+ // on a spy configured with `calledWith(1)` walks and stringifies the whole component graph to
199
+ // build a key that provably cannot match, and throws it away one line later.
200
+ this.#arities = /* @__PURE__ */ new Set();
201
+ /**
202
+ * The configs of exactly one primitive argument, keyed by the argument itself.
203
+ *
204
+ * `calledWith(1)` / `calledWith('id')` is what nearly every spec writes, and it is looked up on
205
+ * **every call** of that spy. Through the string map that costs a rendered key per call — an array
206
+ * from `map`, a string per argument, a joined string, then a hash — for a lookup that a `Map` can
207
+ * do on the value with no allocation at all. The configs live in both maps: the string map still
208
+ * owns `configured()` and the arity set, so nothing about the failure messages or the miss check
209
+ * changes.
210
+ *
211
+ * Only shapes where the two agree go in here. A symbol renders by description, so two distinct
212
+ * symbols that share one are the same key in the string map and different keys in a `Map`; `-0`
213
+ * renders apart from `0` and is the same key under `SameValueZero`. Both stay on the string path.
214
+ */
215
+ this.#exactSinglePrimitive = /* @__PURE__ */ new Map();
216
+ }
217
+ #map;
218
+ #matcherConfigs;
219
+ #arities;
220
+ #exactSinglePrimitive;
211
221
  set(key, value) {
212
222
  if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
213
223
  this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
@@ -0,0 +1,51 @@
1
+ import { clearAllFastSpies, resetAllFastSpies, getSpyEngine, createFastSpy } from './chunk-CUVQUISO.js';
2
+ import { SWEEP_SENTINEL } from './chunk-YHDBRBGU.js';
3
+ import { vi } from 'vitest';
4
+ import { guardAccessorSpies } from './shared-state.js';
5
+
6
+ function asVitestMock(mock) {
7
+ return mock;
8
+ }
9
+ var sweepSentinel = vi.fn();
10
+ Object.defineProperty(sweepSentinel, SWEEP_SENTINEL, { value: true, enumerable: false, configurable: true });
11
+ sweepSentinel.mockClear = function clearAllMocksSweep() {
12
+ clearAllFastSpies();
13
+ return sweepSentinel;
14
+ };
15
+ sweepSentinel.mockReset = function resetAllMocksSweep() {
16
+ resetAllFastSpies();
17
+ return sweepSentinel;
18
+ };
19
+ sweepSentinel();
20
+ function createRunnerMockFn(implementation, name) {
21
+ const mock = implementation ? vi.fn(implementation) : vi.fn();
22
+ if (name !== void 0) {
23
+ mock.mockName(name);
24
+ }
25
+ return mock;
26
+ }
27
+ var vitestMockAdapter = guardAccessorSpies({
28
+ createMockFn(implementation, name) {
29
+ return getSpyEngine() === "auto-spy" ? createFastSpy(implementation, name) : createRunnerMockFn(implementation, name);
30
+ },
31
+ spyOnGetter(target, property) {
32
+ return vi.spyOn(target, property, "get");
33
+ },
34
+ spyOnSetter(target, property) {
35
+ return vi.spyOn(target, property, "set");
36
+ },
37
+ getCalls(mock) {
38
+ return asVitestMock(mock).mock.calls;
39
+ },
40
+ reset(mock) {
41
+ asVitestMock(mock).mockReset();
42
+ },
43
+ clear(mock) {
44
+ asVitestMock(mock).mockClear();
45
+ },
46
+ restoreImplementation(mock, implementation) {
47
+ asVitestMock(mock).mockImplementation(implementation);
48
+ }
49
+ });
50
+
51
+ export { vitestMockAdapter };
@@ -1,4 +1,4 @@
1
- import { resolveUnstubbedGuard, createFunctionSpy } from './chunk-E7HYS4K4.js';
1
+ import { resolveUnstubbedGuard, createFunctionSpy } from './chunk-Q74KQJWG.js';
2
2
  import { DISPOSE } from './chunk-PC3FAZT3.js';
3
3
  import { runClearHook, runConfigReset, AUTO_SPY_MARK, markAsMock, isMarkedMock, readDeepChildren } from './chunk-XRVVZXOM.js';
4
4
  import { withDocs, DOCS_LINKS } from './chunk-B45HLBA4.js';