test-inventory 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +4 -1
- package/dist/ast.d.ts +3 -3
- package/dist/ast.js +4 -4
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -5
- package/dist/config-runs.d.ts +97 -0
- package/dist/config-runs.js +784 -0
- package/dist/config.d.ts +90 -0
- package/dist/config.js +652 -0
- package/dist/diagnostics.js +5 -1
- package/dist/extract.d.ts +8 -0
- package/dist/extract.js +6 -0
- package/dist/filter.js +7 -0
- package/dist/frameworks/bindings.d.ts +22 -0
- package/dist/frameworks/bindings.js +19 -9
- package/dist/frameworks/playwright.d.ts +2 -1
- package/dist/frameworks/playwright.js +1 -0
- package/dist/frameworks/vitest.d.ts +2 -1
- package/dist/frameworks/vitest.js +6 -2
- package/dist/index.d.ts +1 -1
- package/dist/inventory.d.ts +2 -2
- package/dist/inventory.js +2 -1
- package/dist/json.js +2 -0
- package/dist/model.d.ts +6 -1
- package/dist/options.d.ts +2 -2
- package/dist/records.d.ts +54 -1
- package/dist/records.js +192 -28
- package/dist/scan-file.d.ts +5 -1
- package/dist/scan-file.js +5 -2
- package/dist/scan-source.js +1 -1
- package/dist/scan.d.ts +2 -1
- package/dist/scan.js +58 -16
- package/dist/types.d.ts +73 -7
- package/dist/values.d.ts +5 -0
- package/dist/values.js +5 -0
- package/dist/vitest-config.d.ts +6 -4
- package/dist/vitest-config.js +32 -28
- package/dist/vitest-defaults.d.ts +6 -0
- package/dist/vitest-defaults.js +16 -0
- package/package.json +10 -8
- package/schema/v1.json +180 -6
package/dist/extract.d.ts
CHANGED
|
@@ -37,6 +37,9 @@ export interface PendingSuite {
|
|
|
37
37
|
order: number;
|
|
38
38
|
/** Statements of the tests and describes directly inside, left out of the describe's body hash. */
|
|
39
39
|
cuts: Span[];
|
|
40
|
+
/** Declared under a condition, or in a function: it may not run while the file loads. */
|
|
41
|
+
isInCondition: boolean;
|
|
42
|
+
isInFunction: boolean;
|
|
40
43
|
}
|
|
41
44
|
export interface PendingTest {
|
|
42
45
|
scope: Scope;
|
|
@@ -80,6 +83,11 @@ export interface Extraction {
|
|
|
80
83
|
/** Hooks at the top level of the file. */
|
|
81
84
|
hooks: HookCounts;
|
|
82
85
|
usesGlobals: boolean;
|
|
86
|
+
/** The file's `@module-tag` tags, where each is written. */
|
|
87
|
+
fileTags: {
|
|
88
|
+
name: string;
|
|
89
|
+
span: Span;
|
|
90
|
+
}[];
|
|
83
91
|
}
|
|
84
92
|
/**
|
|
85
93
|
* Applies settings written later in the same place: the last value of each wins, and a test is slow when any
|
package/dist/extract.js
CHANGED
|
@@ -175,6 +175,10 @@ class Walker {
|
|
|
175
175
|
problems: [...this.main.adapter.problems, ...this.problems],
|
|
176
176
|
hooks: this.fileScope.hooks,
|
|
177
177
|
usesGlobals: this.main.adapter.usesGlobals,
|
|
178
|
+
fileTags: this.main.adapter.fileTags.map((name, index) => ({
|
|
179
|
+
name,
|
|
180
|
+
span: this.main.adapter.fileTagSpans[index],
|
|
181
|
+
})),
|
|
178
182
|
};
|
|
179
183
|
}
|
|
180
184
|
visit(node, context) {
|
|
@@ -982,6 +986,8 @@ class Walker {
|
|
|
982
986
|
declaredAt: this.declaredAt(call),
|
|
983
987
|
order: context.registeredAt ?? call.start,
|
|
984
988
|
cuts: [],
|
|
989
|
+
isInCondition: context.isInCondition,
|
|
990
|
+
isInFunction: context.isInFunction,
|
|
985
991
|
};
|
|
986
992
|
scope.suite = suite;
|
|
987
993
|
this.suites.push(suite);
|
package/dist/filter.js
CHANGED
|
@@ -55,6 +55,12 @@ const TEST_KEYS = Object.keys({
|
|
|
55
55
|
retryDelay: true,
|
|
56
56
|
retryCondition: true,
|
|
57
57
|
repeats: true,
|
|
58
|
+
timeoutSource: true,
|
|
59
|
+
retriesSource: true,
|
|
60
|
+
repeatsSource: true,
|
|
61
|
+
timeoutConfigText: true,
|
|
62
|
+
retriesConfigText: true,
|
|
63
|
+
repeatsConfigText: true,
|
|
58
64
|
fixtures: true,
|
|
59
65
|
expectCount: true,
|
|
60
66
|
expectedAssertions: true,
|
|
@@ -67,6 +73,7 @@ const TEST_KEYS = Object.keys({
|
|
|
67
73
|
isInLoop: true,
|
|
68
74
|
isInCondition: true,
|
|
69
75
|
isInFunction: true,
|
|
76
|
+
projects: true,
|
|
70
77
|
});
|
|
71
78
|
function list(value, option, allowed) {
|
|
72
79
|
if (value === undefined)
|
|
@@ -54,10 +54,32 @@ export declare function allDeclarators(program: Program): VariableDeclarator[];
|
|
|
54
54
|
export declare function moduleImports(program: Program, isFramework: (source: string) => boolean): Map<string, ModuleImport>;
|
|
55
55
|
/** The module of `require('module')`, or null for any other expression. */
|
|
56
56
|
export declare function requiredModule(expression: Expression): string | null;
|
|
57
|
+
/** What `module.exports = value` assigns, the default export of a CommonJS module; null for any other statement. */
|
|
58
|
+
export declare function moduleExportsValue(statement: Node): Expression | null;
|
|
57
59
|
/** Applies `bind` to each declarator until no more names are bound, so declaration order doesn't matter. */
|
|
58
60
|
export declare function bindAll(declarators: VariableDeclarator[], bind: (declarator: VariableDeclarator) => boolean): void;
|
|
59
61
|
/** Whether a module exports `name` as a test object, or as a function that returns one. */
|
|
60
62
|
export declare function exportsTestObject(program: Program, name: string, objects: TestObjects, exported?: Exported): boolean;
|
|
63
|
+
/** How a module exports `name` itself, in `statement`: declared, or exported by name from a local or another module. */
|
|
64
|
+
export type OwnExport = {
|
|
65
|
+
statement: Node;
|
|
66
|
+
} & ({
|
|
67
|
+
kind: 'default';
|
|
68
|
+
value: Expression;
|
|
69
|
+
} | {
|
|
70
|
+
kind: 'variable' | 'function';
|
|
71
|
+
} | {
|
|
72
|
+
kind: 'specifier';
|
|
73
|
+
local: string;
|
|
74
|
+
source: string | null;
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* The module's own export of `name`; null when it has none and only `export *` may pass the name on. An own export
|
|
78
|
+
* wins over those, as in JavaScript.
|
|
79
|
+
*/
|
|
80
|
+
export declare function ownExport(program: Program, name: string): OwnExport | null;
|
|
81
|
+
/** The module `export * from 'module'` or `module.exports = require('module')` passes every name on from; or null. */
|
|
82
|
+
export declare function starReexport(statement: Node): string | null;
|
|
61
83
|
/** Whether a module imports, re-exports or requires any of the given sources. */
|
|
62
84
|
export declare function importsFrom(program: Program, matches: (source: string) => boolean): boolean;
|
|
63
85
|
/** Whether a name a module imports from another module is a test object there, which follows that module in turn. */
|
|
@@ -135,8 +135,8 @@ export function requiredModule(expression) {
|
|
|
135
135
|
const argument = node.arguments.at(0);
|
|
136
136
|
return argument?.type === 'Literal' && typeof argument.value === 'string' ? argument.value : null;
|
|
137
137
|
}
|
|
138
|
-
/**
|
|
139
|
-
function
|
|
138
|
+
/** What `module.exports = value` assigns, the default export of a CommonJS module; null for any other statement. */
|
|
139
|
+
export function moduleExportsValue(statement) {
|
|
140
140
|
if (statement.type !== 'ExpressionStatement')
|
|
141
141
|
return null;
|
|
142
142
|
const expression = unwrap(statement.expression);
|
|
@@ -147,7 +147,12 @@ function commonJsReexport(statement) {
|
|
|
147
147
|
target.object.type === 'Identifier' &&
|
|
148
148
|
target.object.name === 'module' &&
|
|
149
149
|
propertyName(target) === 'exports';
|
|
150
|
-
return isModuleExports ?
|
|
150
|
+
return isModuleExports ? expression.right : null;
|
|
151
|
+
}
|
|
152
|
+
/** The module of `module.exports = require('module')`, which exports what that module does; null otherwise. */
|
|
153
|
+
function commonJsReexport(statement) {
|
|
154
|
+
const value = moduleExportsValue(statement);
|
|
155
|
+
return value ? requiredModule(value) : null;
|
|
151
156
|
}
|
|
152
157
|
/** Applies `bind` to each declarator until no more names are bound, so declaration order doesn't matter. */
|
|
153
158
|
export function bindAll(declarators, bind) {
|
|
@@ -191,10 +196,10 @@ export function exportsTestObject(program, name, objects, exported = 'test objec
|
|
|
191
196
|
* The module's own export of `name`; null when it has none and only `export *` may pass the name on. An own export
|
|
192
197
|
* wins over those, as in JavaScript.
|
|
193
198
|
*/
|
|
194
|
-
function ownExport(program, name) {
|
|
199
|
+
export function ownExport(program, name) {
|
|
195
200
|
for (const statement of program.body) {
|
|
196
201
|
if (statement.type === 'ExportDefaultDeclaration' && name === 'default') {
|
|
197
|
-
return { kind: 'default', value: statement.declaration };
|
|
202
|
+
return { statement, kind: 'default', value: statement.declaration };
|
|
198
203
|
}
|
|
199
204
|
if (statement.type !== 'ExportNamedDeclaration')
|
|
200
205
|
continue;
|
|
@@ -202,21 +207,26 @@ function ownExport(program, name) {
|
|
|
202
207
|
if (declaration?.type === 'VariableDeclaration') {
|
|
203
208
|
const declared = declaration.declarations.some((item) => item.id.type === 'Identifier' && item.id.name === name);
|
|
204
209
|
if (declared)
|
|
205
|
-
return { kind: 'variable' };
|
|
210
|
+
return { statement, kind: 'variable' };
|
|
206
211
|
}
|
|
207
212
|
const named = declaration?.type === 'FunctionDeclaration' || declaration?.type === 'ClassDeclaration';
|
|
208
213
|
if (named && declaration.id?.name === name)
|
|
209
|
-
return { kind: 'function' };
|
|
214
|
+
return { statement, kind: 'function' };
|
|
210
215
|
for (const specifier of statement.specifiers) {
|
|
211
216
|
if (exportName(specifier.exported) !== name)
|
|
212
217
|
continue;
|
|
213
|
-
return {
|
|
218
|
+
return {
|
|
219
|
+
statement,
|
|
220
|
+
kind: 'specifier',
|
|
221
|
+
local: exportName(specifier.local),
|
|
222
|
+
source: statement.source?.value ?? null,
|
|
223
|
+
};
|
|
214
224
|
}
|
|
215
225
|
}
|
|
216
226
|
return null;
|
|
217
227
|
}
|
|
218
228
|
/** The module `export * from 'module'` or `module.exports = require('module')` passes every name on from; or null. */
|
|
219
|
-
function starReexport(statement) {
|
|
229
|
+
export function starReexport(statement) {
|
|
220
230
|
if (statement.type === 'ExportAllDeclaration')
|
|
221
231
|
return statement.exported ? null : statement.source.value;
|
|
222
232
|
return commonJsReexport(statement);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { CallExpression, Expression, Node, Program } from 'oxc-parser';
|
|
2
|
-
import type { Adapter, ApiCall, CallContext, ModuleReader, Problem } from '../model.ts';
|
|
2
|
+
import type { Adapter, ApiCall, CallContext, ModuleReader, Problem, Span } from '../model.ts';
|
|
3
3
|
import { type FileContext } from './common.ts';
|
|
4
4
|
export declare class PlaywrightAdapter implements Adapter {
|
|
5
5
|
readonly problems: Problem[];
|
|
6
6
|
readonly fileTags: string[];
|
|
7
|
+
readonly fileTagSpans: Span[];
|
|
7
8
|
readonly usesGlobals = false;
|
|
8
9
|
private readonly file;
|
|
9
10
|
private readonly readModule;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CallExpression, Expression, Node } from 'oxc-parser';
|
|
2
|
-
import type { Adapter, ApiCall, CallContext, ModuleReader, Problem } from '../model.ts';
|
|
2
|
+
import type { Adapter, ApiCall, CallContext, ModuleReader, Problem, Span } from '../model.ts';
|
|
3
3
|
import type { ParsedFile } from '../parse.ts';
|
|
4
4
|
import { type FileContext, type Link } from './common.ts';
|
|
5
5
|
type Kind = 'test' | 'describe';
|
|
@@ -11,6 +11,7 @@ interface TestFunction {
|
|
|
11
11
|
export declare class VitestAdapter implements Adapter {
|
|
12
12
|
readonly problems: Problem[];
|
|
13
13
|
readonly fileTags: string[];
|
|
14
|
+
readonly fileTagSpans: Span[];
|
|
14
15
|
usesGlobals: boolean;
|
|
15
16
|
private readonly file;
|
|
16
17
|
private readonly readModule;
|
|
@@ -256,6 +256,7 @@ class VitestBindings {
|
|
|
256
256
|
export class VitestAdapter {
|
|
257
257
|
problems;
|
|
258
258
|
fileTags = [];
|
|
259
|
+
fileTagSpans = [];
|
|
259
260
|
usesGlobals = false;
|
|
260
261
|
file;
|
|
261
262
|
readModule;
|
|
@@ -293,8 +294,10 @@ export class VitestAdapter {
|
|
|
293
294
|
if (atLeast(file.version, 4, 1)) {
|
|
294
295
|
// Vitest's own pattern, over the whole text as Vitest reads it, so the same tags come out.
|
|
295
296
|
for (const match of parsed.source.text.matchAll(/(\/\/|\*)\s*@module-tag\s+([\w\-/]+)\b/g)) {
|
|
297
|
+
const span = { start: match.index, end: match.index + match[0].length };
|
|
296
298
|
this.fileTags.push(match[2]);
|
|
297
|
-
this.
|
|
299
|
+
this.fileTagSpans.push(span);
|
|
300
|
+
this.tagsUsed(span);
|
|
298
301
|
}
|
|
299
302
|
}
|
|
300
303
|
}
|
|
@@ -673,6 +676,7 @@ export class VitestAdapter {
|
|
|
673
676
|
states,
|
|
674
677
|
isOnly: flags.has('only'),
|
|
675
678
|
mode,
|
|
679
|
+
...(skips ? { skipPassedDown: passed.line } : {}),
|
|
676
680
|
details: read.details,
|
|
677
681
|
fn,
|
|
678
682
|
hashed: fn ?? namedFunction(this.file, context.scopes, body),
|
|
@@ -871,7 +875,7 @@ export class VitestAdapter {
|
|
|
871
875
|
if (this.warnedAboutTags)
|
|
872
876
|
return;
|
|
873
877
|
this.warnedAboutTags = true;
|
|
874
|
-
this.problems.push(problem('config-may-change-state', node,
|
|
878
|
+
this.problems.push(problem('config-may-change-state', node, "The file uses Vitest tags, and tags defined in the Vitest config can skip tests or change how they run; the scan can't work out the config's tags."));
|
|
875
879
|
}
|
|
876
880
|
}
|
|
877
881
|
/** Rows in a tagged-template table such as ``each`a | b ${1} | ${2}` ``: values divided by header columns. */
|
package/dist/index.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export { scanSource } from './scan-source.ts';
|
|
|
3
3
|
export { filterInventory, pickTestFields } from './filter.ts';
|
|
4
4
|
export type { InventoryFilter, PickedInventory } from './filter.ts';
|
|
5
5
|
export type { CommentsMode, ScanOptions, ScanSourceOptions } from './options.ts';
|
|
6
|
-
export type { Annotation, DeclaredAt, Diagnostic, DiagnosticCode, DiagnosticLevel, FileRecord, Framework, HookCounts, Inventory, InventoryLine, MetaValue, StateSource, SuiteRecord, Summary, TestRecord, TestState, Tool, } from './types.ts';
|
|
6
|
+
export type { Annotation, ConfigRecord, DeclaredAt, Diagnostic, DiagnosticCode, DiagnosticLevel, FileRecord, Framework, HookCounts, Inventory, InventoryLine, MetaValue, StateSource, SuiteRecord, Summary, TestRecord, TestState, Tool, } from './types.ts';
|
package/dist/inventory.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { FileRecords } from './records.ts';
|
|
2
|
-
import type { Diagnostic, Framework, Inventory } from './types.ts';
|
|
3
|
-
export declare function createInventory(framework: Framework, frameworkVersion: string | null, fileCount: number, files: readonly FileRecords[], projectDiagnostics: readonly Diagnostic[]): Inventory;
|
|
2
|
+
import type { ConfigRecord, Diagnostic, Framework, Inventory } from './types.ts';
|
|
3
|
+
export declare function createInventory(framework: Framework, frameworkVersion: string | null, fileCount: number, files: readonly FileRecords[], projectDiagnostics: readonly Diagnostic[], configs: ConfigRecord[]): Inventory;
|
package/dist/inventory.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { summarize } from "./summary.js";
|
|
2
2
|
import { toolVersion } from "./version.js";
|
|
3
|
-
export function createInventory(framework, frameworkVersion, fileCount, files, projectDiagnostics) {
|
|
3
|
+
export function createInventory(framework, frameworkVersion, fileCount, files, projectDiagnostics, configs) {
|
|
4
4
|
const suites = files.flatMap((file) => file.suites);
|
|
5
5
|
const tests = files.flatMap((file) => file.tests);
|
|
6
6
|
const diagnostics = [...projectDiagnostics, ...files.flatMap((file) => file.diagnostics)];
|
|
@@ -10,6 +10,7 @@ export function createInventory(framework, frameworkVersion, fileCount, files, p
|
|
|
10
10
|
framework,
|
|
11
11
|
frameworkVersion,
|
|
12
12
|
summary: summarize(fileCount, suites, tests, diagnostics),
|
|
13
|
+
configs,
|
|
13
14
|
files: files.map((file) => file.file),
|
|
14
15
|
suites,
|
|
15
16
|
tests,
|
package/dist/json.js
CHANGED
|
@@ -48,6 +48,8 @@ export async function writeInventoryLines(inventory, write) {
|
|
|
48
48
|
const line = (type, record) => emit(`${JSON.stringify({ type, ...record })}\n`);
|
|
49
49
|
const { schemaVersion, tool, framework, frameworkVersion } = inventory;
|
|
50
50
|
await line('inventory', { schemaVersion, tool, framework, frameworkVersion });
|
|
51
|
+
for (const config of inventory.configs)
|
|
52
|
+
await line('config', config);
|
|
51
53
|
for (const file of inventory.files)
|
|
52
54
|
await line('file', file);
|
|
53
55
|
for (const suite of inventory.suites)
|
package/dist/model.d.ts
CHANGED
|
@@ -11,7 +11,8 @@ export interface StateSetting {
|
|
|
11
11
|
reason: string | null;
|
|
12
12
|
/** The reason could not be worked out to a string, so `reason` holds its source text. */
|
|
13
13
|
hasDynamicReason: boolean;
|
|
14
|
-
line
|
|
14
|
+
/** The line in the file that sets the state; null for a state from the config. */
|
|
15
|
+
line: number | null;
|
|
15
16
|
/**
|
|
16
17
|
* Set by code in a test or hook body, which runs only when the test does: a state set while the file loads, on the
|
|
17
18
|
* test or a describe around it, keeps the test from getting there.
|
|
@@ -67,6 +68,8 @@ interface Declaration {
|
|
|
67
68
|
states: StateSetting[];
|
|
68
69
|
isOnly: boolean;
|
|
69
70
|
mode: Mode | null;
|
|
71
|
+
/** Vitest: the line of the describe whose `skip` option reaches this declaration, merged into its options. */
|
|
72
|
+
skipPassedDown?: number;
|
|
70
73
|
details: Details;
|
|
71
74
|
fn: FunctionNode | null;
|
|
72
75
|
/** The function whose code is hashed: `fn`, or a function declared in the file and passed by name. */
|
|
@@ -193,6 +196,8 @@ export interface Adapter {
|
|
|
193
196
|
problems: Problem[];
|
|
194
197
|
/** Tags that apply to every test in the file. */
|
|
195
198
|
fileTags: string[];
|
|
199
|
+
/** Where each of `fileTags` is written. */
|
|
200
|
+
fileTagSpans: Span[];
|
|
196
201
|
usesGlobals: boolean;
|
|
197
202
|
classify(call: CallExpression, context: CallContext): ApiCall | null;
|
|
198
203
|
/**
|
package/dist/options.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ export type { CommentsMode };
|
|
|
5
5
|
export interface ScanOptions {
|
|
6
6
|
/**
|
|
7
7
|
* Glob patterns for the test files, relative to `root`. As in Playwright and Vitest, they match names that start with
|
|
8
|
-
* a dot too.
|
|
8
|
+
* a dot too. Without them, the test files are those the configs in the root and the folders below it run.
|
|
9
9
|
*/
|
|
10
|
-
patterns
|
|
10
|
+
patterns?: string[];
|
|
11
11
|
framework: Framework;
|
|
12
12
|
/** The project root. Paths in the output are relative to it. Defaults to the current directory. */
|
|
13
13
|
root?: string;
|
package/dist/records.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Extraction } from './extract.ts';
|
|
2
|
+
import type { RunSettings } from './model.ts';
|
|
2
3
|
import type { ParsedFile } from './parse.ts';
|
|
3
|
-
import type { Diagnostic, FileRecord, Framework, HookCounts, SuiteRecord, TestRecord } from './types.ts';
|
|
4
|
+
import type { Diagnostic, FileRecord, Framework, HookCounts, MetaValue, SuiteRecord, TestRecord } from './types.ts';
|
|
4
5
|
/** @inline */
|
|
5
6
|
export type CommentsMode = 'all' | 'non-active' | 'none';
|
|
6
7
|
export interface FileRecords {
|
|
@@ -9,6 +10,57 @@ export interface FileRecords {
|
|
|
9
10
|
tests: TestRecord[];
|
|
10
11
|
diagnostics: Diagnostic[];
|
|
11
12
|
}
|
|
13
|
+
/** What the config the file uses sets for its tests, where the file sets nothing. */
|
|
14
|
+
export interface ConfigDefaults {
|
|
15
|
+
/** A run setting the config sets; null when its projects set different values or it depends on a condition. */
|
|
16
|
+
timeout?: number | null;
|
|
17
|
+
retry?: RunSettings['retry'] | null;
|
|
18
|
+
repeats?: number | null;
|
|
19
|
+
/** The source text of a run setting the config sets under a condition; null for any other. */
|
|
20
|
+
timeoutText: string | null;
|
|
21
|
+
retryText: string | null;
|
|
22
|
+
repeatsText: string | null;
|
|
23
|
+
/** Whether tests run in parallel unless the file says otherwise: Playwright's `fullyParallel`, Vitest's `sequence.concurrent`. */
|
|
24
|
+
parallel: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** What a Vitest tag the config defines sets on the tests that carry it. */
|
|
27
|
+
export interface TagOptions {
|
|
28
|
+
skip?: boolean;
|
|
29
|
+
only?: boolean;
|
|
30
|
+
todo?: boolean;
|
|
31
|
+
fails?: boolean;
|
|
32
|
+
concurrent?: boolean;
|
|
33
|
+
run: RunSettings;
|
|
34
|
+
meta?: Record<string, MetaValue>;
|
|
35
|
+
}
|
|
36
|
+
export interface TagDefinition {
|
|
37
|
+
name: string;
|
|
38
|
+
/** Lower numbers win when two tags set the same option; a tag without one loses to every tag with one. */
|
|
39
|
+
priority: number | null;
|
|
40
|
+
options: TagOptions;
|
|
41
|
+
}
|
|
42
|
+
/** The tags the Vitest config defines (Vitest 4.1). */
|
|
43
|
+
export interface VitestTags {
|
|
44
|
+
definitions: TagDefinition[];
|
|
45
|
+
/** `strictTags`: a tag the config doesn't define fails the file while it loads. */
|
|
46
|
+
isStrict: boolean;
|
|
47
|
+
/** From Vitest 5 a tag's options win over the describe's around the test; before, the describe's win. */
|
|
48
|
+
beatsDescribes: boolean;
|
|
49
|
+
/** Vitest 4.1 passes the config's `sequence.concurrent`, when it sets one, to every test, over a tag's `concurrent`. */
|
|
50
|
+
concurrentBeatsTags: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** What the config the file uses gives it. */
|
|
53
|
+
export interface FileConfig {
|
|
54
|
+
/** Whether a `.only` fails the run: Playwright's `forbidOnly`, always, never, or under the condition with this text. */
|
|
55
|
+
forbidOnly: boolean | string;
|
|
56
|
+
/** The names of the projects that run a test, null when unknown, and what they set for it. */
|
|
57
|
+
forTest(test: TestRecord, suites: SuiteRecord[]): {
|
|
58
|
+
projects: string[] | null;
|
|
59
|
+
defaults: ConfigDefaults | null;
|
|
60
|
+
};
|
|
61
|
+
/** Vitest's tags; null when the scan can't work them out, or the projects that run the file define different ones. */
|
|
62
|
+
tags: VitestTags | null;
|
|
63
|
+
}
|
|
12
64
|
interface RecordOptions {
|
|
13
65
|
relativeFilePath: string;
|
|
14
66
|
framework: Framework;
|
|
@@ -16,6 +68,7 @@ interface RecordOptions {
|
|
|
16
68
|
isTypeTest: boolean;
|
|
17
69
|
/** A Vitest 5 benchmark file, such as `*.bench.ts`. */
|
|
18
70
|
isBenchmarkFile: boolean;
|
|
71
|
+
config: FileConfig | null;
|
|
19
72
|
}
|
|
20
73
|
/** The record of a scanned file, from its records and the hooks at its top level. */
|
|
21
74
|
export declare function fileRecord(relativeFilePath: string, hooks: HookCounts, records: Pick<FileRecords, 'suites' | 'tests'>): FileRecord;
|