vitest-auto-spy 5.15.0 → 5.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -255,6 +255,12 @@ reads the member, not where the provider literal is evaluated. A `{ set }` seed
255
255
  and takes the write. Both used to be flattened as the double was built, which turned a throwing
256
256
  seed into a failure during `TestBed.configureTestingModule`, three frames from the branch under test.
257
257
 
258
+ A **registration** is no exception, and it was the half that stayed broken one release longer: the
259
+ merge that puts `registerAutoSpyDefaults` under a call site copied both sides with a spread, so a
260
+ seeded getter was flattened on any class or token the registry knows — whether or not the
261
+ registration names that key — while the same seed stayed live on one it does not. The merge copies
262
+ descriptors now, and the seed behaves the same either way.
263
+
258
264
  ### What a Proxy-backed double cannot do
259
265
 
260
266
  `createAutoMock` and `mockDeep` build a Proxy, not an object, and there is one place where the
@@ -3183,7 +3189,7 @@ blanket downgrade so those keep their severity; do not copy the two names into a
3183
3189
  | `no-inject-before-override` | `error` | — | `TestBed.inject()` / `injectSpy()` / `renderShallow()` in a hook, in a suite that still calls `override*` |
3184
3190
  | `no-private-member-access` | `error` | — | `instance['privateMember']`, `(instance as any).privateMember` (and `as unknown as`, and a decoy type), `vi.spyOn(Object.getPrototypeOf(x), 'm')` → drive the member through the public API. **Type-aware**: silent without `parserOptions.project`, and silent on an index signature |
3185
3191
  | `no-dead-schemas` | `error` | — | `schemas` on a testing module with no `declarations` — the schema applies to nothing; the file decides, so a `declarations` in another `configureTestingModule` call silences it |
3186
- | `no-import-time-spread` | `error` | suggest | `export const x = [...Imported]` at module scope → a `TypeError` while the bundle loads |
3192
+ | `no-import-time-spread` | `error` | suggest | `export const x = [...Imported]` at module scope → a `TypeError`, or a silently empty object, while the bundle loads |
3187
3193
  | `no-unregistered-inject-spy` | `error` | — | `injectSpy(X)` for a token this file never registered → the real instance, whose spy helpers exist only for the compiler |
3188
3194
  | `prefer-render-shallow` | `warn` | suggest | `TestBed.createComponent` in a file that never reads the template → `renderShallow(X)`; 0.24× the per-test cycle at 100 children |
3189
3195
  | `prefer-set-inputs` | `warn` | suggest | a run of `fixture.componentRef.setInput('title', v)` on one fixture → `await setInputs(fixture, { title: v })` — the name is resolved against the compiled definition before the first write (an undeclared one is an `NG0303` and no change) and the value is typed. The run collapses into one call and a `detectChanges()` under it goes; offered, not applied, because `stable()` ticks and a zone.js suite answers that with `NG0101` |
@@ -3275,7 +3281,12 @@ passes: `export const events = [...BaseEvents]` at module scope raises
3275
3281
  `Spread syntax requires ...iterable[Symbol.iterator] to be a function` when a shared chunk is
3276
3282
  evaluated while the binding it re-exports is still `undefined`. Safe under `tsc` and under a
3277
3283
  browser's ESM loader, which is why nothing else catches it. A function body and an instance field are
3278
- not reported (they run later); a `static` field is.
3284
+ not reported (they run later); a `static` field is. An **object** spread is reported through a second
3285
+ message, `noImportTimeSpreadObject`, because that half fails without failing: `[...undefined]` and
3286
+ `f(...undefined)` throw, `{ ...undefined }` is `{}`, so `{ ...ShelfItemTypeEnum, ...Local }` loads
3287
+ clean and every key it meant to copy reads `undefined` for the rest of the run. One message cannot
3288
+ carry both: a reader sent looking for `Spread syntax requires …` in an object spread finds no such
3289
+ error in the log and takes the report for a false positive.
3279
3290
 
3280
3291
  `prefer-as-spy` is the one a migration meets in bulk: a `jest-auto-spies` suite writes
3281
3292
  `TestBed.inject(X) as Spy<X>` once per injected double, and that cast fails here with `TS2352`.
@@ -3461,6 +3472,7 @@ packages, which a subpath export can never be.
3461
3472
  | `setInputs: … declares no input named …` | the key is not an input of that component — a typo, an input renamed since, or one of its own fields | set the names the message lists; a signal the component owns is moved through the signal (§13) |
3462
3473
  | `setInputs: X carries no ɵcmp, so there are no inputs to set` | the fixture's `componentType` is not a compiled `@Component` — a `@Directive` or `@Pipe` class, or one Angular never compiled (a barrel import that resolved to `undefined`) | pass a component fixture; a directive takes its inputs through the host element that applies it (`createDirectiveHost`), and for `undefined` import the class from its own file (§13) |
3463
3474
  | `TypeError: dependencies is not a function`, from `renderShallow({ keepTemplate: true })` | the compiled `ɵcmp.dependencies` is the flat array AOT emits when no cycle forced a factory, and the trim called it | upgrade — all three shapes (array, factory, `null`) are read; nothing to change in the spec |
3475
+ | `renderShallow(X, { keepTemplate: true }): … declared by an NgModule rather than standalone` | an AOT dependency list: ngtsc flattened an imported `NgModule`'s exported declarations into it, and Angular takes only standalone declarations and `NgModule`s in `imports` | drop `keepTemplate` when the spec reads TypeScript state only, or build the component with `TestBed` directly and keep its compiled scope — the declarations named are not the thing to change |
3464
3476
  | `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` |
