vitest-auto-spy 3.15.1 → 3.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 +23 -11
- package/README.md +17 -16
- package/dist/angular.d.ts +5 -5
- package/dist/angular.js +92 -8
- package/dist/bun-angular.d.ts +4 -4
- package/dist/bun-angular.js +4 -4
- package/dist/bun.d.ts +4 -4
- package/dist/bun.js +2 -2
- package/dist/{chunk-GEXYXX4P.js → chunk-3EHP3NKE.js} +92 -8
- package/dist/{chunk-VPRUMHEL.js → chunk-BNZFNS42.js} +1 -1
- package/dist/{chunk-IZO7U34R.js → chunk-YXHG5DXF.js} +1 -1
- package/dist/cli.js +47 -2
- package/dist/console.d.ts +1 -1
- package/dist/{expect-emission-COcg6YzT.d.ts → expect-emission-BhGKIi7_.d.ts} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +92 -8
- package/dist/jasmine-compat.d.ts +1 -1
- package/dist/jasmine.d.ts +2 -2
- package/dist/jasmine.js +1 -1
- package/dist/nestjs.d.ts +2 -2
- package/dist/nestjs.js +2 -2
- package/dist/node.cjs +92 -8
- package/dist/node.d.ts +3 -3
- package/dist/node.js +2 -2
- package/dist/{prop-mock-CEBKBA7k.d.ts → prop-mock-B5TLaKCg.d.ts} +1 -1
- package/dist/react.d.ts +3 -3
- package/dist/react.js +2 -2
- package/dist/rxjs.d.ts +2 -2
- package/dist/setup.d.ts +2 -2
- package/dist/svelte.d.ts +3 -3
- package/dist/svelte.js +2 -2
- package/dist/{track-injections-BU-WSjji.d.ts → track-injections-DXoDu6sG.d.ts} +1 -1
- package/dist/{types-W5kEgzND.d.ts → types-d8Mdj_jK.d.ts} +9 -1
- package/dist/vue.d.ts +4 -4
- package/dist/vue.js +3 -3
- package/dist/{zoneless-DzUXGIYb.d.ts → zoneless-BxqMRfiJ.d.ts} +3 -3
- package/package.json +1 -1
- package/skills/vitest-auto-spy/SKILL.md +60 -59
package/AGENTS.md
CHANGED
|
@@ -265,6 +265,14 @@ across two thousand tests is under a tenth of a second. Call the factory in `bef
|
|
|
265
265
|
`provideAutoSpy` defaults to, and `autoSpyAccessors: true` walks the prototype chain uncached on
|
|
266
266
|
every call — name the accessors instead.
|
|
267
267
|
|
|
268
|
+
Memory is the exception, and only on classes wide enough for it to matter. `lazySpies: true` still
|
|
269
|
+
defines one accessor per method, and that placeholder is nearly all of what an untouched double
|
|
270
|
+
retains: 101.6 kB on a 400-method class against 11.8 kB with `lazySpies: 'proxy'`, which answers
|
|
271
|
+
every method from a single trap object instead (25 B per method against 253 B). It is opt-in because
|
|
272
|
+
a `Proxy` cannot remove itself — +30 ns per read and +43 ns per call, forever — and it loses on a
|
|
273
|
+
five-method service. Reach for it on generated API clients and ngrx facades under `isolate: false`,
|
|
274
|
+
where the doubles of a whole file are alive at once; leave the default everywhere else.
|
|
275
|
+
|
|
268
276
|
---
|
|
269
277
|
|
|
270
278
|
## 3. The 90% recipe
|
|
@@ -468,21 +476,21 @@ createSpyFromClass(MyService, {
|
|
|
468
476
|
gettersToSpyOn: ['userName'],
|
|
469
477
|
settersToSpyOn: ['userName'],
|
|
470
478
|
autoSpyAccessors: true, // discover every accessor on the prototype chain
|
|
471
|
-
lazySpies: true, // build each method spy on first access
|
|
479
|
+
lazySpies: true, // build each method spy on first access ('proxy' for very wide classes)
|
|
472
480
|
returns: { getProducts: of([]) }, // what a spied METHOD answers
|
|
473
481
|
overrides: { products$: subject }, // a member that is not a method result
|
|
474
482
|
});
|
|
475
483
|
```
|
|
476
484
|
|
|
477
|
-
| Key | Semantics
|
|
478
|
-
| ------------------------ |
|
|
479
|
-
| `methodsToSpyOn` | **Additive**, as in `jest-auto-spies`. Same behaviour as `instanceMethodsToSpyOn`.
|
|
480
|
-
| `onlyMethodsToSpyOn` | **Exhaustive whitelist.** Skips discovery; anything not listed is absent.
|
|
481
|
-
| `instanceMethodsToSpyOn` | **Additive.** The name to prefer in new code (see below).
|
|
482
|
-
| `autoSpyAccessors` | Merged with the explicit getter/setter lists.
|
|
483
|
-
| `lazySpies` | Behaviour-identical; only changes _when_ each spy is built.
|
|
484
|
-
| `strict` | Throw on a method nobody configured, instead of answering `undefined` (below).
|
|
485
|
-
| `onUnstubbedCall` | The general form of `strict`; its return value becomes the call's return value.
|
|
485
|
+
| Key | Semantics |
|
|
486
|
+
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
|
|
487
|
+
| `methodsToSpyOn` | **Additive**, as in `jest-auto-spies`. Same behaviour as `instanceMethodsToSpyOn`. |
|
|
488
|
+
| `onlyMethodsToSpyOn` | **Exhaustive whitelist.** Skips discovery; anything not listed is absent. |
|
|
489
|
+
| `instanceMethodsToSpyOn` | **Additive.** The name to prefer in new code (see below). |
|
|
490
|
+
| `autoSpyAccessors` | Merged with the explicit getter/setter lists. |
|
|
491
|
+
| `lazySpies` | Behaviour-identical; only changes _when_ each spy is built. `'proxy'` also changes _what holds the name_. |
|
|
492
|
+
| `strict` | Throw on a method nobody configured, instead of answering `undefined` (below). |
|
|
493
|
+
| `onUnstubbedCall` | The general form of `strict`; its return value becomes the call's return value. |
|
|
486
494
|
|
|
487
495
|
**`instanceMethodsToSpyOn` is not an edge case — it is a top-5 option** (103 of ~370 spec files in
|
|
488
496
|
the reference suite). Method discovery walks the _prototype chain_; a callable assigned to an
|
|
@@ -2334,7 +2342,11 @@ suite that runs green but does not type-check is not done.
|
|
|
2334
2342
|
`doctor` is read-only and finds what a green run cannot: a `tsconfig` `include` pattern that
|
|
2335
2343
|
matches no file (so it type-checks nothing while `tsc --noEmit` still reports success), a
|
|
2336
2344
|
production module importing a `*.spec.ts`, a spec importing another spec, a `@jest-environment`
|
|
2337
|
-
pragma the runner never reads, and configuration left behind for a runner that is gone.
|
|
2345
|
+
pragma the runner never reads, and configuration left behind for a runner that is gone. Three of
|
|
2346
|
+
its checks are about coverage, where the run is green and the report is simply not the one the
|
|
2347
|
+
config describes — `coverage.all` on a Vitest that stopped reading the key, a source-only
|
|
2348
|
+
`coverage.include` in a runner config over a bundle, and a scope so large that `picomatch`
|
|
2349
|
+
recompiling it per file costs more than collecting the coverage does. It is
|
|
2338
2350
|
worth one run after any large edit to a test suite — especially after a codemod, which is where
|
|
2339
2351
|
the eaten glob below came from. Full reference:
|
|
2340
2352
|
<https://asdalexey.github.io/vitest-auto-spy/utilities/cli>.
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ identical API, with **RxJS** spies and **Angular / NestJS / React / Vue·Pinia /
|
|
|
19
19
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
20
20
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
21
21
|
[](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
|
|
22
|
-
[](#install)
|
|
23
23
|
[](https://www.npmjs.com/package/vitest-auto-spy)
|
|
24
24
|
[](https://github.com/ASDAlexey/vitest-auto-spy/actions/workflows/ci.yml)
|
|
25
25
|
[](./LICENSE)
|
|
@@ -239,20 +239,21 @@ error tsconfig-glob-matches-nothing libs/users/tsconfig.spec.json
|
|
|
239
239
|
3 errors, 4 warnings, 1 note
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
-
| Check
|
|
243
|
-
|
|
|
244
|
-
| `tsconfig-glob-matches-nothing`
|
|
245
|
-
| `tsconfig-file-missing`
|
|
246
|
-
| `spec-imported-by-non-spec`
|
|
247
|
-
| `spec-exports-fixture`
|
|
248
|
-
| `foreign-runner-pragma`
|
|
249
|
-
| `dead-runner-config`
|
|
250
|
-
| `orphan-runner-file`
|
|
251
|
-
| `angular-build-splitting-off`
|
|
252
|
-
| `coverage-all-removed`
|
|
253
|
-
| `coverage-include-misses-bundle`
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
242
|
+
| Check | What it finds |
|
|
243
|
+
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
244
|
+
| `tsconfig-glob-matches-nothing` | An `include` pattern that matches no file — so it type-checks nothing |
|
|
245
|
+
| `tsconfig-file-missing` | A `files` entry naming a file that is gone |
|
|
246
|
+
| `spec-imported-by-non-spec` | A production module importing a `*.spec.ts` |
|
|
247
|
+
| `spec-exports-fixture` | A spec importing another spec, whose hooks then run in a foreign file |
|
|
248
|
+
| `foreign-runner-pragma` | `@jest-environment` left in a spec, which Vitest never reads |
|
|
249
|
+
| `dead-runner-config` | `jest.config.*` / `karma.conf.*` for a runner that is not installed |
|
|
250
|
+
| `orphan-runner-file` | A setup file only that dead config referenced |
|
|
251
|
+
| `angular-build-splitting-off` | `@angular/build` in `[22.1.5, 22.1.7)` — the OOM under `--coverage` |
|
|
252
|
+
| `coverage-all-removed` | `coverage.all` in a config, on a Vitest that stopped reading the key |
|
|
253
|
+
| `coverage-include-misses-bundle` | A `coverage.include` of sources only, in a runner config over a bundle |
|
|
254
|
+
| `coverage-include-recompiles-globs` | A coverage scope large enough that `picomatch` recompiling it per file costs more than the coverage. Info |
|
|
255
|
+
| `jasmine-era-project` | `jasmine-core`, `@types/jasmine`, `karma.conf.*` or `@hirez_io/observer-spy` still installed. Info, not an error |
|
|
256
|
+
| `no-agent-instructions` | No instruction file names the package. A note, not an error |
|
|
256
257
|
|
|
257
258
|
The check that motivated the tool: a spec showing `Cannot find name 'vi'` in the editor while
|
|
258
259
|
`tsc --noEmit` reported zero errors. A migration codemod editing `include` had eaten a `/**`,
|
|
@@ -2682,7 +2683,7 @@ as `methodsToSpyOn`, named for callables that live on the instance — `signal()
|
|
|
2682
2683
|
`gettersToSpyOn`, `settersToSpyOn`, `autoSpyAccessors` (discover every getter/setter),
|
|
2683
2684
|
`fillMissing` (answer a name the prototype never carried with a spy — for a **partially** abstract
|
|
2684
2685
|
class, where `abstract` members are erased and the empty-prototype fallback no longer fires),
|
|
2685
|
-
`lazySpies` (materialize method spies on first access — cheaper for wide classes; the `provideAutoSpy` default on Angular)
|
|
2686
|
+
`lazySpies` (materialize method spies on first access — cheaper for wide classes; the `provideAutoSpy` default on Angular. `'proxy'` keeps the laziness and drops the per-method placeholder: 11.8 kB retained against 101.6 kB on a 400-method class, at +30 ns per read — opt-in, and worth it only above ~20 methods)
|
|
2686
2687
|
|
|
2687
2688
|
`ValueConfig` (for `nextWithValues`): `{ value, delay? }` | `{ errorValue, delay? }` | `{ complete?, delay? }`.
|
|
2688
2689
|
|
package/dist/angular.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { l as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, m as provideAutoSpyForToken, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-
|
|
1
|
+
export { l as AngularTokenProvider, A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, m as provideAutoSpyForToken, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-BxqMRfiJ.js';
|
|
2
2
|
import { InjectionToken, Provider, Type, Signal, WritableSignal } from '@angular/core';
|
|
3
3
|
import { TestAPI } from 'vitest';
|
|
4
|
-
import { C as ClassType, S as Spy, a as ClassSpyConfiguration, O as OnlyMethodKeysOf, j as AddSpyMethodsByReturnTypes } from './types-
|
|
5
|
-
export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-
|
|
6
|
-
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-
|
|
7
|
-
export { C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-
|
|
4
|
+
import { C as ClassType, S as Spy, a as ClassSpyConfiguration, O as OnlyMethodKeysOf, j as AddSpyMethodsByReturnTypes } from './types-d8Mdj_jK.js';
|
|
5
|
+
export { I as InjectionLog, T as TrackInjectionsOptions, a as TrackedProvider, t as trackInjections } from './track-injections-DXoDu6sG.js';
|
|
6
|
+
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-B5TLaKCg.js';
|
|
7
|
+
export { C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BhGKIi7_.js';
|
|
8
8
|
import '@angular/core/testing';
|
|
9
9
|
import 'rxjs';
|
|
10
10
|
|
package/dist/angular.js
CHANGED
|
@@ -949,6 +949,87 @@ function fillMissingMembers(autoSpy, unstubbed) {
|
|
|
949
949
|
}
|
|
950
950
|
});
|
|
951
951
|
}
|
|
952
|
+
|
|
953
|
+
// src/lib/lazy-spy-proxy.ts
|
|
954
|
+
var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
|
|
955
|
+
function defineSpy(target, key, value) {
|
|
956
|
+
Object.defineProperty(target, key, { configurable: true, enumerable: true, writable: true, value });
|
|
957
|
+
}
|
|
958
|
+
function materialize(target, state, key) {
|
|
959
|
+
const spy = createFunctionSpy(key, state.unstubbed);
|
|
960
|
+
defineSpy(target, key, spy);
|
|
961
|
+
return spy;
|
|
962
|
+
}
|
|
963
|
+
function pendingDescriptor(target, state, key) {
|
|
964
|
+
return {
|
|
965
|
+
configurable: true,
|
|
966
|
+
enumerable: true,
|
|
967
|
+
get: () => materialize(target, state, key),
|
|
968
|
+
set: (value) => defineSpy(target, key, value)
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
function orderedKeys(target, state) {
|
|
972
|
+
const own = Reflect.ownKeys(target);
|
|
973
|
+
if (!Reflect.isExtensible(target)) {
|
|
974
|
+
return own;
|
|
975
|
+
}
|
|
976
|
+
const ownStrings = own.filter((key) => typeof key === "string");
|
|
977
|
+
const present = new Set(ownStrings);
|
|
978
|
+
return [
|
|
979
|
+
...state.preKeys.filter((key) => present.has(key)),
|
|
980
|
+
...[...state.names].filter((key) => state.isPending(key) || present.has(key)),
|
|
981
|
+
...ownStrings.filter((key) => !state.preSet.has(key) && !state.names.has(key)),
|
|
982
|
+
...own.filter((key) => typeof key === "symbol")
|
|
983
|
+
];
|
|
984
|
+
}
|
|
985
|
+
function createLazySpyProxy(autoSpy, methodNames, unstubbed) {
|
|
986
|
+
const preKeys = Reflect.ownKeys(autoSpy).filter((key) => typeof key === "string");
|
|
987
|
+
const state = {
|
|
988
|
+
// Insertion order doubles as declaration order for `ownKeys`, so no second array is retained.
|
|
989
|
+
names: new Set(methodNames),
|
|
990
|
+
// Only ever holds a name a caller explicitly deleted: without it, `delete spy.method` would leave
|
|
991
|
+
// the name pending again and the next read would resurrect it.
|
|
992
|
+
deleted: /* @__PURE__ */ new Set(),
|
|
993
|
+
preKeys,
|
|
994
|
+
preSet: new Set(preKeys),
|
|
995
|
+
unstubbed,
|
|
996
|
+
isPending: (key) => typeof key === "string" && state.names.has(key) && !state.deleted.has(key) && !hasOwn(autoSpy, key)
|
|
997
|
+
};
|
|
998
|
+
return new Proxy(autoSpy, {
|
|
999
|
+
get(target, key) {
|
|
1000
|
+
return state.isPending(key) ? materialize(target, state, key) : Reflect.get(target, key);
|
|
1001
|
+
},
|
|
1002
|
+
set(target, key, value) {
|
|
1003
|
+
if (state.isPending(key)) {
|
|
1004
|
+
defineSpy(target, key, value);
|
|
1005
|
+
return true;
|
|
1006
|
+
}
|
|
1007
|
+
return Reflect.set(target, key, value);
|
|
1008
|
+
},
|
|
1009
|
+
has(target, key) {
|
|
1010
|
+
return state.isPending(key) || Reflect.has(target, key);
|
|
1011
|
+
},
|
|
1012
|
+
getOwnPropertyDescriptor(target, key) {
|
|
1013
|
+
return state.isPending(key) ? pendingDescriptor(target, state, key) : Reflect.getOwnPropertyDescriptor(target, key);
|
|
1014
|
+
},
|
|
1015
|
+
deleteProperty(target, key) {
|
|
1016
|
+
const wasPending = state.isPending(key);
|
|
1017
|
+
if (typeof key === "string" && state.names.has(key)) {
|
|
1018
|
+
state.deleted.add(key);
|
|
1019
|
+
}
|
|
1020
|
+
return wasPending || Reflect.deleteProperty(target, key);
|
|
1021
|
+
},
|
|
1022
|
+
ownKeys: (target) => orderedKeys(target, state),
|
|
1023
|
+
preventExtensions(target) {
|
|
1024
|
+
state.names.forEach((key) => {
|
|
1025
|
+
if (state.isPending(key)) {
|
|
1026
|
+
materialize(target, state, key);
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
return Reflect.preventExtensions(target);
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
952
1033
|
var EMPTY_CONFIGURATION = {
|
|
953
1034
|
methodsToSpyOn: [],
|
|
954
1035
|
onlyMethodsToSpyOn: [],
|
|
@@ -1162,15 +1243,18 @@ function assembleSpy(ObjectClass, config) {
|
|
|
1162
1243
|
});
|
|
1163
1244
|
warnOnAccessorNamingAMethod(ObjectClass, config);
|
|
1164
1245
|
createAccessorsSpies(autoSpy, accessors.getters, accessors.setters);
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1246
|
+
if (config.lazySpies !== "proxy") {
|
|
1247
|
+
methodNames.forEach((methodName) => {
|
|
1248
|
+
if (config.lazySpies) {
|
|
1249
|
+
defineLazyMethodSpy(autoSpy, methodName, unstubbed);
|
|
1250
|
+
} else {
|
|
1251
|
+
autoSpy[methodName] = createFunctionSpy(methodName, unstubbed);
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1172
1255
|
attachDispose(autoSpy);
|
|
1173
|
-
|
|
1256
|
+
const assembled = config.lazySpies === "proxy" ? createLazySpyProxy(autoSpy, methodNames, unstubbed) : autoSpy;
|
|
1257
|
+
return config.fillMissing ? fillMissingMembers(assembled, unstubbed) : assembled;
|
|
1174
1258
|
}
|
|
1175
1259
|
function hasNothingToRead(ObjectClass, accessors, config) {
|
|
1176
1260
|
return getAllMethodNames(ObjectClass.prototype).length === 0 && accessors.getters.length === 0 && accessors.setters.length === 0 && config.observablePropsToSpyOn.length === 0 && // A *restricting* list asks for the opposite of what the proxy provides. `onlyMethodsToSpyOn`
|
package/dist/bun-angular.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { d as AccessorKeysOf, e as AddAccessorsSpies, f as AddCalledWithObservable, g as AddCalledWithPromise, h as AddCalledWithSpyMethods, A as AddObservableSpyMethods, i as AddPromiseSpyMethods, j as AddSpyMethodsByReturnTypes, k as AddThrowHelper, l as AddVoidReturnHelpers, a as ClassSpyConfiguration, C as ClassType, b as CompleteValueConfig, D as DeepMockProxy, m as DeepPartial, E as ErrorValueConfig, F as Func, M as MethodReturns, n as Mutable, N as NextValueConfig, O as OnlyMethodKeysOf, o as OnlyObservablePropsOf, p as OnlyPropsOf, q as Overload, r as Overloads, P as PropStubValue, S as Spy, s as SpyDisposable, t as SpyOptions, u as StrictSpyConfiguration, U as UnstubbedCall, v as UnstubbedCallHandler, V as ValueConfig, c as ValueConfigPerCall, W as WithMockReturnValue } from './types-
|
|
1
|
+
export { d as AccessorKeysOf, e as AddAccessorsSpies, f as AddCalledWithObservable, g as AddCalledWithPromise, h as AddCalledWithSpyMethods, A as AddObservableSpyMethods, i as AddPromiseSpyMethods, j as AddSpyMethodsByReturnTypes, k as AddThrowHelper, l as AddVoidReturnHelpers, a as ClassSpyConfiguration, C as ClassType, b as CompleteValueConfig, D as DeepMockProxy, m as DeepPartial, E as ErrorValueConfig, F as Func, M as MethodReturns, n as Mutable, N as NextValueConfig, O as OnlyMethodKeysOf, o as OnlyObservablePropsOf, p as OnlyPropsOf, q as Overload, r as Overloads, P as PropStubValue, S as Spy, s as SpyDisposable, t as SpyOptions, u as StrictSpyConfiguration, U as UnstubbedCall, v as UnstubbedCallHandler, V as ValueConfig, c as ValueConfigPerCall, W as WithMockReturnValue } from './types-d8Mdj_jK.js';
|
|
2
2
|
export { ArgCaptor, AsInstances, AssertMockedOptions, ConstructorMock, ConstructorSpy, FixtureFactory, FlushUntilOptions, IntersectionObserverStubOptions, MediaElementState, MediaElementStub, MediaElementStubOptions, MockDeepOptions, ModuleNamespace, ModuleNamespaceOptions, MutationRecordInit, ObserverGlobal, ObserverInstance, ObserverStub, ObserverStubOptions, ResizeEntryRect, TestRunComparison, TestRunReport, TestRunSummary, asInstance, asInstances, asSpy, assertMocked, captureArg, clearAutoSpy, compareTestRuns, createFixture, createFixtureFactory, createFunctionSpy, createMock, createSpyClass, createSpyFromClass, diffByField, errorHandler, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resetAutoSpy, resizeEntry, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './bun.js';
|
|
3
|
-
export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-
|
|
4
|
-
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-
|
|
3
|
+
export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BhGKIi7_.js';
|
|
4
|
+
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-B5TLaKCg.js';
|
|
5
5
|
export { d as describeDuplicateCopies, g as getPackageCopies } from './package-identity-B1pqa-Sh.js';
|
|
6
|
-
export { A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-
|
|
6
|
+
export { A as AngularValueProvider, a as AutoSpiedInstance, C as ComponentInputs, b as CreateWithAutoSpiesOptions, R as RenderShallowOptions, c as ResourceStatusLike, S as SettleResourceOptions, d as ShallowRender, e as SpyRegistry, f as StableOptions, g as createWithAutoSpies, h as flushEffects, i as injectSpy, p as provideAutoSpy, r as renderShallow, j as runEffect, s as settleResource, k as stable } from './zoneless-BxqMRfiJ.js';
|
|
7
7
|
import 'rxjs';
|
|
8
8
|
import 'vitest';
|
|
9
9
|
import '@angular/core';
|
package/dist/bun-angular.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import './chunk-Y4YG7UOK.js';
|
|
2
|
-
import { createSpyForToken } from './chunk-
|
|
2
|
+
import { createSpyForToken } from './chunk-BNZFNS42.js';
|
|
3
3
|
import './chunk-NQXXUJPS.js';
|
|
4
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
4
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-YXHG5DXF.js';
|
|
5
5
|
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-MMKKLL5J.js';
|
|
6
|
-
import { createSpyFromClass } from './chunk-
|
|
7
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
6
|
+
import { createSpyFromClass } from './chunk-3EHP3NKE.js';
|
|
7
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-3EHP3NKE.js';
|
|
8
8
|
import './chunk-PC3FAZT3.js';
|
|
9
9
|
export { createFunctionSpy, errorHandler } from './chunk-52DZMI55.js';
|
|
10
10
|
import { withDocs, DOCS_LINKS, isAutoSpyLike } from './chunk-4K5F2NVN.js';
|
package/dist/bun.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as SpyOptions, C as ClassType, a as ClassSpyConfiguration, O as OnlyMethodKeysOf, S as Spy, m as DeepPartial, D as DeepMockProxy, F as Func, v as UnstubbedCallHandler, j as AddSpyMethodsByReturnTypes } from './types-
|
|
2
|
-
export { d as AccessorKeysOf, e as AddAccessorsSpies, f as AddCalledWithObservable, g as AddCalledWithPromise, h as AddCalledWithSpyMethods, A as AddObservableSpyMethods, i as AddPromiseSpyMethods, k as AddThrowHelper, l as AddVoidReturnHelpers, b as CompleteValueConfig, E as ErrorValueConfig, M as MethodReturns, n as Mutable, N as NextValueConfig, o as OnlyObservablePropsOf, p as OnlyPropsOf, q as Overload, r as Overloads, P as PropStubValue, s as SpyDisposable, u as StrictSpyConfiguration, U as UnstubbedCall, V as ValueConfig, c as ValueConfigPerCall, W as WithMockReturnValue } from './types-
|
|
3
|
-
export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-
|
|
4
|
-
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-
|
|
1
|
+
import { t as SpyOptions, C as ClassType, a as ClassSpyConfiguration, O as OnlyMethodKeysOf, S as Spy, m as DeepPartial, D as DeepMockProxy, F as Func, v as UnstubbedCallHandler, j as AddSpyMethodsByReturnTypes } from './types-d8Mdj_jK.js';
|
|
2
|
+
export { d as AccessorKeysOf, e as AddAccessorsSpies, f as AddCalledWithObservable, g as AddCalledWithPromise, h as AddCalledWithSpyMethods, A as AddObservableSpyMethods, i as AddPromiseSpyMethods, k as AddThrowHelper, l as AddVoidReturnHelpers, b as CompleteValueConfig, E as ErrorValueConfig, M as MethodReturns, n as Mutable, N as NextValueConfig, o as OnlyObservablePropsOf, p as OnlyPropsOf, q as Overload, r as Overloads, P as PropStubValue, s as SpyDisposable, u as StrictSpyConfiguration, U as UnstubbedCall, V as ValueConfig, c as ValueConfigPerCall, W as WithMockReturnValue } from './types-d8Mdj_jK.js';
|
|
3
|
+
export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BhGKIi7_.js';
|
|
4
|
+
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-B5TLaKCg.js';
|
|
5
5
|
export { d as describeDuplicateCopies, g as getPackageCopies } from './package-identity-B1pqa-Sh.js';
|
|
6
6
|
import { Mock } from 'vitest';
|
|
7
7
|
import 'rxjs';
|
package/dist/bun.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import './chunk-Y4YG7UOK.js';
|
|
2
2
|
import './chunk-NQXXUJPS.js';
|
|
3
|
-
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-
|
|
3
|
+
export { asInstance, asInstances, asSpy, assertMocked, captureArg, compareTestRuns, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, diffByField, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, getPackageCopies, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resizeEntry, setEmissionTimeout, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './chunk-YXHG5DXF.js';
|
|
4
4
|
export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-MMKKLL5J.js';
|
|
5
|
-
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-
|
|
5
|
+
export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-3EHP3NKE.js';
|
|
6
6
|
import './chunk-PC3FAZT3.js';
|
|
7
7
|
export { createFunctionSpy, errorHandler } from './chunk-52DZMI55.js';
|
|
8
8
|
import './chunk-4K5F2NVN.js';
|
|
@@ -269,6 +269,87 @@ function fillMissingMembers(autoSpy, unstubbed) {
|
|
|
269
269
|
}
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
|
+
|
|
273
|
+
// src/lib/lazy-spy-proxy.ts
|
|
274
|
+
var hasOwn = (target, key) => Object.prototype.hasOwnProperty.call(target, key);
|
|
275
|
+
function defineSpy(target, key, value) {
|
|
276
|
+
Object.defineProperty(target, key, { configurable: true, enumerable: true, writable: true, value });
|
|
277
|
+
}
|
|
278
|
+
function materialize(target, state, key) {
|
|
279
|
+
const spy = createFunctionSpy(key, state.unstubbed);
|
|
280
|
+
defineSpy(target, key, spy);
|
|
281
|
+
return spy;
|
|
282
|
+
}
|
|
283
|
+
function pendingDescriptor(target, state, key) {
|
|
284
|
+
return {
|
|
285
|
+
configurable: true,
|
|
286
|
+
enumerable: true,
|
|
287
|
+
get: () => materialize(target, state, key),
|
|
288
|
+
set: (value) => defineSpy(target, key, value)
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function orderedKeys(target, state) {
|
|
292
|
+
const own = Reflect.ownKeys(target);
|
|
293
|
+
if (!Reflect.isExtensible(target)) {
|
|
294
|
+
return own;
|
|
295
|
+
}
|
|
296
|
+
const ownStrings = own.filter((key) => typeof key === "string");
|
|
297
|
+
const present = new Set(ownStrings);
|
|
298
|
+
return [
|
|
299
|
+
...state.preKeys.filter((key) => present.has(key)),
|
|
300
|
+
...[...state.names].filter((key) => state.isPending(key) || present.has(key)),
|
|
301
|
+
...ownStrings.filter((key) => !state.preSet.has(key) && !state.names.has(key)),
|
|
302
|
+
...own.filter((key) => typeof key === "symbol")
|
|
303
|
+
];
|
|
304
|
+
}
|
|
305
|
+
function createLazySpyProxy(autoSpy, methodNames, unstubbed) {
|
|
306
|
+
const preKeys = Reflect.ownKeys(autoSpy).filter((key) => typeof key === "string");
|
|
307
|
+
const state = {
|
|
308
|
+
// Insertion order doubles as declaration order for `ownKeys`, so no second array is retained.
|
|
309
|
+
names: new Set(methodNames),
|
|
310
|
+
// Only ever holds a name a caller explicitly deleted: without it, `delete spy.method` would leave
|
|
311
|
+
// the name pending again and the next read would resurrect it.
|
|
312
|
+
deleted: /* @__PURE__ */ new Set(),
|
|
313
|
+
preKeys,
|
|
314
|
+
preSet: new Set(preKeys),
|
|
315
|
+
unstubbed,
|
|
316
|
+
isPending: (key) => typeof key === "string" && state.names.has(key) && !state.deleted.has(key) && !hasOwn(autoSpy, key)
|
|
317
|
+
};
|
|
318
|
+
return new Proxy(autoSpy, {
|
|
319
|
+
get(target, key) {
|
|
320
|
+
return state.isPending(key) ? materialize(target, state, key) : Reflect.get(target, key);
|
|
321
|
+
},
|
|
322
|
+
set(target, key, value) {
|
|
323
|
+
if (state.isPending(key)) {
|
|
324
|
+
defineSpy(target, key, value);
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
return Reflect.set(target, key, value);
|
|
328
|
+
},
|
|
329
|
+
has(target, key) {
|
|
330
|
+
return state.isPending(key) || Reflect.has(target, key);
|
|
331
|
+
},
|
|
332
|
+
getOwnPropertyDescriptor(target, key) {
|
|
333
|
+
return state.isPending(key) ? pendingDescriptor(target, state, key) : Reflect.getOwnPropertyDescriptor(target, key);
|
|
334
|
+
},
|
|
335
|
+
deleteProperty(target, key) {
|
|
336
|
+
const wasPending = state.isPending(key);
|
|
337
|
+
if (typeof key === "string" && state.names.has(key)) {
|
|
338
|
+
state.deleted.add(key);
|
|
339
|
+
}
|
|
340
|
+
return wasPending || Reflect.deleteProperty(target, key);
|
|
341
|
+
},
|
|
342
|
+
ownKeys: (target) => orderedKeys(target, state),
|
|
343
|
+
preventExtensions(target) {
|
|
344
|
+
state.names.forEach((key) => {
|
|
345
|
+
if (state.isPending(key)) {
|
|
346
|
+
materialize(target, state, key);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
return Reflect.preventExtensions(target);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
272
353
|
var EMPTY_CONFIGURATION = {
|
|
273
354
|
methodsToSpyOn: [],
|
|
274
355
|
onlyMethodsToSpyOn: [],
|
|
@@ -482,15 +563,18 @@ function assembleSpy(ObjectClass, config) {
|
|
|
482
563
|
});
|
|
483
564
|
warnOnAccessorNamingAMethod(ObjectClass, config);
|
|
484
565
|
createAccessorsSpies(autoSpy, accessors.getters, accessors.setters);
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
566
|
+
if (config.lazySpies !== "proxy") {
|
|
567
|
+
methodNames.forEach((methodName) => {
|
|
568
|
+
if (config.lazySpies) {
|
|
569
|
+
defineLazyMethodSpy(autoSpy, methodName, unstubbed);
|
|
570
|
+
} else {
|
|
571
|
+
autoSpy[methodName] = createFunctionSpy(methodName, unstubbed);
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
}
|
|
492
575
|
attachDispose(autoSpy);
|
|
493
|
-
|
|
576
|
+
const assembled = config.lazySpies === "proxy" ? createLazySpyProxy(autoSpy, methodNames, unstubbed) : autoSpy;
|
|
577
|
+
return config.fillMissing ? fillMissingMembers(assembled, unstubbed) : assembled;
|
|
494
578
|
}
|
|
495
579
|
function hasNothingToRead(ObjectClass, accessors, config) {
|
|
496
580
|
return getAllMethodNames(ObjectClass.prototype).length === 0 && accessors.getters.length === 0 && accessors.setters.length === 0 && config.observablePropsToSpyOn.length === 0 && // A *restricting* list asks for the opposite of what the proxy provides. `onlyMethodsToSpyOn`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mockValueProp, mockReadonlyPropGetter } from './chunk-MMKKLL5J.js';
|
|
2
|
-
import { createSpyFromClass, createProxyPropStore, describeStoredProp, dropStoredProp, storeDefinedProp, writeStoredAccessor, writeStoredValue, readStoredAccessor, NOT_STORED, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-
|
|
2
|
+
import { createSpyFromClass, createProxyPropStore, describeStoredProp, dropStoredProp, storeDefinedProp, writeStoredAccessor, writeStoredValue, readStoredAccessor, NOT_STORED, disposeAutoSpy, isProtocolKey, isDeletedProp } from './chunk-3EHP3NKE.js';
|
|
3
3
|
import { DISPOSE } from './chunk-PC3FAZT3.js';
|
|
4
4
|
import { defineHelper, serializeValue, createFunctionSpy } from './chunk-52DZMI55.js';
|
|
5
5
|
import { withDocs, DOCS_LINKS, DEEP_CHILDREN } from './chunk-4K5F2NVN.js';
|
package/dist/cli.js
CHANGED
|
@@ -2081,6 +2081,7 @@ var CONFIG_CANDIDATES2 = [
|
|
|
2081
2081
|
var WORKSPACE_FILE = /(^|\/)(?:angular|workspace|project)\.json$/;
|
|
2082
2082
|
var UNIT_TEST_BUILDER = "@angular/build:unit-test";
|
|
2083
2083
|
var ALL_REMOVED_IN = 4;
|
|
2084
|
+
var RECOMPILE_THRESHOLD = 50;
|
|
2084
2085
|
function coverageBlock(text) {
|
|
2085
2086
|
const opening = /coverage\s*:\s*{/.exec(text);
|
|
2086
2087
|
if (opening === null) {
|
|
@@ -2116,10 +2117,13 @@ function ownKeysText(block) {
|
|
|
2116
2117
|
function declaresKey(block, key) {
|
|
2117
2118
|
return new RegExp(`(?:^|[\\s,])${key}\\s*:`).test(ownKeysText(block));
|
|
2118
2119
|
}
|
|
2119
|
-
function
|
|
2120
|
-
const arrays = captures(ownKeysText(block),
|
|
2120
|
+
function arrayPatterns(block, key) {
|
|
2121
|
+
const arrays = captures(ownKeysText(block), new RegExp(`(?:^|[\\s,])${key}\\s*:\\s*\\[([^\\]]*)]`, "g"));
|
|
2121
2122
|
return arrays.flatMap((body) => captures(body, /["'`]([^"'`]+)["'`]/g));
|
|
2122
2123
|
}
|
|
2124
|
+
function includePatterns(block) {
|
|
2125
|
+
return arrayPatterns(block, "include");
|
|
2126
|
+
}
|
|
2123
2127
|
function canMatchBundleChunk(pattern) {
|
|
2124
2128
|
const segment = pattern.slice(pattern.lastIndexOf("/") + 1);
|
|
2125
2129
|
if (!segment.includes(".")) {
|
|
@@ -2128,6 +2132,36 @@ function canMatchBundleChunk(pattern) {
|
|
|
2128
2132
|
const extension = segment.slice(segment.lastIndexOf(".") + 1);
|
|
2129
2133
|
return extension === "*" || /^[cm]?js$/.test(extension) || /^{[^}]*\b[cm]?js\b[^}]*}$/.test(extension);
|
|
2130
2134
|
}
|
|
2135
|
+
function collectTargetScope(value, into) {
|
|
2136
|
+
if (Array.isArray(value)) {
|
|
2137
|
+
for (const item of value) {
|
|
2138
|
+
collectTargetScope(item, into);
|
|
2139
|
+
}
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
if (!isRecord(value)) {
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
const options = value["options"];
|
|
2146
|
+
if ((value["builder"] === UNIT_TEST_BUILDER || value["executor"] === UNIT_TEST_BUILDER) && isRecord(options)) {
|
|
2147
|
+
for (const key of ["coverageInclude", "coverageExclude"]) {
|
|
2148
|
+
const list = options[key];
|
|
2149
|
+
if (Array.isArray(list)) {
|
|
2150
|
+
into.patterns += list.length;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
for (const nested of Object.values(value)) {
|
|
2155
|
+
collectTargetScope(nested, into);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
function targetScopeSize(profile) {
|
|
2159
|
+
const total = { patterns: 0 };
|
|
2160
|
+
for (const file of profile.files.filter((candidate) => WORKSPACE_FILE.test(candidate))) {
|
|
2161
|
+
collectTargetScope(parseJsonc(readTextFile(join(profile.cwd, file)) ?? ""), total);
|
|
2162
|
+
}
|
|
2163
|
+
return total.patterns;
|
|
2164
|
+
}
|
|
2131
2165
|
function collectRunnerConfigs(value, into) {
|
|
2132
2166
|
if (Array.isArray(value)) {
|
|
2133
2167
|
for (const item of value) {
|
|
@@ -2165,6 +2199,7 @@ function installedMajor(cwd, packageName) {
|
|
|
2165
2199
|
}
|
|
2166
2200
|
function checkCoverageConfig(profile) {
|
|
2167
2201
|
const runnerConfigs = unitTestRunnerConfigs(profile);
|
|
2202
|
+
const targetScope = targetScopeSize(profile);
|
|
2168
2203
|
const major = installedMajor(profile.cwd, "vitest");
|
|
2169
2204
|
const findings = [];
|
|
2170
2205
|
for (const file of [.../* @__PURE__ */ new Set([...runnerConfigs, ...CONFIG_CANDIDATES2])]) {
|
|
@@ -2182,6 +2217,16 @@ function checkCoverageConfig(profile) {
|
|
|
2182
2217
|
fix: "Delete `all` and declare `coverage.include` instead. Without an include the report has been covering only the files the run imported \u2014 which is what this config has been silently doing since the upgrade."
|
|
2183
2218
|
});
|
|
2184
2219
|
}
|
|
2220
|
+
const scopeSize = arrayPatterns(block, "include").length + arrayPatterns(block, "exclude").length + targetScope;
|
|
2221
|
+
if (scopeSize >= RECOMPILE_THRESHOLD) {
|
|
2222
|
+
findings.push({
|
|
2223
|
+
check: "coverage-include-recompiles-globs",
|
|
2224
|
+
severity: "info",
|
|
2225
|
+
file,
|
|
2226
|
+
message: `The coverage scope here is ${scopeSize} globs, and \`@vitest/coverage-v8\` recompiles all of them for every filename: its \`globCache\` memoises the verdict, keyed by the file, and never the matcher. Nothing fails \u2014 the report is correct, it is just paid for once per file per pattern.`,
|
|
2227
|
+
fix: 'Swap the provider for a wrapper that compiles the list once: `coverage.provider: "custom"` plus a `customProviderModule` that re-exports `@vitest/coverage-v8` and overwrites `isIncluded` in `getProvider()`. Measured on one 1 725-file suite: 229.59 s \u2192 22.88 s on a shard, with a byte-identical report. The recipe is in the docs \u2014 Adapters \u2192 Angular, "Coverage matching costs more than coverage".'
|
|
2228
|
+
});
|
|
2229
|
+
}
|
|
2185
2230
|
const patterns = runnerConfigs.includes(file) ? includePatterns(block) : [];
|
|
2186
2231
|
if (patterns.length > 0 && !patterns.some(canMatchBundleChunk)) {
|
|
2187
2232
|
findings.push({
|
package/dist/console.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as StrictSpyConfiguration, o as OnlyObservablePropsOf, M as MethodReturns, m as DeepPartial, S as Spy, t as SpyOptions } from './types-
|
|
1
|
+
import { u as StrictSpyConfiguration, o as OnlyObservablePropsOf, M as MethodReturns, m as DeepPartial, S as Spy, t as SpyOptions } from './types-d8Mdj_jK.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Create a fully-typed auto-mock of `T` from its type alone (no class).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { d as AccessorKeysOf, e as AddAccessorsSpies, f as AddCalledWithObservable, g as AddCalledWithPromise, h as AddCalledWithSpyMethods, A as AddObservableSpyMethods, i as AddPromiseSpyMethods, j as AddSpyMethodsByReturnTypes, k as AddThrowHelper, l as AddVoidReturnHelpers, a as ClassSpyConfiguration, C as ClassType, b as CompleteValueConfig, D as DeepMockProxy, m as DeepPartial, E as ErrorValueConfig, F as Func, M as MethodReturns, n as Mutable, N as NextValueConfig, O as OnlyMethodKeysOf, o as OnlyObservablePropsOf, p as OnlyPropsOf, q as Overload, r as Overloads, P as PropStubValue, S as Spy, s as SpyDisposable, t as SpyOptions, u as StrictSpyConfiguration, U as UnstubbedCall, v as UnstubbedCallHandler, V as ValueConfig, c as ValueConfigPerCall, W as WithMockReturnValue } from './types-
|
|
1
|
+
export { d as AccessorKeysOf, e as AddAccessorsSpies, f as AddCalledWithObservable, g as AddCalledWithPromise, h as AddCalledWithSpyMethods, A as AddObservableSpyMethods, i as AddPromiseSpyMethods, j as AddSpyMethodsByReturnTypes, k as AddThrowHelper, l as AddVoidReturnHelpers, a as ClassSpyConfiguration, C as ClassType, b as CompleteValueConfig, D as DeepMockProxy, m as DeepPartial, E as ErrorValueConfig, F as Func, M as MethodReturns, n as Mutable, N as NextValueConfig, O as OnlyMethodKeysOf, o as OnlyObservablePropsOf, p as OnlyPropsOf, q as Overload, r as Overloads, P as PropStubValue, S as Spy, s as SpyDisposable, t as SpyOptions, u as StrictSpyConfiguration, U as UnstubbedCall, v as UnstubbedCallHandler, V as ValueConfig, c as ValueConfigPerCall, W as WithMockReturnValue } from './types-d8Mdj_jK.js';
|
|
2
2
|
export { ArgCaptor, AsInstances, AssertMockedOptions, ConstructorMock, ConstructorSpy, FixtureFactory, FlushUntilOptions, IntersectionObserverStubOptions, MediaElementState, MediaElementStub, MediaElementStubOptions, MockDeepOptions, ModuleNamespace, ModuleNamespaceOptions, MutationRecordInit, ObserverGlobal, ObserverInstance, ObserverStub, ObserverStubOptions, ResizeEntryRect, TestRunComparison, TestRunReport, TestRunSummary, asInstance, asInstances, asSpy, assertMocked, captureArg, clearAutoSpy, compareTestRuns, createFixture, createFixtureFactory, createFunctionSpy, createMock, createSpyClass, createSpyFromClass, diffByField, errorHandler, flushEventLoop, flushEventLoopUntil, formatTestRunComparison, intersectionEntry, mockConstructor, mockDeep, moduleNamespace, mutationRecord, narrow, resetAutoSpy, resizeEntry, settleDynamicImport, stubAbortController, stubConstructor, stubIntersectionObserver, stubMediaElement, stubMutationObserver, stubObserver, stubResizeObserver, summarizeTestRun, withOverrides } from './bun.js';
|
|
3
|
-
export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-
|
|
4
|
-
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-
|
|
3
|
+
export { A as AutoMockConfiguration, C as CallbackSubscribable, E as EmissionObserver, a as EmissionOptions, b as EmissionSource, S as SubscribableLike, c as autoMocked, d as createAutoMock, e as expectCompletion, f as expectEmission, g as expectEmissions, h as expectError, i as expectNoEmission, s as setEmissionTimeout } from './expect-emission-BhGKIi7_.js';
|
|
4
|
+
export { A as AccessorImplementations, R as RestoreProp, c as countMockedProps, m as mockAccessorsProp, a as mockReadonlyProp, b as mockReadonlyPropGetter, d as mockValueProp, r as restoreMockedProps } from './prop-mock-B5TLaKCg.js';
|
|
5
5
|
export { d as describeDuplicateCopies, g as getPackageCopies } from './package-identity-B1pqa-Sh.js';
|
|
6
6
|
import 'rxjs';
|
|
7
7
|
import 'vitest';
|