vitest-auto-spy 4.2.0 → 4.3.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 +89 -2
- package/README.md +135 -6
- package/dist/angular.d.ts +2 -2
- package/dist/angular.js +276 -7
- package/dist/bun-angular.d.ts +3 -3
- package/dist/bun-angular.js +6 -6
- package/dist/bun.d.ts +72 -2
- package/dist/bun.js +4 -4
- package/dist/{chunk-DSIYS6Y5.js → chunk-D5LDT3W4.js} +1 -1
- package/dist/{chunk-2ZG27FVL.js → chunk-EMASXQDZ.js} +1 -1
- package/dist/{chunk-4KK3ES4P.js → chunk-FFKN6QKI.js} +22 -0
- package/dist/{chunk-4KCYFAJX.js → chunk-FYFF67EN.js} +23 -7
- package/dist/{chunk-5URFSYDT.js → chunk-GAY6LNAM.js} +300 -6
- package/dist/{chunk-WQZ2RKS7.js → chunk-KYAJCFUA.js} +1 -1
- package/dist/{chunk-KEKKEIRG.js → chunk-Z4VRMCW2.js} +1 -1
- package/dist/cli.js +606 -16
- package/dist/console.js +2 -2
- package/dist/diagnostics.d.ts +31 -1
- package/dist/diagnostics.js +350 -1
- package/dist/{expect-emission-BDuFuqTb.d.ts → expect-emission-Dy5CvsF2.d.ts} +27 -25
- package/dist/index.d.ts +2 -2
- package/dist/index.js +444 -111
- package/dist/jasmine.js +4 -4
- package/dist/nestjs.js +5 -5
- package/dist/node.cjs +272 -111
- package/dist/node.d.cts +2 -0
- package/dist/node.d.ts +2 -2
- package/dist/node.js +17 -5
- package/dist/react.d.ts +2 -2
- package/dist/react.js +5 -5
- package/dist/setup.js +4 -4
- package/dist/shared-state.js +4 -275
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +5 -5
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +6 -6
- package/dist/{zoneless-DGwkbWKm.d.ts → zoneless-LsBDcSNZ.d.ts} +1 -1
- package/package.json +6 -2
- package/skills/vitest-auto-spy/SKILL.md +4 -1
package/dist/cli.js
CHANGED
|
@@ -187,13 +187,14 @@ function stripJsonComments(text) {
|
|
|
187
187
|
return result.replace(/,(\s*[\]}])/g, "$1");
|
|
188
188
|
}
|
|
189
189
|
function findStringEnd(text, start) {
|
|
190
|
+
const quote = text[start];
|
|
190
191
|
let index = start + 1;
|
|
191
192
|
while (index < text.length) {
|
|
192
193
|
if (text[index] === "\\") {
|
|
193
194
|
index += 2;
|
|
194
195
|
continue;
|
|
195
196
|
}
|
|
196
|
-
if (text[index] ===
|
|
197
|
+
if (text[index] === quote) {
|
|
197
198
|
return index + 1;
|
|
198
199
|
}
|
|
199
200
|
index += 1;
|
|
@@ -643,12 +644,12 @@ function insertIntoBraces(source, host, needs) {
|
|
|
643
644
|
return { start: last, end: last, text: /,$/.test(source.slice(open + 1, last)) ? ` ${addition}` : `, ${addition}` };
|
|
644
645
|
}
|
|
645
646
|
function pickHost(statements, specifier, needs) {
|
|
646
|
-
const
|
|
647
|
-
const value =
|
|
647
|
+
const candidates2 = hostsFor(statements, specifier);
|
|
648
|
+
const value = candidates2.find((host) => !host.statement.typeOnly);
|
|
648
649
|
if (value !== void 0) {
|
|
649
650
|
return value;
|
|
650
651
|
}
|
|
651
|
-
return needs.every((need) => need.typeOnly) ?
|
|
652
|
+
return needs.every((need) => need.typeOnly) ? candidates2[0] : void 0;
|
|
652
653
|
}
|
|
653
654
|
function uniqueNeeds(source, statements, needs) {
|
|
654
655
|
const bound = allBound(source, statements);
|
|
@@ -1076,8 +1077,8 @@ function best(pool) {
|
|
|
1076
1077
|
function partsOf(specifier) {
|
|
1077
1078
|
return specifier.slice(specifier.indexOf("/") + 1).split("-");
|
|
1078
1079
|
}
|
|
1079
|
-
function narrow(
|
|
1080
|
-
return framework === void 0 ? [] :
|
|
1080
|
+
function narrow(candidates2, framework) {
|
|
1081
|
+
return framework === void 0 ? [] : candidates2.filter((candidate) => partsOf(candidate).includes(framework));
|
|
1081
1082
|
}
|
|
1082
1083
|
function sameRuntime(pool, preferred) {
|
|
1083
1084
|
const wanted = pool.filter((candidate) => candidate.startsWith(BUN_PREFIX) === preferred.startsWith(BUN_PREFIX));
|
|
@@ -1096,16 +1097,16 @@ function chooseEntry(map, name, preferred, hint) {
|
|
|
1096
1097
|
}
|
|
1097
1098
|
return specifiers.length === 1 ? { kind: "chosen", entry: best(specifiers) } : decide(specifiers, preferred, hint);
|
|
1098
1099
|
}
|
|
1099
|
-
function decide(
|
|
1100
|
-
const known =
|
|
1100
|
+
function decide(candidates2, preferred, hint) {
|
|
1101
|
+
const known = candidates2.find((candidate) => hint.imported.includes(candidate));
|
|
1101
1102
|
if (known !== void 0) {
|
|
1102
1103
|
return { kind: "chosen", entry: known };
|
|
1103
1104
|
}
|
|
1104
|
-
const scoped = narrow(
|
|
1105
|
+
const scoped = narrow(candidates2, hint.framework);
|
|
1105
1106
|
if (scoped.length > 0) {
|
|
1106
1107
|
return { kind: "chosen", entry: best(sameRuntime(scoped, preferred)) };
|
|
1107
1108
|
}
|
|
1108
|
-
return { kind: "guessed", entry: best(sameRuntime(
|
|
1109
|
+
return { kind: "guessed", entry: best(sameRuntime(candidates2, preferred)), candidates: candidates2 };
|
|
1109
1110
|
}
|
|
1110
1111
|
function entryFor(map, name, preferred) {
|
|
1111
1112
|
const choice = chooseEntry(map, name, preferred, NO_HINT);
|
|
@@ -2353,6 +2354,521 @@ function checkForeignPragma(graph) {
|
|
|
2353
2354
|
}
|
|
2354
2355
|
return findings;
|
|
2355
2356
|
}
|
|
2357
|
+
|
|
2358
|
+
// src/cli/checks/export-map.generated.ts
|
|
2359
|
+
var EXPORT_MAP_VERSION = "4.2.0";
|
|
2360
|
+
var ENTRY_SPECIFIERS = "vitest-auto-spy vitest-auto-spy/bun vitest-auto-spy/bun-angular vitest-auto-spy/node vitest-auto-spy/rxjs vitest-auto-spy/console vitest-auto-spy/dom-stubs vitest-auto-spy/diagnostics vitest-auto-spy/jasmine vitest-auto-spy/jasmine-compat vitest-auto-spy/observer-spy vitest-auto-spy/angular vitest-auto-spy/angular-http vitest-auto-spy/nestjs vitest-auto-spy/react vitest-auto-spy/vue vitest-auto-spy/svelte vitest-auto-spy/setup vitest-auto-spy/zone vitest-auto-spy/eslint-plugin";
|
|
2361
|
+
var EXPORTED_BY = {
|
|
2362
|
+
AccessorImplementations: "0 1 2 3 11 14 15 16",
|
|
2363
|
+
AccessorKeysOf: "0 1 2 3 14 15 16",
|
|
2364
|
+
AddAccessorsSpies: "0 1 2 3 14 15 16",
|
|
2365
|
+
AddCalledWithObservable: "0 1 2 3 14 15 16",
|
|
2366
|
+
AddCalledWithPromise: "0 1 2 3 14 15 16",
|
|
2367
|
+
AddCalledWithSpyMethods: "0 1 2 3 14 15 16",
|
|
2368
|
+
AddObservableSpyMethods: "0 1 2 3 4 14 15 16",
|
|
2369
|
+
AddPromiseSpyMethods: "0 1 2 3 14 15 16",
|
|
2370
|
+
AddSpyMethodsByReturnTypes: "0 1 2 3 14 15 16",
|
|
2371
|
+
AddThrowHelper: "0 1 2 3 14 15 16",
|
|
2372
|
+
AddVoidReturnHelpers: "0 1 2 3 14 15 16",
|
|
2373
|
+
advanceTimers: "17",
|
|
2374
|
+
AngularDiagnosticsOptions: "11",
|
|
2375
|
+
AngularResourceInlinerOptions: "2",
|
|
2376
|
+
AngularTestEnvMode: "11",
|
|
2377
|
+
AngularTestEnvOptions: "11",
|
|
2378
|
+
AngularTokenProvider: "11",
|
|
2379
|
+
AngularValueProvider: "2 8 11",
|
|
2380
|
+
ArgCaptor: "0 1 2 3 14 15 16",
|
|
2381
|
+
asInstance: "0 1 2 3 14 15 16",
|
|
2382
|
+
asInstances: "0 1 2 3 14 15 16",
|
|
2383
|
+
AsInstances: "0 1 2 3 14 15 16",
|
|
2384
|
+
assertComponentDefIntact: "11",
|
|
2385
|
+
assertMocked: "0 1 2 3 14 15 16",
|
|
2386
|
+
AssertMockedOptions: "0 1 2 3 14 15 16",
|
|
2387
|
+
assertNgModuleScopes: "11",
|
|
2388
|
+
assertNoPendingRequests: "11",
|
|
2389
|
+
asSpy: "0 1 2 3 14 15 16",
|
|
2390
|
+
AutoMockConfiguration: "0 1 2 3 14 15 16",
|
|
2391
|
+
autoMocked: "0 1 2 3 14 15 16",
|
|
2392
|
+
AutoSpiedInstance: "2 11",
|
|
2393
|
+
AutoSpyEslintPlugin: "19",
|
|
2394
|
+
AutoSpyFixture: "11",
|
|
2395
|
+
AutoSpyOverride: "11",
|
|
2396
|
+
AutoSpyRxjsTypes: "0 1 2 3 14 15 16",
|
|
2397
|
+
BLOCKED_FETCH_MESSAGE: "17",
|
|
2398
|
+
BLOCKED_XHR_MESSAGE: "17",
|
|
2399
|
+
blockNetwork: "17",
|
|
2400
|
+
BlockNetworkOptions: "17",
|
|
2401
|
+
CallbackSubscribable: "0 1 2 3 11 14 15 16",
|
|
2402
|
+
cancelStrayTimers: "17",
|
|
2403
|
+
captureArg: "0 1 2 3 14 15 16",
|
|
2404
|
+
captureMockRegistry: "17",
|
|
2405
|
+
ClassSpyConfiguration: "0 1 2 3 8 14 15 16",
|
|
2406
|
+
ClassType: "0 1 2 3 8 14 15 16",
|
|
2407
|
+
clearAutoSpy: "0 1 2 3 14 15 16",
|
|
2408
|
+
compareTestRuns: "7",
|
|
2409
|
+
CompleteValueConfig: "0 1 2 3 4 14 15 16",
|
|
2410
|
+
ComponentInputs: "2 11",
|
|
2411
|
+
consoleDebugSpy: "5",
|
|
2412
|
+
consoleErrorSpy: "5",
|
|
2413
|
+
consoleInfoSpy: "5",
|
|
2414
|
+
consoleLogSpy: "5",
|
|
2415
|
+
ConsoleMethodSpy: "5",
|
|
2416
|
+
ConsoleSpies: "5",
|
|
2417
|
+
consoleTimeEndSpy: "5",
|
|
2418
|
+
consoleTimeSpy: "5",
|
|
2419
|
+
consoleTraceSpy: "5",
|
|
2420
|
+
consoleWarnSpy: "5",
|
|
2421
|
+
ConstructorMock: "0 1 2 3 14 15 16",
|
|
2422
|
+
ConstructorSpy: "0 1 2 3 14 15 16",
|
|
2423
|
+
copyWindowGlobals: "2",
|
|
2424
|
+
CountingClock: "17",
|
|
2425
|
+
CountingClockOptions: "17",
|
|
2426
|
+
countMockedProps: "0 1 2 3 11 14 15 16",
|
|
2427
|
+
countNodeMocks: "3",
|
|
2428
|
+
countStrayRejections: "17",
|
|
2429
|
+
countStrayTimers: "17",
|
|
2430
|
+
createAutoMock: "0 1 2 3 14 15 16",
|
|
2431
|
+
createDirectiveHost: "11",
|
|
2432
|
+
createFixture: "0 1 2 3 14 15 16",
|
|
2433
|
+
createFixtureFactory: "0 1 2 3 14 15 16",
|
|
2434
|
+
createFunctionSpy: "0 1 2 3 8 14 15 16",
|
|
2435
|
+
createGlobalRegistratorRegistrar: "2",
|
|
2436
|
+
createJsdomRegistrar: "2",
|
|
2437
|
+
createMock: "0 1 2 3 14 15 16",
|
|
2438
|
+
createNestUnit: "13",
|
|
2439
|
+
CreateNestUnitOptions: "13",
|
|
2440
|
+
createObservableWithValues: "4",
|
|
2441
|
+
createSpyClass: "0 1 2 3 14 15 16",
|
|
2442
|
+
createSpyFromClass: "0 1 2 3 8 14 15 16",
|
|
2443
|
+
createSpyFromInstance: "0 1 2 3 14 15 16",
|
|
2444
|
+
createSpyObj: "8",
|
|
2445
|
+
createWithAutoSpies: "2 11",
|
|
2446
|
+
CreateWithAutoSpiesOptions: "2 11",
|
|
2447
|
+
DeepMockProxy: "0 1 2 3 14 15 16",
|
|
2448
|
+
DeepPartial: "0 1 2 3 14 15 16",
|
|
2449
|
+
default: "19",
|
|
2450
|
+
describeDuplicateCopies: "0 1 2 3 14 15 16 17",
|
|
2451
|
+
diffByField: "7",
|
|
2452
|
+
DirectiveHostOptions: "11",
|
|
2453
|
+
disableAngularDiagnostics: "11",
|
|
2454
|
+
disableTestBedDiagnostics: "11",
|
|
2455
|
+
DomRegistrar: "2",
|
|
2456
|
+
DuplicateCopiesReaction: "17",
|
|
2457
|
+
EmissionObserver: "0 1 2 3 11 14 15 16",
|
|
2458
|
+
EmissionOptions: "0 1 2 3 11 14 15 16",
|
|
2459
|
+
EmissionSource: "0 1 2 3 11 14 15 16",
|
|
2460
|
+
enableAngularDiagnostics: "11",
|
|
2461
|
+
enableJasmineCompat: "8 9",
|
|
2462
|
+
enableTestBedDiagnostics: "11",
|
|
2463
|
+
errorHandler: "0 1 2 3 14 15 16",
|
|
2464
|
+
ErrorValueConfig: "0 1 2 3 4 14 15 16",
|
|
2465
|
+
expectCompletion: "0 1 2 3 11 14 15 16",
|
|
2466
|
+
expectEmission: "0 1 2 3 11 14 15 16",
|
|
2467
|
+
expectEmissions: "0 1 2 3 11 14 15 16",
|
|
2468
|
+
expectError: "0 1 2 3 11 14 15 16",
|
|
2469
|
+
expectNoEmission: "0 1 2 3 11 14 15 16",
|
|
2470
|
+
expectNoRequest: "12",
|
|
2471
|
+
expectRequest: "12",
|
|
2472
|
+
ExpectRequestOptions: "12",
|
|
2473
|
+
explainSpy: "7",
|
|
2474
|
+
extendWithAutoSpies: "11",
|
|
2475
|
+
ExtendWithAutoSpiesOptions: "11",
|
|
2476
|
+
FakeTimersConfig: "17",
|
|
2477
|
+
FixtureFactory: "0 1 2 3 14 15 16",
|
|
2478
|
+
FlatConfig: "19",
|
|
2479
|
+
flushEffects: "2 11",
|
|
2480
|
+
flushEventLoop: "0 1 2 3 14 15 16",
|
|
2481
|
+
flushEventLoopUntil: "0 1 2 3 14 15 16",
|
|
2482
|
+
FlushOptions: "12",
|
|
2483
|
+
flushStrayRejections: "17",
|
|
2484
|
+
FlushUntilOptions: "0 1 2 3 14 15 16",
|
|
2485
|
+
formatSpecTiming: "11",
|
|
2486
|
+
formatTestRunComparison: "7",
|
|
2487
|
+
Func: "0 1 2 3 14 15 16",
|
|
2488
|
+
getMockRegistrySize: "17",
|
|
2489
|
+
getPackageCopies: "0 1 2 3 14 15 16 17",
|
|
2490
|
+
getSpyEngine: "17",
|
|
2491
|
+
getTestBedTiming: "11",
|
|
2492
|
+
getWatchedTimerGlobals: "17",
|
|
2493
|
+
GlobalPatchReaction: "17",
|
|
2494
|
+
GlobalRegistratorOptions: "2",
|
|
2495
|
+
guardGlobalPatches: "17",
|
|
2496
|
+
HttpTestingOptions: "12",
|
|
2497
|
+
InjectionLog: "11 13",
|
|
2498
|
+
injectSpy: "2 11 13",
|
|
2499
|
+
inlineAngularResources: "2",
|
|
2500
|
+
installConsoleSpies: "5",
|
|
2501
|
+
installPerTest: "17",
|
|
2502
|
+
installProxyZonePatch: "18",
|
|
2503
|
+
instrumentTestBed: "11",
|
|
2504
|
+
intersectionEntry: "6",
|
|
2505
|
+
IntersectionObserverStubOptions: "6",
|
|
2506
|
+
jasmine: "8",
|
|
2507
|
+
JasmineAccessorSpies: "8 9",
|
|
2508
|
+
JasmineAccessorSpy: "8 9",
|
|
2509
|
+
JasmineAnd: "8 9",
|
|
2510
|
+
JasmineCallInfo: "8 9",
|
|
2511
|
+
JasmineCalls: "8 9",
|
|
2512
|
+
JasmineClassSpyConfiguration: "8",
|
|
2513
|
+
JasmineClock: "8",
|
|
2514
|
+
JasmineMethodSpy: "8 9",
|
|
2515
|
+
JasmineNamespaces: "8 9",
|
|
2516
|
+
JasmineSpy: "8 9",
|
|
2517
|
+
JasmineStrategies: "8 9",
|
|
2518
|
+
JasmineWithArgsAnd: "8 9",
|
|
2519
|
+
JasmineWithArgsSync: "8 9",
|
|
2520
|
+
JsdomModule: "2",
|
|
2521
|
+
JsdomRegistrarOptions: "2",
|
|
2522
|
+
keepMockRegistered: "17",
|
|
2523
|
+
keepRegisteredMocks: "17",
|
|
2524
|
+
MediaElementState: "6",
|
|
2525
|
+
MediaElementStub: "6",
|
|
2526
|
+
MediaElementStubOptions: "6",
|
|
2527
|
+
MethodReturns: "0 1 2 3 14 15 16",
|
|
2528
|
+
mockAccessorsProp: "0 1 2 3 11 14 15 16",
|
|
2529
|
+
mockConstructor: "0 1 2 3 14 15 16",
|
|
2530
|
+
mockDeep: "0 1 2 3 14 15 16",
|
|
2531
|
+
MockDeepOptions: "0 1 2 3 14 15 16",
|
|
2532
|
+
MockedResource: "11",
|
|
2533
|
+
mockNow: "17",
|
|
2534
|
+
mockReadonlyProp: "0 1 2 3 11 14 15 16",
|
|
2535
|
+
mockReadonlyPropGetter: "0 1 2 3 11 14 15 16",
|
|
2536
|
+
mockResourceProp: "11",
|
|
2537
|
+
mockSignalProp: "11",
|
|
2538
|
+
mockSystemTime: "17",
|
|
2539
|
+
mockValueProp: "0 1 2 3 11 14 15 16",
|
|
2540
|
+
moduleNamespace: "0 1 2 3 14 15 16",
|
|
2541
|
+
ModuleNamespace: "0 1 2 3 14 15 16",
|
|
2542
|
+
ModuleNamespaceOptions: "0 1 2 3 14 15 16",
|
|
2543
|
+
Mutable: "0 1 2 3 14 15 16",
|
|
2544
|
+
mutationRecord: "6",
|
|
2545
|
+
MutationRecordInit: "6",
|
|
2546
|
+
narrow: "0 1 2 3 14 15 16",
|
|
2547
|
+
NestModuleRef: "13",
|
|
2548
|
+
NestUnit: "13",
|
|
2549
|
+
NestUnitClass: "13",
|
|
2550
|
+
NestUnitProvider: "13",
|
|
2551
|
+
NestUnitSpies: "13",
|
|
2552
|
+
NestValueProvider: "13",
|
|
2553
|
+
NextValueConfig: "0 1 2 3 4 14 15 16",
|
|
2554
|
+
ObservableLike: "0 1 2 3 14 15 16",
|
|
2555
|
+
ObserverGlobal: "6",
|
|
2556
|
+
ObserverInstance: "6",
|
|
2557
|
+
ObserverSpy: "10",
|
|
2558
|
+
ObserverSpyConfig: "10",
|
|
2559
|
+
ObserverStub: "6",
|
|
2560
|
+
ObserverStubOptions: "6",
|
|
2561
|
+
OnlyMethodKeysOf: "0 1 2 3 8 14 15 16",
|
|
2562
|
+
OnlyObservablePropsOf: "0 1 2 3 8 14 15 16",
|
|
2563
|
+
OnlyPropsOf: "0 1 2 3 8 14 15 16",
|
|
2564
|
+
Overload: "0 1 2 3 14 15 16",
|
|
2565
|
+
Overloads: "0 1 2 3 14 15 16",
|
|
2566
|
+
overrideAutoSpy: "11",
|
|
2567
|
+
overrideComponentProvider: "11",
|
|
2568
|
+
PerTestHandle: "17",
|
|
2569
|
+
PropStubValue: "0 1 2 3 14 15 16",
|
|
2570
|
+
provideAutoSpy: "2 8 11 13 15",
|
|
2571
|
+
provideAutoSpyForToken: "11",
|
|
2572
|
+
provideHttpTesting: "12",
|
|
2573
|
+
ProxyZonePatchOptions: "18",
|
|
2574
|
+
ProxyZoneScope: "18",
|
|
2575
|
+
pruneMockRegistry: "17",
|
|
2576
|
+
pruneNodeMocks: "3",
|
|
2577
|
+
registerDirectiveMatchers: "11",
|
|
2578
|
+
registerDomGlobals: "2",
|
|
2579
|
+
RegisterDomGlobalsOptions: "2",
|
|
2580
|
+
registerFocusMatchers: "17",
|
|
2581
|
+
registerJasmineMatchers: "8",
|
|
2582
|
+
registerResourceMatchers: "11",
|
|
2583
|
+
registerSignalMatchers: "11",
|
|
2584
|
+
RejectionHost: "17",
|
|
2585
|
+
renderShallow: "2 11",
|
|
2586
|
+
RenderShallowOptions: "2 11",
|
|
2587
|
+
reportSpecTiming: "11",
|
|
2588
|
+
RequestErrorOptions: "12",
|
|
2589
|
+
RequestExpectation: "12",
|
|
2590
|
+
RequestMatcher: "12",
|
|
2591
|
+
resetAutoSpy: "0 1 2 3 14 15 16",
|
|
2592
|
+
resetConsoleSpies: "5",
|
|
2593
|
+
resetMockRegistryTracking: "17",
|
|
2594
|
+
resizeEntry: "6",
|
|
2595
|
+
ResizeEntryRect: "6",
|
|
2596
|
+
ResourceDouble: "11",
|
|
2597
|
+
ResourceDoubleStatus: "11",
|
|
2598
|
+
ResourceLike: "11",
|
|
2599
|
+
ResourceStatusLike: "2 11",
|
|
2600
|
+
ResponseBody: "12",
|
|
2601
|
+
restoreConsole: "5",
|
|
2602
|
+
restoreLongLivedImplementations: "17",
|
|
2603
|
+
restoreMockedProps: "0 1 2 3 11 14 15 16",
|
|
2604
|
+
RestoreProp: "0 1 2 3 11 14 15 16",
|
|
2605
|
+
restoreSpiedInstance: "0 1 2 3 14 15 16",
|
|
2606
|
+
restoreTimerGlobals: "17",
|
|
2607
|
+
RuleSeverity: "19",
|
|
2608
|
+
runEffect: "2 11",
|
|
2609
|
+
SchedulerHost: "17",
|
|
2610
|
+
setEmissionTimeout: "0 1 2 3 11 14 15 16",
|
|
2611
|
+
setSpyEngine: "17",
|
|
2612
|
+
settleDynamicImport: "0 1 2 3 14 15 16",
|
|
2613
|
+
settleResource: "2 11",
|
|
2614
|
+
SettleResourceOptions: "2 11",
|
|
2615
|
+
setupAngularTestEnv: "11",
|
|
2616
|
+
setupAutoSpy: "17",
|
|
2617
|
+
SetupAutoSpyOptions: "17",
|
|
2618
|
+
setupFakeTimers: "17",
|
|
2619
|
+
ShallowRender: "2 11",
|
|
2620
|
+
SignalLike: "11",
|
|
2621
|
+
SpecTiming: "11",
|
|
2622
|
+
SpiedFixtures: "11",
|
|
2623
|
+
Spy: "0 1 2 3 8 14 15 16",
|
|
2624
|
+
SpyDisposable: "0 1 2 3 14 15 16",
|
|
2625
|
+
SpyEngine: "17",
|
|
2626
|
+
SpyObj: "8",
|
|
2627
|
+
SpyOptions: "0 1 2 3 14 15 16",
|
|
2628
|
+
SpyRegistry: "2 11",
|
|
2629
|
+
stable: "2 11",
|
|
2630
|
+
StableOptions: "2 11",
|
|
2631
|
+
StopTrackingNodeMocks: "3",
|
|
2632
|
+
StopTrackingRejections: "17",
|
|
2633
|
+
StopTrackingTimers: "17",
|
|
2634
|
+
StrayRejection: "17",
|
|
2635
|
+
StrictSpyConfiguration: "0 1 2 3 14 15 16",
|
|
2636
|
+
stubAbortController: "6",
|
|
2637
|
+
stubConstructor: "0 1 2 3 14 15 16",
|
|
2638
|
+
stubIntersectionObserver: "6",
|
|
2639
|
+
stubMediaElement: "6",
|
|
2640
|
+
stubMutationObserver: "6",
|
|
2641
|
+
stubObserver: "6",
|
|
2642
|
+
stubResizeObserver: "6",
|
|
2643
|
+
SubjectLike: "0 1 2 3 14 15 16",
|
|
2644
|
+
SubjectOf: "0 1 2 3 14 15 16",
|
|
2645
|
+
SubscribableLike: "0 1 2 3 11 14 15 16",
|
|
2646
|
+
SubscriberSpy: "10",
|
|
2647
|
+
subscribeSpyTo: "10",
|
|
2648
|
+
summarizeTestRun: "7",
|
|
2649
|
+
SystemTime: "17",
|
|
2650
|
+
TestBedDiagnosticsOptions: "11",
|
|
2651
|
+
TestRunComparison: "7",
|
|
2652
|
+
TestRunReport: "7",
|
|
2653
|
+
TestRunSummary: "7",
|
|
2654
|
+
TrackedProvider: "11 13",
|
|
2655
|
+
trackInjections: "11 13",
|
|
2656
|
+
TrackInjectionsOptions: "11 13",
|
|
2657
|
+
trackMockRegistry: "17",
|
|
2658
|
+
trackNodeMocks: "3",
|
|
2659
|
+
trackStrayRejections: "17",
|
|
2660
|
+
trackStrayTimers: "17",
|
|
2661
|
+
UnstubbedCall: "0 1 2 3 14 15 16",
|
|
2662
|
+
UnstubbedCallHandler: "0 1 2 3 14 15 16",
|
|
2663
|
+
useCountingClock: "17",
|
|
2664
|
+
ValueConfig: "0 1 2 3 4 14 15 16",
|
|
2665
|
+
ValueConfigPerCall: "0 1 2 3 4 14 15 16",
|
|
2666
|
+
verifyNoPendingRequests: "12",
|
|
2667
|
+
VueInjectionToken: "15",
|
|
2668
|
+
VueProvideSpy: "15",
|
|
2669
|
+
WithMockReturnValue: "0 1 2 3 14 15 16",
|
|
2670
|
+
withOverrides: "0 1 2 3 14 15 16",
|
|
2671
|
+
withSystemTime: "17",
|
|
2672
|
+
XhrBlockMode: "17"
|
|
2673
|
+
};
|
|
2674
|
+
var AWAITABLE_HELPERS = "advanceTimers expectCompletion expectEmission expectEmissions expectError expectNoEmission flushEventLoop flushEventLoopUntil registerDomGlobals settleDynamicImport settleResource stable withSystemTime";
|
|
2675
|
+
|
|
2676
|
+
// src/cli/checks/literals.ts
|
|
2677
|
+
var QUOTES = /* @__PURE__ */ new Set(["'", '"']);
|
|
2678
|
+
var BLOCK_END = "*/";
|
|
2679
|
+
function endOfLineComment(source, start) {
|
|
2680
|
+
const newline = source.indexOf("\n", start);
|
|
2681
|
+
return newline === -1 ? source.length : newline;
|
|
2682
|
+
}
|
|
2683
|
+
function endOfBlockComment(source, start) {
|
|
2684
|
+
const close = source.indexOf(BLOCK_END, start + BLOCK_END.length);
|
|
2685
|
+
return close === -1 ? source.length : close + BLOCK_END.length;
|
|
2686
|
+
}
|
|
2687
|
+
function endOfInterpolation(source, start) {
|
|
2688
|
+
let depth = 1;
|
|
2689
|
+
let index = start;
|
|
2690
|
+
while (index < source.length) {
|
|
2691
|
+
const char = source.charAt(index);
|
|
2692
|
+
if (char === "`") {
|
|
2693
|
+
index = endOfTemplate(source, index);
|
|
2694
|
+
continue;
|
|
2695
|
+
}
|
|
2696
|
+
if (QUOTES.has(char)) {
|
|
2697
|
+
index = findStringEnd(source, index);
|
|
2698
|
+
continue;
|
|
2699
|
+
}
|
|
2700
|
+
if (char === "{") {
|
|
2701
|
+
depth += 1;
|
|
2702
|
+
}
|
|
2703
|
+
if (char === "}") {
|
|
2704
|
+
depth -= 1;
|
|
2705
|
+
if (depth === 0) {
|
|
2706
|
+
return index + 1;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
index += 1;
|
|
2710
|
+
}
|
|
2711
|
+
return source.length;
|
|
2712
|
+
}
|
|
2713
|
+
function endOfTemplate(source, start) {
|
|
2714
|
+
let index = start + 1;
|
|
2715
|
+
while (index < source.length) {
|
|
2716
|
+
const char = source.charAt(index);
|
|
2717
|
+
if (char === "\\") {
|
|
2718
|
+
index += 2;
|
|
2719
|
+
continue;
|
|
2720
|
+
}
|
|
2721
|
+
if (char === "`") {
|
|
2722
|
+
return index + 1;
|
|
2723
|
+
}
|
|
2724
|
+
if (char === "$" && source.charAt(index + 1) === "{") {
|
|
2725
|
+
index = endOfInterpolation(source, index + 2);
|
|
2726
|
+
continue;
|
|
2727
|
+
}
|
|
2728
|
+
index += 1;
|
|
2729
|
+
}
|
|
2730
|
+
return source.length;
|
|
2731
|
+
}
|
|
2732
|
+
function spanEnd(source, index) {
|
|
2733
|
+
const char = source.charAt(index);
|
|
2734
|
+
if (char === "/") {
|
|
2735
|
+
const next = source.charAt(index + 1);
|
|
2736
|
+
if (next === "/") {
|
|
2737
|
+
return endOfLineComment(source, index);
|
|
2738
|
+
}
|
|
2739
|
+
return next === "*" ? endOfBlockComment(source, index) : -1;
|
|
2740
|
+
}
|
|
2741
|
+
if (QUOTES.has(char)) {
|
|
2742
|
+
return findStringEnd(source, index);
|
|
2743
|
+
}
|
|
2744
|
+
return char === "`" ? endOfTemplate(source, index) : -1;
|
|
2745
|
+
}
|
|
2746
|
+
function literalSpans(source) {
|
|
2747
|
+
const spans = [];
|
|
2748
|
+
let index = 0;
|
|
2749
|
+
while (index < source.length) {
|
|
2750
|
+
const end = spanEnd(source, index);
|
|
2751
|
+
if (end === -1) {
|
|
2752
|
+
index += 1;
|
|
2753
|
+
continue;
|
|
2754
|
+
}
|
|
2755
|
+
spans.push({ start: index, end });
|
|
2756
|
+
index = end;
|
|
2757
|
+
}
|
|
2758
|
+
return spans;
|
|
2759
|
+
}
|
|
2760
|
+
function isInsideLiteral(spans, offset) {
|
|
2761
|
+
return spans.some((span) => span.start <= offset && offset < span.end);
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// src/cli/checks/entry-imports.ts
|
|
2765
|
+
var ENTRIES = ENTRY_SPECIFIERS.split(" ");
|
|
2766
|
+
var AWAITABLE = new Set(AWAITABLE_HELPERS.split(" "));
|
|
2767
|
+
var NO_OWNERS = [];
|
|
2768
|
+
var OWNERS = new Map(
|
|
2769
|
+
Object.entries(EXPORTED_BY).map(([name, indices]) => {
|
|
2770
|
+
const owned = new Set(indices.split(" ").map(Number));
|
|
2771
|
+
return [name, ENTRIES.filter((_entry, index) => owned.has(index))];
|
|
2772
|
+
})
|
|
2773
|
+
);
|
|
2774
|
+
var NAMES_BY_ENTRY = new Map(
|
|
2775
|
+
ENTRIES.map((entry) => [entry, new Set([...OWNERS].filter(([, owners]) => owners.includes(entry)).map(([name]) => name))])
|
|
2776
|
+
);
|
|
2777
|
+
var IMPORT = /\bimport\s+(?:type\s+)?([\s\w$*,{}]*?)\s*from\s*["'](vitest-auto-spy(?:\/[\w-]+)?)["']/g;
|
|
2778
|
+
var BRACED = /{([^}]*)}/g;
|
|
2779
|
+
var RENAME = " as ";
|
|
2780
|
+
function parseClause(clause, entry) {
|
|
2781
|
+
const found = [];
|
|
2782
|
+
for (const inner of captures(clause, BRACED)) {
|
|
2783
|
+
for (const raw of inner.split(",")) {
|
|
2784
|
+
const token = raw.trim().replace(/\s+/g, " ").replace(/^type /, "");
|
|
2785
|
+
const rename = token.indexOf(RENAME);
|
|
2786
|
+
if (token !== "") {
|
|
2787
|
+
found.push({
|
|
2788
|
+
entry,
|
|
2789
|
+
name: rename === -1 ? token : token.slice(0, rename),
|
|
2790
|
+
local: rename === -1 ? token : token.slice(rename + RENAME.length)
|
|
2791
|
+
});
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
return found;
|
|
2796
|
+
}
|
|
2797
|
+
function findEntryImports(source) {
|
|
2798
|
+
const spans = literalSpans(source);
|
|
2799
|
+
const found = [];
|
|
2800
|
+
source.replace(IMPORT, (whole, clause, entry, offset) => {
|
|
2801
|
+
if (!isInsideLiteral(spans, offset)) {
|
|
2802
|
+
found.push(...parseClause(clause, entry));
|
|
2803
|
+
}
|
|
2804
|
+
return whole;
|
|
2805
|
+
});
|
|
2806
|
+
return found;
|
|
2807
|
+
}
|
|
2808
|
+
function entryExports(entry) {
|
|
2809
|
+
return NAMES_BY_ENTRY.get(entry);
|
|
2810
|
+
}
|
|
2811
|
+
function ownersOf(name) {
|
|
2812
|
+
return OWNERS.get(name) ?? NO_OWNERS;
|
|
2813
|
+
}
|
|
2814
|
+
function isAwaitableHelper(name) {
|
|
2815
|
+
return AWAITABLE.has(name);
|
|
2816
|
+
}
|
|
2817
|
+
function majorOf(version) {
|
|
2818
|
+
return captures(version, /^(\d+)\./g)[0];
|
|
2819
|
+
}
|
|
2820
|
+
function installedVersion2(cwd) {
|
|
2821
|
+
let directory = cwd;
|
|
2822
|
+
for (; ; ) {
|
|
2823
|
+
const text = readTextFile(join(directory, "node_modules/vitest-auto-spy/package.json"));
|
|
2824
|
+
const parsed = text === void 0 ? void 0 : parseJsonc(text);
|
|
2825
|
+
const version = isRecord(parsed) ? parsed["version"] : void 0;
|
|
2826
|
+
if (typeof version === "string") {
|
|
2827
|
+
return version;
|
|
2828
|
+
}
|
|
2829
|
+
const parent = dirname(directory);
|
|
2830
|
+
if (parent === directory) {
|
|
2831
|
+
return void 0;
|
|
2832
|
+
}
|
|
2833
|
+
directory = parent;
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
function tableApplies(cwd) {
|
|
2837
|
+
const installed = installedVersion2(cwd);
|
|
2838
|
+
const theirs = installed === void 0 ? void 0 : majorOf(installed);
|
|
2839
|
+
return theirs === void 0 || theirs === majorOf(EXPORT_MAP_VERSION);
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
// src/cli/checks/helper-entry.ts
|
|
2843
|
+
function candidates(owners, preferred) {
|
|
2844
|
+
return owners.includes(preferred) ? [preferred] : owners;
|
|
2845
|
+
}
|
|
2846
|
+
function findingFor(file, entry, name, owners) {
|
|
2847
|
+
const list = owners.map((owner) => `\`${owner}\``).join(" or ");
|
|
2848
|
+
return {
|
|
2849
|
+
check: "helper-from-wrong-entry",
|
|
2850
|
+
severity: "error",
|
|
2851
|
+
file,
|
|
2852
|
+
message: `Imports \`${name}\` from \`${entry}\`, which does not export it.`,
|
|
2853
|
+
fix: `Change the specifier to ${list}. The entry point decides which mock adapter and which framework wiring the file gets, which is why the name is not re-exported from the root.`
|
|
2854
|
+
};
|
|
2855
|
+
}
|
|
2856
|
+
function checkHelperEntry(profile, graph) {
|
|
2857
|
+
if (!tableApplies(profile.cwd)) {
|
|
2858
|
+
return [];
|
|
2859
|
+
}
|
|
2860
|
+
const findings = [];
|
|
2861
|
+
for (const [file, text] of graph.texts) {
|
|
2862
|
+
for (const { entry, name } of findEntryImports(text)) {
|
|
2863
|
+
const exported = entryExports(entry);
|
|
2864
|
+
const owners = candidates(ownersOf(name), profile.entry);
|
|
2865
|
+
if (exported !== void 0 && !exported.has(name) && owners.length > 0) {
|
|
2866
|
+
findings.push(findingFor(file, entry, name, owners));
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
return findings;
|
|
2871
|
+
}
|
|
2356
2872
|
var JASMINE_PACKAGES = ["@hirez_io/observer-spy", "@types/jasmine", "jasmine-auto-spies", "jasmine-core"];
|
|
2357
2873
|
var KARMA_PACKAGE = /^karma/;
|
|
2358
2874
|
var KARMA_CONFIG = /(^|\/)karma\.conf\.[cm]?[jt]s$/;
|
|
@@ -2446,7 +2962,7 @@ function checkOrphanRunnerConfig(profile, graph) {
|
|
|
2446
2962
|
}
|
|
2447
2963
|
|
|
2448
2964
|
// src/cli/checks/spec-imports.ts
|
|
2449
|
-
function
|
|
2965
|
+
function findingFor2(importer, imported) {
|
|
2450
2966
|
if (isSpecFile(importer)) {
|
|
2451
2967
|
return {
|
|
2452
2968
|
check: "spec-exports-fixture",
|
|
@@ -2469,7 +2985,7 @@ function checkSpecImports(graph) {
|
|
|
2469
2985
|
for (const [importer, imported] of graph.imports) {
|
|
2470
2986
|
for (const target of imported) {
|
|
2471
2987
|
if (isSpecFile(target)) {
|
|
2472
|
-
findings.push(
|
|
2988
|
+
findings.push(findingFor2(importer, target));
|
|
2473
2989
|
}
|
|
2474
2990
|
}
|
|
2475
2991
|
}
|
|
@@ -2580,6 +3096,78 @@ function checkTsconfigGlobs(profile) {
|
|
|
2580
3096
|
return configs.flatMap((config) => checkOne(profile.cwd, config, profile.files));
|
|
2581
3097
|
}
|
|
2582
3098
|
|
|
3099
|
+
// src/cli/checks/unawaited-helper.ts
|
|
3100
|
+
var QUOTES2 = /* @__PURE__ */ new Set(["'", '"', "`"]);
|
|
3101
|
+
var SPACING = /* @__PURE__ */ new Set([" ", " "]);
|
|
3102
|
+
var STATEMENT_ENDERS = /* @__PURE__ */ new Set(["", ";", "\n", "\r", "}"]);
|
|
3103
|
+
function awaitableLocals(source) {
|
|
3104
|
+
const locals = findEntryImports(source).filter(({ name }) => isAwaitableHelper(name)).map(({ local }) => local);
|
|
3105
|
+
return [...new Set(locals)];
|
|
3106
|
+
}
|
|
3107
|
+
function endOfCall(source, open) {
|
|
3108
|
+
let depth = 0;
|
|
3109
|
+
let index = open;
|
|
3110
|
+
while (index < source.length) {
|
|
3111
|
+
const char = source.charAt(index);
|
|
3112
|
+
if (QUOTES2.has(char)) {
|
|
3113
|
+
index = findStringEnd(source, index);
|
|
3114
|
+
continue;
|
|
3115
|
+
}
|
|
3116
|
+
if (char === "(") {
|
|
3117
|
+
depth += 1;
|
|
3118
|
+
}
|
|
3119
|
+
if (char === ")") {
|
|
3120
|
+
depth -= 1;
|
|
3121
|
+
if (depth === 0) {
|
|
3122
|
+
return index;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
index += 1;
|
|
3126
|
+
}
|
|
3127
|
+
return -1;
|
|
3128
|
+
}
|
|
3129
|
+
function isStatementEnd(source, from) {
|
|
3130
|
+
let index = from;
|
|
3131
|
+
while (SPACING.has(source.charAt(index))) {
|
|
3132
|
+
index += 1;
|
|
3133
|
+
}
|
|
3134
|
+
return STATEMENT_ENDERS.has(source.charAt(index));
|
|
3135
|
+
}
|
|
3136
|
+
function findUnawaitedCalls(source, locals) {
|
|
3137
|
+
if (locals.length === 0) {
|
|
3138
|
+
return [];
|
|
3139
|
+
}
|
|
3140
|
+
const spans = literalSpans(source);
|
|
3141
|
+
const pattern = new RegExp(`(?:^|[;{}])\\s*(${locals.join("|")})\\s*\\(`, "g");
|
|
3142
|
+
const found = [];
|
|
3143
|
+
source.replace(pattern, (whole, local, offset) => {
|
|
3144
|
+
const close = endOfCall(source, offset + whole.length - 1);
|
|
3145
|
+
if (!isInsideLiteral(spans, offset) && close !== -1 && isStatementEnd(source, close + 1)) {
|
|
3146
|
+
found.push(local);
|
|
3147
|
+
}
|
|
3148
|
+
return whole;
|
|
3149
|
+
});
|
|
3150
|
+
return found;
|
|
3151
|
+
}
|
|
3152
|
+
function checkUnawaitedHelper(profile, graph) {
|
|
3153
|
+
if (!tableApplies(profile.cwd)) {
|
|
3154
|
+
return [];
|
|
3155
|
+
}
|
|
3156
|
+
const findings = [];
|
|
3157
|
+
for (const [file, text] of graph.texts) {
|
|
3158
|
+
for (const local of new Set(findUnawaitedCalls(text, awaitableLocals(text)))) {
|
|
3159
|
+
findings.push({
|
|
3160
|
+
check: "no-unawaited-helper",
|
|
3161
|
+
severity: "error",
|
|
3162
|
+
file,
|
|
3163
|
+
message: `Calls \`${local}()\` as a statement and drops the promise it returns.`,
|
|
3164
|
+
fix: "Await it. Unawaited, it settles after the test has already ended, so the assertion inside it can only report into a later test \u2014 or nowhere at all."
|
|
3165
|
+
});
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
return findings;
|
|
3169
|
+
}
|
|
3170
|
+
|
|
2583
3171
|
// src/cli/doctor.ts
|
|
2584
3172
|
function runDoctor(profile) {
|
|
2585
3173
|
const graph = buildGraph(profile);
|
|
@@ -2591,7 +3179,9 @@ function runDoctor(profile) {
|
|
|
2591
3179
|
...checkAngularBuild(profile),
|
|
2592
3180
|
...checkCoverageConfig(profile),
|
|
2593
3181
|
...checkAgentInstructions(profile),
|
|
2594
|
-
...checkJasmineEra(profile)
|
|
3182
|
+
...checkJasmineEra(profile),
|
|
3183
|
+
...checkHelperEntry(profile, graph),
|
|
3184
|
+
...checkUnawaitedHelper(profile, graph)
|
|
2595
3185
|
];
|
|
2596
3186
|
}
|
|
2597
3187
|
|
|
@@ -3132,10 +3722,10 @@ function findDomFreeSpecs(profile, graph) {
|
|
|
3132
3722
|
for (const [file, text] of graph.texts) {
|
|
3133
3723
|
locals.set(file, classify(file, text, known, aliases));
|
|
3134
3724
|
}
|
|
3135
|
-
const
|
|
3725
|
+
const candidates2 = [...graph.texts].filter(([file, text]) => isSpecFile(file) && !DECLARED_ENVIRONMENT.test(text)).map(([file]) => file);
|
|
3136
3726
|
const setup = profile.setupFiles.map((entry) => entry.replace(/^\.\//, ""));
|
|
3137
|
-
const specs =
|
|
3138
|
-
return { specs, undecided:
|
|
3727
|
+
const specs = candidates2.filter((file) => isClean(file, setup, locals));
|
|
3728
|
+
return { specs, undecided: candidates2.length - specs.length };
|
|
3139
3729
|
}
|
|
3140
3730
|
|
|
3141
3731
|
// src/cli/perf-data.ts
|