3465
3477
  | `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) |
3466
3478
  | `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` |
@@ -3552,6 +3564,7 @@ diagnostic and is free to change: print it, never assert on it.
3552
3564
  | `it('x', (done) => …)` / `beforeEach((done) => …)` | `async` + `await` — Vitest passes a `TestContext`, not `done` |
3553
3565
  | `{ ...modelInstance, flag: true }` (drops every getter) | `withOverrides(modelInstance, { flag: true })` |
3554
3566
  | `if ('params' in link) … else throw` in every spec | `narrow.byKey(link, 'params')` |
3567
+ | `const x = a?.b; assert.exists(x); … x …` on every optional read | `narrow.defined(a?.b)` — it returns the value, so the narrowing sits in the expression |
3555
3568
  | five `asInstance(...)` in one call | `...asInstances(a, b, c, d, e)` |
3556
3569
  | `vi.stubGlobal('Image', vi.fn(() => ({ src: '' })))` | `stubConstructor(globalThis, 'Image', () => ({ src: '' }))` |
3557
3570
  | `Object.defineProperty(document, 'cookie', { value })` | `mockValueProp(document, 'cookie', value)` |
package/README.md CHANGED
@@ -23,7 +23,7 @@ faster at suite scale ([benchmarks](#benchmarks)) — and for
23
23
  [![downloads per month](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.npmjs.org%2Fdownloads%2Fpoint%2Flast-month%2Fvitest-auto-spy&query=%24.downloads&color=brightgreen&logo=npm&label=downloads%2Fmonth)](https://www.npmjs.com/package/vitest-auto-spy)
24
24
  [![downloads over 18 months](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fapi.npmjs.org%2Fdownloads%2Fpoint%2F2026-06-21%3A2030-01-01%2Fvitest-auto-spy&query=%24.downloads&color=brightgreen&logo=npm&label=downloads%2F18mo)](https://www.npmjs.com/package/vitest-auto-spy)
25
25
  [![CI](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml/badge.svg)](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
26
- [![minzipped size](https://img.shields.io/badge/minzip-17.5%20kB-brightgreen)](#install)
26
+ [![minzipped size](https://img.shields.io/badge/minzip-17.6%20kB-brightgreen)](#install)
27
27
  [![types](https://img.shields.io/npm/types/vitest-auto-spy?logo=typescript&logoColor=white)](https://www.npmjs.com/package/vitest-auto-spy)
28
28
  [![coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
29
29
  [![license](https://img.shields.io/npm/l/vitest-auto-spy?color=blue)](./LICENSE)
@@ -2043,6 +2043,10 @@ const platform = createAutoMock<PlatformSupport>({
2043
2043
  expect(() => platform.transceiver).toThrow(); // at the read, not at `TestBed.configureTestingModule`
2044
2044
  ```
2045
2045
 
2046
+ A class or token registered with `registerAutoSpyDefaults` behaves the same: the merge that puts a
2047
+ registration under the call site copies descriptors rather than spreading them, so a seeded getter
2048
+ is not flattened by the mere existence of a registration.
2049
+
2046
2050
  For a double the code under test only **reads** — a DTO, a route snapshot, a config object — that
