vitest-auto-spy 5.41.0 → 5.42.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/CHANGELOG.md +104 -1
- package/README.md +66 -39
- package/agent-docs/angular.md +3 -3
- package/agent-docs/checklist.md +18 -4
- package/agent-docs/configuration.md +5 -2
- package/agent-docs/errors.md +1 -0
- package/agent-docs/factories.md +7 -6
- package/dist/angular-diagnostics.js +3 -3
- package/dist/angular-doubles.d.ts +1 -1
- package/dist/angular-doubles.js +3 -3
- package/dist/angular-router.d.ts +11 -1
- package/dist/angular-router.js +12 -3
- package/dist/angular.d.ts +7 -7
- package/dist/bun-angular.d.ts +5 -5
- package/dist/bun-angular.js +6 -6
- package/dist/bun.d.ts +5 -5
- package/dist/bun.js +3 -3
- package/dist/{chunk-O55MVK7N.js → chunk-25QOHNGU.js} +1 -1
- package/dist/{chunk-HUS2MHK5.js → chunk-CENALW7R.js} +24 -21
- package/dist/{chunk-T7EGA4G4.js → chunk-EYXARTWD.js} +152 -98
- package/dist/{chunk-IE4NI2OQ.js → chunk-J2C3KRTC.js} +39 -17
- package/dist/{chunk-6ZGH56G4.js → chunk-J4IJCTHT.js} +1 -1
- package/dist/{chunk-OWDUWUAO.js → chunk-MHN6GMXP.js} +1 -1
- package/dist/{chunk-DG5EP3PO.js → chunk-RYEBG2KB.js} +2 -2
- package/dist/cli.js +1309 -472
- package/dist/console.d.ts +1 -1
- package/dist/console.js +3 -3
- package/dist/dom-stubs.d.ts +2 -2
- package/dist/dom-stubs.js +38 -16
- package/dist/{expect-emission-CwosjG6t.d.ts → expect-emission-D273986K.d.ts} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +214 -135
- package/dist/jasmine-compat.d.ts +1 -1
- package/dist/jasmine.d.ts +2 -2
- package/dist/jasmine.js +4 -4
- package/dist/nestjs.d.ts +2 -2
- package/dist/nestjs.js +6 -6
- package/dist/node.cjs +174 -117
- package/dist/node.d.ts +4 -4
- package/dist/node.js +175 -118
- package/dist/{package-identity-CBgwC1T6.d.ts → package-identity-BnqwTQIn.d.ts} +1 -1
- package/dist/{prop-mock-C8PJ-Vo8.d.ts → prop-mock-Cz0yKWEP.d.ts} +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/rstest.d.ts +4 -4
- package/dist/rstest.js +4 -4
- package/dist/rxjs.d.ts +2 -2
- package/dist/setup.d.ts +3 -3
- package/dist/setup.js +38 -16
- package/dist/svelte.d.ts +4 -4
- package/dist/{track-injections-Bp8TgLjG.d.ts → track-injections-BTJKOqWz.d.ts} +1 -1
- package/dist/{track-signal-runs-DUZUFWf-.d.ts → track-signal-runs-bs2umXNE.d.ts} +3 -3
- package/dist/{types-DJ0OGc3C.d.ts → types-CyRUgJVd.d.ts} +17 -15
- package/dist/vue.d.ts +5 -5
- package/package.json +1 -1
- package/skills/vitest-auto-spy/SKILL.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,108 @@ The latest released version here must always match the one published on
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [5.42.0] - 2026-09-27
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`npx vitest-auto-spy ng-test` — sharding and changed-only runs under the Angular unit-test
|
|
18
|
+
builder.** `ng test` has no pass-through for Vitest's flags: `startVitest()` receives an object the
|
|
19
|
+
builder built, and Vitest's own `--changed` / `--related` find nothing there because its module graph
|
|
20
|
+
holds the builder's bundles, not your sources. `ng-test --shard 2/4` lists the target's specs with
|
|
21
|
+
`ng test --list-tests` (`@angular/build` 21+), splits them the way Vitest does and hands the shard to
|
|
22
|
+
the builder as `--include` paths, so it compiles only that shard; `ng-test --changed [ref]` and
|
|
23
|
+
`--related <files>` run the specs whose imports reach a changed file (relative imports,
|
|
24
|
+
`compilerOptions.paths` aliases, a template or stylesheet through the component naming it; a config,
|
|
25
|
+
a lockfile or a change the setup files reach runs everything). Everything after `--` goes to
|
|
26
|
+
`ng run <project>:<target>`. On a 700-spec workspace with coverage and the builder cache off, as in
|
|
27
|
+
CI, the slower of two `ng-test` shards took 7.58 s against 11.21 s for the whole run, and 9.38 s for
|
|
28
|
+
a `test.shard` set in the runner config, which still compiles every spec.
|
|
29
|
+
- **`provideActivatedRoute({ resources })` / `createActivatedRoute({ resources })`.** Angular 22.2
|
|
30
|
+
gave a route a `resources` record (developer preview), and a component reading
|
|
31
|
+
`route.resources['user']` got `undefined` from the double. The record now lands on
|
|
32
|
+
`route.resources` and on every snapshot's `resources` — the same object, carried into each new
|
|
33
|
+
snapshot as a navigation that keeps the route does. Arrange a value with
|
|
34
|
+
`mockResourceProp(resources, 'user', undefined)` on that record. On Angular 20 and 21 the key
|
|
35
|
+
exists in the type as `never`, so nothing can be passed where the router has no such field.
|
|
36
|
+
- **`doctor` points at the module cache where the unit-test builder runs istanbul.**
|
|
37
|
+
`angular-build-istanbul-module-cache` (info) fires for an `@angular/build:unit-test` target on 21+
|
|
38
|
+
and Vitest 5 whose coverage provider resolves to istanbul and whose runner config lacks
|
|
39
|
+
`fsModuleCache`; on a 700-file Angular 22.2 suite the cache took the run from
|
|
40
|
+
24.55 s to 13.20 s (−46 %), −41 % with the builder cache off as on CI. The fix names the runner
|
|
41
|
+
config, or asks for `"runnerConfig"` on the target, and adds the CI cache step when no CI config
|
|
42
|
+
keeps `node_modules/.vitest-cache`. Quiet with v8, where the cache gained nothing, and for a
|
|
43
|
+
`browsers` target unless its runner config names istanbul itself: browser mode was not measured.
|
|
44
|
+
- **`doctor` warns before `fsModuleCache` breaks an Analog suite.** `analog-module-cache-inline-styles`
|
|
45
|
+
(warning): with the Analog plugin in JIT mode and a component with inline `styles`, the warm run
|
|
46
|
+
fails with `Cannot find module '/@id/__x00__virtual:angular:jit:style:inline;<hash>'` (verified on
|
|
47
|
+
Analog 2.7.5, Angular 22.2, Vitest 5.0.0).
|
|
48
|
+
- **`doctor` warns when Analog `fastCompile` drops constructor types.**
|
|
49
|
+
`analog-fast-compile-ctor-injection` (warning): with `fastCompile` in JIT mode, an `@Injectable`
|
|
50
|
+
class that takes a constructor parameter known only by its type gets no `ctorParameters`, so it
|
|
51
|
+
throws NG0202 in `TestBed.inject` and `createWithAutoSpies` alike. The finding lists each class and
|
|
52
|
+
the fixes: `inject()`, `@Inject(X)`, or `fastCompile` off.
|
|
53
|
+
- **`doctor` notes happy-dom for builder users.** `angular-build-happy-dom` (info): on
|
|
54
|
+
`@angular/build` 21+ the builder picks happy-dom itself once installed; −4.6 % wall and −6 % RSS on
|
|
55
|
+
the 700-file suite.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- **`createSpyFromClass` builds a double of a class with 8 or more methods as a `Proxy`.** When
|
|
60
|
+
`lazySpies` is not set, a class of 8+ methods gets `lazySpies: 'proxy'`; a narrower one keeps the
|
|
61
|
+
accessor placeholders it had. Why upgrade: a wide double a test touches holds 21–68 % less and is
|
|
62
|
+
built 2–6× faster — measured per double with one and two methods called: 2 110 → 1 417 B and
|
|
63
|
+
3 269 → 2 573 B at 8–16 methods, 4 412 → 1 417 B and 5 570 → 2 577 B at 45; create and call 2.2 →
|
|
64
|
+
1.1 µs at 8 methods, 6.5 → 1.0 µs at 45. The accessor placeholders put a touched double into a
|
|
65
|
+
property dictionary as wide as the class; the proxy defines nothing until a method is read. What a
|
|
66
|
+
wide class's double now does differently: every read of a member costs ~20 ns more;
|
|
67
|
+
`util.types.isProxy(double)` is `true`; `console.log` shows only the methods already read;
|
|
68
|
+
`vi.spyOn` on a method nobody has read returns the double's own spy, so `mockRestore()` resets it;
|
|
69
|
+
`Object.create(double).method` builds the spy on the double; an untouched double is ~100 B heavier.
|
|
70
|
+
Snapshots, `toEqual`, `Object.keys` and spread are unchanged. `lazySpies: true` brings the
|
|
71
|
+
placeholders back for one class, `registerAutoSpyDefaults(Class, { lazySpies: true })` for all its
|
|
72
|
+
doubles. `provideAutoSpy` and `injectSpy` follow the same rule.
|
|
73
|
+
- **`lazySpies: 'proxy'` holds ~0.26 kB per untouched double at any width**, down from 1 860 B at 10
|
|
74
|
+
methods and 4 097 B at 100 (`bench:memory`, 258 and 259 B): one trap handler per double and one
|
|
75
|
+
method-name set per class.
|
|
76
|
+
- **`createSpyFromClass` without `returns`, `selfReturning` or `overrides` no longer builds its message
|
|
77
|
+
label** — eight regex replacements per call, −0.2 µs per double in every mode.
|
|
78
|
+
- **A double retains less.** A materialised method spy no longer allocates an empty `Once` queue, a
|
|
79
|
+
closure context for its callable, a separate state object, or a six-slot context for its dispatch
|
|
80
|
+
(−128 B per method); the empty `accessorSpies` bag of a class without spied accessors is built from
|
|
81
|
+
objects sized to hold nothing (−64 B per double, identical to `{}` to every reader); and
|
|
82
|
+
`createAutoMock` / `mockDeep` nodes create their accessor and tombstone collections on first write
|
|
83
|
+
(−336 B each). `bench:memory` on the `lazySpies: true` arm (the default before this release):
|
|
84
|
+
untouched 243 → 178 B at 100 methods, all called 128 956 → 116 082 B (−10 %); `createAutoMock`
|
|
85
|
+
untouched 705 → 369 B (−48 %). Construction and call timings are unchanged within noise.
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
|
|
89
|
+
- **`vi.when` on a method spy no longer reports the `calledWith()` as deciding nothing.** Vitest 5's
|
|
90
|
+
`vi.when(spy)` reads the spy's implementation and installs a wrapper that answers its own rows and
|
|
91
|
+
passes every other call through to it — to the library's dispatch, so the `calledWith` chain keeps
|
|
92
|
+
deciding. Both orders printed the "replaced the dispatch" warning, and under
|
|
93
|
+
`setupAutoSpy({ preset: 'strict' })` it threw. An implementation installed right after
|
|
94
|
+
`getMockImplementation()` handed out the current one is now treated as a wrapper; a `vi.when` over
|
|
95
|
+
a `mockReturnValue` is still reported.
|
|
96
|
+
- **A `calledWith` after a `mockReturnValue` that was the spy's first touch since `vi.resetAllMocks()`
|
|
97
|
+
is reported again.** The pending reset was applied after the replacement was recorded and erased it.
|
|
98
|
+
- **`perf` stops giving advice that fails under `@angular/build:unit-test` and Analog.** Under the
|
|
99
|
+
builder the settings findings (`perf-transform`, `perf-workers`, `perf-isolation`,
|
|
100
|
+
`perf-environment-engine`) name the runner config the run reads — `--runner-config` in `--command`,
|
|
101
|
+
then the target's `runnerConfig` — instead of the first `vite(st).config.*` in the tree, say to add
|
|
102
|
+
`"runnerConfig": "vitest-base.config.mts"` to the target when it names none, and say the setting is
|
|
103
|
+
not available on `@angular/build` 20.x, which reads no runner config. `perf-vitest-doctor` no longer
|
|
104
|
+
sends a builder workspace to `npx vitest doctor`, which fails there on every file with
|
|
105
|
+
`describe is not defined`; it gives an A/B recipe through
|
|
106
|
+
`ng run <project>:<target> --runner-config=<variant>` instead. `isolate` and `environment` the
|
|
107
|
+
builder passes to Vitest itself no longer count as the user's choice, and the DOM-engine advice
|
|
108
|
+
there becomes "install `happy-dom`": from 21 the builder picks it by itself. The barrel advice is
|
|
109
|
+
off under the builder, and the confirmed-finding card names a spec's `spec-*.js` bundle after the
|
|
110
|
+
spec and drops `chunk-*.js`, neither of which exists on disk. Under `@analogjs/vite-plugin-angular`
|
|
111
|
+
2.7.5 and older with an inline-styled component, `perf-transform` is a warning not to turn
|
|
112
|
+
`fsModuleCache` on: the warm run fails with
|
|
113
|
+
`Cannot find module '/@id/__x00__virtual:angular:jit:style:inline;<hash>'`.
|
|
114
|
+
|
|
13
115
|
## [5.41.0] - 2026-09-27
|
|
14
116
|
|
|
15
117
|
### Changed
|
|
@@ -5590,7 +5692,8 @@ moved under 1 %: `/angular` +192 B (+1.0 %) for the override queue and the HTTP
|
|
|
5590
5692
|
This copy ships with the package and carries 5.x only. Releases before 5.0.0 are in the
|
|
5591
5693
|
[full changelog](https://github.com/ASDAlexey/vitest-auto-spy/blob/master/CHANGELOG.md).
|
|
5592
5694
|
|
|
5593
|
-
[Unreleased]: https://github.com/ASDAlexey/vitest-auto-spy/compare/v5.
|
|
5695
|
+
[Unreleased]: https://github.com/ASDAlexey/vitest-auto-spy/compare/v5.42.0...HEAD
|
|
5696
|
+
[5.42.0]: https://github.com/ASDAlexey/vitest-auto-spy/compare/v5.41.0...v5.42.0
|
|
5594
5697
|
[5.41.0]: https://github.com/ASDAlexey/vitest-auto-spy/compare/v5.40.1...v5.41.0
|
|
5595
5698
|
[5.40.1]: https://github.com/ASDAlexey/vitest-auto-spy/compare/v5.40.0...v5.40.1
|
|
5596
5699
|
[5.40.0]: https://github.com/ASDAlexey/vitest-auto-spy/compare/v5.39.0...v5.40.0
|
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)
|
|
@@ -998,8 +998,14 @@ npx vitest-auto-spy doctor # read-only. Exits 1 when it finds something
|
|
|
998
998
|
npx vitest-auto-spy perf # where the suite's CPU time goes. --gate fails a budget and says why
|
|
999
999
|
npx vitest-auto-spy codemod # prints the migration diff. Writes nothing without --write
|
|
1000
1000
|
npx vitest-auto-spy init # writes the agent instructions pointer
|
|
1001
|
+
npx vitest-auto-spy ng-test # ng test with --shard / --changed the Angular builder does not pass through
|
|
1001
1002
|
```
|
|
1002
1003
|
|
|
1004
|
+
[`ng-test`](https://asdalexey.github.io/vitest-auto-spy/utilities/cli#ng-test-—-sharding-and-changed-only-runs-under-the-angular-builder)
|
|
1005
|
+
shards a suite under `@angular/build:unit-test`, or runs only the specs a change reaches: `ng test`
|
|
1006
|
+
passes neither Vitest's `--shard` nor its `--changed` through, so it picks the specs itself and hands
|
|
1007
|
+
them to the builder as `--include` paths.
|
|
1008
|
+
|
|
1003
1009
|
**Exit `0` means "ran, nothing to report"; `1` means "ran, and here is the finding"; `2` means
|
|
1004
1010
|
"there was nothing to judge".** The third one is the reason to read this line: an unknown flag for a
|
|
1005
1011
|
known command is an error and **nothing runs** — `init --dryrun` used to write the files and
|
|
@@ -1035,31 +1041,35 @@ error tsconfig-glob-matches-nothing libs/users/tsconfig.spec.json
|
|
|
1035
1041
|
3 errors, 4 warnings, 1 note
|
|
1036
1042
|
```
|
|
1037
1043
|
|
|
1038
|
-
| Check
|
|
1039
|
-
|
|
|
1040
|
-
| `tsconfig-glob-matches-nothing`
|
|
1041
|
-
| `tsconfig-file-missing`
|
|
1042
|
-
| `spec-imported-by-non-spec`
|
|
1043
|
-
| `spec-exports-fixture`
|
|
1044
|
-
| `foreign-runner-pragma`
|
|
1045
|
-
| `dead-runner-config`
|
|
1046
|
-
| `orphan-runner-file`
|
|
1047
|
-
| `angular-build-splitting-off`
|
|
1048
|
-
| `angular-build-splitting-deprecated`
|
|
1049
|
-
| `analog-behind-angular-build`
|
|
1050
|
-
| `
|
|
1051
|
-
| `
|
|
1052
|
-
| `
|
|
1053
|
-
| `
|
|
1054
|
-
| `
|
|
1055
|
-
| `
|
|
1056
|
-
| `
|
|
1057
|
-
| `vitest-5-
|
|
1058
|
-
| `
|
|
1059
|
-
| `
|
|
1060
|
-
| `
|
|
1061
|
-
| `
|
|
1062
|
-
| `
|
|
1044
|
+
| Check | What it finds |
|
|
1045
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1046
|
+
| `tsconfig-glob-matches-nothing` | An `include` pattern that matches no file — so it type-checks nothing; `info` when nothing beside the config is there to miss yet |
|
|
1047
|
+
| `tsconfig-file-missing` | A `files` entry naming a file that is gone |
|
|
1048
|
+
| `spec-imported-by-non-spec` | A production module importing a `*.spec.ts` |
|
|
1049
|
+
| `spec-exports-fixture` | A spec importing another spec, whose hooks then run in a foreign file |
|
|
1050
|
+
| `foreign-runner-pragma` | `@jest-environment` left in a spec, which Vitest never reads |
|
|
1051
|
+
| `dead-runner-config` | `jest.config.*` / `karma.conf.*` for a runner that is not installed |
|
|
1052
|
+
| `orphan-runner-file` | A setup file only that dead config referenced |
|
|
1053
|
+
| `angular-build-splitting-off` | `@angular/build` in `[22.1.5, 22.1.7)` — the OOM under `--coverage` |
|
|
1054
|
+
| `angular-build-splitting-deprecated` | `"splitting"` on a unit-test target under `@angular/build` 22.2+, which deprecates it — `true` is a no-op, `false` still costs the memory |
|
|
1055
|
+
| `analog-behind-angular-build` | `@analogjs/vite-plugin-angular` below 2.7.5 next to `@angular/build` 22.2+ — `TypeError: cache.has is not a function` at startup |
|
|
1056
|
+
| `analog-fast-compile-ctor-injection` | Analog `fastCompile` in JIT mode with an `@Injectable` whose constructor parameter is known only by its type — NG0202 at injection |
|
|
1057
|
+
| `analog-module-cache-inline-styles` | `fsModuleCache` on under the Analog plugin with a component that has inline `styles` — the warm run fails on `virtual:angular:jit:style:inline` |
|
|
1058
|
+
| `angular-build-istanbul-module-cache` | istanbul coverage under the unit-test builder (not in `browsers`) without `fsModuleCache` — −46 % on a 700-file Angular 22.2 suite. Info |
|
|
1059
|
+
| `angular-build-happy-dom` | jsdom only because `happy-dom` is not installed; the builder picks it by itself from 21 — −4.6 % wall, −6 % RSS. Info |
|
|
1060
|
+
| `coverage-all-removed` | `coverage.all` in a config, on a Vitest that stopped reading the key |
|
|
1061
|
+
| `coverage-include-misses-bundle` | A `coverage.include` of sources only, in a runner config over a bundle |
|
|
1062
|
+
| `coverage-include-recompiles-globs` | A coverage scope large enough that `picomatch` recompiling it per file costs more than the coverage. Info |
|
|
1063
|
+
| `vitest-5-removed` | What Vitest 5 removed — `vitest/reporters`-style imports, `.sequential`, `--outputJson`/`--compare`; error on 5, note on 4. Also `poolOptions` (warning, ignored since 4) |
|
|
1064
|
+
| `vitest-5-deprecated` | `experimental_clearCache` / `experimental_parseSpecifications` on Vitest 5, which nothing warns about at run time. Info |
|
|
1065
|
+
| `vitest-5-clear-mocks` | `clearMocks: true` restating the Vitest 5 default, or a Vitest 4 suite that never decided and will have mocks cleared after the upgrade. Info |
|
|
1066
|
+
| `mock-reset-config-unread` | `no-redundant-mock-reset` given a `configFile` whose default export is a factory or `mergeConfig` call and no flag beside it — the rule reads none of the flags that call sets. Info |
|
|
1067
|
+
| `vitest-5-available` | Vitest 4 with nothing holding back 5 — what it buys (−46 % v8 / −35.5 % istanbul on a 700-file Angular suite with coverage) — or what holds it back. Info |
|
|
1068
|
+
| `fs-module-cache-not-persisted` | `fsModuleCache` on, and no CI config caches its directory — every CI run starts cold |
|
|
1069
|
+
| `jasmine-era-project` | `jasmine-core`, `@types/jasmine`, `karma.conf.*` or `@hirez_io/observer-spy` still installed. Info, not an error |
|
|
1070
|
+
| `no-agent-instructions` | No instruction file names the package. A note, not an error |
|
|
1071
|
+
| `helper-from-wrong-entry` | A named import taken from an entry that does not export it — `provideAutoSpy` from the root |
|
|
1072
|
+
| `no-unawaited-helper` | An `expectEmission` / `stable` / `flushEventLoop` call dropped as a bare statement, so nothing awaits it |
|
|
1063
1073
|
|
|
1064
1074
|
The check that motivated the tool: a spec showing `Cannot find name 'vi'` in the editor while
|
|
1065
1075
|
`tsc --noEmit` reported zero errors. A migration codemod editing `include` had eaten a `/**`,
|
|
@@ -1879,7 +1889,8 @@ multipliers do not transfer to suite scale: building a double is on the order of
|
|
|
1879
1889
|
so a 10× win on the double shows up as a few per cent on the run, and nearly everything else in a
|
|
1880
1890
|
suite swamps it.
|
|
1881
1891
|
|
|
1882
|
-
**Memory, `isolate: false`, 100-method class, 10 000 tests, peak RSS
|
|
1892
|
+
**Memory, `isolate: false`, 100-method class, 10 000 tests, peak RSS** — measured before 2026-09-27,
|
|
1893
|
+
on the accessor-placeholder default and the proxy mode of that time:
|
|
1883
1894
|
|
|
1884
1895
|
| Arm | Peak RSS |
|
|
1885
1896
|
| ------------------------------------- | -------: |
|
|
@@ -1891,19 +1902,35 @@ Hand-written doubles use 3.0x the default's peak RSS here — the difference bet
|
|
|
1891
1902
|
OOM'd worker on a large suite.
|
|
1892
1903
|
|
|
1893
1904
|
That gap traces down to a single double: on the same 100-method class, untouched, a hand-written
|
|
1894
|
-
double retains **414 462 B**.
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
rather than minted per double — and `lazySpies: 'proxy'` retains **4 090 B**, nineteen times more.
|
|
1899
|
-
Full retained-memory tables:
|
|
1905
|
+
double retains **414 462 B**. Re-measured 2026-09-27 (`npm run bench:memory`, Node 24, Vitest 5), the
|
|
1906
|
+
default on that class retains **259 B** per untouched double and `lazySpies: true` **178 B** — the lazy
|
|
1907
|
+
placeholder's accessor pair is shared by method name rather than minted per double. Full
|
|
1908
|
+
retained-memory tables:
|
|
1900
1909
|
[Performance](https://asdalexey.github.io/vitest-auto-spy/core/performance#retained-memory-per-double).
|
|
1901
1910
|
|
|
1911
|
+
The first read is where the accessor placeholders pay: it drops the double into a property
|
|
1912
|
+
dictionary as wide as the class. That dictionary is why a class of 8 methods or more gets `'proxy'`
|
|
1913
|
+
when `lazySpies` is not set. The proxy answers every method from one trap handler and one name set
|
|
1914
|
+
per class and defines nothing, so there is no shared map to leave and no dictionary to grow. Bytes
|
|
1915
|
+
per double with one and two methods called (1 000 doubles held at once, 2026-09-27):
|
|
1916
|
+
|
|
1917
|
+
| Methods in the class | `true`, 1 / 2 touched | `'proxy'`, 1 / 2 touched | Saving |
|
|
1918
|
+
| -------------------: | --------------------: | -----------------------: | ------------: |
|
|
1919
|
+
| 4–6 | 1 743 / 2 887 B | 1 415 / 2 573 B | −19 % / −11 % |
|
|
1920
|
+
| 8–16 | 2 110 / 3 269 B | 1 417 / 2 573 B | −33 % / −21 % |
|
|
1921
|
+
| 20–30 | 2 877 / 4 036 B | 1 416 / 2 573 B | −51 % / −36 % |
|
|
1922
|
+
| 45 | 4 412 / 5 570 B | 1 417 / 2 577 B | −68 % / −54 % |
|
|
1923
|
+
|
|
1924
|
+
The steps are V8's: the dictionary holds `pow2ceil(1.5·(width + 3))` slots. Building and touching the
|
|
1925
|
+
double is cheaper too — 2.2 → 1.1 µs at 8 methods, 6.5 → 1.0 µs at 45. The price is a trap on every
|
|
1926
|
+
read of a member for the life of the double, about 25 ns against 5 ns for a plain property, ~100 B more
|
|
1927
|
+
on a double nobody touches, and a double a spec can see is a `Proxy`. Eight methods is the smallest
|
|
1928
|
+
width where the proxy saves at least 15 % on both profiles; below it the default stays a plain object.
|
|
1929
|
+
`lazySpies: true` opts a wide class out.
|
|
1930
|
+
|
|
1902
1931
|
**Guidance keyed to suite size:** `isolate: false` is worth about 4x on its own — more than any
|
|
1903
|
-
library choice measured here — and it makes memory, not wall-clock, the binding constraint.
|
|
1904
|
-
|
|
1905
|
-
is still faster at, building a double of a very wide class, and it taxes every read for the life of
|
|
1906
|
-
that double (53 ns against 7 ns).
|
|
1932
|
+
library choice measured here — and it makes memory, not wall-clock, the binding constraint. Leave
|
|
1933
|
+
`lazySpies` alone: the width picks the lighter double.
|
|
1907
1934
|
|
|
1908
1935
|
Full write-up, methodology and the complete suite-scale tables:
|
|
1909
1936
|
[Performance](https://asdalexey.github.io/vitest-auto-spy/core/performance).
|
|
@@ -2630,7 +2657,7 @@ beforeEach(() => {
|
|
|
2630
2657
|
> startup with `TypeError: cache.has is not a function`.
|
|
2631
2658
|
|
|
2632
2659
|
> **Lazy by default, everywhere.** Every factory builds each method spy on first access
|
|
2633
|
-
> (`
|
|
2660
|
+
> (accessor placeholders below 8 methods, a `Proxy` from 8), since Angular tests typically spy a wide service but call
|
|
2634
2661
|
> only a few of its methods — and the margin widens as the class does: **1.4×** on a ten-method
|
|
2635
2662
|
> class a test calls twice, **1.9×** on a forty-method one it calls three times. Behaviour is
|
|
2636
2663
|
> unchanged; pass `{ lazySpies: false }` to build every spy eagerly.
|
|
@@ -4336,7 +4363,7 @@ as `methodsToSpyOn`, named for callables that live on the instance — `signal()
|
|
|
4336
4363
|
`gettersToSpyOn`, `settersToSpyOn`, `autoSpyAccessors` (discover every getter/setter),
|
|
4337
4364
|
`fillMissing` (answer a name the prototype never carried with a spy — for a **partially** abstract
|
|
4338
4365
|
class, where `abstract` members are erased and the empty-prototype fallback no longer fires),
|
|
4339
|
-
`lazySpies` (
|
|
4366
|
+
`lazySpies` (build each method spy on first read. Unset: accessor placeholders below 8 methods, `'proxy'` from 8 — a `Proxy` that defines nothing per method, 1.4 kB against 2.1 kB for a 8–16-method double with one method called and 1.4 against 4.4 kB at 45, at ~20 ns per read. `true` keeps a plain object at any width, `false` builds every spy up front — see [Performance](https://asdalexey.github.io/vitest-auto-spy/core/performance#retained-memory-per-double))
|
|
4340
4367
|
|
|
4341
4368
|
`ValueConfig` (for `nextWithValues`): `{ value, delay? }` | `{ errorValue, delay? }` | `{ complete?, delay? }`.
|
|
4342
4369
|
|
package/agent-docs/angular.md
CHANGED
|
@@ -14,8 +14,8 @@ TestBed.configureTestingModule({
|
|
|
14
14
|
const myService = injectSpy(MyService); // Spy<MyService>
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`provideAutoSpy`
|
|
18
|
-
`{ lazySpies: false }` to opt out. The spies never touch `NgZone`, so they work zoneless and with
|
|
17
|
+
`provideAutoSpy` is lazy by default, as `createSpyFromClass` is: an unset `lazySpies` is `true` below 8
|
|
18
|
+
methods and `'proxy'` from 8. Pass `{ lazySpies: false }` to opt out. The spies never touch `NgZone`, so they work zoneless and with
|
|
19
19
|
zone.js alike. The entry needs **Angular >= 20** (§1); on 16 or 17 it does not link at all, because
|
|
20
20
|
`ɵSIGNAL` is not there to import.
|
|
21
21
|
|
|
@@ -524,7 +524,7 @@ built over one record, so every stream, both `ParamMap`s and `snapshot` read the
|
|
|
524
524
|
|
|
525
525
|
| Call | Does |
|
|
526
526
|
| --- | --- |
|
|
527
|
-
| `provideActivatedRoute(init?)` | a `FactoryProvider` — a fresh route per injector; `init`: `params`, `queryParams`, `data`, `title`, `fragment`, `url`, `outlet`, `component`, `routeConfig`, `resolve` |
|
|
527
|
+
| `provideActivatedRoute(init?)` | a `FactoryProvider` — a fresh route per injector; `init`: `params`, `queryParams`, `data`, `title`, `fragment`, `url`, `outlet`, `component`, `routeConfig`, `resolve`, `children`, `resources` (22.2+: one record on the route and every snapshot — fill it with `mockResourceProp(resources, 'user', …)`) |
|
|
528
528
|
| `injectActivatedRoute(injector?)` | the handle: `.route`, `setParams`, `setQueryParams`, `setData`, `setFragment`, `setUrl`, `set({ … })` |
|
|
529
529
|
| `createActivatedRoute(init?)` | the same handle without a `TestBed` — for `new Page(route)`, or a guard given `route.snapshot` |
|
|
530
530
|
|
package/agent-docs/checklist.md
CHANGED
|
@@ -50,9 +50,16 @@ a unit-test target, Analog below 2.7.5, `vite` below 6.4, or Node below 22.12 in
|
|
|
50
50
|
`.node-version`, CI or a private package's `engines`. `fs-module-cache-not-persisted` warns when
|
|
51
51
|
`fsModuleCache` is on and no CI config caches its directory. Renamed config keys Vitest 5 still
|
|
52
52
|
honours (`experimental.fsModuleCache`, `browser.isolate`, `cache.dir`, …) are left to Vitest's own
|
|
53
|
-
deprecation line.
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
deprecation line. Four more cover the Angular unit-test builder and Analog:
|
|
54
|
+
`angular-build-istanbul-module-cache` notes an istanbul run under `@angular/build:unit-test` 21+ on
|
|
55
|
+
Vitest 5 without `fsModuleCache` in the target's runner config (−46 % measured), and
|
|
56
|
+
`analog-module-cache-inline-styles` warns that `fsModuleCache` under the Analog plugin breaks the
|
|
57
|
+
warm run of any spec reaching a component with inline `styles`. `angular-build-happy-dom` notes a
|
|
58
|
+
builder target on jsdom only because `happy-dom` is not installed.
|
|
59
|
+
`analog-fast-compile-ctor-injection` warns that Analog `fastCompile` in JIT mode leaves
|
|
60
|
+
`@Injectable` constructor parameters without a token (NG0202). `mock-reset-config-unread` notes a
|
|
61
|
+
`no-redundant-mock-reset` whose `configFile` names a config built by a factory or `mergeConfig`,
|
|
62
|
+
with no flag beside it: the rule cannot see the flags that call sets.
|
|
56
63
|
It is worth one run after any large edit to a test suite — especially after a codemod, which is where
|
|
57
64
|
the eaten glob below came from.
|
|
58
65
|
|
|
@@ -133,6 +140,11 @@ per file on 5, where it is the wait for Vite's transforms and `import`/`setup` a
|
|
|
133
140
|
totals are CPU time summed across every worker, not wall clock** — a report showing `20.29s of CPU
|
|
134
141
|
time` under `986ms wall clock` is not a bug, it is the work spread over workers.
|
|
135
142
|
|
|
143
|
+
Under `@angular/build:unit-test`, `ng test` takes no Vitest flag. Shard or run only what a change
|
|
144
|
+
reaches with `npx vitest-auto-spy ng-test --shard 1/4` / `--changed [ref]` / `--related <files>`
|
|
145
|
+
(`@angular/build` 21+; everything after `--` goes to `ng`); `test.repeats` in the runner config
|
|
146
|
+
reaches Vitest as it is. `vitest doctor` does not work there — use `perf --command`.
|
|
147
|
+
|
|
136
148
|
When `environment` dominates, the `perf-environment` finding names spec files that could run under
|
|
137
149
|
the `node` environment instead — but only the ones it could _prove_ reach no DOM: the spec, its
|
|
138
150
|
configured setup files, and every repository module any of them imports were all read, none
|
|
@@ -173,7 +185,9 @@ used rather than the machine's cores; under `isolate: false`, `perf-heap` lists
|
|
|
173
185
|
to its lane's heap. Environment time is counted once per lane (`concurrencyId`) and value — not per
|
|
174
186
|
`workerId`, which Vitest 5 renews for every file even in a reused worker. A finding about a switch
|
|
175
187
|
also prints `perf-vitest-doctor`: confirm it with `npx vitest doctor`, Vitest's own A/B runner, not
|
|
176
|
-
this package's `doctor`.
|
|
188
|
+
this package's `doctor`. Under `@angular/build:unit-test` it gives an A/B through `ng run <project>:<target> --runner-config=<variant>`
|
|
189
|
+
instead, because `npx vitest doctor` cannot build that suite; every settings finding there names the runner config
|
|
190
|
+
the target reads. A bare run on Vitest 5 passes `--experimental.diagnostics=false` so Vitest's
|
|
177
191
|
own hints do not repeat these. The reporter rewrites a `partial: true` report every ~2 s while the run
|
|
178
192
|
goes, so a killed or timed-out run still leaves one: `perf` prints it under a warning and the gate
|
|
179
193
|
refuses it like a red run.
|
|
@@ -15,7 +15,7 @@ createSpyFromClass(MyService, {
|
|
|
15
15
|
gettersToSpyOn: ['userName'],
|
|
16
16
|
settersToSpyOn: ['userName'],
|
|
17
17
|
autoSpyAccessors: true, // discover every accessor on the prototype chain
|
|
18
|
-
lazySpies: true, //
|
|
18
|
+
lazySpies: true, // unset: true below 8 methods, 'proxy' from 8; false = eager
|
|
19
19
|
returns: { getProducts: of([]) }, // what a spied METHOD answers
|
|
20
20
|
selfReturning: ['where'], // a method that answers the double itself, for a chained call
|
|
21
21
|
overrides: { products$: subject }, // a member that is not a method result
|
|
@@ -28,7 +28,7 @@ createSpyFromClass(MyService, {
|
|
|
28
28
|
| `onlyMethodsToSpyOn` | **Exhaustive whitelist.** Skips discovery; anything not listed is absent. |
|
|
29
29
|
| `instanceMethodsToSpyOn` | **Additive.** The name to prefer in new code (see below). |
|
|
30
30
|
| `autoSpyAccessors` | Merged with the explicit getter/setter lists. |
|
|
31
|
-
| `lazySpies` |
|
|
31
|
+
| `lazySpies` | Unset: `true` (accessor placeholders) below 8 methods, `'proxy'` (a `Proxy`, lighter once touched) from 8. Explicit `true` / `false` / `'proxy'` apply at any width. Calls, `Object.keys`, spread and snapshots behave the same in every mode. |
|
|
32
32
|
| `strict` | Throw on a method nobody configured, instead of answering `undefined` (below). |
|
|
33
33
|
| `onUnstubbedCall` | The general form of `strict`; its return value becomes the call's return value. |
|
|
34
34
|
| `selfReturning` | The named methods answer the double itself — a default like `returns`; a name in both answers `returns`. |
|
|
@@ -251,6 +251,9 @@ Precedence, first one set wins: the double's `onUnstubbedCall` → the double's
|
|
|
251
251
|
double is built, or `resolveWith` / `nextWith` / `failWith` — which a `calledWith` still wins over.
|
|
252
252
|
The report is this library's own spy engine's, so Vitest and Rstest have it; Bun, `node:test` and
|
|
253
253
|
`setSpyEngine('runner')` do not. The `Once` family is never reported.
|
|
254
|
+
`vi.when(spy)` (Vitest 5) is not reported either: it wraps the dispatch rather than replacing it,
|
|
255
|
+
so a `calledWith` on the same method still answers every call `vi.when` has no row for. A
|
|
256
|
+
`vi.when` over a `mockReturnValue` still is.
|
|
254
257
|
- **A throw something swallowed still fails the test.** Under `setupAutoSpy({ strict: true })` every
|
|
255
258
|
strict throw is recorded, and one that a `try`/`catch` in the code under test or an RxJS error with
|
|
256
259
|
no handler (its rethrow waits on a fake clock) kept from the test fails it after the test
|
package/agent-docs/errors.md
CHANGED
|
@@ -126,6 +126,7 @@ Part of the agent reference [`AGENTS.md`](../AGENTS.md), which maps every sectio
|
|
|
126
126
|
| `flushEventLoopUntil` timing out on the **first** such test only, the rest green | a cold dynamic `import()` outran the turn budget; later tests hit the module cache | `await settleDynamicImport(() => import('…'))` — await the module, do not count turns |
|
|
127
127
|
| `Expected to be running in 'ProxyZone', but it was not found` | `zone.js/testing` patches jasmine/mocha/jest, not Vitest | `import 'vitest-auto-spy/zone'` after zone.js, with `globals: true` (§14) |
|
|
128
128
|
| `nextWith` demanding `HttpEvent<T>` on a generated API client | `Parameters`/`ReturnType` read the **last** overload | `asSpy<Client, { overload: 'first' }>(…)`, or `Overload<M, 0>` — never `@ts-expect-error`, which `no-ts-expect-error-on-double` reports (§16) |
|
|
129
|
+
| `NG0202 … dependency at index N of the parameter list is invalid` from `createWithAutoSpies` or plain `TestBed.inject`, under Analog `fastCompile: true` | the plugin drops the constructor types of `@Injectable` classes in JIT mode — not a library bug (`doctor` reports `analog-fast-compile-ctor-injection` and lists the classes) | an `inject()` field, or `@Inject(X)` on the parameter; or turn `fastCompile` off (§13) |
|
|
129
130
|
| `NG0303` / `NG0304` / nothing at all, from a directive spec | the host is `standalone: false`, or the module is in the TestBed | `createDirectiveHost({ template, scope: [Module] })`; on Angular ≥ 22.2, for a directive with no static host attribute, `TemplateRef` or sibling markup, `TestBed.createDirective(Dir, { tagName, bindings })` (§13) |
|
|
130
131
|
| `setInputs: … declares no input named …` (with a `Did you mean` for a near typo) | the key is not an input of that component — a typo, an input renamed since, or one of its own fields | take the suggestion, or set a name the message lists; a signal the component owns is moved through the signal (§13) |
|
|
131
132
|
| `setInputs: X carries no ɵcmp, so there are no inputs to set` (or `the component class is undefined`, `X is a @Pipe`) | the fixture's `componentType` is not a compiled `@Component` — a `@Pipe`, a class Angular never compiled, or `undefined` from a barrel split across chunks | pass the `@Component` class the fixture was created from; call a pipe's `transform()` directly; for `undefined` import the class from its own file (§13) |
|
package/agent-docs/factories.md
CHANGED
|
@@ -349,12 +349,13 @@ retains: an untouched 100-method double holds **215 B** where it held 25 593, an
|
|
|
349
349
|
construction on very wide classes — building a 300-method double costs about 28 % more — and
|
|
350
350
|
materialising every method of one is about 26 % cheaper in exchange.
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
352
|
+
The first materialisation is where the accessor path pays: it drops the double into a property
|
|
353
|
+
dictionary as wide as the class. So since 2026-09-27 an unset `lazySpies` depends on width: a class of
|
|
354
|
+
8 methods or more gets `'proxy'`, which defines nothing per method and never enters dictionary mode —
|
|
355
|
+
21–68 % lighter once touched, 2–6× faster to build — for ~20 ns on every read and ~100 B more on an
|
|
356
|
+
untouched double. A narrower class keeps the accessor placeholders. A spec on a wide class that needs a
|
|
357
|
+
plain object (`util.types.isProxy`, `console.log` of an unread double, `vi.spyOn` wrapping an unread
|
|
358
|
+
method) passes `lazySpies: true`.
|
|
358
359
|
|
|
359
360
|
A frozen or sealed double is fine now. `Object.freeze(spy)` — a deep-freeze fixture helper, a
|
|
360
361
|
dev-mode state guard — used to make the first read of any method throw `Cannot redefine property`
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { pendingRequestsReport, assertAngularInternals, instrumentTestBed, onTestingModuleConfigured, onComponentCreated, beforeTestBedReset, verifyOnTeardown } from './chunk-JFOJFCVQ.js';
|
|
2
2
|
export { disableTestBedDiagnostics, enableTestBedDiagnostics, formatSpecTiming, getTestBedTiming, instrumentTestBed, reportSpecTiming } from './chunk-JFOJFCVQ.js';
|
|
3
|
-
import { failOnUnspiedProvider } from './chunk-
|
|
3
|
+
import { failOnUnspiedProvider } from './chunk-MHN6GMXP.js';
|
|
4
4
|
import './chunk-GG7BQKEK.js';
|
|
5
5
|
import './chunk-MNY4ZHEQ.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-EYXARTWD.js';
|
|
7
7
|
import './chunk-FOL5RH22.js';
|
|
8
8
|
import './chunk-PC3FAZT3.js';
|
|
9
|
-
import './chunk-
|
|
9
|
+
import './chunk-CENALW7R.js';
|
|
10
10
|
import { isAutoSpyLike } from './chunk-Q7L4AWI7.js';
|
|
11
11
|
import { count, sourceClassName, taskName } from './chunk-DYAS4OK4.js';
|
|
12
12
|
import { angularPendingRequests, angularShadowedProviders, angularDeadSchemas, angularNgModuleScopesAuto } from './chunk-5FQZGJLJ.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InjectionToken, AbstractType, Injector, ValueProvider, FactoryProvider, ProviderToken } from '@angular/core';
|
|
2
|
-
import { h as AddSpyMethodsByReturnTypes } from './types-
|
|
2
|
+
import { h as AddSpyMethodsByReturnTypes } from './types-CyRUgJVd.js';
|
|
3
3
|
import 'vitest';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/angular-doubles.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { describeInstance } from './chunk-XEIOGUGP.js';
|
|
2
|
-
import { useVitestAdapter } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
import { useVitestAdapter } from './chunk-J4IJCTHT.js';
|
|
3
|
+
import './chunk-J2C3KRTC.js';
|
|
4
4
|
import './chunk-YHDBRBGU.js';
|
|
5
5
|
import './chunk-TXDBDMIL.js';
|
|
6
6
|
import './chunk-FOL5RH22.js';
|
|
7
7
|
import './chunk-PC3FAZT3.js';
|
|
8
|
-
import { createFunctionSpy } from './chunk-
|
|
8
|
+
import { createFunctionSpy } from './chunk-CENALW7R.js';
|
|
9
9
|
import './chunk-Q7L4AWI7.js';
|
|
10
10
|
import { sourceClassName } from './chunk-DYAS4OK4.js';
|
|
11
11
|
import { angularDialog } from './chunk-5FQZGJLJ.js';
|
package/dist/angular-router.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Type, Injector, FactoryProvider, Provider } from '@angular/core';
|
|
2
2
|
import { Params, Data, UrlSegment, ActivatedRoute, Route, ResolveData, Navigation, Router, Event } from '@angular/router';
|
|
3
|
-
import { h as AddSpyMethodsByReturnTypes } from './types-
|
|
3
|
+
import { h as AddSpyMethodsByReturnTypes } from './types-CyRUgJVd.js';
|
|
4
4
|
import { SpyLocation } from '@angular/common/testing';
|
|
5
5
|
import 'vitest';
|
|
6
6
|
|
|
@@ -38,6 +38,11 @@ interface ActivatedRouteChange {
|
|
|
38
38
|
/** The matched URL segments. A string is split on `/`; pass `UrlSegment`s for matrix parameters. */
|
|
39
39
|
url?: UrlSegment[] | string;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* `ActivatedRoute.resources` where the installed `@angular/router` has it (22.2 on), `never` before —
|
|
43
|
+
* so the init key stays harmless on 20 and 21.
|
|
44
|
+
*/
|
|
45
|
+
type RouteResources = NonNullable<ActivatedRoute[Extract<'resources', keyof ActivatedRoute>]>;
|
|
41
46
|
/** The route a spec starts from: what a navigation moves, plus what stays fixed for the route's life. */
|
|
42
47
|
interface ActivatedRouteInit extends ActivatedRouteChange {
|
|
43
48
|
/** The outlet the route is rendered into. Default `'primary'`. */
|
|
@@ -48,6 +53,11 @@ interface ActivatedRouteInit extends ActivatedRouteChange {
|
|
|
48
53
|
routeConfig?: Route | null;
|
|
49
54
|
/** The resolve record — the snapshot's own `_resolve`, kept apart from `data` as Angular keeps it. */
|
|
50
55
|
resolve?: ResolveData;
|
|
56
|
+
/**
|
|
57
|
+
* The record a route's `resources` function returned — `route.resources` and `snapshot.resources`,
|
|
58
|
+
* the same object on every snapshot, as a navigation that keeps the route carries it over.
|
|
59
|
+
*/
|
|
60
|
+
resources?: RouteResources;
|
|
51
61
|
/** Child routes, each a double of its own: `route.children`, `firstChild` and a child's `parent` answer them. */
|
|
52
62
|
children?: readonly ActivatedRouteInit[];
|
|
53
63
|
}
|
package/dist/angular-router.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describeInstance } from './chunk-XEIOGUGP.js';
|
|
2
2
|
import { angularInternalsError } from './chunk-GG7BQKEK.js';
|
|
3
|
-
import { createFunctionSpy } from './chunk-
|
|
3
|
+
import { createFunctionSpy } from './chunk-CENALW7R.js';
|
|
4
4
|
import './chunk-Q7L4AWI7.js';
|
|
5
5
|
import { count } from './chunk-DYAS4OK4.js';
|
|
6
6
|
import { angularRouteDouble, angularRouterInject, angularRouterEvents, angularLocationDouble, angularRouteWiring, angularRouterDouble } from './chunk-5FQZGJLJ.js';
|
|
@@ -110,7 +110,14 @@ function buildSnapshot(state, fixed) {
|
|
|
110
110
|
fixed.routeConfig,
|
|
111
111
|
state.resolve
|
|
112
112
|
];
|
|
113
|
-
|
|
113
|
+
const snapshot = Reflect.construct(ActivatedRouteSnapshot, args);
|
|
114
|
+
withResources(snapshot, fixed);
|
|
115
|
+
return snapshot;
|
|
116
|
+
}
|
|
117
|
+
function withResources(target, fixed) {
|
|
118
|
+
if (fixed.resources !== void 0) {
|
|
119
|
+
Reflect.set(target, "resources", fixed.resources);
|
|
120
|
+
}
|
|
114
121
|
}
|
|
115
122
|
function routeWiringError(member) {
|
|
116
123
|
return new Error(
|
|
@@ -187,13 +194,15 @@ function constructRoute(streams, fixed, snapshot) {
|
|
|
187
194
|
snapshot
|
|
188
195
|
]);
|
|
189
196
|
route.snapshot = snapshot;
|
|
197
|
+
withResources(route, fixed);
|
|
190
198
|
return route;
|
|
191
199
|
}
|
|
192
200
|
function buildActivatedRoute(init) {
|
|
193
201
|
const fixed = {
|
|
194
202
|
outlet: init.outlet ?? PRIMARY_OUTLET,
|
|
195
203
|
component: init.component ?? null,
|
|
196
|
-
routeConfig: init.routeConfig ?? null
|
|
204
|
+
routeConfig: init.routeConfig ?? null,
|
|
205
|
+
resources: init.resources
|
|
197
206
|
};
|
|
198
207
|
let state = initialState(init);
|
|
199
208
|
const streams = streamsOf(state);
|
package/dist/angular.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { u as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, E as ElementConstructor, N as NativeElementHolder, 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 hostElement, k as injectSpy, p as provideAutoSpy, v as provideAutoSpyForToken, q as queryElement, r as renderShallow, l as runEffect, s as setInputs, m as settleResource, n as stable, t as trackEffectRuns, o as trackRecomputations } from './track-signal-runs-
|
|
2
|
-
import { o as DeepPartial, C as ClassType, m as ClassSpyConfiguration, S as Spy, s as OnlyMethodKeysOf, h as AddSpyMethodsByReturnTypes, r as NotAPublicKey } from './types-
|
|
3
|
-
export { H as SubjectOf } from './types-
|
|
1
|
+
export { u as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, E as ElementConstructor, N as NativeElementHolder, 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 hostElement, k as injectSpy, p as provideAutoSpy, v as provideAutoSpyForToken, q as queryElement, r as renderShallow, l as runEffect, s as setInputs, m as settleResource, n as stable, t as trackEffectRuns, o as trackRecomputations } from './track-signal-runs-bs2umXNE.js';
|
|
2
|
+
import { o as DeepPartial, C as ClassType, m as ClassSpyConfiguration, S as Spy, s as OnlyMethodKeysOf, h as AddSpyMethodsByReturnTypes, r as NotAPublicKey } from './types-CyRUgJVd.js';
|
|
3
|
+
export { H as SubjectOf } from './types-CyRUgJVd.js';
|
|
4
4
|
import { InjectionToken, Provider, Type, WritableSignal, Signal } from '@angular/core';
|
|
5
|
-
import { A as AutoMockConfiguration, D as DeepReadonly } from './expect-emission-
|
|
6
|
-
export { C as CallbackSubscribable, E as EmissionObserver, c as EmissionOptions, d as EmissionSource, S as SubscribableLike, h as expectAllEmissions, i as expectCompletion, j as expectEmission, k as expectEmissions, l as expectError, m as expectNoEmission, s as setEmissionTimeout } from './expect-emission-
|
|
5
|
+
import { A as AutoMockConfiguration, D as DeepReadonly } from './expect-emission-D273986K.js';
|
|
6
|
+
export { C as CallbackSubscribable, E as EmissionObserver, c as EmissionOptions, d as EmissionSource, S as SubscribableLike, h as expectAllEmissions, i as expectCompletion, j as expectEmission, k as expectEmissions, l as expectError, m as expectNoEmission, s as setEmissionTimeout } from './expect-emission-D273986K.js';
|
|
7
7
|
import { TestAPI } from 'vitest';
|
|
8
|
-
export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-
|
|
9
|
-
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, e as restoreMockedProps } from './prop-mock-
|
|
8
|
+
export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-BTJKOqWz.js';
|
|
9
|
+
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, e as restoreMockedProps } from './prop-mock-Cz0yKWEP.js';
|
|
10
10
|
import '@angular/core/testing';
|
|
11
11
|
|
|
12
12
|
/**
|