@grest-ts/testkit 0.0.5 → 0.0.7

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.
Files changed (46) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +418 -413
  3. package/dist/src/runner/isolated-loader.mjs +91 -91
  4. package/dist/src/runner/worker-loader.mjs +49 -49
  5. package/dist/tsconfig.publish.tsbuildinfo +1 -1
  6. package/package.json +12 -12
  7. package/src/GGBundleTest.ts +89 -89
  8. package/src/GGTest.ts +318 -318
  9. package/src/GGTestContext.ts +74 -74
  10. package/src/GGTestRunner.ts +308 -308
  11. package/src/GGTestRuntime.ts +265 -265
  12. package/src/GGTestRuntimeWorker.ts +159 -159
  13. package/src/GGTestSharedRef.ts +116 -116
  14. package/src/GGTestkitExtensionsDiscovery.ts +26 -26
  15. package/src/IGGLocalDiscoveryServer.ts +16 -16
  16. package/src/callOn/GGCallOnSelector.ts +61 -61
  17. package/src/callOn/GGContractClass.implement.ts +43 -43
  18. package/src/callOn/GGTestActionForLocatorOnCall.ts +134 -134
  19. package/src/callOn/TestableIPC.ts +81 -81
  20. package/src/callOn/callOn.ts +224 -224
  21. package/src/callOn/registerOnCallHandler.ts +123 -123
  22. package/src/index-node.ts +64 -64
  23. package/src/mockable/GGMockable.ts +22 -22
  24. package/src/mockable/GGMockableCall.ts +45 -45
  25. package/src/mockable/GGMockableIPC.ts +20 -20
  26. package/src/mockable/GGMockableInterceptor.ts +44 -44
  27. package/src/mockable/GGMockableInterceptorsServer.ts +69 -69
  28. package/src/mockable/mockable.ts +71 -71
  29. package/src/runner/InlineRunner.ts +47 -47
  30. package/src/runner/IsolatedRunner.ts +179 -179
  31. package/src/runner/RuntimeRunner.ts +15 -15
  32. package/src/runner/WorkerRunner.ts +179 -179
  33. package/src/runner/isolated-loader.mjs +91 -91
  34. package/src/runner/worker-loader.mjs +49 -49
  35. package/src/testers/GGCallInterceptor.ts +224 -224
  36. package/src/testers/GGMockWith.ts +92 -92
  37. package/src/testers/GGSpyWith.ts +115 -115
  38. package/src/testers/GGTestAction.ts +332 -332
  39. package/src/testers/GGTestComponent.ts +16 -16
  40. package/src/testers/GGTestSelector.ts +223 -223
  41. package/src/testers/IGGTestInterceptor.ts +10 -10
  42. package/src/testers/IGGTestWith.ts +15 -15
  43. package/src/testers/RuntimeSelector.ts +151 -151
  44. package/src/utils/GGExpectations.ts +78 -78
  45. package/src/utils/GGTestError.ts +36 -36
  46. package/src/utils/captureStack.ts +53 -53