2047
2051
  caveat is the wrong trade, and [`createMock<T>()`](#utilities) is the other half of the pair: it
2048
2052
  returns a plain `T` built from the fields you seed, with no spies anywhere.
@@ -2404,7 +2408,14 @@ it, or `null` for a component that imports nothing — and which one is not deci
2404
2408
  AOT: JIT always emits the factory, AOT emits the array unless a cycle between two components forces
2405
2409
  it to defer the read. All three are handled; calling the array unconditionally was a
2406
2410
  `TypeError: dependencies is not a function` on an AOT-compiled component with no cycle in its
2407
- imports. A child re-exported by an imported `NgModule` still renders — the module is kept whole.
2411
+ imports. A child re-exported by an imported `NgModule` still renders **under JIT**, where the module
2412
+ is in that list and is kept whole. Under AOT it is not: ngtsc resolves the module at compile time and
2413
+ flattens its exported declarations into the list, so a `standalone: false` pipe or directive is what
2414
+ arrives, and Angular takes only standalone declarations and `NgModule`s in `imports`. That scope
2415
+ cannot be rebuilt from what the definition holds, so `renderShallow` refuses it by name instead of
2416
+ letting Angular answer `The "X" pipe … is not standalone` — a message aimed at the pipe's author,
2417
+ about a pipe that is fine and that works under JIT. Drop `keepTemplate` when the spec reads
2418
+ TypeScript state only, or build the component with `TestBed` directly and keep its compiled scope.
2408
2419
  Reach for it when the spec reads
2409
2420
  something the template creates, and keep `keepChildren` for the handful of children it genuinely
2410
2421
  needs resolvable. Full write-up:
@@ -2878,7 +2889,7 @@ single-purpose utility you can pick up independently — they all ride on the sa
2878
2889
  | `captureArg<T>()` | core | Take hold of a callback or config the code under test built, instead of describing its shape — assertions only, never `calledWith` |
2879
2890
  | `explainSpy(spy, method?)` | `/diagnostics` | Every configured argument list next to every recorded call, each attributed to the config it hit — before anything failed |
2880
2891
  | `asInstances(...spies)` | core | `asInstance` for a whole argument list — one edit against one compiler error, not five |
2881
- | `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 |
2892
+ | `narrow(value, guard)` / `narrow.byKey` / `narrow.defined` / `narrow.observable` | core | The branch of a union a test knows it got, failing with the shape the value actually had |
2882
2893
  | `withOverrides(model, overrides?)` | core | A fixture from a model instance: its getters read once, as data — a spread drops them |
2883
2894
  | `compareTestRuns(a, b, root?)` | core | Whether a migration lost a test — the set of `file::name`, which matching counters cannot answer |
2884
2895
  | `provideAutoSpyForToken(TOKEN, overrides?)` | `/angular` | The provider for a dependency behind an `InjectionToken` — no stand-in class to write |
@@ -3456,7 +3467,7 @@ export can never be.
3456
3467
  | `no-inject-before-override` | `error` | — | `TestBed.inject()` / `injectSpy()` / `renderShallow()` in a hook, in a suite that still calls `override*` |
3457
3468
  | `no-private-member-access` | `error` | — | `instance['privateMember']`, `(instance as any).privateMember` and `vi.spyOn(Object.getPrototypeOf(x), 'm')` — the three spellings that get past `private`; **type-aware**, and silent without `parserOptions.project` |
3458
3469
  | `no-dead-schemas` | `error` | — | `schemas` on a testing module that declares nothing — a charm protecting nobody, and one that starts working the day `declarations` arrive |
3459
- | `no-import-time-spread` | `error` | suggest | `export const x = [...Imported]` at module scope → a `TypeError` while the bundle loads |
3470
+ | `no-import-time-spread` | `error` | suggest | `export const x = [...Imported]` at module scope → a `TypeError`, or a silently empty object, while the bundle loads |
3460
3471
  | `no-unregistered-inject-spy` | `error` | — | `injectSpy(X)` for a token this file never registered → the real instance, whose spy helpers exist only for the compiler |
3461
3472
  | `prefer-render-shallow` | `warn` | suggest | `TestBed.createComponent` in a file that never reads the template → `renderShallow(X)`; 0.24× the per-test cycle at 100 children |
3462
3473
  | `prefer-set-inputs` | `warn` | suggest | a run of `fixture.componentRef.setInput('title', v)` on one fixture → `await setInputs(fixture, { title: v })`, which resolves every name against the compiled definition before it writes one — an undeclared name is an `NG0303` on the console and no change at all — and types the value. The suggestion collapses the run, drops a `detectChanges()` under it and makes the callback `async`; it is offered rather than applied, because `stable()` ticks and a zone.js suite can answer that with `NG0101` |
@@ -3538,7 +3549,12 @@ while a binding it re-exports is still `undefined`, so the spread throws
3538
3549
  `Spread syntax requires ...iterable[Symbol.iterator] to be a function`. An AST pass found exactly
3539
3550
  seven sites in an 8 673-file workspace, which is small enough to flag at the cursor. A function body
3540
3551
  and an instance field are deliberately not reported — they run later than the module does — while a
3541
- `static` field is.
3552
+ `static` field is. An **object** spread of the same binding gets a message of its own,
3553
+ because it fails without failing: `[...undefined]` throws, `{ ...undefined }` is `{}`, so
3554
+ `export const ItemType = { ...ShelfItemTypeEnum, ...Local }` loads clean and every key it meant to
3555
+ copy reads `undefined` for the rest of the run. Told to look for `Spread syntax requires …`, a
3556
+ reader finds no such error and takes the report for a false positive — so the object message opens
3557
+ by saying there is nothing to find.
3542
3558
 
3543
3559
  `no-unregistered-inject-spy` catches `injectSpy(X)` for a token nothing in the file
3544
3560
  registered as an auto-spy. What comes back is whatever Angular DI already had — the real service, or
package/dist/angular.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { o as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, d as RunCounter, S as SettleResourceOptions, e as ShallowRender, f as SpyRegistry, g as StableOptions, h as createWithAutoSpies, i as flushEffects, j as injectSpy, p as provideAutoSpy, q as provideAutoSpyForToken, r as renderShallow, k as runEffect, s as setInputs, l as settleResource, m as stable, t as trackEffectRuns, n as trackRecomputations } from './track-signal-runs-C-DgtCj9.js';
1
+ export { o as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, d as RunCounter, S as SettleResourceOptions, e as ShallowRender, f as SpyRegistry, g as StableOptions, h as createWithAutoSpies, i as flushEffects, j as injectSpy, p as provideAutoSpy, q as provideAutoSpyForToken, r as renderShallow, k as runEffect, s as setInputs, l as settleResource, m as stable, t as trackEffectRuns, n as trackRecomputations } from './track-signal-runs-BOfsdYsC.js';
2
2
  import { InjectionToken, Provider, Type, WritableSignal, Signal, ProviderToken, FactoryProvider, AbstractType, Injector, ValueProvider } from '@angular/core';
3
3
  import { A as AutoMockConfiguration, D as DeepReadonly } from './expect-emission-CmN9ADyN.js';
4
4
  export { C as CallbackSubscribable, E as EmissionObserver, b as EmissionOptions, c as EmissionSource, S as SubscribableLike, g as expectCompletion, h as expectEmission, i as expectEmissions, j as expectError, k as expectNoEmission, s as setEmissionTimeout } from './expect-emission-CmN9ADyN.js';
package/dist/angular.js CHANGED
@@ -729,6 +729,12 @@ function baseList(base) {
729
729
  function baseObject(base) {
730
730
  return isMergeable(base) ? base : {};
731
731
  }
732
+ function mergeObjects(base, written) {
733
+ const merged = {};
734
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(base));
735
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(written));
736
+ return merged;
737
+ }
732
738
  function mergeAutoSpyDefaults(ObjectClass, local) {
733
739
  const defaults = registry().get(ObjectClass);
734
740
  if (!defaults) {
@@ -749,7 +755,7 @@ function mergeInto(defaults, written) {
749
755
  if (Array.isArray(value)) {
750
756
  merged[key] = [.../* @__PURE__ */ new Set([...baseList(base), ...value])];
751
757
  } else if (isMergeable(value)) {
752
- merged[key] = { ...baseObject(base), ...value };
758
+ merged[key] = mergeObjects(baseObject(base), value);
753
759
  } else {
754
760
  merged[key] = value;
755
761
  }
@@ -3300,15 +3306,38 @@ function importsOf(definition2) {
3300
3306
  function isChildComponent(dependency) {
3301
3307
  return Reflect.get(dependency, "\u0275cmp") !== void 0;
3302
3308
  }
3303
- function keptScope(definition2, options) {
3309
+ var DECLARATION_KEYS = ["\u0275cmp", "\u0275dir", "\u0275pipe"];
3310
+ function refusedInImports(dependency) {
3311
+ if (Reflect.get(dependency, "\u0275mod") !== void 0) {
3312
+ return void 0;
3313
+ }
3314
+ const definition2 = DECLARATION_KEYS.map((key) => Reflect.get(dependency, key)).find((value) => value !== void 0);
3315
+ return definition2 !== void 0 && Reflect.get(definition2, "standalone") !== true ? dependency.name : void 0;
3316
+ }
3317
+ function assertScopeIsImportable(component, kept) {
3318
+ const refused = kept.map(refusedInImports).filter((name) => name !== void 0);
3319
+ if (refused.length === 0) {
3320
+ return;
3321
+ }
3322
+ throw new Error(
3323
+ withDocs(
3324
+ `[vitest-auto-spy] renderShallow(${component.name}, { keepTemplate: true }): ${refused.length} of its template dependencies are declared by an NgModule rather than standalone \u2014 ${refused.join(", ")} \u2014 and Angular takes only standalone declarations and NgModules in \`imports\`.
3325
+ Nothing is wrong with those declarations, and the same call works under JIT. This is an AOT dependency list: ngtsc resolves an imported NgModule at compile time and flattens its exported declarations into the component, so the module that would carry them is not in the list to keep. The scope cannot be rebuilt from what the definition holds.
3326
+ Drop \`keepTemplate\` when the spec reads TypeScript state only \u2014 that is the case \`renderShallow\` is for \u2014 or build ${component.name} with \`TestBed\` directly, which keeps its compiled scope untouched, and hold the cost down by seeding the services its children inject rather than by trimming the template.`,
3327
+ DOCS_LINKS.angular
3328
+ )
3329
+ );
3330
+ }
3331
+ function keptScope(component, definition2, options) {
3304
3332
  const kept = importsOf(definition2).filter((dependency) => !isChildComponent(dependency));
3305
3333
  kept.push(...options.keepChildren ?? NOTHING);
3334
+ assertScopeIsImportable(component, kept);
3306
3335
  return kept;
3307
3336
  }
