@vitest/runner 4.0.17 → 4.1.0-beta.2
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/dist/chunk-tasks.js +244 -3
- package/dist/index.d.ts +2 -4
- package/dist/index.js +141 -57
- package/dist/{tasks.d-C7UxawJ9.d.ts → tasks.d-CLPU8HE4.d.ts} +277 -14
- package/dist/types.d.ts +2 -182
- package/dist/utils.d.ts +8 -4
- package/dist/utils.js +1 -1
- package/package.json +2 -2
package/dist/chunk-tasks.js
CHANGED
|
@@ -34,7 +34,7 @@ function createChainable(keys, fn) {
|
|
|
34
34
|
/**
|
|
35
35
|
* If any tasks been marked as `only`, mark all other tasks as `skip`.
|
|
36
36
|
*/
|
|
37
|
-
function interpretTaskModes(file, namePattern, testLocations, onlyMode, parentIsOnly, allowOnly) {
|
|
37
|
+
function interpretTaskModes(file, namePattern, testLocations, testIds, testTagsFilter, onlyMode, parentIsOnly, allowOnly) {
|
|
38
38
|
const matchedLocations = [];
|
|
39
39
|
const traverseSuite = (suite, parentIsOnly, parentMatchedWithLocation) => {
|
|
40
40
|
const suiteIsOnly = parentIsOnly || suite.mode === "only";
|
|
@@ -60,7 +60,7 @@ function interpretTaskModes(file, namePattern, testLocations, onlyMode, parentIs
|
|
|
60
60
|
}
|
|
61
61
|
let hasLocationMatch = parentMatchedWithLocation;
|
|
62
62
|
// Match test location against provided locations, only run if present
|
|
63
|
-
// in `testLocations`. Note: if `
|
|
63
|
+
// in `testLocations`. Note: if `includeTaskLocation` is not enabled,
|
|
64
64
|
// all test will be skipped.
|
|
65
65
|
if (testLocations !== undefined && testLocations.length !== 0) {
|
|
66
66
|
if (t.location && (testLocations === null || testLocations === void 0 ? void 0 : testLocations.includes(t.location.line))) {
|
|
@@ -77,6 +77,12 @@ function interpretTaskModes(file, namePattern, testLocations, onlyMode, parentIs
|
|
|
77
77
|
if (namePattern && !getTaskFullName(t).match(namePattern)) {
|
|
78
78
|
t.mode = "skip";
|
|
79
79
|
}
|
|
80
|
+
if (testIds && !testIds.includes(t.id)) {
|
|
81
|
+
t.mode = "skip";
|
|
82
|
+
}
|
|
83
|
+
if (testTagsFilter && !testTagsFilter(t.tags || [])) {
|
|
84
|
+
t.mode = "skip";
|
|
85
|
+
}
|
|
80
86
|
} else if (t.type === "suite") {
|
|
81
87
|
if (t.mode === "skip") {
|
|
82
88
|
skipAllTasks(t);
|
|
@@ -274,6 +280,241 @@ function partitionSuiteChildren(suite) {
|
|
|
274
280
|
return tasksGroups;
|
|
275
281
|
}
|
|
276
282
|
|
|
283
|
+
function validateTags(config, tags) {
|
|
284
|
+
if (!config.strictTags) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const availableTags = new Set(config.tags.map((tag) => tag.name));
|
|
288
|
+
for (const tag of tags) {
|
|
289
|
+
if (!availableTags.has(tag)) {
|
|
290
|
+
throw createNoTagsError(config.tags, tag);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function createNoTagsError(availableTags, tag, prefix = "tag") {
|
|
295
|
+
if (!availableTags.length) {
|
|
296
|
+
throw new Error(`The Vitest config does't define any "tags", cannot apply "${tag}" ${prefix} for this test. See: https://vitest.dev/guide/test-tags`);
|
|
297
|
+
}
|
|
298
|
+
throw new Error(`The ${prefix} "${tag}" is not defined in the configuration. Available tags are:\n${availableTags.map((t) => `- ${t.name}${t.description ? `: ${t.description}` : ""}`).join("\n")}`);
|
|
299
|
+
}
|
|
300
|
+
function createTagsFilter(tagsExpr, availableTags) {
|
|
301
|
+
const matchers = tagsExpr.map((expr) => parseTagsExpression(expr, availableTags));
|
|
302
|
+
return (testTags) => {
|
|
303
|
+
return matchers.every((matcher) => matcher(testTags));
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function parseTagsExpression(expr, availableTags) {
|
|
307
|
+
const tokens = tokenize(expr);
|
|
308
|
+
const stream = new TokenStream(tokens, expr);
|
|
309
|
+
const ast = parseOrExpression(stream, availableTags);
|
|
310
|
+
if (stream.peek().type !== "EOF") {
|
|
311
|
+
throw new Error(`Invalid tags expression: unexpected "${formatToken(stream.peek())}" in "${expr}"`);
|
|
312
|
+
}
|
|
313
|
+
return (tags) => evaluateNode(ast, tags);
|
|
314
|
+
}
|
|
315
|
+
function formatToken(token) {
|
|
316
|
+
switch (token.type) {
|
|
317
|
+
case "TAG": return token.value;
|
|
318
|
+
default: return formatTokenType(token.type);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function tokenize(expr) {
|
|
322
|
+
const tokens = [];
|
|
323
|
+
let i = 0;
|
|
324
|
+
while (i < expr.length) {
|
|
325
|
+
if (expr[i] === " " || expr[i] === " ") {
|
|
326
|
+
i++;
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (expr[i] === "(") {
|
|
330
|
+
tokens.push({ type: "LPAREN" });
|
|
331
|
+
i++;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (expr[i] === ")") {
|
|
335
|
+
tokens.push({ type: "RPAREN" });
|
|
336
|
+
i++;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (expr[i] === "!") {
|
|
340
|
+
tokens.push({ type: "NOT" });
|
|
341
|
+
i++;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (expr.slice(i, i + 2) === "&&") {
|
|
345
|
+
tokens.push({ type: "AND" });
|
|
346
|
+
i += 2;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
if (expr.slice(i, i + 2) === "||") {
|
|
350
|
+
tokens.push({ type: "OR" });
|
|
351
|
+
i += 2;
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
if (/^and(?:\s|\)|$)/i.test(expr.slice(i))) {
|
|
355
|
+
tokens.push({ type: "AND" });
|
|
356
|
+
i += 3;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (/^or(?:\s|\)|$)/i.test(expr.slice(i))) {
|
|
360
|
+
tokens.push({ type: "OR" });
|
|
361
|
+
i += 2;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (/^not\s/i.test(expr.slice(i))) {
|
|
365
|
+
tokens.push({ type: "NOT" });
|
|
366
|
+
i += 3;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
let tag = "";
|
|
370
|
+
while (i < expr.length && expr[i] !== " " && expr[i] !== " " && expr[i] !== "(" && expr[i] !== ")" && expr[i] !== "!" && expr[i] !== "&" && expr[i] !== "|") {
|
|
371
|
+
const remaining = expr.slice(i);
|
|
372
|
+
// Only treat and/or/not as operators if we're at the start of a tag (after whitespace)
|
|
373
|
+
// This allows tags like "demand", "editor", "cannot" to work correctly
|
|
374
|
+
if (tag === "" && (/^and(?:\s|\)|$)/i.test(remaining) || /^or(?:\s|\)|$)/i.test(remaining) || /^not\s/i.test(remaining))) {
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
tag += expr[i];
|
|
378
|
+
i++;
|
|
379
|
+
}
|
|
380
|
+
if (tag) {
|
|
381
|
+
tokens.push({
|
|
382
|
+
type: "TAG",
|
|
383
|
+
value: tag
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
tokens.push({ type: "EOF" });
|
|
388
|
+
return tokens;
|
|
389
|
+
}
|
|
390
|
+
class TokenStream {
|
|
391
|
+
pos = 0;
|
|
392
|
+
constructor(tokens, expr) {
|
|
393
|
+
this.tokens = tokens;
|
|
394
|
+
this.expr = expr;
|
|
395
|
+
}
|
|
396
|
+
peek() {
|
|
397
|
+
return this.tokens[this.pos];
|
|
398
|
+
}
|
|
399
|
+
next() {
|
|
400
|
+
return this.tokens[this.pos++];
|
|
401
|
+
}
|
|
402
|
+
expect(type) {
|
|
403
|
+
const token = this.next();
|
|
404
|
+
if (token.type !== type) {
|
|
405
|
+
if (type === "RPAREN" && token.type === "EOF") {
|
|
406
|
+
throw new Error(`Invalid tags expression: missing closing ")" in "${this.expr}"`);
|
|
407
|
+
}
|
|
408
|
+
throw new Error(`Invalid tags expression: expected "${formatTokenType(type)}" but got "${formatToken(token)}" in "${this.expr}"`);
|
|
409
|
+
}
|
|
410
|
+
return token;
|
|
411
|
+
}
|
|
412
|
+
unexpectedToken() {
|
|
413
|
+
const token = this.peek();
|
|
414
|
+
if (token.type === "EOF") {
|
|
415
|
+
throw new Error(`Invalid tags expression: unexpected end of expression in "${this.expr}"`);
|
|
416
|
+
}
|
|
417
|
+
throw new Error(`Invalid tags expression: unexpected "${formatToken(token)}" in "${this.expr}"`);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function formatTokenType(type) {
|
|
421
|
+
switch (type) {
|
|
422
|
+
case "TAG": return "tag";
|
|
423
|
+
case "AND": return "and";
|
|
424
|
+
case "OR": return "or";
|
|
425
|
+
case "NOT": return "not";
|
|
426
|
+
case "LPAREN": return "(";
|
|
427
|
+
case "RPAREN": return ")";
|
|
428
|
+
case "EOF": return "end of expression";
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function parseOrExpression(stream, availableTags) {
|
|
432
|
+
let left = parseAndExpression(stream, availableTags);
|
|
433
|
+
while (stream.peek().type === "OR") {
|
|
434
|
+
stream.next();
|
|
435
|
+
const right = parseAndExpression(stream, availableTags);
|
|
436
|
+
left = {
|
|
437
|
+
type: "or",
|
|
438
|
+
left,
|
|
439
|
+
right
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
return left;
|
|
443
|
+
}
|
|
444
|
+
function parseAndExpression(stream, availableTags) {
|
|
445
|
+
let left = parseUnaryExpression(stream, availableTags);
|
|
446
|
+
while (stream.peek().type === "AND") {
|
|
447
|
+
stream.next();
|
|
448
|
+
const right = parseUnaryExpression(stream, availableTags);
|
|
449
|
+
left = {
|
|
450
|
+
type: "and",
|
|
451
|
+
left,
|
|
452
|
+
right
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
return left;
|
|
456
|
+
}
|
|
457
|
+
function parseUnaryExpression(stream, availableTags) {
|
|
458
|
+
if (stream.peek().type === "NOT") {
|
|
459
|
+
stream.next();
|
|
460
|
+
const operand = parseUnaryExpression(stream, availableTags);
|
|
461
|
+
return {
|
|
462
|
+
type: "not",
|
|
463
|
+
operand
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
return parsePrimaryExpression(stream, availableTags);
|
|
467
|
+
}
|
|
468
|
+
function parsePrimaryExpression(stream, availableTags) {
|
|
469
|
+
const token = stream.peek();
|
|
470
|
+
if (token.type === "LPAREN") {
|
|
471
|
+
stream.next();
|
|
472
|
+
const expr = parseOrExpression(stream, availableTags);
|
|
473
|
+
stream.expect("RPAREN");
|
|
474
|
+
return expr;
|
|
475
|
+
}
|
|
476
|
+
if (token.type === "TAG") {
|
|
477
|
+
stream.next();
|
|
478
|
+
const tagValue = token.value;
|
|
479
|
+
const pattern = resolveTagPattern(tagValue, availableTags);
|
|
480
|
+
return {
|
|
481
|
+
type: "tag",
|
|
482
|
+
value: tagValue,
|
|
483
|
+
pattern
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
stream.unexpectedToken();
|
|
487
|
+
}
|
|
488
|
+
function createWildcardRegex(pattern) {
|
|
489
|
+
return new RegExp(`^${pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")}$`);
|
|
490
|
+
}
|
|
491
|
+
function resolveTagPattern(tagPattern, availableTags) {
|
|
492
|
+
if (tagPattern.includes("*")) {
|
|
493
|
+
const regex = createWildcardRegex(tagPattern);
|
|
494
|
+
const hasMatch = availableTags.some((tag) => regex.test(tag.name));
|
|
495
|
+
if (!hasMatch) {
|
|
496
|
+
throw createNoTagsError(availableTags, tagPattern, "tag pattern");
|
|
497
|
+
}
|
|
498
|
+
return regex;
|
|
499
|
+
}
|
|
500
|
+
if (!availableTags.length || !availableTags.some((tag) => tag.name === tagPattern)) {
|
|
501
|
+
throw createNoTagsError(availableTags, tagPattern, "tag pattern");
|
|
502
|
+
}
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
function evaluateNode(node, tags) {
|
|
506
|
+
switch (node.type) {
|
|
507
|
+
case "tag":
|
|
508
|
+
if (node.pattern) {
|
|
509
|
+
return tags.some((tag) => node.pattern.test(tag));
|
|
510
|
+
}
|
|
511
|
+
return tags.includes(node.value);
|
|
512
|
+
case "not": return !evaluateNode(node.operand, tags);
|
|
513
|
+
case "and": return evaluateNode(node.left, tags) && evaluateNode(node.right, tags);
|
|
514
|
+
case "or": return evaluateNode(node.left, tags) || evaluateNode(node.right, tags);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
277
518
|
function isTestCase(s) {
|
|
278
519
|
return s.type === "test";
|
|
279
520
|
}
|
|
@@ -337,4 +578,4 @@ function createTaskName(names, separator = " > ") {
|
|
|
337
578
|
return names.filter((name) => name !== undefined).join(separator);
|
|
338
579
|
}
|
|
339
580
|
|
|
340
|
-
export { calculateSuiteHash as a, createFileTask as b, createChainable as c, generateHash as d,
|
|
581
|
+
export { calculateSuiteHash as a, createFileTask as b, createChainable as c, generateHash as d, createTagsFilter as e, findTestFileStackTrace as f, generateFileHash as g, createTaskName as h, interpretTaskModes as i, getFullName as j, getNames as k, limitConcurrency as l, getSuites as m, getTasks as n, getTestName as o, partitionSuiteChildren as p, getTests as q, hasFailed as r, someTasksAreOnly as s, hasTests as t, isTestCase as u, validateTags as v, createNoTagsError as w };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as AfterAllListener,
|
|
1
|
+
import { T as TestArtifact, a as Test, S as Suite, b as SuiteHooks, F as FileSpecification, V as VitestRunner, c as File, d as TaskUpdateEvent, e as Task, f as TestAPI, g as SuiteAPI, h as SuiteCollector } from './tasks.d-CLPU8HE4.js';
|
|
2
|
+
export { A as AfterAllListener, s as AfterEachListener, B as BeforeAllListener, t as BeforeEachListener, C as CancelReason, u as Fixture, v as FixtureFn, w as FixtureOptions, x as Fixtures, I as ImportDuration, y as InferFixturesTypes, O as OnTestFailedHandler, z as OnTestFinishedHandler, R as Retry, D as RunMode, E as RuntimeContext, G as SequenceHooks, H as SequenceSetupFiles, J as SerializableRetry, K as SuiteFactory, L as TaskBase, M as TaskCustomOptions, N as TaskEventPack, P as TaskHook, Q as TaskMeta, U as TaskPopulated, W as TaskResult, X as TaskResultPack, Y as TaskState, Z as TestAnnotation, _ as TestAnnotationArtifact, $ as TestAnnotationLocation, a0 as TestArtifactBase, a1 as TestArtifactLocation, a2 as TestArtifactRegistry, a3 as TestAttachment, a4 as TestContext, a5 as TestFunction, a6 as TestOptions, n as TestTagDefinition, a7 as TestTags, a8 as Use, a9 as VisualRegressionArtifact, p as VitestRunnerConfig, q as VitestRunnerConstructor, r as VitestRunnerImportSource, i as afterAll, j as afterEach, k as beforeAll, l as beforeEach, o as onTestFailed, m as onTestFinished } from './tasks.d-CLPU8HE4.js';
|
|
3
3
|
import { Awaitable } from '@vitest/utils';
|
|
4
|
-
import { FileSpecification, VitestRunner } from './types.js';
|
|
5
|
-
export { CancelReason, VitestRunnerConfig, VitestRunnerConstructor, VitestRunnerImportSource } from './types.js';
|
|
6
4
|
import '@vitest/utils/diff';
|
|
7
5
|
|
|
8
6
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { processError } from '@vitest/utils/error';
|
|
2
|
-
import { isObject, createDefer, assertTypes, toArray, isNegativeNaN, objectAttr, shuffle } from '@vitest/utils/helpers';
|
|
2
|
+
import { isObject, filterOutComments, createDefer, assertTypes, toArray, isNegativeNaN, unique, objectAttr, shuffle } from '@vitest/utils/helpers';
|
|
3
3
|
import { getSafeTimers } from '@vitest/utils/timers';
|
|
4
4
|
import { format, formatRegExp, objDisplay } from '@vitest/utils/display';
|
|
5
|
-
import { c as createChainable,
|
|
5
|
+
import { c as createChainable, v as validateTags, h as createTaskName, w as createNoTagsError, f as findTestFileStackTrace, e as createTagsFilter, b as createFileTask, a as calculateSuiteHash, s as someTasksAreOnly, i as interpretTaskModes, l as limitConcurrency, p as partitionSuiteChildren, t as hasTests, r as hasFailed } from './chunk-tasks.js';
|
|
6
6
|
import '@vitest/utils/source-map';
|
|
7
7
|
import 'pathe';
|
|
8
8
|
|
|
@@ -311,31 +311,6 @@ function getUsedProps(fn) {
|
|
|
311
311
|
}
|
|
312
312
|
return props;
|
|
313
313
|
}
|
|
314
|
-
function filterOutComments(s) {
|
|
315
|
-
const result = [];
|
|
316
|
-
let commentState = "none";
|
|
317
|
-
for (let i = 0; i < s.length; ++i) {
|
|
318
|
-
if (commentState === "singleline") {
|
|
319
|
-
if (s[i] === "\n") {
|
|
320
|
-
commentState = "none";
|
|
321
|
-
}
|
|
322
|
-
} else if (commentState === "multiline") {
|
|
323
|
-
if (s[i - 1] === "*" && s[i] === "/") {
|
|
324
|
-
commentState = "none";
|
|
325
|
-
}
|
|
326
|
-
} else if (commentState === "none") {
|
|
327
|
-
if (s[i] === "/" && s[i + 1] === "/") {
|
|
328
|
-
commentState = "singleline";
|
|
329
|
-
} else if (s[i] === "/" && s[i + 1] === "*") {
|
|
330
|
-
commentState = "multiline";
|
|
331
|
-
i += 2;
|
|
332
|
-
} else {
|
|
333
|
-
result.push(s[i]);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return result.join("");
|
|
338
|
-
}
|
|
339
314
|
function splitByComma(s) {
|
|
340
315
|
const result = [];
|
|
341
316
|
const stack = [];
|
|
@@ -693,18 +668,22 @@ function getRunner() {
|
|
|
693
668
|
}
|
|
694
669
|
function createDefaultSuite(runner) {
|
|
695
670
|
const config = runner.config.sequence;
|
|
696
|
-
const
|
|
671
|
+
const options = {};
|
|
672
|
+
if (config.concurrent != null) {
|
|
673
|
+
options.concurrent = config.concurrent;
|
|
674
|
+
}
|
|
675
|
+
const collector = suite("", options, () => {});
|
|
697
676
|
// no parent suite for top-level tests
|
|
698
677
|
delete collector.suite;
|
|
699
678
|
return collector;
|
|
700
679
|
}
|
|
701
680
|
function clearCollectorContext(file, currentRunner) {
|
|
681
|
+
currentTestFilepath = file.filepath;
|
|
682
|
+
runner = currentRunner;
|
|
702
683
|
if (!defaultSuite) {
|
|
703
684
|
defaultSuite = createDefaultSuite(currentRunner);
|
|
704
685
|
}
|
|
705
686
|
defaultSuite.file = file;
|
|
706
|
-
runner = currentRunner;
|
|
707
|
-
currentTestFilepath = file.filepath;
|
|
708
687
|
collectorContext.tasks.length = 0;
|
|
709
688
|
defaultSuite.clear();
|
|
710
689
|
collectorContext.currentSuite = defaultSuite;
|
|
@@ -722,6 +701,7 @@ function createSuiteHooks() {
|
|
|
722
701
|
afterEach: []
|
|
723
702
|
};
|
|
724
703
|
}
|
|
704
|
+
const POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
|
|
725
705
|
function parseArguments(optionsOrFn, timeoutOrTest) {
|
|
726
706
|
if (timeoutOrTest != null && typeof timeoutOrTest === "object") {
|
|
727
707
|
throw new TypeError(`Signature "test(name, fn, { ... })" was deprecated in Vitest 3 and removed in Vitest 4. Please, provide options as a second argument instead.`);
|
|
@@ -753,27 +733,47 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
|
|
|
753
733
|
let suite;
|
|
754
734
|
initSuite(true);
|
|
755
735
|
const task = function(name = "", options = {}) {
|
|
756
|
-
var _collectorContext$cur, _collectorContext$cur2, _collectorContext$cur3;
|
|
757
|
-
const timeout = (options === null || options === void 0 ? void 0 : options.timeout) ?? runner.config.testTimeout;
|
|
736
|
+
var _collectorContext$cur, _collectorContext$cur2, _collectorContext$cur3, _collectorContext$cur4;
|
|
758
737
|
const currentSuite = (_collectorContext$cur = collectorContext.currentSuite) === null || _collectorContext$cur === void 0 ? void 0 : _collectorContext$cur.suite;
|
|
738
|
+
const parentTask = currentSuite ?? ((_collectorContext$cur2 = collectorContext.currentSuite) === null || _collectorContext$cur2 === void 0 ? void 0 : _collectorContext$cur2.file);
|
|
739
|
+
const parentTags = (parentTask === null || parentTask === void 0 ? void 0 : parentTask.tags) || [];
|
|
740
|
+
const testTags = unique([...parentTags, ...toArray(options.tags)]);
|
|
741
|
+
const tagsOptions = testTags.map((tag) => {
|
|
742
|
+
var _runner$config$tags;
|
|
743
|
+
const tagDefinition = (_runner$config$tags = runner.config.tags) === null || _runner$config$tags === void 0 ? void 0 : _runner$config$tags.find((t) => t.name === tag);
|
|
744
|
+
if (!tagDefinition && runner.config.strictTags) {
|
|
745
|
+
throw createNoTagsError(runner.config.tags, tag);
|
|
746
|
+
}
|
|
747
|
+
return tagDefinition;
|
|
748
|
+
}).filter((r) => r != null).sort((tag1, tag2) => (tag2.priority ?? POSITIVE_INFINITY) - (tag1.priority ?? POSITIVE_INFINITY)).reduce((acc, tag) => {
|
|
749
|
+
const { name, description, priority, ...options } = tag;
|
|
750
|
+
Object.assign(acc, options);
|
|
751
|
+
return acc;
|
|
752
|
+
}, {});
|
|
753
|
+
options = {
|
|
754
|
+
...tagsOptions,
|
|
755
|
+
...options
|
|
756
|
+
};
|
|
757
|
+
const timeout = options.timeout ?? runner.config.testTimeout;
|
|
759
758
|
const task = {
|
|
760
759
|
id: "",
|
|
761
760
|
name,
|
|
762
|
-
fullName: createTaskName([(currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fullName) ?? ((_collectorContext$
|
|
761
|
+
fullName: createTaskName([(currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fullName) ?? ((_collectorContext$cur3 = collectorContext.currentSuite) === null || _collectorContext$cur3 === void 0 || (_collectorContext$cur3 = _collectorContext$cur3.file) === null || _collectorContext$cur3 === void 0 ? void 0 : _collectorContext$cur3.fullName), name]),
|
|
763
762
|
fullTestName: createTaskName([currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fullTestName, name]),
|
|
764
763
|
suite: currentSuite,
|
|
765
764
|
each: options.each,
|
|
766
765
|
fails: options.fails,
|
|
767
766
|
context: undefined,
|
|
768
767
|
type: "test",
|
|
769
|
-
file: (currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.file) ?? ((_collectorContext$
|
|
768
|
+
file: (currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.file) ?? ((_collectorContext$cur4 = collectorContext.currentSuite) === null || _collectorContext$cur4 === void 0 ? void 0 : _collectorContext$cur4.file),
|
|
770
769
|
timeout,
|
|
771
770
|
retry: options.retry ?? runner.config.retry,
|
|
772
771
|
repeats: options.repeats,
|
|
773
772
|
mode: options.only ? "only" : options.skip ? "skip" : options.todo ? "todo" : "run",
|
|
774
773
|
meta: options.meta ?? Object.create(null),
|
|
775
774
|
annotations: [],
|
|
776
|
-
artifacts: []
|
|
775
|
+
artifacts: [],
|
|
776
|
+
tags: testTags
|
|
777
777
|
};
|
|
778
778
|
const handler = options.handler;
|
|
779
779
|
if (task.mode === "run" && !handler) {
|
|
@@ -818,8 +818,14 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
|
|
|
818
818
|
options = Object.assign({}, suiteOptions, options);
|
|
819
819
|
}
|
|
820
820
|
// inherit concurrent / sequential from suite
|
|
821
|
-
|
|
822
|
-
options.
|
|
821
|
+
const concurrent = this.concurrent ?? (!this.sequential && (options === null || options === void 0 ? void 0 : options.concurrent));
|
|
822
|
+
if (options.concurrent != null && concurrent != null) {
|
|
823
|
+
options.concurrent = concurrent;
|
|
824
|
+
}
|
|
825
|
+
const sequential = this.sequential ?? (!this.concurrent && (options === null || options === void 0 ? void 0 : options.sequential));
|
|
826
|
+
if (options.sequential != null && sequential != null) {
|
|
827
|
+
options.sequential = sequential;
|
|
828
|
+
}
|
|
823
829
|
const test = task(formatName(name), {
|
|
824
830
|
...this,
|
|
825
831
|
...options,
|
|
@@ -854,25 +860,29 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
|
|
|
854
860
|
getHooks(suite)[name].push(...fn);
|
|
855
861
|
}
|
|
856
862
|
function initSuite(includeLocation) {
|
|
857
|
-
var _collectorContext$
|
|
863
|
+
var _collectorContext$cur5, _collectorContext$cur6, _collectorContext$cur7, _collectorContext$cur8;
|
|
858
864
|
if (typeof suiteOptions === "number") {
|
|
859
865
|
suiteOptions = { timeout: suiteOptions };
|
|
860
866
|
}
|
|
861
|
-
const currentSuite = (_collectorContext$
|
|
867
|
+
const currentSuite = (_collectorContext$cur5 = collectorContext.currentSuite) === null || _collectorContext$cur5 === void 0 ? void 0 : _collectorContext$cur5.suite;
|
|
868
|
+
const parentTask = currentSuite ?? ((_collectorContext$cur6 = collectorContext.currentSuite) === null || _collectorContext$cur6 === void 0 ? void 0 : _collectorContext$cur6.file);
|
|
869
|
+
const suiteTags = toArray(suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.tags);
|
|
870
|
+
validateTags(runner.config, suiteTags);
|
|
862
871
|
suite = {
|
|
863
872
|
id: "",
|
|
864
873
|
type: "suite",
|
|
865
874
|
name,
|
|
866
|
-
fullName: createTaskName([(currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fullName) ?? ((_collectorContext$
|
|
875
|
+
fullName: createTaskName([(currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fullName) ?? ((_collectorContext$cur7 = collectorContext.currentSuite) === null || _collectorContext$cur7 === void 0 || (_collectorContext$cur7 = _collectorContext$cur7.file) === null || _collectorContext$cur7 === void 0 ? void 0 : _collectorContext$cur7.fullName), name]),
|
|
867
876
|
fullTestName: createTaskName([currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fullTestName, name]),
|
|
868
877
|
suite: currentSuite,
|
|
869
878
|
mode,
|
|
870
879
|
each,
|
|
871
|
-
file: (currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.file) ?? ((_collectorContext$
|
|
880
|
+
file: (currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.file) ?? ((_collectorContext$cur8 = collectorContext.currentSuite) === null || _collectorContext$cur8 === void 0 ? void 0 : _collectorContext$cur8.file),
|
|
872
881
|
shuffle: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.shuffle,
|
|
873
882
|
tasks: [],
|
|
874
883
|
meta: Object.create(null),
|
|
875
|
-
concurrent: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.concurrent
|
|
884
|
+
concurrent: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.concurrent,
|
|
885
|
+
tags: unique([...(parentTask === null || parentTask === void 0 ? void 0 : parentTask.tags) || [], ...suiteTags])
|
|
876
886
|
};
|
|
877
887
|
if (runner && includeLocation && runner.config.includeTaskLocation) {
|
|
878
888
|
const limit = Error.stackTraceLimit;
|
|
@@ -930,25 +940,33 @@ function createSuite() {
|
|
|
930
940
|
if (getCurrentTest()) {
|
|
931
941
|
throw new Error("Calling the suite function inside test function is not allowed. It can be only called at the top level or inside another suite function.");
|
|
932
942
|
}
|
|
933
|
-
let mode = this.only ? "only" : this.skip ? "skip" : this.todo ? "todo" : "run";
|
|
934
943
|
const currentSuite = collectorContext.currentSuite || defaultSuite;
|
|
935
944
|
let { options, handler: factory } = parseArguments(factoryOrOptions, optionsOrFactory);
|
|
936
|
-
if (mode === "run" && !factory) {
|
|
937
|
-
mode = "todo";
|
|
938
|
-
}
|
|
939
945
|
const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false;
|
|
940
946
|
const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false;
|
|
941
947
|
// inherit options from current suite
|
|
942
948
|
options = {
|
|
943
949
|
...currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.options,
|
|
944
|
-
...options
|
|
945
|
-
shuffle: this.shuffle ?? options.shuffle ?? (currentSuite === null || currentSuite === void 0 || (_currentSuite$options = currentSuite.options) === null || _currentSuite$options === void 0 ? void 0 : _currentSuite$options.shuffle) ?? (runner === null || runner === void 0 ? void 0 : runner.config.sequence.shuffle)
|
|
950
|
+
...options
|
|
946
951
|
};
|
|
952
|
+
const shuffle = this.shuffle ?? options.shuffle ?? (currentSuite === null || currentSuite === void 0 || (_currentSuite$options = currentSuite.options) === null || _currentSuite$options === void 0 ? void 0 : _currentSuite$options.shuffle) ?? (runner === null || runner === void 0 ? void 0 : runner.config.sequence.shuffle);
|
|
953
|
+
if (shuffle != null) {
|
|
954
|
+
options.shuffle = shuffle;
|
|
955
|
+
}
|
|
956
|
+
let mode = this.only ?? options.only ? "only" : this.skip ?? options.skip ? "skip" : this.todo ?? options.todo ? "todo" : "run";
|
|
957
|
+
// passed as test(name), assume it's a "todo"
|
|
958
|
+
if (mode === "run" && !factory) {
|
|
959
|
+
mode = "todo";
|
|
960
|
+
}
|
|
947
961
|
// inherit concurrent / sequential from suite
|
|
948
962
|
const isConcurrent = isConcurrentSpecified || options.concurrent && !isSequentialSpecified;
|
|
949
963
|
const isSequential = isSequentialSpecified || options.sequential && !isConcurrentSpecified;
|
|
950
|
-
|
|
951
|
-
|
|
964
|
+
if (isConcurrent != null) {
|
|
965
|
+
options.concurrent = isConcurrent && !isSequential;
|
|
966
|
+
}
|
|
967
|
+
if (isSequential != null) {
|
|
968
|
+
options.sequential = isSequential && !isConcurrent;
|
|
969
|
+
}
|
|
952
970
|
return createSuiteCollector(formatName(name), factory, mode, this.each, options, currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fixtures());
|
|
953
971
|
}
|
|
954
972
|
suiteFn.each = function(cases, ...args) {
|
|
@@ -1360,18 +1378,24 @@ async function collectTests(specs, runner) {
|
|
|
1360
1378
|
const files = [];
|
|
1361
1379
|
const config = runner.config;
|
|
1362
1380
|
const $ = runner.trace;
|
|
1381
|
+
let defaultTagsFilter;
|
|
1363
1382
|
for (const spec of specs) {
|
|
1364
1383
|
const filepath = typeof spec === "string" ? spec : spec.filepath;
|
|
1365
1384
|
await $("collect_spec", { "code.file.path": filepath }, async () => {
|
|
1366
|
-
var _runner$onCollectStar;
|
|
1367
1385
|
const testLocations = typeof spec === "string" ? undefined : spec.testLocations;
|
|
1386
|
+
const testNamePattern = typeof spec === "string" ? undefined : spec.testNamePattern;
|
|
1387
|
+
const testIds = typeof spec === "string" ? undefined : spec.testIds;
|
|
1388
|
+
const testTagsFilter = typeof spec === "object" && spec.testTagsFilter ? createTagsFilter(spec.testTagsFilter, config.tags) : undefined;
|
|
1389
|
+
const fileTags = typeof spec === "string" ? [] : spec.fileTags || [];
|
|
1368
1390
|
const file = createFileTask(filepath, config.root, config.name, runner.pool, runner.viteEnvironment);
|
|
1369
1391
|
setFileContext(file, Object.create(null));
|
|
1392
|
+
file.tags = fileTags;
|
|
1370
1393
|
file.shuffle = config.sequence.shuffle;
|
|
1371
|
-
(_runner$onCollectStar = runner.onCollectStart) === null || _runner$onCollectStar === void 0 ? void 0 : _runner$onCollectStar.call(runner, file);
|
|
1372
|
-
clearCollectorContext(file, runner);
|
|
1373
1394
|
try {
|
|
1374
|
-
var _runner$getImportDura;
|
|
1395
|
+
var _runner$onCollectStar, _runner$getImportDura;
|
|
1396
|
+
validateTags(runner.config, fileTags);
|
|
1397
|
+
(_runner$onCollectStar = runner.onCollectStart) === null || _runner$onCollectStar === void 0 ? void 0 : _runner$onCollectStar.call(runner, file);
|
|
1398
|
+
clearCollectorContext(file, runner);
|
|
1375
1399
|
const setupFiles = toArray(config.setupFiles);
|
|
1376
1400
|
if (setupFiles.length) {
|
|
1377
1401
|
const setupStart = now$1();
|
|
@@ -1420,7 +1444,10 @@ async function collectTests(specs, runner) {
|
|
|
1420
1444
|
}
|
|
1421
1445
|
calculateSuiteHash(file);
|
|
1422
1446
|
const hasOnlyTasks = someTasksAreOnly(file);
|
|
1423
|
-
|
|
1447
|
+
if (!testTagsFilter && !defaultTagsFilter && config.tagsFilter) {
|
|
1448
|
+
defaultTagsFilter = createTagsFilter(config.tagsFilter, config.tags);
|
|
1449
|
+
}
|
|
1450
|
+
interpretTaskModes(file, testNamePattern ?? config.testNamePattern, testLocations, testIds, testTagsFilter ?? defaultTagsFilter, hasOnlyTasks, false, config.allowOnly);
|
|
1424
1451
|
if (file.mode === "queued") {
|
|
1425
1452
|
file.mode = "run";
|
|
1426
1453
|
}
|
|
@@ -1440,6 +1467,37 @@ function mergeHooks(baseHooks, hooks) {
|
|
|
1440
1467
|
const now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
|
|
1441
1468
|
const unixNow = Date.now;
|
|
1442
1469
|
const { clearTimeout, setTimeout } = getSafeTimers();
|
|
1470
|
+
/**
|
|
1471
|
+
* Normalizes retry configuration to extract individual values.
|
|
1472
|
+
* Handles both number and object forms.
|
|
1473
|
+
*/
|
|
1474
|
+
function getRetryCount(retry) {
|
|
1475
|
+
if (retry === undefined) {
|
|
1476
|
+
return 0;
|
|
1477
|
+
}
|
|
1478
|
+
if (typeof retry === "number") {
|
|
1479
|
+
return retry;
|
|
1480
|
+
}
|
|
1481
|
+
return retry.count ?? 0;
|
|
1482
|
+
}
|
|
1483
|
+
function getRetryDelay(retry) {
|
|
1484
|
+
if (retry === undefined) {
|
|
1485
|
+
return 0;
|
|
1486
|
+
}
|
|
1487
|
+
if (typeof retry === "number") {
|
|
1488
|
+
return 0;
|
|
1489
|
+
}
|
|
1490
|
+
return retry.delay ?? 0;
|
|
1491
|
+
}
|
|
1492
|
+
function getRetryCondition(retry) {
|
|
1493
|
+
if (retry === undefined) {
|
|
1494
|
+
return undefined;
|
|
1495
|
+
}
|
|
1496
|
+
if (typeof retry === "number") {
|
|
1497
|
+
return undefined;
|
|
1498
|
+
}
|
|
1499
|
+
return retry.condition;
|
|
1500
|
+
}
|
|
1443
1501
|
function updateSuiteHookState(task, name, state, runner) {
|
|
1444
1502
|
if (!task.result) {
|
|
1445
1503
|
task.result = { state: "run" };
|
|
@@ -1603,6 +1661,25 @@ async function callCleanupHooks(runner, cleanups) {
|
|
|
1603
1661
|
}
|
|
1604
1662
|
}
|
|
1605
1663
|
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Determines if a test should be retried based on its retryCondition configuration
|
|
1666
|
+
*/
|
|
1667
|
+
function passesRetryCondition(test, errors) {
|
|
1668
|
+
const condition = getRetryCondition(test.retry);
|
|
1669
|
+
if (!errors || errors.length === 0) {
|
|
1670
|
+
return false;
|
|
1671
|
+
}
|
|
1672
|
+
if (!condition) {
|
|
1673
|
+
return true;
|
|
1674
|
+
}
|
|
1675
|
+
const error = errors[errors.length - 1];
|
|
1676
|
+
if (condition instanceof RegExp) {
|
|
1677
|
+
return condition.test(error.message || "");
|
|
1678
|
+
} else if (typeof condition === "function") {
|
|
1679
|
+
return condition(error);
|
|
1680
|
+
}
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1606
1683
|
async function runTest(test, runner) {
|
|
1607
1684
|
var _runner$onBeforeRunTa, _test$result, _runner$onAfterRunTas;
|
|
1608
1685
|
await ((_runner$onBeforeRunTa = runner.onBeforeRunTask) === null || _runner$onBeforeRunTa === void 0 ? void 0 : _runner$onBeforeRunTa.call(runner, test));
|
|
@@ -1631,7 +1708,7 @@ async function runTest(test, runner) {
|
|
|
1631
1708
|
const $ = runner.trace;
|
|
1632
1709
|
const repeats = test.repeats ?? 0;
|
|
1633
1710
|
for (let repeatCount = 0; repeatCount <= repeats; repeatCount++) {
|
|
1634
|
-
const retry = test.retry
|
|
1711
|
+
const retry = getRetryCount(test.retry);
|
|
1635
1712
|
for (let retryCount = 0; retryCount <= retry; retryCount++) {
|
|
1636
1713
|
var _test$onFinished, _test$onFailed, _runner$onAfterRetryT, _test$result2, _test$result3;
|
|
1637
1714
|
let beforeEachCleanups = [];
|
|
@@ -1712,9 +1789,16 @@ async function runTest(test, runner) {
|
|
|
1712
1789
|
break;
|
|
1713
1790
|
}
|
|
1714
1791
|
if (retryCount < retry) {
|
|
1715
|
-
|
|
1792
|
+
const shouldRetry = passesRetryCondition(test, test.result.errors);
|
|
1793
|
+
if (!shouldRetry) {
|
|
1794
|
+
break;
|
|
1795
|
+
}
|
|
1716
1796
|
test.result.state = "run";
|
|
1717
1797
|
test.result.retryCount = (test.result.retryCount ?? 0) + 1;
|
|
1798
|
+
const delay = getRetryDelay(test.retry);
|
|
1799
|
+
if (delay > 0) {
|
|
1800
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1801
|
+
}
|
|
1718
1802
|
}
|
|
1719
1803
|
// update retry info
|
|
1720
1804
|
updateTask("test-retried", test, runner);
|
|
@@ -1,5 +1,205 @@
|
|
|
1
|
+
import { DiffOptions } from '@vitest/utils/diff';
|
|
1
2
|
import { TestError, Awaitable } from '@vitest/utils';
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* This is a subset of Vitest config that's required for the runner to work.
|
|
6
|
+
*/
|
|
7
|
+
interface VitestRunnerConfig {
|
|
8
|
+
root: string;
|
|
9
|
+
setupFiles: string[];
|
|
10
|
+
name?: string;
|
|
11
|
+
passWithNoTests: boolean;
|
|
12
|
+
testNamePattern?: RegExp;
|
|
13
|
+
allowOnly?: boolean;
|
|
14
|
+
sequence: {
|
|
15
|
+
shuffle?: boolean;
|
|
16
|
+
concurrent?: boolean;
|
|
17
|
+
seed: number;
|
|
18
|
+
hooks: SequenceHooks;
|
|
19
|
+
setupFiles: SequenceSetupFiles;
|
|
20
|
+
};
|
|
21
|
+
chaiConfig?: {
|
|
22
|
+
truncateThreshold?: number;
|
|
23
|
+
};
|
|
24
|
+
maxConcurrency: number;
|
|
25
|
+
testTimeout: number;
|
|
26
|
+
hookTimeout: number;
|
|
27
|
+
retry: SerializableRetry;
|
|
28
|
+
includeTaskLocation?: boolean;
|
|
29
|
+
diffOptions?: DiffOptions;
|
|
30
|
+
tags: TestTagDefinition[];
|
|
31
|
+
tagsFilter?: string[];
|
|
32
|
+
strictTags: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Possible options to run a single file in a test.
|
|
36
|
+
*/
|
|
37
|
+
interface FileSpecification {
|
|
38
|
+
filepath: string;
|
|
39
|
+
fileTags?: string[];
|
|
40
|
+
testLocations: number[] | undefined;
|
|
41
|
+
testNamePattern: RegExp | undefined;
|
|
42
|
+
testTagsFilter: string[] | undefined;
|
|
43
|
+
testIds: string[] | undefined;
|
|
44
|
+
}
|
|
45
|
+
interface TestTagDefinition extends Omit<TestOptions, "tags" | "shuffle"> {
|
|
46
|
+
/**
|
|
47
|
+
* The name of the tag. This is what you use in the `tags` array in tests.
|
|
48
|
+
*/
|
|
49
|
+
name: keyof TestTags extends never ? string : TestTags[keyof TestTags];
|
|
50
|
+
/**
|
|
51
|
+
* A description for the tag. This will be shown in the CLI help and UI.
|
|
52
|
+
*/
|
|
53
|
+
description?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Priority for merging options when multiple tags with the same options are applied to a test.
|
|
56
|
+
*
|
|
57
|
+
* Lower number means higher priority. E.g., priority 1 takes precedence over priority 3.
|
|
58
|
+
*/
|
|
59
|
+
priority?: number;
|
|
60
|
+
}
|
|
61
|
+
type VitestRunnerImportSource = "collect" | "setup";
|
|
62
|
+
interface VitestRunnerConstructor {
|
|
63
|
+
new (config: VitestRunnerConfig): VitestRunner;
|
|
64
|
+
}
|
|
65
|
+
type CancelReason = "keyboard-input" | "test-failure" | (string & Record<string, never>);
|
|
66
|
+
interface VitestRunner {
|
|
67
|
+
/**
|
|
68
|
+
* First thing that's getting called before actually collecting and running tests.
|
|
69
|
+
*/
|
|
70
|
+
onBeforeCollect?: (paths: string[]) => unknown;
|
|
71
|
+
/**
|
|
72
|
+
* Called after the file task was created but not collected yet.
|
|
73
|
+
*/
|
|
74
|
+
onCollectStart?: (file: File) => unknown;
|
|
75
|
+
/**
|
|
76
|
+
* Called after collecting tests and before "onBeforeRun".
|
|
77
|
+
*/
|
|
78
|
+
onCollected?: (files: File[]) => unknown;
|
|
79
|
+
/**
|
|
80
|
+
* Called when test runner should cancel next test runs.
|
|
81
|
+
* Runner should listen for this method and mark tests and suites as skipped in
|
|
82
|
+
* "onBeforeRunSuite" and "onBeforeRunTask" when called.
|
|
83
|
+
*/
|
|
84
|
+
cancel?: (reason: CancelReason) => unknown;
|
|
85
|
+
/**
|
|
86
|
+
* Called before running a single test. Doesn't have "result" yet.
|
|
87
|
+
*/
|
|
88
|
+
onBeforeRunTask?: (test: Test) => unknown;
|
|
89
|
+
/**
|
|
90
|
+
* Called before actually running the test function. Already has "result" with "state" and "startTime".
|
|
91
|
+
*/
|
|
92
|
+
onBeforeTryTask?: (test: Test, options: {
|
|
93
|
+
retry: number;
|
|
94
|
+
repeats: number;
|
|
95
|
+
}) => unknown;
|
|
96
|
+
/**
|
|
97
|
+
* When the task has finished running, but before cleanup hooks are called
|
|
98
|
+
*/
|
|
99
|
+
onTaskFinished?: (test: Test) => unknown;
|
|
100
|
+
/**
|
|
101
|
+
* Called after result and state are set.
|
|
102
|
+
*/
|
|
103
|
+
onAfterRunTask?: (test: Test) => unknown;
|
|
104
|
+
/**
|
|
105
|
+
* Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws.
|
|
106
|
+
*/
|
|
107
|
+
onAfterTryTask?: (test: Test, options: {
|
|
108
|
+
retry: number;
|
|
109
|
+
repeats: number;
|
|
110
|
+
}) => unknown;
|
|
111
|
+
/**
|
|
112
|
+
* Called after the retry resolution happend. Unlike `onAfterTryTask`, the test now has a new state.
|
|
113
|
+
* All `after` hooks were also called by this point.
|
|
114
|
+
*/
|
|
115
|
+
onAfterRetryTask?: (test: Test, options: {
|
|
116
|
+
retry: number;
|
|
117
|
+
repeats: number;
|
|
118
|
+
}) => unknown;
|
|
119
|
+
/**
|
|
120
|
+
* Called before running a single suite. Doesn't have "result" yet.
|
|
121
|
+
*/
|
|
122
|
+
onBeforeRunSuite?: (suite: Suite) => unknown;
|
|
123
|
+
/**
|
|
124
|
+
* Called after running a single suite. Has state and result.
|
|
125
|
+
*/
|
|
126
|
+
onAfterRunSuite?: (suite: Suite) => unknown;
|
|
127
|
+
/**
|
|
128
|
+
* If defined, will be called instead of usual Vitest suite partition and handling.
|
|
129
|
+
* "before" and "after" hooks will not be ignored.
|
|
130
|
+
*/
|
|
131
|
+
runSuite?: (suite: Suite) => Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function.
|
|
134
|
+
* "before" and "after" hooks will not be ignored.
|
|
135
|
+
*/
|
|
136
|
+
runTask?: (test: Test) => Promise<void>;
|
|
137
|
+
/**
|
|
138
|
+
* Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests.
|
|
139
|
+
*/
|
|
140
|
+
onTaskUpdate?: (task: TaskResultPack[], events: TaskEventPack[]) => Promise<void>;
|
|
141
|
+
/**
|
|
142
|
+
* Called when annotation is added via the `context.annotate` method.
|
|
143
|
+
*/
|
|
144
|
+
onTestAnnotate?: (test: Test, annotation: TestAnnotation) => Promise<TestAnnotation>;
|
|
145
|
+
/**
|
|
146
|
+
* @experimental
|
|
147
|
+
*
|
|
148
|
+
* Called when artifacts are recorded on tests via the `recordArtifact` utility.
|
|
149
|
+
*/
|
|
150
|
+
onTestArtifactRecord?: <Artifact extends TestArtifact>(test: Test, artifact: Artifact) => Promise<Artifact>;
|
|
151
|
+
/**
|
|
152
|
+
* Called before running all tests in collected paths.
|
|
153
|
+
*/
|
|
154
|
+
onBeforeRunFiles?: (files: File[]) => unknown;
|
|
155
|
+
/**
|
|
156
|
+
* Called right after running all tests in collected paths.
|
|
157
|
+
*/
|
|
158
|
+
onAfterRunFiles?: (files: File[]) => unknown;
|
|
159
|
+
/**
|
|
160
|
+
* Called when new context for a test is defined. Useful if you want to add custom properties to the context.
|
|
161
|
+
* If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead.
|
|
162
|
+
*
|
|
163
|
+
* @see https://vitest.dev/advanced/runner#your-task-function
|
|
164
|
+
*/
|
|
165
|
+
extendTaskContext?: (context: TestContext) => TestContext;
|
|
166
|
+
/**
|
|
167
|
+
* Called when test and setup files are imported. Can be called in two situations: when collecting tests and when importing setup files.
|
|
168
|
+
*/
|
|
169
|
+
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
|
|
170
|
+
/**
|
|
171
|
+
* Function that is called when the runner attempts to get the value when `test.extend` is used with `{ injected: true }`
|
|
172
|
+
*/
|
|
173
|
+
injectValue?: (key: string) => unknown;
|
|
174
|
+
/**
|
|
175
|
+
* Gets the time spent importing each individual non-externalized file that Vitest collected.
|
|
176
|
+
*/
|
|
177
|
+
getImportDurations?: () => Record<string, ImportDuration>;
|
|
178
|
+
/**
|
|
179
|
+
* Publicly available configuration.
|
|
180
|
+
*/
|
|
181
|
+
config: VitestRunnerConfig;
|
|
182
|
+
/**
|
|
183
|
+
* The name of the current pool. Can affect how stack trace is inferred on the server side.
|
|
184
|
+
*/
|
|
185
|
+
pool?: string;
|
|
186
|
+
/**
|
|
187
|
+
* The current Vite environment that processes the files on the server.
|
|
188
|
+
*/
|
|
189
|
+
viteEnvironment?: string;
|
|
190
|
+
/**
|
|
191
|
+
* Return the worker context for fixtures specified with `scope: 'worker'`
|
|
192
|
+
*/
|
|
193
|
+
getWorkerContext?: () => Record<string, unknown>;
|
|
194
|
+
onCleanupWorkerContext?: (cleanup: () => unknown) => void;
|
|
195
|
+
trace?<T>(name: string, cb: () => T): T;
|
|
196
|
+
trace?<T>(name: string, attributes: Record<string, any>, cb: () => T): T;
|
|
197
|
+
/** @private */
|
|
198
|
+
_currentTaskStartTime?: number;
|
|
199
|
+
/** @private */
|
|
200
|
+
_currentTaskTimeout?: number;
|
|
201
|
+
}
|
|
202
|
+
|
|
3
203
|
interface FixtureItem extends FixtureOptions {
|
|
4
204
|
prop: string;
|
|
5
205
|
value: any;
|
|
@@ -226,10 +426,12 @@ interface TaskBase {
|
|
|
226
426
|
*/
|
|
227
427
|
result?: TaskResult;
|
|
228
428
|
/**
|
|
229
|
-
*
|
|
429
|
+
* Retry configuration for the task.
|
|
430
|
+
* - If a number, specifies how many times to retry
|
|
431
|
+
* - If an object, allows fine-grained retry control
|
|
230
432
|
* @default 0
|
|
231
433
|
*/
|
|
232
|
-
retry?:
|
|
434
|
+
retry?: Retry;
|
|
233
435
|
/**
|
|
234
436
|
* The amount of times the task should be repeated after the successful run.
|
|
235
437
|
* If the task fails, it will not be retried unless `retry` is specified.
|
|
@@ -251,6 +453,10 @@ interface TaskBase {
|
|
|
251
453
|
* @experimental
|
|
252
454
|
*/
|
|
253
455
|
dynamic?: boolean;
|
|
456
|
+
/**
|
|
457
|
+
* Custom tags of the task. Useful for filtering tasks.
|
|
458
|
+
*/
|
|
459
|
+
tags?: string[];
|
|
254
460
|
}
|
|
255
461
|
interface TaskPopulated extends TaskBase {
|
|
256
462
|
/**
|
|
@@ -448,18 +654,68 @@ type ChainableTestAPI<ExtraContext = object> = ChainableFunction<"concurrent" |
|
|
|
448
654
|
for: TestForFunction<ExtraContext>;
|
|
449
655
|
}>;
|
|
450
656
|
type TestCollectorOptions = Omit<TestOptions, "shuffle">;
|
|
657
|
+
/**
|
|
658
|
+
* Retry configuration for tests.
|
|
659
|
+
* Can be a number for simple retry count, or an object for advanced retry control.
|
|
660
|
+
*/
|
|
661
|
+
type Retry = number | {
|
|
662
|
+
/**
|
|
663
|
+
* The number of times to retry the test if it fails.
|
|
664
|
+
* @default 0
|
|
665
|
+
*/
|
|
666
|
+
count?: number;
|
|
667
|
+
/**
|
|
668
|
+
* Delay in milliseconds between retry attempts.
|
|
669
|
+
* @default 0
|
|
670
|
+
*/
|
|
671
|
+
delay?: number;
|
|
672
|
+
/**
|
|
673
|
+
* Condition to determine if a test should be retried based on the error.
|
|
674
|
+
* - If a RegExp, it is tested against the error message
|
|
675
|
+
* - If a function, called with the TestError object; return true to retry
|
|
676
|
+
*
|
|
677
|
+
* NOTE: Functions can only be used in test files, not in vitest.config.ts,
|
|
678
|
+
* because the configuration is serialized when passed to worker threads.
|
|
679
|
+
*
|
|
680
|
+
* @default undefined (retry on all errors)
|
|
681
|
+
*/
|
|
682
|
+
condition?: RegExp | ((error: TestError) => boolean);
|
|
683
|
+
};
|
|
684
|
+
/**
|
|
685
|
+
* Serializable retry configuration (used in config files).
|
|
686
|
+
* Functions cannot be serialized, so only string conditions are allowed.
|
|
687
|
+
*/
|
|
688
|
+
type SerializableRetry = number | {
|
|
689
|
+
/**
|
|
690
|
+
* The number of times to retry the test if it fails.
|
|
691
|
+
* @default 0
|
|
692
|
+
*/
|
|
693
|
+
count?: number;
|
|
694
|
+
/**
|
|
695
|
+
* Delay in milliseconds between retry attempts.
|
|
696
|
+
* @default 0
|
|
697
|
+
*/
|
|
698
|
+
delay?: number;
|
|
699
|
+
/**
|
|
700
|
+
* Condition to determine if a test should be retried based on the error.
|
|
701
|
+
* Must be a RegExp tested against the error message.
|
|
702
|
+
*
|
|
703
|
+
* @default undefined (retry on all errors)
|
|
704
|
+
*/
|
|
705
|
+
condition?: RegExp;
|
|
706
|
+
};
|
|
451
707
|
interface TestOptions {
|
|
452
708
|
/**
|
|
453
709
|
* Test timeout.
|
|
454
710
|
*/
|
|
455
711
|
timeout?: number;
|
|
456
712
|
/**
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
713
|
+
* Retry configuration for the test.
|
|
714
|
+
* - If a number, specifies how many times to retry
|
|
715
|
+
* - If an object, allows fine-grained retry control
|
|
460
716
|
* @default 0
|
|
461
717
|
*/
|
|
462
|
-
retry?:
|
|
718
|
+
retry?: Retry;
|
|
463
719
|
/**
|
|
464
720
|
* How many times the test will run again.
|
|
465
721
|
* Only inner tests will repeat if set on `describe()`, nested `describe()` will inherit parent's repeat by default.
|
|
@@ -478,10 +734,6 @@ interface TestOptions {
|
|
|
478
734
|
*/
|
|
479
735
|
sequential?: boolean;
|
|
480
736
|
/**
|
|
481
|
-
* Whether the tasks of the suite run in a random order.
|
|
482
|
-
*/
|
|
483
|
-
shuffle?: boolean;
|
|
484
|
-
/**
|
|
485
737
|
* Whether the test should be skipped.
|
|
486
738
|
*/
|
|
487
739
|
skip?: boolean;
|
|
@@ -497,6 +749,17 @@ interface TestOptions {
|
|
|
497
749
|
* Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail.
|
|
498
750
|
*/
|
|
499
751
|
fails?: boolean;
|
|
752
|
+
/**
|
|
753
|
+
* Custom tags of the test. Useful for filtering tests.
|
|
754
|
+
*/
|
|
755
|
+
tags?: keyof TestTags extends never ? string[] | string : TestTags[keyof TestTags] | TestTags[keyof TestTags][];
|
|
756
|
+
}
|
|
757
|
+
interface TestTags {}
|
|
758
|
+
interface SuiteOptions extends TestOptions {
|
|
759
|
+
/**
|
|
760
|
+
* Whether the tasks of the suite run in a random order.
|
|
761
|
+
*/
|
|
762
|
+
shuffle?: boolean;
|
|
500
763
|
}
|
|
501
764
|
interface ExtendedAPI<ExtraContext> {
|
|
502
765
|
skipIf: (condition: any) => ChainableTestAPI<ExtraContext>;
|
|
@@ -551,7 +814,7 @@ type Fixtures<
|
|
|
551
814
|
type InferFixturesTypes<T> = T extends TestAPI<infer C> ? C : T;
|
|
552
815
|
interface SuiteCollectorCallable<ExtraContext = object> {
|
|
553
816
|
<OverrideExtraContext extends ExtraContext = ExtraContext>(name: string | Function, fn?: SuiteFactory<OverrideExtraContext>, options?: number): SuiteCollector<OverrideExtraContext>;
|
|
554
|
-
<OverrideExtraContext extends ExtraContext = ExtraContext>(name: string | Function, options:
|
|
817
|
+
<OverrideExtraContext extends ExtraContext = ExtraContext>(name: string | Function, options: SuiteOptions, fn?: SuiteFactory<OverrideExtraContext>): SuiteCollector<OverrideExtraContext>;
|
|
555
818
|
}
|
|
556
819
|
type ChainableSuiteAPI<ExtraContext = object> = ChainableFunction<"concurrent" | "sequential" | "only" | "skip" | "todo" | "shuffle", SuiteCollectorCallable<ExtraContext>, {
|
|
557
820
|
each: TestEachFunction;
|
|
@@ -602,7 +865,7 @@ interface TaskCustomOptions extends TestOptions {
|
|
|
602
865
|
interface SuiteCollector<ExtraContext = object> {
|
|
603
866
|
readonly name: string;
|
|
604
867
|
readonly mode: RunMode;
|
|
605
|
-
options?:
|
|
868
|
+
options?: SuiteOptions;
|
|
606
869
|
type: "collector";
|
|
607
870
|
test: TestAPI<ExtraContext>;
|
|
608
871
|
tasks: (Suite | Test<ExtraContext> | SuiteCollector<ExtraContext>)[];
|
|
@@ -830,5 +1093,5 @@ interface TestArtifactRegistry {}
|
|
|
830
1093
|
*/
|
|
831
1094
|
type TestArtifact = TestAnnotationArtifact | VisualRegressionArtifact | TestArtifactRegistry[keyof TestArtifactRegistry];
|
|
832
1095
|
|
|
833
|
-
export { createChainable as
|
|
834
|
-
export type {
|
|
1096
|
+
export { createChainable as ab, afterAll as i, afterEach as j, beforeAll as k, beforeEach as l, onTestFinished as m, onTestFailed as o };
|
|
1097
|
+
export type { TestAnnotationLocation as $, AfterAllListener as A, BeforeAllListener as B, CancelReason as C, RunMode as D, RuntimeContext as E, FileSpecification as F, SequenceHooks as G, SequenceSetupFiles as H, ImportDuration as I, SerializableRetry as J, SuiteFactory as K, TaskBase as L, TaskCustomOptions as M, TaskEventPack as N, OnTestFailedHandler as O, TaskHook as P, TaskMeta as Q, Retry as R, Suite as S, TestArtifact as T, TaskPopulated as U, VitestRunner as V, TaskResult as W, TaskResultPack as X, TaskState as Y, TestAnnotation as Z, TestAnnotationArtifact as _, Test as a, TestArtifactBase as a0, TestArtifactLocation as a1, TestArtifactRegistry as a2, TestAttachment as a3, TestContext as a4, TestFunction as a5, TestOptions as a6, TestTags as a7, Use as a8, VisualRegressionArtifact as a9, ChainableFunction as aa, SuiteHooks as b, File as c, TaskUpdateEvent as d, Task as e, TestAPI as f, SuiteAPI as g, SuiteCollector as h, TestTagDefinition as n, VitestRunnerConfig as p, VitestRunnerConstructor as q, VitestRunnerImportSource as r, AfterEachListener as s, BeforeEachListener as t, Fixture as u, FixtureFn as v, FixtureOptions as w, Fixtures as x, InferFixturesTypes as y, OnTestFinishedHandler as z };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,183 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
export { A as AfterAllListener, n as AfterEachListener, B as BeforeAllListener, p as BeforeEachListener, q as Fixture, r as FixtureFn, s as FixtureOptions, t as Fixtures, u as InferFixturesTypes, O as OnTestFailedHandler, v as OnTestFinishedHandler, R as RunMode, w as RuntimeContext, g as SuiteAPI, h as SuiteCollector, z as SuiteFactory, d as SuiteHooks, T as Task, D as TaskBase, E as TaskCustomOptions, H as TaskHook, J as TaskMeta, K as TaskPopulated, L as TaskResult, N as TaskState, e as TaskUpdateEvent, f as TestAPI, Q as TestAnnotationArtifact, U as TestAnnotationLocation, V as TestArtifactBase, W as TestArtifactLocation, X as TestArtifactRegistry, Y as TestAttachment, _ as TestFunction, $ as TestOptions, a0 as Use, a1 as VisualRegressionArtifact } from './tasks.d-C7UxawJ9.js';
|
|
1
|
+
export { A as AfterAllListener, s as AfterEachListener, B as BeforeAllListener, t as BeforeEachListener, C as CancelReason, c as File, F as FileSpecification, u as Fixture, v as FixtureFn, w as FixtureOptions, x as Fixtures, I as ImportDuration, y as InferFixturesTypes, O as OnTestFailedHandler, z as OnTestFinishedHandler, R as Retry, D as RunMode, E as RuntimeContext, G as SequenceHooks, H as SequenceSetupFiles, J as SerializableRetry, S as Suite, g as SuiteAPI, h as SuiteCollector, K as SuiteFactory, b as SuiteHooks, e as Task, L as TaskBase, M as TaskCustomOptions, N as TaskEventPack, P as TaskHook, Q as TaskMeta, U as TaskPopulated, W as TaskResult, X as TaskResultPack, Y as TaskState, d as TaskUpdateEvent, a as Test, f as TestAPI, Z as TestAnnotation, _ as TestAnnotationArtifact, $ as TestAnnotationLocation, T as TestArtifact, a0 as TestArtifactBase, a1 as TestArtifactLocation, a2 as TestArtifactRegistry, a3 as TestAttachment, a4 as TestContext, a5 as TestFunction, a6 as TestOptions, n as TestTagDefinition, a7 as TestTags, a8 as Use, a9 as VisualRegressionArtifact, V as VitestRunner, p as VitestRunnerConfig, q as VitestRunnerConstructor, r as VitestRunnerImportSource } from './tasks.d-CLPU8HE4.js';
|
|
2
|
+
import '@vitest/utils/diff';
|
|
4
3
|
import '@vitest/utils';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* This is a subset of Vitest config that's required for the runner to work.
|
|
8
|
-
*/
|
|
9
|
-
interface VitestRunnerConfig {
|
|
10
|
-
root: string;
|
|
11
|
-
setupFiles: string[];
|
|
12
|
-
name?: string;
|
|
13
|
-
passWithNoTests: boolean;
|
|
14
|
-
testNamePattern?: RegExp;
|
|
15
|
-
allowOnly?: boolean;
|
|
16
|
-
sequence: {
|
|
17
|
-
shuffle?: boolean;
|
|
18
|
-
concurrent?: boolean;
|
|
19
|
-
seed: number;
|
|
20
|
-
hooks: SequenceHooks;
|
|
21
|
-
setupFiles: SequenceSetupFiles;
|
|
22
|
-
};
|
|
23
|
-
chaiConfig?: {
|
|
24
|
-
truncateThreshold?: number;
|
|
25
|
-
};
|
|
26
|
-
maxConcurrency: number;
|
|
27
|
-
testTimeout: number;
|
|
28
|
-
hookTimeout: number;
|
|
29
|
-
retry: number;
|
|
30
|
-
includeTaskLocation?: boolean;
|
|
31
|
-
diffOptions?: DiffOptions;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Possible options to run a single file in a test.
|
|
35
|
-
*/
|
|
36
|
-
interface FileSpecification {
|
|
37
|
-
filepath: string;
|
|
38
|
-
testLocations: number[] | undefined;
|
|
39
|
-
}
|
|
40
|
-
type VitestRunnerImportSource = "collect" | "setup";
|
|
41
|
-
interface VitestRunnerConstructor {
|
|
42
|
-
new (config: VitestRunnerConfig): VitestRunner;
|
|
43
|
-
}
|
|
44
|
-
type CancelReason = "keyboard-input" | "test-failure" | (string & Record<string, never>);
|
|
45
|
-
interface VitestRunner {
|
|
46
|
-
/**
|
|
47
|
-
* First thing that's getting called before actually collecting and running tests.
|
|
48
|
-
*/
|
|
49
|
-
onBeforeCollect?: (paths: string[]) => unknown;
|
|
50
|
-
/**
|
|
51
|
-
* Called after the file task was created but not collected yet.
|
|
52
|
-
*/
|
|
53
|
-
onCollectStart?: (file: File) => unknown;
|
|
54
|
-
/**
|
|
55
|
-
* Called after collecting tests and before "onBeforeRun".
|
|
56
|
-
*/
|
|
57
|
-
onCollected?: (files: File[]) => unknown;
|
|
58
|
-
/**
|
|
59
|
-
* Called when test runner should cancel next test runs.
|
|
60
|
-
* Runner should listen for this method and mark tests and suites as skipped in
|
|
61
|
-
* "onBeforeRunSuite" and "onBeforeRunTask" when called.
|
|
62
|
-
*/
|
|
63
|
-
cancel?: (reason: CancelReason) => unknown;
|
|
64
|
-
/**
|
|
65
|
-
* Called before running a single test. Doesn't have "result" yet.
|
|
66
|
-
*/
|
|
67
|
-
onBeforeRunTask?: (test: Test) => unknown;
|
|
68
|
-
/**
|
|
69
|
-
* Called before actually running the test function. Already has "result" with "state" and "startTime".
|
|
70
|
-
*/
|
|
71
|
-
onBeforeTryTask?: (test: Test, options: {
|
|
72
|
-
retry: number;
|
|
73
|
-
repeats: number;
|
|
74
|
-
}) => unknown;
|
|
75
|
-
/**
|
|
76
|
-
* When the task has finished running, but before cleanup hooks are called
|
|
77
|
-
*/
|
|
78
|
-
onTaskFinished?: (test: Test) => unknown;
|
|
79
|
-
/**
|
|
80
|
-
* Called after result and state are set.
|
|
81
|
-
*/
|
|
82
|
-
onAfterRunTask?: (test: Test) => unknown;
|
|
83
|
-
/**
|
|
84
|
-
* Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws.
|
|
85
|
-
*/
|
|
86
|
-
onAfterTryTask?: (test: Test, options: {
|
|
87
|
-
retry: number;
|
|
88
|
-
repeats: number;
|
|
89
|
-
}) => unknown;
|
|
90
|
-
/**
|
|
91
|
-
* Called after the retry resolution happend. Unlike `onAfterTryTask`, the test now has a new state.
|
|
92
|
-
* All `after` hooks were also called by this point.
|
|
93
|
-
*/
|
|
94
|
-
onAfterRetryTask?: (test: Test, options: {
|
|
95
|
-
retry: number;
|
|
96
|
-
repeats: number;
|
|
97
|
-
}) => unknown;
|
|
98
|
-
/**
|
|
99
|
-
* Called before running a single suite. Doesn't have "result" yet.
|
|
100
|
-
*/
|
|
101
|
-
onBeforeRunSuite?: (suite: Suite) => unknown;
|
|
102
|
-
/**
|
|
103
|
-
* Called after running a single suite. Has state and result.
|
|
104
|
-
*/
|
|
105
|
-
onAfterRunSuite?: (suite: Suite) => unknown;
|
|
106
|
-
/**
|
|
107
|
-
* If defined, will be called instead of usual Vitest suite partition and handling.
|
|
108
|
-
* "before" and "after" hooks will not be ignored.
|
|
109
|
-
*/
|
|
110
|
-
runSuite?: (suite: Suite) => Promise<void>;
|
|
111
|
-
/**
|
|
112
|
-
* If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function.
|
|
113
|
-
* "before" and "after" hooks will not be ignored.
|
|
114
|
-
*/
|
|
115
|
-
runTask?: (test: Test) => Promise<void>;
|
|
116
|
-
/**
|
|
117
|
-
* Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests.
|
|
118
|
-
*/
|
|
119
|
-
onTaskUpdate?: (task: TaskResultPack[], events: TaskEventPack[]) => Promise<void>;
|
|
120
|
-
/**
|
|
121
|
-
* Called when annotation is added via the `context.annotate` method.
|
|
122
|
-
*/
|
|
123
|
-
onTestAnnotate?: (test: Test, annotation: TestAnnotation) => Promise<TestAnnotation>;
|
|
124
|
-
/**
|
|
125
|
-
* @experimental
|
|
126
|
-
*
|
|
127
|
-
* Called when artifacts are recorded on tests via the `recordArtifact` utility.
|
|
128
|
-
*/
|
|
129
|
-
onTestArtifactRecord?: <Artifact extends TestArtifact>(test: Test, artifact: Artifact) => Promise<Artifact>;
|
|
130
|
-
/**
|
|
131
|
-
* Called before running all tests in collected paths.
|
|
132
|
-
*/
|
|
133
|
-
onBeforeRunFiles?: (files: File[]) => unknown;
|
|
134
|
-
/**
|
|
135
|
-
* Called right after running all tests in collected paths.
|
|
136
|
-
*/
|
|
137
|
-
onAfterRunFiles?: (files: File[]) => unknown;
|
|
138
|
-
/**
|
|
139
|
-
* Called when new context for a test is defined. Useful if you want to add custom properties to the context.
|
|
140
|
-
* If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead.
|
|
141
|
-
*
|
|
142
|
-
* @see https://vitest.dev/advanced/runner#your-task-function
|
|
143
|
-
*/
|
|
144
|
-
extendTaskContext?: (context: TestContext) => TestContext;
|
|
145
|
-
/**
|
|
146
|
-
* Called when test and setup files are imported. Can be called in two situations: when collecting tests and when importing setup files.
|
|
147
|
-
*/
|
|
148
|
-
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
|
|
149
|
-
/**
|
|
150
|
-
* Function that is called when the runner attempts to get the value when `test.extend` is used with `{ injected: true }`
|
|
151
|
-
*/
|
|
152
|
-
injectValue?: (key: string) => unknown;
|
|
153
|
-
/**
|
|
154
|
-
* Gets the time spent importing each individual non-externalized file that Vitest collected.
|
|
155
|
-
*/
|
|
156
|
-
getImportDurations?: () => Record<string, ImportDuration>;
|
|
157
|
-
/**
|
|
158
|
-
* Publicly available configuration.
|
|
159
|
-
*/
|
|
160
|
-
config: VitestRunnerConfig;
|
|
161
|
-
/**
|
|
162
|
-
* The name of the current pool. Can affect how stack trace is inferred on the server side.
|
|
163
|
-
*/
|
|
164
|
-
pool?: string;
|
|
165
|
-
/**
|
|
166
|
-
* The current Vite environment that processes the files on the server.
|
|
167
|
-
*/
|
|
168
|
-
viteEnvironment?: string;
|
|
169
|
-
/**
|
|
170
|
-
* Return the worker context for fixtures specified with `scope: 'worker'`
|
|
171
|
-
*/
|
|
172
|
-
getWorkerContext?: () => Record<string, unknown>;
|
|
173
|
-
onCleanupWorkerContext?: (cleanup: () => unknown) => void;
|
|
174
|
-
trace?<T>(name: string, cb: () => T): T;
|
|
175
|
-
trace?<T>(name: string, attributes: Record<string, any>, cb: () => T): T;
|
|
176
|
-
/** @private */
|
|
177
|
-
_currentTaskStartTime?: number;
|
|
178
|
-
/** @private */
|
|
179
|
-
_currentTaskTimeout?: number;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export { File, ImportDuration, SequenceHooks, SequenceSetupFiles, Suite, TaskEventPack, TaskResultPack, Test, TestAnnotation, TestArtifact, TestContext };
|
|
183
|
-
export type { CancelReason, FileSpecification, VitestRunner, VitestRunnerConfig, VitestRunnerConstructor, VitestRunnerImportSource };
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { S as Suite,
|
|
2
|
-
export {
|
|
1
|
+
import { S as Suite, c as File, e as Task, n as TestTagDefinition, p as VitestRunnerConfig, a as Test } from './tasks.d-CLPU8HE4.js';
|
|
2
|
+
export { aa as ChainableFunction, ab as createChainable } from './tasks.d-CLPU8HE4.js';
|
|
3
3
|
import { ParsedStack, Arrayable } from '@vitest/utils';
|
|
4
|
+
import '@vitest/utils/diff';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* If any tasks been marked as `only`, mark all other tasks as `skip`.
|
|
7
8
|
*/
|
|
8
|
-
declare function interpretTaskModes(file: Suite, namePattern?: string | RegExp, testLocations?: number[] | undefined, onlyMode?: boolean, parentIsOnly?: boolean, allowOnly?: boolean): void;
|
|
9
|
+
declare function interpretTaskModes(file: Suite, namePattern?: string | RegExp, testLocations?: number[] | undefined, testIds?: string[] | undefined, testTagsFilter?: ((testTags: string[]) => boolean) | undefined, onlyMode?: boolean, parentIsOnly?: boolean, allowOnly?: boolean): void;
|
|
9
10
|
declare function someTasksAreOnly(suite: Suite): boolean;
|
|
10
11
|
declare function generateHash(str: string): string;
|
|
11
12
|
declare function calculateSuiteHash(parent: Suite): void;
|
|
@@ -31,6 +32,9 @@ declare function limitConcurrency(concurrency?: number): <
|
|
|
31
32
|
*/
|
|
32
33
|
declare function partitionSuiteChildren(suite: Suite): Task[][];
|
|
33
34
|
|
|
35
|
+
declare function validateTags(config: VitestRunnerConfig, tags: string[]): void;
|
|
36
|
+
declare function createTagsFilter(tagsExpr: string[], availableTags: TestTagDefinition[]): (testTags: string[]) => boolean;
|
|
37
|
+
|
|
34
38
|
declare function isTestCase(s: Task): s is Test;
|
|
35
39
|
declare function getTests(suite: Arrayable<Task>): Test[];
|
|
36
40
|
declare function getTasks(tasks?: Arrayable<Task>): Task[];
|
|
@@ -42,4 +46,4 @@ declare function getFullName(task: Task, separator?: string): string;
|
|
|
42
46
|
declare function getTestName(task: Task, separator?: string): string;
|
|
43
47
|
declare function createTaskName(names: readonly (string | undefined)[], separator?: string): string;
|
|
44
48
|
|
|
45
|
-
export { calculateSuiteHash, createFileTask, createTaskName, findTestFileStackTrace, generateFileHash, generateHash, getFullName, getNames, getSuites, getTasks, getTestName, getTests, hasFailed, hasTests, interpretTaskModes, isTestCase, limitConcurrency, partitionSuiteChildren, someTasksAreOnly };
|
|
49
|
+
export { calculateSuiteHash, createFileTask, createTagsFilter, createTaskName, findTestFileStackTrace, generateFileHash, generateHash, getFullName, getNames, getSuites, getTasks, getTestName, getTests, hasFailed, hasTests, interpretTaskModes, isTestCase, limitConcurrency, partitionSuiteChildren, someTasksAreOnly, validateTags };
|
package/dist/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as calculateSuiteHash, c as createChainable, b as createFileTask, e as createTaskName, f as findTestFileStackTrace, g as generateFileHash, d as generateHash,
|
|
1
|
+
export { a as calculateSuiteHash, c as createChainable, b as createFileTask, e as createTagsFilter, h as createTaskName, f as findTestFileStackTrace, g as generateFileHash, d as generateHash, j as getFullName, k as getNames, m as getSuites, n as getTasks, o as getTestName, q as getTests, r as hasFailed, t as hasTests, i as interpretTaskModes, u as isTestCase, l as limitConcurrency, p as partitionSuiteChildren, s as someTasksAreOnly, v as validateTags } from './chunk-tasks.js';
|
|
2
2
|
import '@vitest/utils/error';
|
|
3
3
|
import '@vitest/utils/source-map';
|
|
4
4
|
import 'pathe';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest/runner",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.1.0-beta.2",
|
|
5
5
|
"description": "Vitest test runner",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"pathe": "^2.0.3",
|
|
42
|
-
"@vitest/utils": "4.0.
|
|
42
|
+
"@vitest/utils": "4.1.0-beta.2"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "premove dist && rollup -c",
|