@@ -1,151 +1,151 @@
1
- import type {GGTestRuntime} from "../GGTestRuntime";
2
-
3
- /**
4
- * Constructor type for a runtime class that has a static NAME property.
5
- * This enforces that all runtimes used with the selector system define NAME.
6
- *
7
- * Note: We use `unknown` instead of `GGRuntime` to avoid circular dependency
8
- * between @grest-ts/testkit and @grest-ts/runtime.
9
- */
10
- export interface RuntimeConstructor<N extends string = string> {
11
- new(): unknown;
12
-
13
- /** Name of the runtime - must be unique across all runtimes */
14
- readonly NAME: N;
15
- /** Source path set by GGRuntime.cli() - used for worker/isolated modes */
16
- readonly SOURCE_MODULE_URL?: string;
17
- }
18
-
19
- /**
20
- * Extension interface for selector capabilities.
21
- * Modules augment this interface to add their accessors (config, logs, metrics, etc.)
22
- *
23
- * @example
24
- * // In @grest-ts/config module:
25
- * declare module '@grest-ts/testkit' {
26
- * interface SelectorExtensions<T extends RuntimeConstructor[]> {
27
- * config: GGTestConfigAccessor<T>;
28
- * }
29
- * }
30
- */
31
- export interface SelectorExtensions<T extends RuntimeConstructor[]> {
32
- // Base interface - modules add properties via declaration merging
33
- }
34
-
35
- /**
36
- * Selector for a group of runtime instances.
37
- * Provides access to selected runtimes and their extension accessors.
38
- *
39
- * @example
40
- * const t = GGTest.startWorker(MainRuntime);
41
- * t.logs.cursor();
42
- * t[0].logs.cursor();
43
- * await t.stop();
44
- */
45
- export interface Selector<T extends RuntimeConstructor[]> extends SelectorExtensions<T> {
46
- /**
47
- * Get the underlying runtime instances
48
- */
49
- readonly runtimes: GGTestRuntime[];
50
-
51
- /**
52
- * Access individual instance by index
53
- */
54
- [index: number]: Selector<[T[number]]>;
55
-
56
- /**
57
- * Number of selected instances
58
- */
59
- readonly length: number;
60
-
61
- /**
62
- * Stop runtimes (teardown services but keep IPC alive for log retrieval).
63
- * After stop(), you can still call commands like log retrieval.
64
- */
65
- stop(): Promise<void>;
66
-
67
- /**
68
- * Fully shutdown runtimes (terminate workers/processes).
69
- * After shutdown(), no commands can be sent.
70
- */
71
- shutdown(): Promise<void>;
72
- }
73
-
74
- // ============================================================================
75
- // Input types for startWorker/startInline/startIsolated
76
- // ============================================================================
77
-
78
- /**
79
- * Input can be a single runtime, array of runtimes, or object mapping names to runtimes.
80
- */
81
- export type RuntimeInput =
82
- | RuntimeConstructor
83
- | RuntimeConstructor[]
84
- | Record<string, RuntimeConstructor | RuntimeConstructor[]>;
85
-
86
- /**
87
- * Normalize a single runtime or array to always be an array.
88
- */
89
- type NormalizeToArray<T> = T extends RuntimeConstructor[] ? T : [T];
90
-
91
- /**
92
- * Result type for object input: each key maps to a Selector.
93
- */
94
- export type ObjectResult<T extends Record<string, RuntimeConstructor | RuntimeConstructor[]>> = {
95
- [K in keyof T]: Selector<NormalizeToArray<T[K]>>;
96
- } & {
97
- /**
98
- * Stop all runtimes in this group.
99
- */
100
- stop(): Promise<void>;
101
-
102
- /**
103
- * Shutdown all runtimes in this group.
104
- */
105
- shutdown(): Promise<void>;
106
- };
107
-
108
- /**
109
- * Result type based on input shape:
110
- * - Single runtime → Selector
111
- * - Array of runtimes → Selector
112
- * - Object → ObjectResult with named selectors
113
- */
114
- export type StartResult<T extends RuntimeInput> =
115
- T extends Record<string, RuntimeConstructor | RuntimeConstructor[]>
116
- ? ObjectResult<T>
117
- : T extends RuntimeConstructor[]
118
- ? Selector<T>
119
- : T extends RuntimeConstructor
120
- ? Selector<[T]>
121
- : never;
122
-
123
- // ============================================================================
124
- // Legacy RuntimeResult (for backwards compatibility with .get())
125
- // ============================================================================
126
-
127
- /**
128
- * @deprecated Use the new startWorker overloads instead.
129
- * Legacy result type that provides .get() method.
130
- */
131
- export interface RuntimeResult<T extends RuntimeConstructor[]> {
132
- /**
133
- * Get selector for a specific runtime type
134
- */
135
- get<R extends T[number]>(runtime: R): Selector<[R]>;
136
-
137
- /**
138
- * Get selector for all runtimes
139
- */
140
- all(): Selector<T>;
141
-
142
- /**
143
- * Stop all runtimes.
144
- */
145
- stop(): Promise<void>;
146
-
147
- /**
148
- * Shutdown all runtimes.
149
- */
150
- shutdown(): Promise<void>;
151
- }
1
+ import type {GGTestRuntime} from "../GGTestRuntime";
2
+
3
+ /**
4
+ * Constructor type for a runtime class that has a static NAME property.
5
+ * This enforces that all runtimes used with the selector system define NAME.
6
+ *
7
+ * Note: We use `unknown` instead of `GGRuntime` to avoid circular dependency
8
+ * between @grest-ts/testkit and @grest-ts/runtime.
9
+ */
10
+ export interface RuntimeConstructor<N extends string = string> {
11
+ new(): unknown;
12
+
13
+ /** Name of the runtime - must be unique across all runtimes */
14
+ readonly NAME: N;
15
+ /** Source path set by GGRuntime.cli() - used for worker/isolated modes */
16
+ readonly SOURCE_MODULE_URL?: string;
17
+ }
18
+
19
+ /**
20
+ * Extension interface for selector capabilities.
21
+ * Modules augment this interface to add their accessors (config, logs, metrics, etc.)
22
+ *
23
+ * @example
24
+ * // In @grest-ts/config module:
25
+ * declare module '@grest-ts/testkit' {
26
+ * interface SelectorExtensions<T extends RuntimeConstructor[]> {
27
+ * config: GGTestConfigAccessor<T>;
28
+ * }
29
+ * }
30
+ */
31
+ export interface SelectorExtensions<T extends RuntimeConstructor[]> {
32
+ // Base interface - modules add properties via declaration merging
33
+ }
34
+
35
+ /**
36
+ * Selector for a group of runtime instances.
37
+ * Provides access to selected runtimes and their extension accessors.
38
+ *
39
+ * @example
40
+ * const t = GGTest.startWorker(MainRuntime);
41
+ * t.logs.cursor();
42
+ * t[0].logs.cursor();
43
+ * await t.stop();
44
+ */
45
+ export interface Selector<T extends RuntimeConstructor[]> extends SelectorExtensions<T> {
46
+ /**
47
+ * Get the underlying runtime instances
48
+ */
49
+ readonly runtimes: GGTestRuntime[];
50
+
51
+ /**
52
+ * Access individual instance by index
53
+ */
54
+ [index: number]: Selector<[T[number]]>;
55
+
56
+ /**
57
+ * Number of selected instances
58
+ */
59
+ readonly length: number;
60
+
61
+ /**
62
+ * Stop runtimes (teardown services but keep IPC alive for log retrieval).
63
+ * After stop(), you can still call commands like log retrieval.
64
+ */
65
+ stop(): Promise<void>;
66
+
67
+ /**
68
+ * Fully shutdown runtimes (terminate workers/processes).
69
+ * After shutdown(), no commands can be sent.
70
+ */
71
+ shutdown(): Promise<void>;
72
+ }
73
+
74
+ // ============================================================================
75
+ // Input types for startWorker/startInline/startIsolated
76
+ // ============================================================================
77
+
78
+ /**
79
+ * Input can be a single runtime, array of runtimes, or object mapping names to runtimes.
80
+ */
81
+ export type RuntimeInput =
82
+ | RuntimeConstructor
83
+ | RuntimeConstructor[]
84
+ | Record<string, RuntimeConstructor | RuntimeConstructor[]>;
85
+
86
+ /**
87
+ * Normalize a single runtime or array to always be an array.
88
+ */
89
+ type NormalizeToArray<T> = T extends RuntimeConstructor[] ? T : [T];
90
+
91
+ /**
92
+ * Result type for object input: each key maps to a Selector.
93
+ */
94
+ export type ObjectResult<T extends Record<string, RuntimeConstructor | RuntimeConstructor[]>> = {
95
+ [K in keyof T]: Selector<NormalizeToArray<T[K]>>;
96
+ } & {
97
+ /**
98
+ * Stop all runtimes in this group.
99
+ */
100
+ stop(): Promise<void>;
101
+
102
+ /**
103
+ * Shutdown all runtimes in this group.
104
+ */
105
+ shutdown(): Promise<void>;
106
+ };
107
+
108
+ /**
109
+ * Result type based on input shape:
110
+ * - Single runtime → Selector
111
+ * - Array of runtimes → Selector
112
+ * - Object → ObjectResult with named selectors
113
+ */
114
+ export type StartResult<T extends RuntimeInput> =
115
+ T extends Record<string, RuntimeConstructor | RuntimeConstructor[]>
116
+ ? ObjectResult<T>
117
+ : T extends RuntimeConstructor[]
118
+ ? Selector<T>
119
+ : T extends RuntimeConstructor
120
+ ? Selector<[T]>
121
+ : never;
122
+
123
+ // ============================================================================
124
+ // Legacy RuntimeResult (for backwards compatibility with .get())
125
+ // ============================================================================
126
+
127
+ /**
128
+ * @deprecated Use the new startWorker overloads instead.
129
+ * Legacy result type that provides .get() method.
130
+ */
131
+ export interface RuntimeResult<T extends RuntimeConstructor[]> {
132
+ /**
133
+ * Get selector for a specific runtime type
134
+ */
135
+ get<R extends T[number]>(runtime: R): Selector<[R]>;
136
+
137
+ /**
138
+ * Get selector for all runtimes
139
+ */
140
+ all(): Selector<T>;
141
+
142
+ /**
143
+ * Stop all runtimes.
144
+ */
145
+ stop(): Promise<void>;
146
+
147
+ /**
148
+ * Shutdown all runtimes.
149
+ */
150
+ shutdown(): Promise<void>;
151
+ }
@@ -1,78 +1,78 @@
1
- import {Raw} from "@grest-ts/schema";
2
- import {updateErrorStack} from "./captureStack";
3
-
4
- interface Expectation<Data> {
5
- err: Error;
6
- execute: (input: Data) => void;
7
- }
8
-
9
- /**
10
- * Collection of expectations to validate data.
11
- * Pure validation utility - does not know about HTTP response structure.
12
- */
13
- export class GGExpectations<Data> {
14
-
15
- private readonly expectations: Expectation<Data>[] = []
16
-
17
- public check(data: Data) {
18
- this.expectations.forEach(expectation => {
19
- try {
20
- expectation.execute(data)
21
- } catch (e: any) {
22
- throw updateErrorStack(e, expectation.err)
23
- }
24
- })
25
- }
26
-
27
- public flush() {
28
- this.expectations.length = 0;
29
- }
30
-
31
- private add(execute: (input: Data) => void): void {
32
- this.expectations.push({
33
- err: new Error(),
34
- execute: execute
35
- })
36
- }
37
-
38
- public toEqual(expectedData: Data): void {
39
- return this.add((input) => expect(input).toEqual(expectedData))
40
- }
41
-
42
- public toMatchObject(expectedData: Data): void {
43
- return this.add((input) => expect(input).toMatchObject(expectedData as any))
44
- }
45
-
46
- public toBeUndefined(): void {
47
- return this.add((input) => expect(input).toBeUndefined())
48
- }
49
-
50
- public toHaveLength(length: number) {
51
- return this.add((input: any) => {
52
- if (input?.length === undefined) {
53
- throw new Error("expect.length is not defined on: " + JSON.stringify(input, null, 2));
54
- }
55
- expect(input.length).toEqual(length)
56
- })
57
- }
58
-
59
- public arrayToContain<Item extends Data extends Array<infer R> ? R : never>(...items: Partial<Raw<Item>>[]) {
60
- return this.add((input: any) => {
61
- expect(Array.isArray(input)).toBe(true)
62
- expect(input).toEqual(
63
- expect.arrayContaining(
64
- items.map(item => expect.objectContaining(item as any))
65
- )
66
- );
67
- })
68
- }
69
-
70
- public arrayToContainEqual<Item extends Data extends Array<infer R> ? R : never>(...items: Partial<Raw<Item>>[]) {
71
- return this.add((input: any) => {
72
- expect(Array.isArray(input)).toBe(true)
73
- for (const item of items) {
74
- expect(input).toContainEqual(item);
75
- }
76
- })
77
- }
78
- }
1
+ import {Raw} from "@grest-ts/schema";
2
+ import {updateErrorStack} from "./captureStack";
3
+
4
+ interface Expectation<Data> {
5
+ err: Error;
6
+ execute: (input: Data) => void;
7
+ }
8
+
9
+ /**
10
+ * Collection of expectations to validate data.
11
+ * Pure validation utility - does not know about HTTP response structure.
12
+ */
13
+ export class GGExpectations<Data> {
14
+
15
+ private readonly expectations: Expectation<Data>[] = []
16
+
17
+ public check(data: Data) {
18
+ this.expectations.forEach(expectation => {
19
+ try {
20
+ expectation.execute(data)
21
+ } catch (e: any) {
22
+ throw updateErrorStack(e, expectation.err)
23
+ }
24
+ })
25
+ }
26
+
27
+ public flush() {
28
+ this.expectations.length = 0;
29
+ }
30
+
31
+ private add(execute: (input: Data) => void): void {
32
+ this.expectations.push({
33
+ err: new Error(),
34
+ execute: execute
35
+ })
36
+ }
37
+
38
+ public toEqual(expectedData: Data): void {
39
+ return this.add((input) => expect(input).toEqual(expectedData))
40
+ }
41
+
42
+ public toMatchObject(expectedData: Data): void {
43
+ return this.add((input) => expect(input).toMatchObject(expectedData as any))
44
+ }
45
+
46
+ public toBeUndefined(): void {
47
+ return this.add((input) => expect(input).toBeUndefined())
48
+ }
49
+
50
+ public toHaveLength(length: number) {
51
+ return this.add((input: any) => {
52
+ if (input?.length === undefined) {
53
+ throw new Error("expect.length is not defined on: " + JSON.stringify(input, null, 2));
54
+ }
55
+ expect(input.length).toEqual(length)
56
+ })
57
+ }
58
+
59
+ public arrayToContain<Item extends Data extends Array<infer R> ? R : never>(...items: Partial<Raw<Item>>[]) {
60
+ return this.add((input: any) => {
61
+ expect(Array.isArray(input)).toBe(true)
62
+ expect(input).toEqual(
63
+ expect.arrayContaining(
64
+ items.map(item => expect.objectContaining(item as any))
65
+ )
66
+ );
67
+ })
68
+ }
69
+
70
+ public arrayToContainEqual<Item extends Data extends Array<infer R> ? R : never>(...items: Partial<Raw<Item>>[]) {
71
+ return this.add((input: any) => {
72
+ expect(Array.isArray(input)).toBe(true)
73
+ for (const item of items) {
74
+ expect(input).toContainEqual(item);
75
+ }
76
+ })
77
+ }
78
+ }
@@ -1,37 +1,37 @@
1
- import {LOG_COLORS} from "@grest-ts/logger-console";
2
-
3
- export class GGTestError extends Error {
4
-
5
- constructor(data: CreateErrorInput) {
6
-
7
- const tab = (n: number, str: string) => {
8
- return str.split("\n").join("\n" + ("\t".repeat(n)));
9
- }
10
-
11
- const fixValue = (value: any) => {
12
- if (value instanceof Error) {
13
- return value.stack
14
- } else if (typeof value === "object") {
15
- return JSON.stringify(value, null, 2)
16
- } else {
17
- return String(value);
18
- }
19
- }
20
-
21
- super("Error: " + (data.context ? data.context + " " : "") + data.test + "\n" +
22
- "\nExpected: " + LOG_COLORS.green + tab(1, fixValue(data.expected)) + LOG_COLORS.reset +
23
- "\nReceived: " + tab(1, fixValue(data.received)) +
24
- (data.extra ? "\n\t" + tab(1, data.extra) : "") +
25
- (data.sourceFile ? "\n\t" + tab(1, data.sourceFile) : "") +
26
- "\n");
27
- }
28
- }
29
-
30
- interface CreateErrorInput {
31
- context?: string;
32
- test: string,
33
- expected: any,
34
- received: any,
35
- extra?: any
36
- sourceFile?: string;
1
+ import {LOG_COLORS} from "@grest-ts/logger-console";
2
+
3
+ export class GGTestError extends Error {
4
+
5
+ constructor(data: CreateErrorInput) {
6
+
7
+ const tab = (n: number, str: string) => {
8
+ return str.split("\n").join("\n" + ("\t".repeat(n)));
9
+ }
10
+
11
+ const fixValue = (value: any) => {
12
+ if (value instanceof Error) {
13
+ return value.stack
14
+ } else if (typeof value === "object") {
15
+ return JSON.stringify(value, null, 2)
16
+ } else {
17
+ return String(value);
18
+ }
19
+ }
20
+
21
+ super("Error: " + (data.context ? data.context + " " : "") + data.test + "\n" +
22
+ "\nExpected: " + LOG_COLORS.green + tab(1, fixValue(data.expected)) + LOG_COLORS.reset +
23
+ "\nReceived: " + tab(1, fixValue(data.received)) +
24
+ (data.extra ? "\n\t" + tab(1, data.extra) : "") +
25
+ (data.sourceFile ? "\n\t" + tab(1, data.sourceFile) : "") +
26
+ "\n");
27
+ }
28
+ }
29
+
30
+ interface CreateErrorInput {
31
+ context?: string;
32
+ test: string,
33
+ expected: any,
34
+ received: any,
35
+ extra?: any
36
+ sourceFile?: string;
37
37
  }
@@ -1,54 +1,54 @@
1
- /**
2
- * @returns path to the source test file
3
- */
4
- export function captureStackSourceFile(): string {
5
- return getLinesFromTestFile(new Error().stack.split("\n"))[0] ?? "[Source not found]";
6
- }
7
-
8
- /**
9
- * Switches source files part of the stack for err with actualSourceLocation, but keeping the original error message.
10
- */
11
- export function updateErrorStack(err: Error, actualSourceLocation?: Error) {
12
- const lines = (err.stack ?? '').split("\n");
13
- const errorLines = getErrorLinesOnly(lines);
14
- const errLines = (actualSourceLocation?.stack ?? err.stack ?? '').split("\n");
15
- const fileLines = getLinesFromTestFile(errLines);
16
- err.stack = errorLines.join("\n") + "\n" + fileLines.join("\n");
17
- return err;
18
- }
19
-
20
- /**
21
- * Returns error message part of the stack lines. Skips all lines after first path is detected.
22
- */
23
- function getErrorLinesOnly(lines: string[]): string [] {
24
- const addedLines: string[] = [];
25
- for (let i = 0; i < lines.length; i++) {
26
- const line = lines[i];
27
- if (line.startsWith(" at ")) {
28
- break;
29
- }
30
- addedLines.push(line);
31
- }
32
- return addedLines;
33
- }
34
-
35
- /**
36
- * Returns source file path lines from the lines.
37
- * Starts stack from the "test" source file and skips all framework paths.
38
- * For example:
39
- * ' at PATH_TO_SOURCE'
40
- */
41
- function getLinesFromTestFile(lines: string[]): string[] {
42
- const startIdx = lines.findIndex(line => {
43
- return line.includes('.test.ts')
44
- || line.includes('.spec.ts')
45
- });
46
- const endIds = lines.findIndex(line => {
47
- return line.includes('@vitest')
48
- });
49
- if (startIdx === -1) {
50
- return [];
51
- }
52
- return lines.slice(startIdx, endIds);
53
-
1
+ /**
2
+ * @returns path to the source test file
3
+ */
4
+ export function captureStackSourceFile(): string {
5
+ return getLinesFromTestFile(new Error().stack.split("\n"))[0] ?? "[Source not found]";
6
+ }
7
+
8
+ /**
9
+ * Switches source files part of the stack for err with actualSourceLocation, but keeping the original error message.
10
+ */
11
+ export function updateErrorStack(err: Error, actualSourceLocation?: Error) {
12
+ const lines = (err.stack ?? '').split("\n");
13
+ const errorLines = getErrorLinesOnly(lines);
14
+ const errLines = (actualSourceLocation?.stack ?? err.stack ?? '').split("\n");
15
+ const fileLines = getLinesFromTestFile(errLines);
16
+ err.stack = errorLines.join("\n") + "\n" + fileLines.join("\n");
17
+ return err;
18
+ }
19
+
20
+ /**
21
+ * Returns error message part of the stack lines. Skips all lines after first path is detected.
22
+ */
23
+ function getErrorLinesOnly(lines: string[]): string [] {
24
+ const addedLines: string[] = [];
25
+ for (let i = 0; i < lines.length; i++) {
26
+ const line = lines[i];
27
+ if (line.startsWith(" at ")) {
28
+ break;
29
+ }
30
+ addedLines.push(line);
31
+ }
32
+ return addedLines;
33
+ }
34
+
35
+ /**
36
+ * Returns source file path lines from the lines.
37
+ * Starts stack from the "test" source file and skips all framework paths.
38
+ * For example:
39
+ * ' at PATH_TO_SOURCE'
40
+ */
41
+ function getLinesFromTestFile(lines: string[]): string[] {
42
+ const startIdx = lines.findIndex(line => {
43
+ return line.includes('.test.ts')
44
+ || line.includes('.spec.ts')
45
+ });
46
+ const endIds = lines.findIndex(line => {
47
+ return line.includes('@vitest')
48
+ });
49
+ if (startIdx === -1) {
50
+ return [];
51
+ }
52
+ return lines.slice(startIdx, endIds);
53
+
54
54
  }