3308
- function buildOverride(definition2, options) {
3337
+ function buildOverride(component, definition2, options) {
3309
3338
  const override = {};
3310
3339
  if (isStandalone3(definition2)) {
3311
- override.imports = options.keepTemplate ? keptScope(definition2, options) : options.keepChildren ?? NOTHING;
3340
+ override.imports = options.keepTemplate ? keptScope(component, definition2, options) : options.keepChildren ?? NOTHING;
3312
3341
  override.schemas = PERMISSIVE_SCHEMAS;
3313
3342
  }
3314
3343
  if (!options.keepTemplate) {
@@ -3335,7 +3364,7 @@ function renderShallow(component, options = {}) {
3335
3364
  // is right to report one, which made these two features of the same package cancel each other out.
3336
3365
  ...standalone ? {} : { schemas: PERMISSIVE_SCHEMAS }
3337
3366
  });
3338
- TestBed.overrideComponent(component, { set: buildOverride(definition2, options) });
3367
+ TestBed.overrideComponent(component, { set: buildOverride(component, definition2, options) });
3339
3368
  options.beforeCreate?.();
3340
3369
  const fixture = TestBed.createComponent(component);
3341
3370
  applyInputs(fixture, options.inputs);
@@ -3,7 +3,7 @@ export { ArgCaptor, AsInstances, AssertMockedOptions, ConstructorMock, Construct
3
3
  export { A as AutoMockConfiguration, a as AutoSpyDefaultEntry, C as CallbackSubscribable, E as EmissionObserver, b as EmissionOptions, c as EmissionSource, S as SubscribableLike, d as autoMocked, e as clearAutoSpyDefaults, f as createAutoMock, g as expectCompletion, h as expectEmission, i as expectEmissions, j as expectError, k as expectNoEmission, r as registerAutoSpyDefaults, s as setEmissionTimeout } from './expect-emission-CmN9ADyN.js';
4
4
  export { c as createFunctionSpy, d as describeDuplicateCopies, g as getPackageCopies } from './package-identity-lm-gqZAR.js';
5
5
  export { A as AccessorImplementations, O as OutsideHookReaction, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as reportPropsOutsideHooks, e as restoreMockedProps } from './prop-mock-DnYNBNJL.js';
6
- export { A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, d as RunCounter, S as SettleResourceOptions, e as ShallowRender, f as SpyRegistry, g as StableOptions, h as createWithAutoSpies, i as flushEffects, j as injectSpy, p as provideAutoSpy, r as renderShallow, k as runEffect, s as setInputs, l as settleResource, m as stable, t as trackEffectRuns, n as trackRecomputations } from './track-signal-runs-C-DgtCj9.js';
6
+ export { A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, d as RunCounter, S as SettleResourceOptions, e as ShallowRender, f as SpyRegistry, g as StableOptions, h as createWithAutoSpies, i as flushEffects, j as injectSpy, p as provideAutoSpy, r as renderShallow, k as runEffect, s as setInputs, l as settleResource, m as stable, t as trackEffectRuns, n as trackRecomputations } from './track-signal-runs-BOfsdYsC.js';
7
7
  import 'vitest';
8
8
  import '@angular/core';
9
9
  import '@angular/core/testing';
@@ -1,12 +1,12 @@
1
1
  import { stable, flushEffects } from './chunk-M5BULP7X.js';
2
2
  export { flushEffects, stable } from './chunk-M5BULP7X.js';
3
3
  import './chunk-M6VMOOZ2.js';
4
- 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-63S25O6W.js';
4
+ 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-4SJ7EGIY.js';
5
5
  import { currentSpecFile, mockValueProp } from './chunk-N3T7KWWA.js';
6
6
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
7
- import { createSpyForToken } from './chunk-I6AIKRUJ.js';
8
- import { createSpyFromClass } from './chunk-C3EFC33U.js';
9
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
7
+ import { createSpyForToken } from './chunk-DUFMKOKF.js';
8
+ import { createSpyFromClass } from './chunk-WAMFS3UI.js';
9
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
10
10
  import './chunk-OS4PTU6D.js';
11
11
  import './chunk-DTZCPCMA.js';
12
12
  import './chunk-PC3FAZT3.js';
@@ -317,15 +317,38 @@ function importsOf(definition) {
317
317
  function isChildComponent(dependency) {
318
318
  return Reflect.get(dependency, "\u0275cmp") !== void 0;
319
319
  }
320
- function keptScope(definition, options) {
320
+ var DECLARATION_KEYS = ["\u0275cmp", "\u0275dir", "\u0275pipe"];
321
+ function refusedInImports(dependency) {
322
+ if (Reflect.get(dependency, "\u0275mod") !== void 0) {
323
+ return void 0;
324
+ }
325
+ const definition = DECLARATION_KEYS.map((key) => Reflect.get(dependency, key)).find((value) => value !== void 0);
326
+ return definition !== void 0 && Reflect.get(definition, "standalone") !== true ? dependency.name : void 0;
327
+ }
328
+ function assertScopeIsImportable(component, kept) {
329
+ const refused = kept.map(refusedInImports).filter((name) => name !== void 0);
330
+ if (refused.length === 0) {
331
+ return;
332
+ }
333
+ throw new Error(
334
+ withDocs(
335
+ `[vitest-auto-spy] renderShallow(${component.name}, { keepTemplate: true }): ${refused.length} of its template dependencies are declared by an NgModule rather than standalone \u2014 ${refused.join(", ")} \u2014 and Angular takes only standalone declarations and NgModules in \`imports\`.
336
+ Nothing is wrong with those declarations, and the same call works under JIT. This is an AOT dependency list: ngtsc resolves an imported NgModule at compile time and flattens its exported declarations into the component, so the module that would carry them is not in the list to keep. The scope cannot be rebuilt from what the definition holds.
337
+ Drop \`keepTemplate\` when the spec reads TypeScript state only \u2014 that is the case \`renderShallow\` is for \u2014 or build ${component.name} with \`TestBed\` directly, which keeps its compiled scope untouched, and hold the cost down by seeding the services its children inject rather than by trimming the template.`,
338
+ DOCS_LINKS.angular
339
+ )
340
+ );
341
+ }
342
+ function keptScope(component, definition, options) {
321
343
  const kept = importsOf(definition).filter((dependency) => !isChildComponent(dependency));
322
344
  kept.push(...options.keepChildren ?? NOTHING);
345
+ assertScopeIsImportable(component, kept);
323
346
  return kept;
324
347
  }
325
- function buildOverride(definition, options) {
348
+ function buildOverride(component, definition, options) {
326
349
  const override = {};
327
350
  if (isStandalone(definition)) {
328
- override.imports = options.keepTemplate ? keptScope(definition, options) : options.keepChildren ?? NOTHING;
351
+ override.imports = options.keepTemplate ? keptScope(component, definition, options) : options.keepChildren ?? NOTHING;
329
352
  override.schemas = PERMISSIVE_SCHEMAS;
330
353
  }
331
354
  if (!options.keepTemplate) {
@@ -352,7 +375,7 @@ function renderShallow(component, options = {}) {
352
375
  // is right to report one, which made these two features of the same package cancel each other out.
353
376
  ...standalone ? {} : { schemas: PERMISSIVE_SCHEMAS }
354
377
  });
355
- TestBed.overrideComponent(component, { set: buildOverride(definition, options) });
378
+ TestBed.overrideComponent(component, { set: buildOverride(component, definition, options) });
356
379
  options.beforeCreate?.();
357
380
  const fixture = TestBed.createComponent(component);
358
381
  applyInputs(fixture, options.inputs);
package/dist/bun.d.ts CHANGED
@@ -551,6 +551,27 @@ type Subscribable<T> = [Extract<T, {
551
551
  }>] extends [never] ? T : Extract<T, {
552
552
  subscribe: Func;
553
553
  }>;
554
+ /**
555
+ * The narrowing every optional read needs: neither `null` nor `undefined`, handed back.
556
+ *
557
+ * ```ts
558
+ * const covers = narrow.defined(row.content?.covers);
559
+ *
560
+ * expect(covers.map((cover) => cover.code)).toEqual(['a', 'b']);
561
+ * ```
562
+ *
563
+ * `expect(value).toBeDefined()` and `assert.exists(value)` both assert this, and neither **returns**
564
+ * it — so under a strict spec type-check each optional read costs two statements and a local that
565
+ * exists for the narrowing alone (`const x = obj.member; assert.exists(x); … x …`). That shape
566
+ * multiplies: one suite hit it fifteen times across four files, and twice it grew a helper function
567
+ * per member of a stub. This returns the value, so the narrowing sits inside the expression that
568
+ * needed it.
569
+ *
570
+ * It is not a replacement for `assert.exists` where the *assertion* is the point of the test. The
571
+ * difference is which of the two the line is about: asserting that a value arrived, or reading a
572
+ * value the test already knows arrived.
573
+ */
574
+ declare function defined<T>(value: T, label?: string): NonNullable<T>;
554
575
  /**
555
576
  * The most common narrowing, without writing the guard: the branch that has this key.
556
577
  *
@@ -581,6 +602,8 @@ interface Narrow {
581
602
  <T>(value: T, predicate: (candidate: T) => boolean, label?: string): T;
582
603
  /** {@link byKey} */
583
604
  byKey: typeof byKey;
605
+ /** {@link defined} */
606
+ defined: typeof defined;
584
607
  /** {@link observable} */
585
608
  observable: typeof observable;
586
609
  }
package/dist/bun.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import './chunk-M6VMOOZ2.js';
2
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-63S25O6W.js';
2
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, createSpyFromInstance, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, restoreSpiedInstance, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-4SJ7EGIY.js';
3
3
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
4
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
4
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
5
5
  import './chunk-OS4PTU6D.js';
6
6
  import './chunk-DTZCPCMA.js';
7
7
  import './chunk-PC3FAZT3.js';
@@ -1,5 +1,5 @@
1
1
  import { mockValueProp, mockAccessorsProp } from './chunk-N3T7KWWA.js';
2
- import { resolveConfiguration, mergeMethodNames, getCallableMemberNames, applyConfiguredReturns, createSpyFromClass, resolveAccessors, createAccessorsSpies, createProxyPropStore, storeWriteTraps, describeStoredProp, readStoredAccessor, NOT_STORED, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-C3EFC33U.js';
2
+ import { resolveConfiguration, mergeMethodNames, getCallableMemberNames, applyConfiguredReturns, createSpyFromClass, resolveAccessors, createAccessorsSpies, createProxyPropStore, storeWriteTraps, describeStoredProp, readStoredAccessor, NOT_STORED, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-WAMFS3UI.js';
3
3
  import { resolveReadGuard, createTrackedPropSpy } from './chunk-OS4PTU6D.js';
4
4
  import { redefineFailure } from './chunk-DTZCPCMA.js';
5
5
  import { DISPOSE } from './chunk-PC3FAZT3.js';
@@ -554,6 +554,12 @@ var narrowValue = defineHelper((value, predicate, label) => {
554
554
  }
555
555
  return value;
556
556
  });
557
+ function defined(value, label = "a value that is neither null nor undefined") {
558
+ if (value === null || value === void 0) {
559
+ throw narrowingFailed(label, value);
560
+ }
561
+ return value;
562
+ }
557
563
  function byKey(value, key) {
558
564
  if (typeof value !== "object" || value === null || !(key in value)) {
559
565
  throw narrowingFailed(`an object with a '${String(key)}' property`, value);
@@ -568,6 +574,7 @@ function observable(value) {
568
574
  }
569
575
  var narrow = Object.assign(narrowValue, {
570
576
  byKey: defineHelper(byKey),
577
+ defined: defineHelper(defined),
571
578
  observable: defineHelper(observable)
572
579
  });
573
580
 
@@ -1,4 +1,4 @@
1
- import { createSpyFromClass, createAutoMock } from './chunk-C3EFC33U.js';
1
+ import { createSpyFromClass, createAutoMock } from './chunk-WAMFS3UI.js';
2
2
  import { withDocs, DOCS_LINKS } from './chunk-Q477VHHF.js';
3
3
 
4
4
  // src/lib/track-injections.ts
@@ -301,6 +301,12 @@ function baseList(base) {
301
301
  function baseObject(base) {
302
302
  return isMergeable(base) ? base : {};
303
303
  }
304
+ function mergeObjects(base, written) {
305
+ const merged = {};
306
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(base));
307
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(written));
308
+ return merged;
309
+ }
304
310
  function mergeAutoSpyDefaults(ObjectClass, local) {
305
311
  const defaults = registry().get(ObjectClass);
306
312
  if (!defaults) {
@@ -317,7 +323,7 @@ function mergeInto(defaults, written) {
317
323
  if (Array.isArray(value)) {
318
324
  merged[key] = [.../* @__PURE__ */ new Set([...baseList(base), ...value])];
319
325
  } else if (isMergeable(value)) {
320
- merged[key] = { ...baseObject(base), ...value };
326
+ merged[key] = mergeObjects(baseObject(base), value);
321
327
  } else {
322
328
  merged[key] = value;
323
329
  }
package/dist/cli.js CHANGED
@@ -2455,7 +2455,7 @@ function checkForeignPragma(graph) {
2455
2455
  }
2456
2456
 
2457
2457
  // src/cli/checks/export-map.generated.ts
2458
- var EXPORT_MAP_VERSION = "5.15.0";
2458
+ var EXPORT_MAP_VERSION = "5.16.0";
2459
2459
  var ENTRY_SPECIFIERS = "vitest-auto-spy vitest-auto-spy/bun vitest-auto-spy/bun-angular vitest-auto-spy/node vitest-auto-spy/rstest vitest-auto-spy/rxjs vitest-auto-spy/console vitest-auto-spy/dom-stubs vitest-auto-spy/diagnostics vitest-auto-spy/jasmine vitest-auto-spy/jasmine-compat vitest-auto-spy/observer-spy vitest-auto-spy/angular vitest-auto-spy/angular-http vitest-auto-spy/angular-router vitest-auto-spy/signal-forms vitest-auto-spy/nestjs vitest-auto-spy/react vitest-auto-spy/vue vitest-auto-spy/svelte vitest-auto-spy/setup vitest-auto-spy/zone vitest-auto-spy/eslint-plugin";
2460
2460
  var EXPORTED_BY = {
2461
2461
  AccessorImplementations: "0 1 2 3 4 12 17 18 19",
@@ -779,6 +779,8 @@ var SPY_FACTORIES = /* @__PURE__ */ new Set([
779
779
  "autoMocked",
780
780
  "createActivatedRoute",
781
781
  "createAutoMock",
782
+ "createComponentStub",
783
+ "createDirectiveHost",
782
784
  "createDocumentDouble",
783
785
  "createMock",
784
786
  "createRouterDouble",
@@ -904,6 +906,9 @@ function spreadOfImport(context, node) {
904
906
  const binding = findBinding(context.sourceCode.getScope(node), argument.name);
905
907
  return binding?.defs.some((definition) => definition.type === IMPORT_DEFINITION2) ? argument : void 0;
906
908
  }
909
+ function spreadFailureMode(node) {
910
+ return isObjectExpression(node.parent) ? "object" : "iterable";
911
+ }
907
912
  function isDeferred(node) {
908
913
  return isFunctionNode(node) || node.type === "PropertyDefinition" && Reflect.get(node, "static") !== true;
909
914
  }
@@ -3311,7 +3316,8 @@ var noImportTimeSpread = defineRule({
3311
3316
  description: "Do not spread an imported binding at module scope \u2014 inside a bundle it can still be undefined",
3312
3317
  hasSuggestions: true,
3313
3318
  messages: {
3314
- noImportTimeSpread: "This spreads `{{name}}`, a binding another module owns, while this module is still being evaluated. Under `tsc` and under a browser\u2019s ESM loader that is safe \u2014 nothing runs before its dependency. Inside one bundle it is not: the spec bundle emits shared chunks, a chunk can be evaluated while the binding it re-exports is still `undefined`, and `[...undefined]` throws `Spread syntax requires ...iterable[Symbol.iterator] to be a function` before a single test runs \u2014 on a tree whose every test passes. Build the value lazily (a function, called where it is read), or inline the constant so nothing has to be imported for this line to work. Nothing inside a function body is reported: that runs later, which is the whole repair."
3319
+ noImportTimeSpread: "This spreads `{{name}}`, a binding another module owns, while this module is still being evaluated. Under `tsc` and under a browser\u2019s ESM loader that is safe \u2014 nothing runs before its dependency. Inside one bundle it is not: the spec bundle emits shared chunks, a chunk can be evaluated while the binding it re-exports is still `undefined`, and `[...undefined]` throws `Spread syntax requires ...iterable[Symbol.iterator] to be a function` before a single test runs \u2014 on a tree whose every test passes. Build the value lazily (a function, called where it is read), or inline the constant so nothing has to be imported for this line to work. Nothing inside a function body is reported: that runs later, which is the whole repair.",
3320
+ noImportTimeSpreadObject: "This spreads `{{name}}`, a binding another module owns, into an object literal while this module is still being evaluated. Under `tsc` and under a browser\u2019s ESM loader that is safe \u2014 nothing runs before its dependency. Inside one bundle it is not: the spec bundle emits shared chunks, and a chunk can be evaluated while the binding it re-exports is still `undefined`. Do not look for an error \u2014 an object spread of `undefined` throws nothing, `{ ...undefined }` is `{}`, so the module loads and every key this line was meant to copy reads `undefined` for the rest of the run, on a tree whose every test passes. Build the value lazily (a function, called where it is read), or write the keys out so nothing has to be imported for this line to work. Nothing inside a function body is reported: that runs later, which is the whole repair."
3315
3321
  },
3316
3322
  create: (context) => ({
3317
3323
  SpreadElement: (node) => {
@@ -3320,7 +3326,8 @@ var noImportTimeSpread = defineRule({
3320
3326
  return;
3321
3327
  }
3322
3328
  const suggestion = lazyValueSuggestion(context, node);
3323
- const report = { node, messageId: "noImportTimeSpread", data: { name: imported.name } };
3329
+ const messageId = spreadFailureMode(node) === "object" ? "noImportTimeSpreadObject" : "noImportTimeSpread";
3330
+ const report = { node, messageId, data: { name: imported.name } };
3324
3331
  context.report(suggestion ? { ...report, suggest: [suggestion] } : report);
3325
3332
  }
3326
3333
  })
package/dist/index.js CHANGED
@@ -1892,6 +1892,12 @@ function baseList(base) {
1892
1892
  function baseObject(base) {
1893
1893
  return isMergeable(base) ? base : {};
1894
1894
  }
1895
+ function mergeObjects(base, written) {
1896
+ const merged = {};
1897
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(base));
1898
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(written));
1899
+ return merged;
1900
+ }
1895
1901
  function mergeAutoSpyDefaults(ObjectClass, local) {
1896
1902
  const defaults = registry().get(ObjectClass);
1897
1903
  if (!defaults) {
@@ -1908,7 +1914,7 @@ function mergeInto(defaults, written) {
1908
1914
  if (Array.isArray(value)) {
1909
1915
  merged[key] = [.../* @__PURE__ */ new Set([...baseList(base), ...value])];
1910
1916
  } else if (isMergeable(value)) {
1911
- merged[key] = { ...baseObject(base), ...value };
1917
+ merged[key] = mergeObjects(baseObject(base), value);
1912
1918
  } else {
1913
1919
  merged[key] = value;
1914
1920
  }
@@ -2879,6 +2885,12 @@ var narrowValue = defineHelper((value, predicate, label) => {
2879
2885
  }
2880
2886
  return value;
2881
2887
  });
2888
+ function defined(value, label = "a value that is neither null nor undefined") {
2889
+ if (value === null || value === void 0) {
2890
+ throw narrowingFailed(label, value);
2891
+ }
2892
+ return value;
2893
+ }
2882
2894
  function byKey(value, key) {
2883
2895
  if (typeof value !== "object" || value === null || !(key in value)) {
2884
2896
  throw narrowingFailed(`an object with a '${String(key)}' property`, value);
@@ -2893,6 +2905,7 @@ function observable(value) {
2893
2905
  }
2894
2906
  var narrow = Object.assign(narrowValue, {
2895
2907
  byKey: defineHelper(byKey),
2908
+ defined: defineHelper(defined),
2896
2909
  observable: defineHelper(observable)
2897
2910
  });
2898
2911
 
package/dist/jasmine.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { useVitestAdapter } from './chunk-PA4ZNLNZ.js';
2
2
  import { enableJasmineCompat } from './chunk-MAKQSO2R.js';
3
3
  export { enableJasmineCompat } from './chunk-MAKQSO2R.js';
4
- import { createSpyFromClass } from './chunk-C3EFC33U.js';
4
+ import { createSpyFromClass } from './chunk-WAMFS3UI.js';
5
5
  import './chunk-OS4PTU6D.js';
6
6
  import './chunk-ZU55UY2M.js';
7
7
  import './chunk-33NJHIS2.js';
package/dist/nestjs.js CHANGED
@@ -1,6 +1,6 @@
1
- import { createSpyForToken } from './chunk-I6AIKRUJ.js';
2
- export { trackInjections } from './chunk-I6AIKRUJ.js';
3
- import { createSpyFromClass } from './chunk-C3EFC33U.js';
1
+ import { createSpyForToken } from './chunk-DUFMKOKF.js';
2
+ export { trackInjections } from './chunk-DUFMKOKF.js';
3
+ import { createSpyFromClass } from './chunk-WAMFS3UI.js';
4
4
  import './chunk-OS4PTU6D.js';
5
5
  import { vitestMockAdapter } from './chunk-ZU55UY2M.js';
6
6
  import './chunk-33NJHIS2.js';
package/dist/node.cjs CHANGED
@@ -1614,6 +1614,12 @@ function baseList(base) {
1614
1614
  function baseObject(base) {
1615
1615
  return isMergeable(base) ? base : {};
1616
1616
  }
1617
+ function mergeObjects(base, written) {
1618
+ const merged = {};
1619
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(base));
1620
+ Object.defineProperties(merged, Object.getOwnPropertyDescriptors(written));
1621
+ return merged;
1622
+ }
1617
1623
  function mergeAutoSpyDefaults(ObjectClass, local) {
1618
1624
  const defaults = registry().get(ObjectClass);
1619
1625
  if (!defaults) {
@@ -1630,7 +1636,7 @@ function mergeInto(defaults, written) {
1630
1636
  if (Array.isArray(value)) {
1631
1637
  merged[key] = [.../* @__PURE__ */ new Set([...baseList(base), ...value])];
1632
1638
  } else if (isMergeable(value)) {
1633
- merged[key] = { ...baseObject(base), ...value };
1639
+ merged[key] = mergeObjects(baseObject(base), value);
1634
1640
  } else {
1635
1641
  merged[key] = value;
1636
1642
  }
@@ -2612,6 +2618,12 @@ var narrowValue = defineHelper((value, predicate, label) => {
2612
2618
  }
2613
2619
  return value;
2614
2620
  });
2621
+ function defined(value, label = "a value that is neither null nor undefined") {
2622
+ if (value === null || value === void 0) {
2623
+ throw narrowingFailed(label, value);
2624
+ }
2625
+ return value;
2626
+ }
2615
2627
  function byKey(value, key) {
2616
2628
  if (typeof value !== "object" || value === null || !(key in value)) {
2617
2629
  throw narrowingFailed(`an object with a '${String(key)}' property`, value);
@@ -2626,6 +2638,7 @@ function observable(value) {
2626
2638
  }
2627
2639
  var narrow = Object.assign(narrowValue, {
2628
2640
  byKey: defineHelper(byKey),
2641
+ defined: defineHelper(defined),
2629
2642
  observable: defineHelper(observable)
2630
2643
  });
2631
2644
 
package/dist/node.js CHANGED
@@ -1,6 +1,6 @@
1
- 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-63S25O6W.js';
1
+ 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-4SJ7EGIY.js';
2
2
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
3
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
3
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
4
4
  import './chunk-OS4PTU6D.js';
5
5
  import { guardAccessorSpies, createRedefineMockAdapter } from './chunk-DTZCPCMA.js';
6
6
  import './chunk-PC3FAZT3.js';
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
- 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-63S25O6W.js';
1
+ 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-4SJ7EGIY.js';
2
2
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
3
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
3
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
4
4
  import './chunk-OS4PTU6D.js';
5
5
  import { vitestMockAdapter } from './chunk-ZU55UY2M.js';
6
6
  import './chunk-33NJHIS2.js';
package/dist/rstest.js CHANGED
@@ -1,6 +1,6 @@
1
- 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-63S25O6W.js';
1
+ 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-4SJ7EGIY.js';
2
2
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
3
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
3
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
4
4
  import './chunk-OS4PTU6D.js';
5
5
  import { clearAllFastSpies, resetAllFastSpies, getSpyEngine, createFastSpy } from './chunk-33NJHIS2.js';
6
6
  import { guardAccessorSpies, spyOnAccessorByRedefine } from './chunk-DTZCPCMA.js';
package/dist/svelte.js CHANGED
@@ -1,6 +1,6 @@
1
- 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-63S25O6W.js';
1
+ 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-4SJ7EGIY.js';
2
2
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
3
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
3
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
4
4
  import './chunk-OS4PTU6D.js';
5
5
  import { vitestMockAdapter } from './chunk-ZU55UY2M.js';
6
6
  import './chunk-33NJHIS2.js';
@@ -239,8 +239,14 @@ interface RenderShallowOptions<T> {
239
239
  /**
240
240
  * Keep the real template instead of blanking it — for `viewChild`, content projection, host
241
241
  * bindings. The template's own pipes and directives stay resolvable; child components are still
242
- * dropped, which is what keeps the render shallow. A child re-exported by an imported `NgModule`
243
- * is the one thing that survives, because the module is kept whole.
242
+ * dropped, which is what keeps the render shallow. Under JIT a child re-exported by an imported
243
+ * `NgModule` survives, because the module is kept whole.
244
+ *
245
+ * Under **AOT** an imported `NgModule` is not in the compiled dependency list at all — ngtsc
246
+ * resolves its exported scope and flattens the declarations into the list instead — so a
247
+ * `standalone: false` pipe or directive is what arrives, and Angular refuses one of those in
248
+ * `imports`. That case throws with the declaration named rather than letting Angular blame the
249
+ * pipe's author; see the error for what to do instead.
244
250
  */
245
251
  keepTemplate?: boolean;
246
252
  /** Child components/directives/pipes to keep resolvable in the template (everything else is dropped). */
package/dist/vue.js CHANGED
@@ -1,7 +1,7 @@
1
- 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-63S25O6W.js';
1
+ 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-4SJ7EGIY.js';
2
2
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, reportPropsOutsideHooks, restoreMockedProps } from './chunk-N3T7KWWA.js';
3
- import { createSpyFromClass } from './chunk-C3EFC33U.js';
4
- export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-C3EFC33U.js';
3
+ import { createSpyFromClass } from './chunk-WAMFS3UI.js';
4
+ export { autoMocked, clearAutoSpy, clearAutoSpyDefaults, createAutoMock, createSpyFromClass, registerAutoSpyDefaults, resetAutoSpy } from './chunk-WAMFS3UI.js';
5
5
  import './chunk-OS4PTU6D.js';
6
6
  import { vitestMockAdapter } from './chunk-ZU55UY2M.js';
7
7
  import './chunk-33NJHIS2.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-auto-spy",
3
- "version": "5.15.0",
3
+ "version": "5.16.0",
4
4
  "description": "Auto-generate fully-typed test spies from a class — across Vitest, Bun, node:test and Rstest, with Angular/NestJS/React/Vue/Svelte recipes. Drop-in replacement for jest-auto-spies and jasmine-auto-spies.",
5
5
  "keywords": [
6
6
  "auto-mock",