vitest-auto-spy 4.2.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +101 -2
- package/README.md +147 -6
- package/dist/angular.d.ts +2 -2
- package/dist/angular.js +276 -7
- package/dist/bun-angular.d.ts +3 -3
- package/dist/bun-angular.js +6 -6
- package/dist/bun.d.ts +72 -2
- package/dist/bun.js +4 -4
- package/dist/{chunk-DSIYS6Y5.js → chunk-D5LDT3W4.js} +1 -1
- package/dist/{chunk-2ZG27FVL.js → chunk-EMASXQDZ.js} +1 -1
- package/dist/{chunk-4KK3ES4P.js → chunk-FFKN6QKI.js} +22 -0
- package/dist/{chunk-4KCYFAJX.js → chunk-FYFF67EN.js} +23 -7
- package/dist/{chunk-5URFSYDT.js → chunk-GAY6LNAM.js} +300 -6
- package/dist/{chunk-WQZ2RKS7.js → chunk-KYAJCFUA.js} +1 -1
- package/dist/{chunk-KEKKEIRG.js → chunk-Z4VRMCW2.js} +1 -1
- package/dist/cli.js +608 -16
- package/dist/console.js +2 -2
- package/dist/diagnostics.d.ts +31 -1
- package/dist/diagnostics.js +350 -1
- package/dist/{expect-emission-BDuFuqTb.d.ts → expect-emission-Dy5CvsF2.d.ts} +27 -25
- package/dist/index.d.ts +2 -2
- package/dist/index.js +444 -111
- package/dist/jasmine.js +4 -4
- package/dist/nestjs.js +5 -5
- package/dist/node.cjs +272 -111
- package/dist/node.d.cts +2 -0
- package/dist/node.d.ts +2 -2
- package/dist/node.js +17 -5
- package/dist/react.d.ts +2 -2
- package/dist/react.js +5 -5
- package/dist/setup.d.ts +69 -11
- package/dist/setup.js +91 -13
- package/dist/shared-state.js +4 -275
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +5 -5
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +6 -6
- package/dist/{zoneless-DGwkbWKm.d.ts → zoneless-LsBDcSNZ.d.ts} +1 -1
- package/package.json +6 -2
- package/skills/vitest-auto-spy/SKILL.md +66 -62
package/AGENTS.md
CHANGED
|
@@ -88,6 +88,8 @@ Do you have a real class at runtime?
|
|
|
88
88
|
├── one spec, a couple of fields → createMock<T>(partial?) → T (no spies)
|
|
89
89
|
└── many specs, one shared model → createFixtureFactory<T>(defaults) → (overrides?) => T
|
|
90
90
|
|
|
91
|
+
Object already built, other code already holds it?
|
|
92
|
+
→ createSpyFromInstance(obj, config?) → Spy<T>, patched IN PLACE
|
|
91
93
|
One standalone function? → createFunctionSpy<Fn>('name')
|
|
92
94
|
Code under test does `new Foo()`? → a real class? createSpyClass(Foo)
|
|
93
95
|
→ only a shape? mockConstructor<T>(() => instance)
|
|
@@ -106,6 +108,37 @@ noise scales with the number of them.
|
|
|
106
108
|
`createMock<T>()` is the one to reach for on data shapes — it returns a plain `T`, so it satisfies a
|
|
107
109
|
`no-type-assertion` lint rule without an `eslint-disable` on every fixture.
|
|
108
110
|
|
|
111
|
+
**`createSpyFromInstance(instance, config?)` is the one case where nothing is constructed.** Every
|
|
112
|
+
factory above builds the double, which is no help once the object exists and other code already
|
|
113
|
+
points at it — a service a factory built, a third-party client, a half-real `TestBed.inject(X)`. It
|
|
114
|
+
patches that object in place and hands the same object back typed as `Spy<T>`, so a closure, a DI
|
|
115
|
+
container or a live subscription that captured it first sees the spies:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const client = new PaymentsClient(config); // real, already wired into the code under test
|
|
119
|
+
const spy = createSpyFromInstance(client);
|
|
120
|
+
|
|
121
|
+
spy.charge.calledWith(100).resolveWith({ ok: true });
|
|
122
|
+
await checkout.pay(100);
|
|
123
|
+
|
|
124
|
+
restoreSpiedInstance(client); // client.charge is the real method again
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Discovery is the object's own function-valued fields **plus** every prototype method up to but not
|
|
128
|
+
including `Object.prototype` — so an arrow-function property needs no `instanceMethodsToSpyOn` here,
|
|
129
|
+
and `hasOwnProperty` / `toString` are never replaced. The configuration is `createSpyFromClass`',
|
|
130
|
+
minus the two options that describe a double being built rather than an object being patched:
|
|
131
|
+
`lazySpies` (the members already exist) and `fillMissing` (an instance is not an erased `abstract`
|
|
132
|
+
declaration). Every write is journaled through the same mechanism as the `mock*Prop` helpers, so
|
|
133
|
+
three ways back compose — `restoreSpiedInstance(instance)` for one object mid-test,
|
|
134
|
+
`restoreMockedProps()` (which `setupAutoSpy()` already runs) for the sweep, and
|
|
135
|
+
`using spy = createSpyFromInstance(client)`, whose dispose **restores** rather than merely resets:
|
|
136
|
+
the only sense disposal can have for an object the consumer owns. A frozen or sealed instance, and a
|
|
137
|
+
member declared `configurable: false`, come back as this package's diagnostic rather than a bare
|
|
138
|
+
`TypeError` (§17). Nothing else in the field does this — `vi.mockObject` is Vitest-only,
|
|
139
|
+
`sinon.createStubInstance` builds a new object from a constructor instead of patching the one you
|
|
140
|
+
hold, and `bun:test` and `node:test` have nothing.
|
|
141
|
+
|
|
109
142
|
**`createFixture<T>(defaults, overrides?)` / `createFixtureFactory<T>(defaults)` are for the model
|
|
110
143
|
that more than one spec builds.** The difference from `createMock` is the `defaults` argument: it is
|
|
111
144
|
a **complete** `T`, checked in full, in one place — so a field the model dropped fails there instead
|
|
@@ -846,6 +879,12 @@ setupAutoSpy({ globalFakeTimers: true });
|
|
|
846
879
|
setEmissionTimeout(100); // the clock is frozen; a real second buys nothing
|
|
847
880
|
```
|
|
848
881
|
|
|
882
|
+
**The code frame these failures open is the spec line, not this package.** The helpers build their
|
|
883
|
+
error inside a `subscribe` or timer callback, so the stack is captured at helper entry and pinned on
|
|
884
|
+
when the failure is finally built; only errors these helpers make themselves are re-anchored, and
|
|
885
|
+
the error `expectError` resolves with keeps the stack of the code under test. Do not wrap them in
|
|
886
|
+
`vi.defineHelper` — its `__VITEST_HELPER__` frame lands last and Vitest then drops the stack whole.
|
|
887
|
+
|
|
849
888
|
**`expectEmission` subscribes when you call it, not when you await it**, and that is load-bearing
|
|
850
889
|
rather than an implementation detail. It is what converts the test whose source has to be poked
|
|
851
890
|
_after_ somebody is listening — a router event, a `Subject` the spec pushes into, anything that
|
|
@@ -1144,6 +1183,17 @@ the realm, not owned by `globalThis`), and with `isolate: false` the next file d
|
|
|
1144
1183
|
own `useFakeTimers` with `Cannot read properties of undefined (reading 'now')`. If you see that,
|
|
1145
1184
|
the file in the stack is not the cause.
|
|
1146
1185
|
|
|
1186
|
+
`restoreWebStorage` is the other repair that is on by default. Vitest copies a DOM environment's
|
|
1187
|
+
globals onto `globalThis` behind `if (k in global) return KEYS.includes(k)`, and neither
|
|
1188
|
+
`localStorage` nor `sessionStorage` is in `KEYS` — both used to arrive only because Node put neither
|
|
1189
|
+
on `globalThis`, so the first half of that condition was false. Node's own Web Storage made the key
|
|
1190
|
+
exist, and the environment's storage stopped arriving: `setItem is not a function` on Node 25,
|
|
1191
|
+
`undefined` on Node 26, under jsdom and happy-dom alike, because the filter runs before either. The
|
|
1192
|
+
suite stays green until a spec touches storage, so this lands as "CI moved to a new Node and eleven
|
|
1193
|
+
unrelated specs died". The repair writes a key, reads it back and removes it — a storage that
|
|
1194
|
+
survives that is left alone, whoever implemented it — and it installs nothing in a `node`
|
|
1195
|
+
environment, which is supposed to have no Web Storage at all.
|
|
1196
|
+
|
|
1147
1197
|
`hookTimeoutHint` is on by default too, and it is the one that pays off on the day a suite lands in
|
|
1148
1198
|
CI. Jest resolves **one** budget — `hook.timeout || getState().testTimeout` for a hook,
|
|
1149
1199
|
`test.timeout || getState().testTimeout` for a body — while Vitest resolves `hookTimeout` on its
|
|
@@ -2104,6 +2154,17 @@ thing to check by hand after the swap: Suites' double answers every property nam
|
|
|
2104
2154
|
stubbed a since-renamed method was passing over nothing and will now fail. Full mapping:
|
|
2105
2155
|
<https://asdalexey.github.io/vitest-auto-spy/migrating-suites>.
|
|
2106
2156
|
|
|
2157
|
+
**A spec importing `@testing-library/angular` usually keeps it.** `render`, `screen` and the query
|
|
2158
|
+
set are a different discipline and have no twin here. What overlaps is the secondary
|
|
2159
|
+
`@testing-library/angular/vitest-utils` entry alone — 52 lines, four exports:
|
|
2160
|
+
`createMock` → `createSpyFromClass`, `createMockWithValues` → `createSpyFromClass(X, { overrides })`,
|
|
2161
|
+
`provideMock` → `provideAutoSpy`, `provideMockWithValues` → `provideAutoSpy(X, { overrides })` —
|
|
2162
|
+
`overrides` and not `returns`, because those values replace the member rather than configure it. Its
|
|
2163
|
+
walk assigns a mock only where `typeof descriptor?.value === 'function'`, so accessors are dropped
|
|
2164
|
+
silently while its `Mock<T>` still types them callable, and it recurses past `Object.prototype`, so
|
|
2165
|
+
`hasOwnProperty` and `toString` end up as `vi.fn()`. Full mapping, verified against the 19.4.2
|
|
2166
|
+
tarball: <https://asdalexey.github.io/vitest-auto-spy/migrating-testing-library-angular>.
|
|
2167
|
+
|
|
2107
2168
|
- **`renderShallow` has no single speed number, and quoting one is a bug.** This repository commits
|
|
2108
2169
|
no harness for the helper, so no surface publishes a ratio for it and none may be invented.
|
|
2109
2170
|
Describe the shape instead: `renderShallow` is flat in the number of children because it never
|
|
@@ -2148,6 +2209,18 @@ and it never throws: the class is reached through the undocumented `mock.constru
|
|
|
2148
2209
|
constructed tracker is probed first and any failure leaves spies on `node:test`'s own tracker.
|
|
2149
2210
|
Spies created **before** the call stay there too. `mock.reset()` in `afterEach` is the fallback.
|
|
2150
2211
|
|
|
2212
|
+
**A `node:test` spy now prints under its method name.** `mock.fn()` takes no name and has no
|
|
2213
|
+
`mockName()`, so a spy inherited the library's internal dispatcher and read back as
|
|
2214
|
+
`[Function: dispatch]` everywhere. The adapter names the *implementation* at creation and lets
|
|
2215
|
+
`mock.fn()` carry that name onto the mock, which is where a `node:test` mock takes its `name` from;
|
|
2216
|
+
`displayName` is set on the mock alongside it. The name survives `mock.reset()`, `mock.restore()`,
|
|
2217
|
+
`resetCalls()` and a `mockImplementation()` swap, and it is what `node:assert` diffs, what
|
|
2218
|
+
`util.inspect()` prints and what this package's own messages read. Do not "simplify" this into
|
|
2219
|
+
`Object.defineProperty(mock, 'name', …)`: redefining `name` drops the function out of V8's fast map
|
|
2220
|
+
and costs +206 B per mock against +65 B for naming at creation, measured over 200 000 mocks. `getMockName()` still does not exist there: read `spy.method.name`. Nothing labels a
|
|
2221
|
+
mock in `node:test`'s reporter output on its own. Full account:
|
|
2222
|
+
<https://asdalexey.github.io/vitest-auto-spy/runtimes/node#spy-names>.
|
|
2223
|
+
|
|
2151
2224
|
---
|
|
2152
2225
|
|
|
2153
2226
|
## 14. `fakeAsync` needs `vitest-auto-spy/zone`
|
|
@@ -2401,6 +2474,8 @@ packages, which a subpath export can never be.
|
|
|
2401
2474
|
| `advanceTimers() requires fake timers` | no fake timers installed | `setupFakeTimers()` or `vi.useFakeTimers()` first |
|
|
2402
2475
|
| `Nothing configured X.method, and strict mode is on` | a strict double was asked for a method no line configured | configure it (`mockReturnValue` / `resolveWith` / `nextWith` / `calledWith`), or `{ strict: false }` on that double (§5) |
|
|
2403
2476
|
| `Cannot redefine property: …` from a library accessor spy | the target is an ES module namespace a bundler inlined | no spy library can win this — give the code a real seam (inject it, pass it in) and spy on that |
|
|
2477
|
+
| `Cannot spy on this instance in place: it is not extensible` | `createSpyFromInstance` was handed a frozen or sealed object | spy it before it is frozen, or build a separate double with `createSpyFromClass` (§2) |
|
|
2478
|
+
| `Cannot mock the property 'X': it is not configurable` | the member was defined with `configurable: false`, so it cannot be redefined | members replaced before it are still restorable — `restoreSpiedInstance(instance)` or `restoreMockedProps()` |
|
|
2404
2479
|
| `overrideComponentProvider(…): the override did not apply` | the component injects a different token, or a later `overrideProvider` won | pass the token the component actually injects (a base class, an `InjectionToken`), and override after nothing else re-configures |
|
|
2405
2480
|
| `the test ended with N unflushed HttpTestingController request(s)` | `enableAngularDiagnostics({ pendingRequests })` — nothing answered them | flush each (`controller.expectOne(url).flush(body)`), or `controller.verify()` where absence is the assertion (§13) |
|
|
2406
2481
|
| `NgModule(s) with an empty runtime scope: …` | `ngModuleScopes` (or `assertNgModuleScopes`) — an AOT test bundle stripped `ɵɵsetNgModuleScope`, so the import contributes nothing | declare what the spec needs in the TestBed module directly; pass only modules expected to bring declarations (§13) |
|
|
@@ -2420,6 +2495,7 @@ packages, which a subpath export can never be.
|
|
|
2420
2495
|
| a spy is never called, no warning | the method is an instance field, not on the prototype | `instanceMethodsToSpyOn`, or `createAutoMock<T>()` |
|
|
2421
2496
|
| `Cannot access '__vi_import_N__' before initialization` | `vi.mock()` on `@angular/core` or a relative path | you cannot mock it — the specs are bundled. Assert the result instead |
|
|
2422
2497
|
| `AggregateError at Object.dispatchError`, for a request nothing asserts on | jsdom really served an `XMLHttpRequest` — `blockNetwork` used to cover only `fetch` | `setupAutoSpy({ blockNetwork: true })`, or `{ xhr: 'empty' }` for tracker pings (§10) |
|
|
2498
|
+
| `localStorage.setItem is not a function`, or `localStorage` undefined | Node's own Web Storage made Vitest's global filter skip the environment's — Node 25 and up, jsdom and happy-dom alike | on by default in `setupAutoSpy()`; `restoreWebStorage()` on its own (§10) |
|
|
2423
2499
|
| `Schedulers cannot synchronously execute watches while scheduling` | a timer from a **previous** file, under `isolate: false` | track and cancel pending timers/frames in the setup file (§10) |
|
|
2424
2500
|
| `signal read during notification phase` | same — a stray `requestAnimationFrame` callback | same |
|
|
2425
2501
|
| an assertion error printed to stderr, every test green and the run exiting 0 | zone.js swallowed a rejection nobody handled | `setupAutoSpy({ strayRejections: true })` fails the test it surfaced in (§10) |
|
|
@@ -2479,6 +2555,18 @@ nothing in the spec: `of(double)` never emitting; `accessorSpies.setters.X` stil
|
|
|
2479
2555
|
`mockReturnValue` missing on a generic method; a `mock*Prop` patch surfacing in a `describe` that
|
|
2480
2556
|
never patched anything.
|
|
2481
2557
|
|
|
2558
|
+
**When the double is the suspect and no message names it, print it.**
|
|
2559
|
+
`import { explainSpy } from 'vitest-auto-spy/diagnostics'` — it sits on that entry, not the root,
|
|
2560
|
+
because ESM re-export is eager and a reader calls it at a breakpoint, not from a spec.
|
|
2561
|
+
`console.log(explainSpy(spy))`
|
|
2562
|
+
reports every spied member with its configured argument lists numbered and every recorded call
|
|
2563
|
+
attributed to the config it hit — or to the default it fell through to, which is the shape of "the
|
|
2564
|
+
method answered `undefined` and nothing said why". `explainSpy(spy, 'load')` narrows to one member,
|
|
2565
|
+
`explainSpy(spy.load)` takes a bare function spy, `calledWith` and `mustBeCalledWith` share one
|
|
2566
|
+
numbering, and it never throws — a foreign mock is reported as one in the text. The wording is a
|
|
2567
|
+
diagnostic and is free to change: print it, never assert on it.
|
|
2568
|
+
<https://asdalexey.github.io/vitest-auto-spy/utilities/explain-spy>.
|
|
2569
|
+
|
|
2482
2570
|
---
|
|
2483
2571
|
|
|
2484
2572
|
## 18. Do not write this
|
|
@@ -2574,8 +2662,19 @@ config describes — `coverage.all` on a Vitest that stopped reading the key, a
|
|
|
2574
2662
|
`coverage.include` in a runner config over a bundle, and a scope so large that `picomatch`
|
|
2575
2663
|
recompiling it per file costs more than collecting the coverage does. It is
|
|
2576
2664
|
worth one run after any large edit to a test suite — especially after a codemod, which is where
|
|
2577
|
-
the eaten glob below came from.
|
|
2578
|
-
|
|
2665
|
+
the eaten glob below came from.
|
|
2666
|
+
|
|
2667
|
+
Two of its checks are about this package's own names. `helper-from-wrong-entry` catches a named
|
|
2668
|
+
import taken from an entry that does not export it — `provideAutoSpy` from the root rather than
|
|
2669
|
+
`/angular` or `/nestjs`, `expectRequest` from anywhere but `/angular-http`. `no-unawaited-helper`
|
|
2670
|
+
catches an `expectEmission` / `expectError` / `stable` / `flushEventLoop` called as a bare statement
|
|
2671
|
+
and dropped, so the promise settles after the test ended and its assertion reports into a later test
|
|
2672
|
+
or nowhere. Both resolve the name against a table **generated from this package's own `exports`
|
|
2673
|
+
map**, which is why they are `doctor` checks and not lint rules: a per-file linter has none. Both
|
|
2674
|
+
are conservative — the callee must have been imported from this package in that same file (a rename
|
|
2675
|
+
with `as` still counts), the call must both begin and end a statement, and the pair goes quiet when
|
|
2676
|
+
the installed major differs from the table's. Neither has a fixer; `doctor` still never writes.
|
|
2677
|
+
Full reference: <https://asdalexey.github.io/vitest-auto-spy/utilities/cli>.
|
|
2579
2678
|
|
|
2580
2679
|
### If you were asked why a suite is slow
|
|
2581
2680
|
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ faster at suite scale ([benchmarks](#benchmarks)) — and for
|
|
|
23
23
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
24
24
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
25
25
|
[](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
|
|
26
|
-
[](#install)
|
|
27
27
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
28
28
|
[](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
|
|
29
29
|
[](./LICENSE)
|
|
@@ -48,10 +48,11 @@ faster at suite scale ([benchmarks](#benchmarks)) — and for
|
|
|
48
48
|
|
|
49
49
|
- 🧪 Reads a class and generates a typed spy for **every** method — no hand-written `vi.fn()` lists
|
|
50
50
|
- 🧬 Or mock from a **type/interface** alone — `createAutoMock<T>()`, no class required
|
|
51
|
+
- 🪛 Or patch the object you already hold, in place — `createSpyFromInstance(client)` spies a real instance without replacing it, so a closure or a DI container that captured it first sees the spies; `restoreSpiedInstance` puts it back
|
|
51
52
|
- 🌐 One `MockAdapter` core — **Vitest**, **Bun** and **`node:test`**, identical API on each
|
|
52
53
|
- 🧩 Framework recipes: **Angular**, **NestJS**, **React**, **Vue/Pinia** and **Svelte**
|
|
53
54
|
- 🎯 Return-type-aware helpers — sync, `Promise`, and `Observable` all get the right API
|
|
54
|
-
- 🔀 `calledWith` / `mustBeCalledWith` argument dispatch
|
|
55
|
+
- 🔀 `calledWith` / `mustBeCalledWith` argument dispatch — and `explainSpy(spy)` prints every configured list next to every recorded call, before anything has failed
|
|
55
56
|
- 📡 First-class RxJS `Observable` spying (`nextWith`, `nextWithValues`, `throwWith`, …)
|
|
56
57
|
- ⚙️ Getter / setter spies via `accessorSpies` — **including on Bun**, where `bun:test`'s own `spyOn(obj, 'prop', 'get')` throws _"does not support accessor properties yet"_ (verified on Bun 1.4.0); no library that generates a double from a class or a type has accessor spies on any runner
|
|
57
58
|
- 🧰 DI & mocking utilities — `provideAutoSpy` / `injectSpy` (Angular, NestJS, Vue), `createFunctionSpy`, `mockReadonlyProp` for signals
|
|
@@ -74,7 +75,7 @@ faster at suite scale ([benchmarks](#benchmarks)) — and for
|
|
|
74
75
|
- 🌀 `fakeAsync` / `waitForAsync` on Vitest — one import of `vitest-auto-spy/zone`; zone.js stays out of every other entry
|
|
75
76
|
- 🧩 Module mocks that prove they applied — `assertMocked`, `moduleNamespace`, for a `vi.mock()` a bundler quietly ignored
|
|
76
77
|
- 🧾 Fixtures without casts — deep-partial `createMock`, `createFixture` / `createFixtureFactory`, `narrow()`, `withOverrides()`, `asInstances()`, `captureArg()`
|
|
77
|
-
- 🚚 A migration you can verify — `vitest-auto-spy/diagnostics`: `compareTestRuns` on the two JSON reports, `summarizeTestRun` / `formatTestRunComparison` to read the answer, `diffByField` for the assertion the reporter collapses
|
|
78
|
+
- 🚚 A migration you can verify — `vitest-auto-spy/diagnostics`: `compareTestRuns` on the two JSON reports, `summarizeTestRun` / `formatTestRunComparison` to read the answer, `diffByField` for the assertion the reporter collapses, `explainSpy` for a double that answered something you did not configure
|
|
78
79
|
- 📏 Lint rules and one-line test-run hygiene — nineteen rules in `vitest-auto-spy/eslint-plugin` (three `--fix`, seven suggestions, four of them for a suite mid-migration off jasmine), `setupAutoSpy()`
|
|
79
80
|
- 🩺 [Editor diagnostics](#editor-diagnostics--webstorm--vs-code) — the same anti-patterns underlined while you type: native ESLint inspections in **WebStorm** and the other JetBrains IDEs, the ESLint extension in **VS Code**, no extra plugin either way
|
|
80
81
|
- 🔎 [`npx vitest-auto-spy doctor`](#the-cli--doctor-perf-codemod-and-init) — suite-level defects **that never fail a run**: a `tsconfig` `include` matching no file, a production module importing a spec, a `@jest-environment` pragma the runner never reads, config left behind for a runner that is gone. Read-only, no config, exits 1 in CI
|
|
@@ -125,6 +126,7 @@ includes — that one import is what keeps `returnSubject()` typed as rxjs's own
|
|
|
125
126
|
- [How to mock](#how-to-mock)
|
|
126
127
|
- [A service behind Angular DI](#how-to-mock-a-service-behind-angular-di)
|
|
127
128
|
- [A service without DI](#how-to-mock-a-service-without-di)
|
|
129
|
+
- [An object the test already holds](#how-to-mock-an-object-the-test-already-holds)
|
|
128
130
|
- [Reading a spy back from DI](#how-to-mock-reading-a-spy-back-from-di)
|
|
129
131
|
- [A whole class's dependencies at once](#how-to-mock-a-whole-classs-dependencies-at-once)
|
|
130
132
|
- [A readonly property or a signal](#how-to-mock-a-readonly-property-or-a-signal)
|
|
@@ -147,6 +149,7 @@ includes — that one import is what keeps `returnSubject()` typed as rxjs's own
|
|
|
147
149
|
- [Migrating from jest-auto-spies](#migrating-from-jest-auto-spies)
|
|
148
150
|
- [Migrating from jasmine-auto-spies](#migrating-from-jasmine-auto-spies)
|
|
149
151
|
- [Migrating from @ngneat/spectator](https://asdalexey.github.io/vitest-auto-spy/migrating-spectator)
|
|
152
|
+
- [Migrating from @testing-library/angular](https://asdalexey.github.io/vitest-auto-spy/migrating-testing-library-angular)
|
|
150
153
|
- [Configuration](#configuration)
|
|
151
154
|
- [Spying instance-assigned callables (`signal()`, arrow props, `signalStore()`)](#spying-instance-assigned-callables-signal-arrow-props-signalstore)
|
|
152
155
|
- [Strict doubles — fail on a method nobody configured](#strict-doubles--fail-on-a-method-nobody-configured)
|
|
@@ -176,6 +179,7 @@ includes — that one import is what keeps `returnSubject()` typed as rxjs's own
|
|
|
176
179
|
- [Which factory, and what it costs](#which-factory-and-what-it-costs)
|
|
177
180
|
- [Utilities](#utilities)
|
|
178
181
|
- [Console spies — `vitest-auto-spy/console`](#console-spies--vitest-auto-spyconsole)
|
|
182
|
+
- [Why a spy answered what it did — `explainSpy`](#why-a-spy-answered-what-it-did--explainspy)
|
|
179
183
|
- [Observable assertions](#observable-assertions)
|
|
180
184
|
- [Test-run hygiene](#test-run-hygiene)
|
|
181
185
|
- [Fake timers](#fake-timers)
|
|
@@ -290,6 +294,8 @@ error tsconfig-glob-matches-nothing libs/users/tsconfig.spec.json
|
|
|
290
294
|
| `coverage-include-recompiles-globs` | A coverage scope large enough that `picomatch` recompiling it per file costs more than the coverage. Info |
|
|
291
295
|
| `jasmine-era-project` | `jasmine-core`, `@types/jasmine`, `karma.conf.*` or `@hirez_io/observer-spy` still installed. Info, not an error |
|
|
292
296
|
| `no-agent-instructions` | No instruction file names the package. A note, not an error |
|
|
297
|
+
| `helper-from-wrong-entry` | A named import taken from an entry that does not export it — `provideAutoSpy` from the root |
|
|
298
|
+
| `no-unawaited-helper` | An `expectEmission` / `stable` / `flushEventLoop` call dropped as a bare statement, so nothing awaits it |
|
|
293
299
|
|
|
294
300
|
The check that motivated the tool: a spec showing `Cannot find name 'vi'` in the editor while
|
|
295
301
|
`tsc --noEmit` reported zero errors. A migration codemod editing `include` had eaten a `/**`,
|
|
@@ -298,6 +304,16 @@ spec tsconfigs still covered their specs.
|
|
|
298
304
|
|
|
299
305
|
`doctor` never writes. There is no `--fix`.
|
|
300
306
|
|
|
307
|
+
The last two checks resolve a **name**, and both read the same table: the entry each helper is
|
|
308
|
+
exported from, generated from this package's own `exports` map by compiling the barrels and reading
|
|
309
|
+
the symbols back out of the compiler. That table is why they are `doctor` checks and not lint rules
|
|
310
|
+
— a per-file linter has none. Both are conservative in the same way: the callee has to have been
|
|
311
|
+
imported from this package in that same file (a rename with `as` still counts), `no-unawaited-helper`
|
|
312
|
+
reports only a call that both begins and ends a statement, and the pair goes quiet when the installed
|
|
313
|
+
major differs from the table's, because a helper moves between entries only in a major. Over this
|
|
314
|
+
repository's own 755 source files they report nothing outside their own fixtures. Neither has a
|
|
315
|
+
fixer.
|
|
316
|
+
|
|
301
317
|
### `perf` — where the CPU time actually goes
|
|
302
318
|
|
|
303
319
|
Vitest prints one summary line per run with a phase breakdown; it is the only place those numbers
|
|
@@ -720,6 +736,48 @@ const gateway = createAutoMock<PaymentGateway>(); // from a type/interface alone
|
|
|
720
736
|
The constructor is never called, so no side effects run. `createAutoMock<T>()` is for the case
|
|
721
737
|
where there is no runtime class to read — an interface, a type alias, an imported `.d.ts`.
|
|
722
738
|
|
|
739
|
+
### How to mock: an object the test already holds
|
|
740
|
+
|
|
741
|
+
Every factory above _constructs_ the double, which is no help once the object exists and other code
|
|
742
|
+
already points at it — a service a factory built, a third-party client, a half-real
|
|
743
|
+
`TestBed.inject(X)`. `createSpyFromInstance` patches that object **in place**:
|
|
744
|
+
|
|
745
|
+
```ts
|
|
746
|
+
import { createSpyFromInstance, restoreSpiedInstance } from 'vitest-auto-spy';
|
|
747
|
+
|
|
748
|
+
const client = new PaymentsClient(config); // real, and already wired into the code under test
|
|
749
|
+
const spy = createSpyFromInstance(client); // same object, now typed as Spy<PaymentsClient>
|
|
750
|
+
|
|
751
|
+
spy.charge.calledWith(100).resolveWith({ ok: true });
|
|
752
|
+
await checkout.pay(100);
|
|
753
|
+
|
|
754
|
+
expect(spy.charge).toHaveBeenCalledWith(100);
|
|
755
|
+
restoreSpiedInstance(client); // client.charge is the real method again
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
Mutating rather than copying is the whole point: anything that captured the object before the spec
|
|
759
|
+
ran — a closure, a DI container, a live subscription — sees the spies. Discovery is the object's own
|
|
760
|
+
function-valued fields _plus_ every prototype method up to but not including `Object.prototype`, so
|
|
761
|
+
an arrow-function property needs no `instanceMethodsToSpyOn` here and `hasOwnProperty` / `toString`
|
|
762
|
+
are never replaced. The configuration is `createSpyFromClass`' — `methodsToSpyOn`,
|
|
763
|
+
`onlyMethodsToSpyOn`, `instanceMethodsToSpyOn`, the array shorthand, `observablePropsToSpyOn`,
|
|
764
|
+
`gettersToSpyOn`, `settersToSpyOn`, `autoSpyAccessors`, `returns`, `overrides`, `strict`,
|
|
765
|
+
`onUnstubbedCall` — minus the two that describe a double being built rather than an object being
|
|
766
|
+
patched: `lazySpies` (the members already exist) and `fillMissing` (an instance is not an erased
|
|
767
|
+
`abstract` declaration).
|
|
768
|
+
|
|
769
|
+
Every write is journaled through the same mechanism as the [`mock*Prop` helpers](#how-to-mock-a-readonly-property-or-a-signal),
|
|
770
|
+
so there are three ways back and they compose: `restoreSpiedInstance(instance)` for one object mid-test,
|
|
771
|
+
`restoreMockedProps()` for the sweep `setupAutoSpy()` already runs, and
|
|
772
|
+
`using spy = createSpyFromInstance(client)`, whose dispose **restores** rather than merely resets —
|
|
773
|
+
the only sense disposal can have for an object the consumer owns. A frozen or sealed instance, and a
|
|
774
|
+
member defined with `configurable: false`, are reported with the object described and the repair
|
|
775
|
+
named rather than as a bare `TypeError`.
|
|
776
|
+
|
|
777
|
+
Nothing else in the field does this: `vi.mockObject` is Vitest-only, `sinon.createStubInstance`
|
|
778
|
+
builds a new object from a constructor instead of patching the one you hold, and `bun:test` and
|
|
779
|
+
`node:test` have nothing.
|
|
780
|
+
|
|
723
781
|
### How to mock: reading a spy back from DI
|
|
724
782
|
|
|
725
783
|
```ts
|
|
@@ -1037,11 +1095,19 @@ Node / Bun / React / Vue project pulls **neither rxjs nor Angular into its runti
|
|
|
1037
1095
|
> file while every Angular consumer imports `/angular` alongside it. The root now reaches the loader
|
|
1038
1096
|
> as **2 modules instead of 8** and `/angular` as **2 instead of 10** — measured at ~0.8 ms less per
|
|
1039
1097
|
> spec file for the root and ~1.0 ms for an Angular consumer, at a cost of ~120 kB in a dev-only
|
|
1040
|
-
> dependency that never reaches a production bundle. The
|
|
1098
|
+
> dependency that never reaches a production bundle. The five modules that hold process-wide state —
|
|
1099
|
+
> `mock-adapter`, `observable-support`, `jasmine-support`, `package-identity` and `emission-timeout` —
|
|
1041
1100
|
> stay in one shared `dist/shared-state.js` that every ESM entry imports, so there is still exactly
|
|
1042
1101
|
> one mock-adapter registry — two copies of it is what `No mock adapter registered` and
|
|
1043
|
-
> `Observable spies require rxjs` used to mean. Only
|
|
1044
|
-
>
|
|
1102
|
+
> `Observable spies require rxjs` used to mean. Only the **state** goes in, never the code that reads
|
|
1103
|
+
> it: `expect-emission` used to be the member, and it dragged its 10 kB of pure helper into every
|
|
1104
|
+
> entry that imports the shared file. Splitting it so that only its `defaultTimeoutMs` cell —
|
|
1105
|
+
> `emission-timeout` — is pinned, while the helper is code-split normally, took **−10.0 kB** off the
|
|
1106
|
+
> module graph of `/rxjs`, `/console`, `/nestjs`, `/setup`, `/jasmine`, `/jasmine-compat` and
|
|
1107
|
+
> `/dom-stubs`, none of which export an emission helper, and **−2.5 kB** off the eight entries that
|
|
1108
|
+
> do — module count unchanged on every entry, `/setup` min+gzip 12 092 → 12 072 B, measured
|
|
1109
|
+
> 2026-09-04. Only these two entries: de-chunking them all costs +429 kB and duplicates the
|
|
1110
|
+
> registries.
|
|
1045
1111
|
|
|
1046
1112
|
```ts
|
|
1047
1113
|
import { createSpyFromClass } from 'vitest-auto-spy';
|
|
@@ -1481,6 +1547,14 @@ is `createNestUnit(S)` and `TestBed.sociable(S).expose(D).compile()` is
|
|
|
1481
1547
|
refuses, is in
|
|
1482
1548
|
[Migrating from @suites/unit](https://asdalexey.github.io/vitest-auto-spy/migrating-suites).
|
|
1483
1549
|
|
|
1550
|
+
On [`@testing-library/angular`](https://github.com/testing-library/angular-testing-library) there is
|
|
1551
|
+
one page here that tells you to **keep** the library you came from. `render`, `screen` and the query
|
|
1552
|
+
set have no twin in this package and should not move; what overlaps is the secondary
|
|
1553
|
+
`/vitest-utils` entry point alone — 52 lines, four exports, `createMock` → `createSpyFromClass` and
|
|
1554
|
+
`provideMock` → `provideAutoSpy`, with the eager walk and the two defects
|
|
1555
|
+
[above](#testing-libraryangular-vitest-utils) as the reason to make the swap:
|
|
1556
|
+
[Migrating from @testing-library/angular](https://asdalexey.github.io/vitest-auto-spy/migrating-testing-library-angular).
|
|
1557
|
+
|
|
1484
1558
|
## Configuration
|
|
1485
1559
|
|
|
1486
1560
|
```ts
|
|
@@ -2390,6 +2464,7 @@ single-purpose utility you can pick up independently — they all ride on the sa
|
|
|
2390
2464
|
| `moduleNamespace(exports, opts?)` | core | The `vi.mock` factory result an interop probe recognises — `default` + `__esModule` in place |
|
|
2391
2465
|
| `diffByField(actual, expected)` | core | Which field of an array of records moved, and in how many elements — the diff the reporter collapses |
|
|
2392
2466
|
| `captureArg<T>()` | core | Take hold of a callback or config the code under test built, instead of describing its shape — assertions only, never `calledWith` |
|
|
2467
|
+
| `explainSpy(spy, method?)` | `/diagnostics` | Every configured argument list next to every recorded call, each attributed to the config it hit — before anything failed |
|
|
2393
2468
|
| `asInstances(...spies)` | core | `asInstance` for a whole argument list — one edit against one compiler error, not five |
|
|
2394
2469
|
| `narrow(value, guard)` / `narrow.byKey` / `narrow.observable` | core | The branch of a union a test knows it got, failing with the shape the value actually had |
|
|
2395
2470
|
| `withOverrides(model, overrides?)` | core | A fixture from a model instance: its getters read once, as data — a spread drops them |
|
|
@@ -2417,6 +2492,7 @@ single-purpose utility you can pick up independently — they all ride on the sa
|
|
|
2417
2492
|
| `installPerTest(install)` | `/setup` | Re-install a stub before every test of the block — a `describe`-level stub is restored away after the first |
|
|
2418
2493
|
| `setupAngularTestEnv(opts)` | `/angular` | Zone and zoneless spec files in one worker, switching platforms per file |
|
|
2419
2494
|
| `restoreTimerGlobals()` | `/setup` | Put back timer globals that uninstalling the fakes deleted rather than restored |
|
|
2495
|
+
| `restoreWebStorage(options?)` | `/setup` | Give `globalThis` a `localStorage` / `sessionStorage` that work when the runner's copy never arrived ([details](#test-run-hygiene)) |
|
|
2420
2496
|
| `trackMockRegistry()` / `keepMockRegistered(mock)` / `restoreLongLivedImplementations()` | `/setup` | Keep @vitest/spy's mock registry to the mocks that outlive a file; mark one the split would miss; put back an implementation a cross-file `vi.resetAllMocks()` dropped ([details](#test-run-hygiene)) |
|
|
2421
2497
|
| `trackNodeMocks()` / `pruneNodeMocks()` / `countNodeMocks()` | `/node` | Give this library its own `node:test` `MockTracker` so a dropped spy is freed — 21× less retained heap; sweep by hand, and read the count back |
|
|
2422
2498
|
| `setSpyEngine(engine)` / `getSpyEngine()` | `/setup` | Build method spies from this library's own mock (`'auto-spy'`, the default) or from `vi.fn()` (`'runner'`) ([details](#the-spy-engine)) |
|
|
@@ -2477,6 +2553,47 @@ service.doWork();
|
|
|
2477
2553
|
expect(fakeConsole.info).toHaveBeenCalledWith('done');
|
|
2478
2554
|
```
|
|
2479
2555
|
|
|
2556
|
+
### Why a spy answered what it did — `explainSpy`
|
|
2557
|
+
|
|
2558
|
+
`mustBeCalledWith` already prints wanted next to actual — but only on the call that breaks. While a
|
|
2559
|
+
test is red for some _other_ reason, the question is different: which of my configs did this call
|
|
2560
|
+
hit, and which one never fired at all. `explainSpy` answers it on demand.
|
|
2561
|
+
|
|
2562
|
+
```ts
|
|
2563
|
+
import { explainSpy } from 'vitest-auto-spy/diagnostics';
|
|
2564
|
+
|
|
2565
|
+
console.log(explainSpy(users)); // every spied member; explainSpy(users, 'load') for one, explainSpy(users.load) for a bare spy
|
|
2566
|
+
```
|
|
2567
|
+
|
|
2568
|
+
```text
|
|
2569
|
+
[vitest-auto-spy] explainSpy
|
|
2570
|
+
|
|
2571
|
+
load — 3 calls, 2 configured
|
|
2572
|
+
configured:
|
|
2573
|
+
#1 calledWith(1)
|
|
2574
|
+
#2 calledWith(Any<String>)
|
|
2575
|
+
calls:
|
|
2576
|
+
#1 load(1) -> matched #1
|
|
2577
|
+
#2 load(2) -> no configured arguments matched; the default value was used
|
|
2578
|
+
#3 load('ada') -> matched #2
|
|
2579
|
+
|
|
2580
|
+
save — 1 call, nothing configured
|
|
2581
|
+
calls:
|
|
2582
|
+
#1 save('ada')
|
|
2583
|
+
|
|
2584
|
+
remove — never called, 1 configured
|
|
2585
|
+
configured:
|
|
2586
|
+
#1 mustBeCalledWith(9)
|
|
2587
|
+
```
|
|
2588
|
+
|
|
2589
|
+
`calledWith` and `mustBeCalledWith` share one numbering, so a call names a single number whichever
|
|
2590
|
+
chain answered it. An accessor spy appears as `get name` / `set name`, read from the double's
|
|
2591
|
+
`accessorSpies` bag so that naming one never invokes the live accessor. It never throws — a foreign
|
|
2592
|
+
mock, or anything that is not one of this library's doubles, is reported as one in the text, because
|
|
2593
|
+
this is reached from a spec that is already failing. The wording is a diagnostic, not an API: print
|
|
2594
|
+
it, never assert on it. Full reference:
|
|
2595
|
+
[explainSpy](https://asdalexey.github.io/vitest-auto-spy/utilities/explain-spy).
|
|
2596
|
+
|
|
2480
2597
|
## Observable assertions
|
|
2481
2598
|
|
|
2482
2599
|
`expect(...)` inside a `subscribe()` callback is the most common way to write a test that passes
|
|
@@ -2517,6 +2634,16 @@ saved$ did not emit within 1000 ms (0 emission(s) received). Either the stream n
|
|
|
2517
2634
|
the trigger and any provider spy feeding it — or it is slower than the timeout; …
|
|
2518
2635
|
```
|
|
2519
2636
|
|
|
2637
|
+
**The code frame opens your spec line, not this package.** These helpers build their failure inside
|
|
2638
|
+
a `subscribe` or timer callback, long after the call returned, so the stack the runner used to see
|
|
2639
|
+
started in `node_modules/vitest-auto-spy/…` and carried no spec frame at all. The stack is now
|
|
2640
|
+
captured at helper entry, before anything subscribes, and pinned onto the failure when it is finally
|
|
2641
|
+
built — so the frame the reporter shows is the `await expectEmission(…)` line. Only errors these
|
|
2642
|
+
helpers build themselves are re-anchored: the error `expectError` resolves with belongs to the code
|
|
2643
|
+
under test and keeps the stack it was created with. `vi.defineHelper`, which covers the helpers that
|
|
2644
|
+
throw while the caller's frame is still live, cannot serve these — its `__VITEST_HELPER__` frame
|
|
2645
|
+
lands last and Vitest then drops the stack whole, code frame included.
|
|
2646
|
+
|
|
2520
2647
|
| Option | Default | Notes |
|
|
2521
2648
|
| --------- | ------- | ------------------------------------------------------------ |
|
|
2522
2649
|
| `timeout` | `1000` | Milliseconds to wait. `0` waits indefinitely |
|
|
@@ -2607,6 +2734,16 @@ expensive to diagnose when it is missing. The first three are on by default:
|
|
|
2607
2734
|
which is a fact rather than a guess, and names the `setImmediate` case that reaches this with no
|
|
2608
2735
|
timer in sight: a request matching no Express route is ended by `finalhandler` on `setImmediate`,
|
|
2609
2736
|
so the 404 is never written and a routing mistake is reported as a slow test.
|
|
2737
|
+
11. **Web Storage the runner never handed over.** On by default, because it only ever repairs.
|
|
2738
|
+
Vitest copies a DOM environment's globals onto `globalThis` behind `if (k in global) return
|
|
2739
|
+
KEYS.includes(k)`, and neither `localStorage` nor `sessionStorage` is in `KEYS` — they used to
|
|
2740
|
+
arrive only because Node put neither on `globalThis`, so the first half was false. Node's own
|
|
2741
|
+
Web Storage made the key exist, and now the environment's storage never arrives: `setItem is
|
|
2742
|
+
not a function` on Node 25, `undefined` on Node 26, under jsdom and happy-dom alike, since the
|
|
2743
|
+
filter runs before either. A suite stays green with this broken — only the specs that touch
|
|
2744
|
+
storage fail — so it arrives as "CI moved to a new Node and eleven unrelated specs died". The
|
|
2745
|
+
repair decides by using the storage rather than looking at it, replaces only one that cannot
|
|
2746
|
+
keep a value, and installs nothing at all in a `node` environment.
|
|
2610
2747
|
|
|
2611
2748
|
| Option | Default | Notes |
|
|
2612
2749
|
| --------------------- | --------- | ------------------------------------------------------------------------------------- |
|
|
@@ -2620,6 +2757,7 @@ expensive to diagnose when it is missing. The first three are on by default:
|
|
|
2620
2757
|
| `guardGlobals` | `'off'` | Report a test that redefines a global property as non-configurable |
|
|
2621
2758
|
| `globalFakeTimers` | `false` | Fake timers for every test **and between them** — Jest's `enableGlobally` |
|
|
2622
2759
|
| `restoreTimerGlobals` | `true` | Put back timer globals that uninstalling the fakes deleted |
|
|
2760
|
+
| `restoreWebStorage` | `true` | Give the run a `localStorage` / `sessionStorage` that work |
|
|
2623
2761
|
| `pruneMockRegistry` | `false` | Keep @vitest/spy's ever-growing mock registry to the mocks that outlive a file |
|
|
2624
2762
|
| `hookTimeoutHint` | `true` | Explain a hook that ran out of `hookTimeout` while `testTimeout` is larger |
|
|
2625
2763
|
| `frozenClockHint` | `true` | Explain a timeout that happened because nothing advanced the fake clock |
|
|
@@ -3015,6 +3153,8 @@ another, and the next one is in that same file.
|
|
|
3015
3153
|
| Export | Description |
|
|
3016
3154
|
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
3017
3155
|
| `createSpyFromClass(Class, methodsOrConfig?)` | Build a fully-typed `Spy<T>` from a class |
|
|
3156
|
+
| `createSpyFromInstance(instance, methodsOrConfig?)` | Patch an object the test already holds **in place**, so everything that captured it sees the spies |
|
|
3157
|
+
| `restoreSpiedInstance(instance)` | Put one spied instance back — `restoreMockedProps()` and `using` do the same, and all three compose |
|
|
3018
3158
|
| `createAutoMock<T>(overrides?, config?)` | Build a `Spy<T>` from a **type/interface** alone (Proxy, no class); `{ returns, observablePropsToSpyOn }` configure it |
|
|
3019
3159
|
| `createMock<T>(partial?)` | Build a plain, spy-free `T` from the fields a test seeds — for data shapes the code under test reads |
|
|
3020
3160
|
| `createFixture<T>(defaults, overrides?)` / `createFixtureFactory<T>(defaults)` | A model written out and checked once, stamped into a fresh copy per test — for the fixture eight specs would otherwise each keep a copy of |
|
|
@@ -3063,6 +3203,7 @@ another, and the next one is in that same file.
|
|
|
3063
3203
|
| `guardGlobalPatches(reaction)` / `installPerTest(install)` _(`/setup`)_ | Name the test that sealed a global property; re-install a stub before every test |
|
|
3064
3204
|
| `consoleDebugSpy` … `consoleWarnSpy` _(`/console`)_ | Silent typed spies replacing the global `console` methods on import |
|
|
3065
3205
|
| `installConsoleSpies()` / `resetConsoleSpies()` / `restoreConsole()` | Install / clear / undo the console spies |
|
|
3206
|
+
| `explainSpy(spy, method?)` _(`/diagnostics`)_ | Every configured argument list next to every recorded call, attributed to the config it hit |
|
|
3066
3207
|
| `errorHandler` | The `mustBeCalledWith` argument-mismatch error helper |
|
|
3067
3208
|
|
|
3068
3209
|
**Spied sync method:** `mockReturnValue`, `calledWith(...)`, `mustBeCalledWith(...)` — `calledWith`
|
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-
|
|
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-LsBDcSNZ.js';
|
|
2
2
|
import { InjectionToken, Provider, Type, Signal, WritableSignal } from '@angular/core';
|
|
3
3
|
import { TestAPI } from 'vitest';
|
|
4
4
|
import { C as ClassType, S as Spy, k as ClassSpyConfiguration, o as OnlyMethodKeysOf, g as AddSpyMethodsByReturnTypes } from './types-CQLPjw8z.js';
|
|
5
5
|
export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-CAqxzlhV.js';
|
|
6
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-
|
|
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';
|
|
8
8
|
import '@angular/core/testing';
|
|
9
9
|
|
|
10
10
|
/**
|