sxy-test-runner 2.4.11 → 2.4.13
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/checkMeta.js.map +1 -1
- package/dist/cli/cliTypes.d.ts +12 -0
- package/dist/cli/cliTypes.js +3 -0
- package/dist/cli/cliTypes.js.map +1 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/lib/addBasePath.js.map +1 -1
- package/dist/cli/lib/addExports.js +6 -1
- package/dist/cli/lib/addExports.js.map +1 -1
- package/dist/cli/lib/agentReport.d.ts +2 -1
- package/dist/cli/lib/agentReport.js.map +1 -1
- package/dist/cli/lib/alwaysCacheBust.js.map +1 -1
- package/dist/cli/lib/applyConfigDefaults.js.map +1 -1
- package/dist/cli/lib/buildDependencyTree.js.map +1 -1
- package/dist/cli/lib/buildDependencyTrees.js.map +1 -1
- package/dist/cli/lib/consoleCapture.js.map +1 -1
- package/dist/cli/lib/defaultConfig.js.map +1 -1
- package/dist/cli/lib/doUserSetup.js +1 -1
- package/dist/cli/lib/doUserSetup.js.map +1 -1
- package/dist/cli/lib/doUserTeardown.js +1 -1
- package/dist/cli/lib/doUserTeardown.js.map +1 -1
- package/dist/cli/lib/exitCodes.js.map +1 -1
- package/dist/cli/lib/failureEntries.d.ts +2 -1
- package/dist/cli/lib/failureEntries.js +2 -0
- package/dist/cli/lib/failureEntries.js.map +1 -1
- package/dist/cli/lib/failureLines.d.ts +2 -1
- package/dist/cli/lib/failureLines.js.map +1 -1
- package/dist/cli/lib/filter.js.map +1 -1
- package/dist/cli/lib/findTestFiles.js.map +1 -1
- package/dist/cli/lib/findingTestsMessage.d.ts +1 -1
- package/dist/cli/lib/findingTestsMessage.js.map +1 -1
- package/dist/cli/lib/getAllowedFlags.d.ts +1 -1
- package/dist/cli/lib/getAllowedFlags.js.map +1 -1
- package/dist/cli/lib/globArgCombine.js.map +1 -1
- package/dist/cli/lib/handleUserInput.d.ts +2 -2
- package/dist/cli/lib/handleUserInput.js +1 -1
- package/dist/cli/lib/handleUserInput.js.map +1 -1
- package/dist/cli/lib/injectProperties.js.map +1 -1
- package/dist/cli/lib/isTest.js.map +1 -1
- package/dist/cli/lib/listenToUser.d.ts +3 -3
- package/dist/cli/lib/listenToUser.js +33 -8
- package/dist/cli/lib/listenToUser.js.map +1 -1
- package/dist/cli/lib/loadConfig.js.map +1 -1
- package/dist/cli/lib/loadTestFile.d.ts +10 -1
- package/dist/cli/lib/loadTestFile.js +23 -11
- package/dist/cli/lib/loadTestFile.js.map +1 -1
- package/dist/cli/lib/makeWatchRunState.js.map +1 -1
- package/dist/cli/lib/parseCommandLineArguments.d.ts +1 -1
- package/dist/cli/lib/parseCommandLineArguments.js.map +1 -1
- package/dist/cli/lib/parseDescribe.js +3 -3
- package/dist/cli/lib/parseDescribe.js.map +1 -1
- package/dist/cli/lib/reRunManager.d.ts +1 -1
- package/dist/cli/lib/reRunManager.js +1 -1
- package/dist/cli/lib/reRunManager.js.map +1 -1
- package/dist/cli/lib/reservedExportKeys.js.map +1 -1
- package/dist/cli/lib/resolveCommand.js.map +1 -1
- package/dist/cli/lib/runDescribe.d.ts +16 -1
- package/dist/cli/lib/runDescribe.js.map +1 -1
- package/dist/cli/lib/runDescribeRun.d.ts +2 -1
- package/dist/cli/lib/runDescribeRun.js +1 -1
- package/dist/cli/lib/runDescribeRun.js.map +1 -1
- package/dist/cli/lib/runIt.d.ts +9 -1
- package/dist/cli/lib/runIt.js +11 -7
- package/dist/cli/lib/runIt.js.map +1 -1
- package/dist/cli/lib/runTasks.d.ts +1 -1
- package/dist/cli/lib/runTasks.js +6 -4
- package/dist/cli/lib/runTasks.js.map +1 -1
- package/dist/cli/lib/runTest.d.ts +19 -1
- package/dist/cli/lib/runTest.js +4 -3
- package/dist/cli/lib/runTest.js.map +1 -1
- package/dist/cli/lib/runTests.d.ts +15 -3
- package/dist/cli/lib/runTests.js +25 -8
- package/dist/cli/lib/runTests.js.map +1 -1
- package/dist/cli/lib/showTestLoadingError.d.ts +2 -1
- package/dist/cli/lib/showTestLoadingError.js +1 -1
- package/dist/cli/lib/showTestLoadingError.js.map +1 -1
- package/dist/cli/lib/showTestResult.d.ts +2 -1
- package/dist/cli/lib/showTestResult.js +48 -45
- package/dist/cli/lib/showTestResult.js.map +1 -1
- package/dist/cli/lib/showTtyHelp.js.map +1 -1
- package/dist/cli/lib/shutdown.d.ts +1 -1
- package/dist/cli/lib/shutdown.js +11 -3
- package/dist/cli/lib/shutdown.js.map +1 -1
- package/dist/cli/lib/statusFile.js.map +1 -1
- package/dist/cli/lib/stopSignal.js.map +1 -1
- package/dist/cli/lib/timeProfier.js.map +1 -1
- package/dist/cli/lib/validateConfig.js.map +1 -1
- package/dist/cli/lib/watchFilesAndRunTests.js.map +1 -1
- package/dist/cli/lib/watchFilesAndRunTestsChokidar.js +3 -3
- package/dist/cli/lib/watchFilesAndRunTestsChokidar.js.map +1 -1
- package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.d.ts +5 -3
- package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.js +18 -11
- package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.js.map +1 -1
- package/dist/cli/lib/watchFilesChokidar.d.ts +1 -3
- package/dist/cli/lib/watchFilesChokidar.js +52 -43
- package/dist/cli/lib/watchFilesChokidar.js.map +1 -1
- package/dist/cli/lib/watchFilesNodeWatch.d.ts +2 -3
- package/dist/cli/lib/watchFilesNodeWatch.js +3 -3
- package/dist/cli/lib/watchFilesNodeWatch.js.map +1 -1
- package/dist/cli/once.js.map +1 -1
- package/dist/cli/version.js.map +1 -1
- package/dist/cli/watch.d.ts +2 -0
- package/dist/cli/watch.js +43 -18
- package/dist/cli/watch.js.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/describe.js +1 -1
- package/dist/describe.js.map +1 -1
- package/dist/indexNumberToLetters.js.map +1 -1
- package/dist/meta.js.map +1 -1
- package/dist/output.js +2 -0
- package/dist/output.js.map +1 -1
- package/dist/packages/chalk.js.map +1 -1
- package/dist/packages/esmReload.js.map +1 -1
- package/dist/packages/figures.js.map +1 -1
- package/dist/packages/loadConfig.js.map +1 -1
- package/dist/packages/mergeStructuredConfig.js.map +1 -1
- package/dist/packages/slash.js.map +1 -1
- package/dist/packages/timeProfiler.js.map +1 -1
- package/dist/types.d.ts +13 -81
- package/dist/types.js.map +1 -1
- package/package.json +5 -4
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import chalk from '../../packages/chalk.js';
|
|
3
|
+
import figures from '../../packages/figures.js';
|
|
1
4
|
import { createTimeProfiler } from '../../packages/timeProfiler.js';
|
|
2
5
|
import { showTimeProfiling } from '../../config.js';
|
|
3
|
-
import _chalk from 'chalk';
|
|
4
|
-
import chalk from '../../packages/chalk.js';
|
|
5
6
|
import { out as mainOut } from '../../output.js';
|
|
6
|
-
import figures from '../../packages/figures.js';
|
|
7
7
|
import { indexNumberToLetters } from '../../indexNumberToLetters.js';
|
|
8
|
-
import { inspect } from 'node:util';
|
|
9
8
|
const { timeProfileAsync } = createTimeProfiler(showTimeProfiling);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
function IsErrorLike(v) {
|
|
10
|
+
return typeof v === 'object' && v !== null
|
|
11
|
+
&& 'name' in v && typeof v.name === 'string'
|
|
12
|
+
&& 'message' in v && typeof v.message === 'string';
|
|
13
|
+
}
|
|
14
|
+
function ErrorLikeIsAssertionLike(v) {
|
|
15
|
+
return ('actual' in v || 'expected' in v);
|
|
16
16
|
}
|
|
17
17
|
// Node's assertion messages run to several lines. Later lines are indented to the message
|
|
18
18
|
// column and blank ones dropped; a single line message passes through untouched.
|
|
@@ -31,11 +31,16 @@ function showValue(value, column) {
|
|
|
31
31
|
}
|
|
32
32
|
return value.split('\n').join(`\n${column}`);
|
|
33
33
|
}
|
|
34
|
+
function display(u) {
|
|
35
|
+
if (typeof u === 'string')
|
|
36
|
+
return u;
|
|
37
|
+
return inspect(u);
|
|
38
|
+
}
|
|
34
39
|
export async function showTestResult(config, testResult, customOut) {
|
|
35
40
|
const out = customOut ?? mainOut;
|
|
36
41
|
await timeProfileAsync('show test result', () => {
|
|
37
42
|
out();
|
|
38
|
-
out(chalk.grey `File ${testResult.file}`);
|
|
43
|
+
out(chalk.grey `File ${testResult.sourceFile ?? testResult.file}`);
|
|
39
44
|
const indent = ' ';
|
|
40
45
|
if (testResult.logs.length > 0) {
|
|
41
46
|
out();
|
|
@@ -60,27 +65,18 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
60
65
|
});
|
|
61
66
|
out();
|
|
62
67
|
}
|
|
63
|
-
if (
|
|
68
|
+
if ('error' in describeResult) {
|
|
64
69
|
const describeError = describeResult.error;
|
|
65
|
-
const describeErrorText = (typeof describeError === 'object'
|
|
66
|
-
&& describeError !== null
|
|
67
|
-
&& 'name' in describeError
|
|
68
|
-
&& 'message' in describeError
|
|
69
|
-
&& typeof describeError.name === 'string'
|
|
70
|
-
&& typeof describeError.message === 'string')
|
|
71
|
-
? `${describeError.name}: ${describeError.message}`
|
|
72
|
-
: String(describeError); // eslint-disable-line @typescript-eslint/no-base-to-string -- only a fallback, if it gives poor results, change it
|
|
73
70
|
out(chalk.mediumred(`${indent}Threw:`));
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
out();
|
|
83
|
-
out(chalk.grey(describeErrorStack));
|
|
71
|
+
if (IsErrorLike(describeError)) {
|
|
72
|
+
out(chalk.mediumred(`${indent}${describeError.name}: ${describeError.message}`));
|
|
73
|
+
if (config.showErrorTrace && 'stack' in describeError) {
|
|
74
|
+
out();
|
|
75
|
+
out(chalk.grey(display(describeError.stack)));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
out(chalk.mediumred(`${indent}${display(describeError)}`));
|
|
84
80
|
}
|
|
85
81
|
out();
|
|
86
82
|
}
|
|
@@ -96,23 +92,30 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
96
92
|
+ chalk.mediumred ` ${figures.cross} ${itResult.should}` + itTime);
|
|
97
93
|
out();
|
|
98
94
|
const spacer = `${indent}${' '.repeat(letters.length)} `;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
95
|
+
if ('error' in itResult) {
|
|
96
|
+
const err = itResult.error;
|
|
97
|
+
if (IsErrorLike(err)) {
|
|
98
|
+
if (ErrorLikeIsAssertionLike(err)) {
|
|
99
|
+
out(chalk.mediumred(
|
|
100
|
+
//`${spacer}Assertion Failed: ${alignMessage(err.message, spacer)}`
|
|
101
|
+
`${spacer}${err.name}: ${alignMessage(err.message, spacer)}`));
|
|
102
|
+
// shown whenever the error carries them, so a falsy actual or
|
|
103
|
+
// expected - 0, '', false, null - still gets its diff
|
|
104
|
+
const valueColumn = `${spacer} `;
|
|
105
|
+
out(chalk.yellow `${spacer}Actual ${showValue(err.actual, valueColumn)}\n`
|
|
106
|
+
+ chalk.brightblue `${spacer}Expected ${showValue(err.expected, valueColumn)}`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
out(chalk.mediumred(`${spacer}${err.name}: ${alignMessage(err.message, spacer)}`));
|
|
110
|
+
}
|
|
111
|
+
// stack trace
|
|
112
|
+
if (config.showErrorTrace && 'stack' in err) {
|
|
113
|
+
out();
|
|
114
|
+
out(chalk.grey(display(err.stack)));
|
|
115
|
+
}
|
|
108
116
|
}
|
|
109
117
|
else {
|
|
110
|
-
out(chalk.mediumred(`${spacer}${
|
|
111
|
-
}
|
|
112
|
-
// stack trace
|
|
113
|
-
if (config.showErrorTrace) {
|
|
114
|
-
out();
|
|
115
|
-
out(chalk.grey(err.stack ?? ''));
|
|
118
|
+
out(chalk.mediumred(`${spacer}${display(err)}`));
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"showTestResult.js","sourceRoot":"","sources":["../../../src/cli/lib/showTestResult.ts"],"names":[],"mappings":"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","sourcesContent":["import { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { showTimeProfiling } from '../../config.js'\nimport _chalk from 'chalk'\nimport chalk from '../../packages/chalk.js'\nimport { out as mainOut } from '../../output.js'\nimport figures from '../../packages/figures.js'\nimport { indexNumberToLetters } from '../../indexNumberToLetters.js'\n\nimport type { FinalConfig, OutFn, TestError, TestResult } from '../../types.js'\nimport { inspect } from 'node:util'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\n// Assertion failures are recognised by shape, not by where they came from. Importing an\n// assertion library to test `instanceof` against cannot work here: the runner would need it\n// as a dependency, and the copy a test file throws from is a separate ESM instance anyway,\n// so the check fails for the very errors it is meant to catch.\nfunction isAssertionLike(error: TestError): boolean {\n return 'actual' in error || 'expected' in error\n}\n\n// Node's assertion messages run to several lines. Later lines are indented to the message\n// column and blank ones dropped; a single line message passes through untouched.\nfunction alignMessage(message: string, spacer: string): string {\n return message.split('\\n').reduce<string[]>(\n (previous, line) => (previous.length === 0)\n ? [line]\n : (line.trim()) ? [...previous, spacer + line] : previous,\n []\n ).join('\\n')\n}\n\n// A multi line string is shown as text, indented under its label. inspect() would render it\n// as one quoted chunk per line joined with `+`, which buries the content it is there to\n// show. Everything else - objects, and single line strings, whose quotes reveal padding and\n// emptiness - still goes through inspect.\nfunction showValue(value: unknown, column: string): string {\n if (typeof value !== 'string' || !value.includes('\\n')) {\n return inspect(value, { depth: 5 })\n }\n return value.split('\\n').join(`\\n${column}`)\n}\n\nexport async function showTestResult(config: FinalConfig, testResult: TestResult, customOut?: OutFn): Promise<void> {\n const out = customOut ?? mainOut\n\n await timeProfileAsync('show test result', () => {\n out()\n out(chalk.grey`File ${testResult.file}`)\n\n const indent = ' '\n\n if (testResult.logs.length > 0) {\n out()\n out(chalk.grey`console.logs:`)\n testResult.logs.forEach(log => {\n out(...log)\n })\n out()\n }\n\n let first = true\n\n for (const describeResult of testResult.describeResults) {\n if (!first) out()\n first = false\n\n out(chalk.lightgrey`${describeResult.counter}) describing ` + chalk.brightblue(describeResult.thing)\n + chalk.grey` ${describeResult.time.toLocaleString()}ms`)\n out()\n\n if (describeResult.logs && describeResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n describeResult.logs.forEach(log => {\n out(...log)\n })\n out()\n }\n\n if (describeResult.error !== undefined) {\n const describeError = describeResult.error\n const describeErrorText = (\n typeof describeError === 'object'\n && describeError !== null\n && 'name' in describeError\n && 'message' in describeError\n && typeof describeError.name === 'string'\n && typeof describeError.message === 'string'\n )\n ? `${describeError.name}: ${describeError.message}`\n : String(describeError) // eslint-disable-line @typescript-eslint/no-base-to-string -- only a fallback, if it gives poor results, change it\n\n out(chalk.mediumred(`${indent}Threw:`))\n out(chalk.mediumred(`${indent}${describeErrorText}`))\n if (config.showErrorTrace) {\n const describeErrorStack = (\n typeof describeError === 'object'\n && describeError !== null\n && 'stack' in describeError\n && typeof describeError.stack === 'string'\n )\n ? describeError.stack\n : ''\n out()\n out(chalk.grey(describeErrorStack))\n }\n out()\n }\n\n for (const itResult of describeResult.itResults) {\n const letters = indexNumberToLetters(itResult.counter) ?? ''\n const itTime = chalk.grey` ${itResult.time.toLocaleString()}ms`\n if (itResult.success === true) {\n out(chalk.lightgrey`${indent}${letters})`\n + chalk.mediumgreen` ${figures.tick} ${itResult.should}` + itTime)\n } else {\n out(chalk.lightgrey`${indent}${letters})`\n + chalk.mediumred` ${figures.cross} ${itResult.should}` + itTime)\n out()\n const spacer = `${indent}${' '.repeat(letters.length)} `\n const err = itResult.error\n if (err) {\n if (isAssertionLike(err)) {\n out(chalk.mediumred(\n `${spacer}Assertion Failed: ${alignMessage(err.message, spacer)}`\n ))\n // shown whenever the error carries them, so a falsy actual or\n // expected - 0, '', false, null - still gets its diff\n const valueColumn = `${spacer} `\n out(\n _chalk.yellow`${spacer}Actual ${showValue(err.actual, valueColumn)}\\n`\n + _chalk.blueBright`${spacer}Expected ${showValue(err.expected, valueColumn)}`\n )\n } else {\n out(chalk.mediumred(\n `${spacer}${err.name}: ${alignMessage(err.message, spacer)}`\n ))\n }\n // stack trace\n if (config.showErrorTrace) {\n out()\n out(chalk.grey(err.stack ?? ''))\n }\n }\n }\n\n out()\n if (itResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n itResult.logs.forEach(log => {\n out(...log)\n })\n out()\n }\n }\n }\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"showTestResult.js","sourceRoot":"","sources":["../../../src/cli/lib/showTestResult.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport type { Expand } from 'sxy-lib/types/Expand.js'\nimport { inspect } from 'node:util'\n\nimport type { FinalConfig, OutFn } from '../../types.js'\nimport type { TestResult } from './runTest.js'\nimport chalk from '../../packages/chalk.js'\nimport figures from '../../packages/figures.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { showTimeProfiling } from '../../config.js'\nimport { out as mainOut } from '../../output.js'\nimport { indexNumberToLetters } from '../../indexNumberToLetters.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\n// Assertion failures are recognised by shape, not by where they came from. Importing an\n// assertion library to test `instanceof` against cannot work here: the runner would need it\n// as a dependency, and the copy a test file throws from is a separate ESM instance anyway,\n// so the check fails for the very errors it is meant to catch.\n\n\ninterface ErrorLike {\n name: string\n message: string\n stack?: unknown\n cause?: unknown\n}\ninterface AssertionLike extends ErrorLike {\n actual?: unknown\n expected?: unknown\n}\nfunction IsErrorLike(v: unknown): v is Expand<ErrorLike> {\n return typeof v === 'object' && v !== null\n && 'name' in v && typeof v.name === 'string'\n && 'message' in v && typeof v.message === 'string'\n}\nfunction ErrorLikeIsAssertionLike(v: ErrorLike): v is Expand<AssertionLike> {\n return ('actual' in v || 'expected' in v)\n}\n\n\n// Node's assertion messages run to several lines. Later lines are indented to the message\n// column and blank ones dropped; a single line message passes through untouched.\nfunction alignMessage(message: string, spacer: string): string {\n return message.split('\\n').reduce<string[]>(\n (previous, line) => (previous.length === 0)\n ? [line]\n : (line.trim()) ? [...previous, spacer + line] : previous,\n []\n ).join('\\n')\n}\n\n// A multi line string is shown as text, indented under its label. inspect() would render it\n// as one quoted chunk per line joined with `+`, which buries the content it is there to\n// show. Everything else - objects, and single line strings, whose quotes reveal padding and\n// emptiness - still goes through inspect.\nfunction showValue(value: unknown, column: string): string {\n if (typeof value !== 'string' || !value.includes('\\n')) {\n return inspect(value, { depth: 5 })\n }\n return value.split('\\n').join(`\\n${column}`)\n}\n\nfunction display(u: unknown): string {\n if (typeof u === 'string') return u\n return inspect(u)\n}\n\nexport async function showTestResult(config: FinalConfig, testResult: TestResult, customOut?: OutFn): Promise<void> {\n const out = customOut ?? mainOut\n\n await timeProfileAsync('show test result', () => {\n out()\n out(chalk.grey`File ${testResult.sourceFile ?? testResult.file}`)\n\n const indent = ' '\n\n if (testResult.logs.length > 0) {\n out()\n out(chalk.grey`console.logs:`)\n testResult.logs.forEach(log => {\n out(...log)\n })\n out()\n }\n\n let first = true\n\n for (const describeResult of testResult.describeResults) {\n if (!first) out()\n first = false\n\n out(chalk.lightgrey`${describeResult.counter}) describing ` + chalk.brightblue(describeResult.thing)\n + chalk.grey` ${describeResult.time.toLocaleString()}ms`)\n out()\n\n if (describeResult.logs && describeResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n describeResult.logs.forEach(log => {\n out(...log)\n })\n out()\n }\n\n if ('error' in describeResult) {\n const describeError = describeResult.error\n\n out(chalk.mediumred(`${indent}Threw:`))\n if (IsErrorLike(describeError)) {\n out(chalk.mediumred(`${indent}${describeError.name}: ${describeError.message}`))\n if (config.showErrorTrace && 'stack' in describeError) {\n out()\n out(chalk.grey(display(describeError.stack)))\n }\n } else {\n out(chalk.mediumred(`${indent}${display(describeError)}`))\n }\n out()\n }\n\n for (const itResult of describeResult.itResults) {\n const letters = indexNumberToLetters(itResult.counter) ?? ''\n const itTime = chalk.grey` ${itResult.time.toLocaleString()}ms`\n if (itResult.success === true) {\n out(chalk.lightgrey`${indent}${letters})`\n + chalk.mediumgreen` ${figures.tick} ${itResult.should}` + itTime)\n } else {\n out(chalk.lightgrey`${indent}${letters})`\n + chalk.mediumred` ${figures.cross} ${itResult.should}` + itTime)\n out()\n const spacer = `${indent}${' '.repeat(letters.length)} `\n if ('error' in itResult) {\n const err = itResult.error\n if (IsErrorLike(err)) {\n if (ErrorLikeIsAssertionLike(err)) {\n out(chalk.mediumred(\n //`${spacer}Assertion Failed: ${alignMessage(err.message, spacer)}`\n `${spacer}${err.name}: ${alignMessage(err.message, spacer)}`\n ))\n // shown whenever the error carries them, so a falsy actual or\n // expected - 0, '', false, null - still gets its diff\n const valueColumn = `${spacer} `\n out(\n chalk.yellow`${spacer}Actual ${showValue(err.actual, valueColumn)}\\n`\n + chalk.brightblue`${spacer}Expected ${showValue(err.expected, valueColumn)}`\n )\n } else {\n out(chalk.mediumred(\n `${spacer}${err.name}: ${alignMessage(err.message, spacer)}`\n ))\n }\n // stack trace\n if (config.showErrorTrace && 'stack' in err) {\n out()\n out(chalk.grey(display(err.stack)))\n }\n } else {\n out(chalk.mediumred(\n `${spacer}${display(err)}`\n ))\n }\n }\n }\n\n out()\n if (itResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n itResult.logs.forEach(log => {\n out(...log)\n })\n out()\n }\n }\n }\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"showTtyHelp.js","sourceRoot":"","sources":["../../../src/cli/lib/showTtyHelp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"showTtyHelp.js","sourceRoot":"","sources":["../../../src/cli/lib/showTtyHelp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,yBAAyB,CAAA;AAC3C,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGhD,MAAM,UAAU,WAAW,CACvB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAC3B,YAAmB,OAAO;IAE1B,IAAI,CAAC,KAAK;QAAE,OAAM;IAElB,SAAS,CAAC,KAAK,CAAC,IAAI,CAChB,sDAAsD,CACzD,CAAC,CAAA;AACN,CAAC","sourcesContent":["\nimport type { OutFn } from '../../types.js'\nimport chalk from '../../packages/chalk.js'\nimport { out as mainOut } from '../../output.js'\n\n\nexport function showTtyHelp(\n isTty = process.stdin.isTTY,\n customOut: OutFn = mainOut\n): void {\n if (!isTty) return\n\n customOut(chalk.grey(\n 'a = re-run all, l = re-run last, f = re-run failures'\n ))\n}\n"]}
|
|
@@ -5,5 +5,5 @@ export interface ShutdownOptions {
|
|
|
5
5
|
timeoutMs?: number;
|
|
6
6
|
}
|
|
7
7
|
export declare function makeShutdown(config: FinalConfig, options: ShutdownOptions): (signal: string) => Promise<void>;
|
|
8
|
-
export declare function registerShutdownHandlers(config: FinalConfig, options: ShutdownOptions): void;
|
|
8
|
+
export declare function registerShutdownHandlers(config: FinalConfig, options: ShutdownOptions): () => void;
|
|
9
9
|
//# sourceMappingURL=shutdown.d.ts.map
|
package/dist/cli/lib/shutdown.js
CHANGED
|
@@ -50,10 +50,18 @@ export function makeShutdown(config, options) {
|
|
|
50
50
|
}
|
|
51
51
|
export function registerShutdownHandlers(config, options) {
|
|
52
52
|
const shutdown = makeShutdown(config, options);
|
|
53
|
-
|
|
53
|
+
const handlers = shutdownSignals.map(signal => {
|
|
54
|
+
const handler = () => { void shutdown(signal); };
|
|
54
55
|
// attaching a listener replaces the default behaviour for these signals, so shutdown
|
|
55
56
|
// is now solely responsible for actually ending the process
|
|
56
|
-
process.on(signal,
|
|
57
|
-
|
|
57
|
+
process.on(signal, handler);
|
|
58
|
+
return [signal, handler];
|
|
59
|
+
});
|
|
60
|
+
return () => {
|
|
61
|
+
for (const [signal, handler] of handlers) {
|
|
62
|
+
process.off(signal, handler);
|
|
63
|
+
}
|
|
64
|
+
handlers.length = 0; // idempotency
|
|
65
|
+
};
|
|
58
66
|
}
|
|
59
67
|
//# sourceMappingURL=shutdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/cli/lib/shutdown.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/cli/lib/shutdown.ts"],"names":[],"mappings":"AACA,wFAAwF;AACxF,6FAA6F;AAC7F,0CAA0C;AAC1C,EAAE;AACF,4FAA4F;AAC5F,8FAA8F;AAC9F,qFAAqF;AAKrF,+FAA+F;AAC/F,+EAA+E;AAC/E,oCAAoC;AACpC,2FAA2F;AAC3F,0FAA0F;AAC1F,yEAAyE;AACzE,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAU,CAAA;AAElE,MAAM,eAAe,GAA2B;IAC5C,MAAM,EAAE,GAAG;IACX,QAAQ,EAAE,GAAG;IACb,OAAO,EAAE,GAAG;CACf,CAAA;AASD,SAAS,KAAK,CAAC,EAAU;IACrB,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QACrC,iDAAiD;QACjD,KAAK,CAAC,KAAK,EAAE,CAAA;IACjB,CAAC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,UAAU,YAAY,CACxB,MAAmB,EACnB,OAAwB;IAExB,IAAI,WAAW,GAAG,KAAK,CAAA;IAEvB,OAAO,KAAK,UAAU,QAAQ,CAAC,MAAc;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAE7C,mEAAmE;QACnE,IAAI,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACtB,OAAM;QACV,CAAC;QACD,WAAW,GAAG,IAAI,CAAA;QAElB,IAAI,CAAC;YACD,MAAM,OAAO,CAAC,IAAI,CAAC;gBACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACxB,KAAK,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;aACnC,CAAC,CAAA;QACN,CAAC;QAAC,MAAM,CAAC;YACL,2DAA2D;QAC/D,CAAC;gBAAS,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC1B,CAAC;IACL,CAAC,CAAA;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB,CACpC,MAAmB,EACnB,OAAwB;IAExB,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE9C,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QAC1C,MAAM,OAAO,GAAG,GAAG,EAAE,GAAG,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAA;QAC/C,qFAAqF;QACrF,4DAA4D;QAC5D,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,CAAU,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,EAAE;QACR,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAChC,CAAC;QACD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA,CAAC,cAAc;IACtC,CAAC,CAAA;AACL,CAAC","sourcesContent":["\n// Watch mode never finishes - it parks on a promise that never settles - so there is no\n// natural point at which to run the user's teardown. The only way it gets a chance is on the\n// way out, when the process is signalled.\n//\n// All the logic lives in makeShutdown so it can be tested by calling the returned function.\n// registerShutdownHandlers is deliberately trivial: attaching the listeners is the one part a\n// test cannot exercise, because delivering a real signal would kill the test runner.\n\nimport type { FinalConfig } from '../../types.js'\n\n\n// SIGINT - ctrl-c. In watch mode with ttyActionsOnKeypress the terminal is in raw mode, so the\n// OS does not raise it; listenToUser re-raises it by hand when it sees ctrl-c.\n// SIGBREAK - ctrl-break on Windows.\n// SIGTERM - not delivered by Windows, but the usual way a POSIX/CI parent asks us to stop.\n// SIGHUP is left out on purpose: Windows hard-kills roughly ten seconds after the console\n// window closes, so honouring it would only ever be a partial guarantee.\nconst shutdownSignals = ['SIGINT', 'SIGBREAK', 'SIGTERM'] as const\n\nconst signalExitCodes: Record<string, number> = {\n SIGINT: 130,\n SIGBREAK: 130,\n SIGTERM: 143\n}\n\nexport interface ShutdownOptions {\n teardown: (config: FinalConfig) => Promise<void>\n exit: (code: number) => void\n // how long teardown gets before we leave anyway\n timeoutMs?: number\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n const timer = setTimeout(resolve, ms)\n // must not be the reason the process stays alive\n timer.unref()\n })\n}\n\nexport function makeShutdown(\n config: FinalConfig,\n options: ShutdownOptions\n): (signal: string) => Promise<void> {\n let tearingDown = false\n\n return async function shutdown(signal: string): Promise<void> {\n const exitCode = signalExitCodes[signal] ?? 0\n\n // a second signal means the user is not willing to wait any longer\n if (tearingDown) {\n options.exit(exitCode)\n return\n }\n tearingDown = true\n\n try {\n await Promise.race([\n options.teardown(config),\n delay(options.timeoutMs ?? 5000)\n ])\n } catch {\n // a failing teardown must not trap the user in the process\n } finally {\n options.exit(exitCode)\n }\n }\n}\n\nexport function registerShutdownHandlers(\n config: FinalConfig,\n options: ShutdownOptions\n): () => void {\n const shutdown = makeShutdown(config, options)\n \n const handlers = shutdownSignals.map(signal => {\n const handler = () => { void shutdown(signal) }\n // attaching a listener replaces the default behaviour for these signals, so shutdown\n // is now solely responsible for actually ending the process\n process.on(signal, handler)\n return [signal, handler] as const\n })\n\n return () => {\n for (const [signal, handler] of handlers) {\n process.off(signal, handler)\n }\n handlers.length = 0 // idempotency\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statusFile.js","sourceRoot":"","sources":["../../../src/cli/lib/statusFile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"statusFile.js","sourceRoot":"","sources":["../../../src/cli/lib/statusFile.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport fs from 'fs'\nimport path from 'path'\n\nimport type { FinalConfig } from '../../types.js'\nimport chalk from '../../packages/chalk.js'\nimport { packageName } from '../../config.js'\nimport { log } from '../../output.js'\n\n\n// The status file holds the result of the latest run: `<code> - <description>` on the first\n// line, then any detail. Watch mode resets it to -1 on startup so a stale result is never\n// mistaken for the current one.\nexport const statusCodes = {\n notRunYet: -1, // watch mode has started, but no run has finished\n passed: 0,\n failed: 1, // tests ran and failed\n aborted: 2, // the run died partway - a test file failed to load, or a describe threw\n couldNotRun: 3 // nothing ran at all - no test files, or no match for the filters\n} as const\n\nexport type StatusCode = typeof statusCodes[keyof typeof statusCodes]\n\n// The same states as words, for the agent stream. A number needs the table above to mean\n// anything; a reader of one line should not have to go and find it. Defined here so the two\n// cannot drift apart.\nexport const statusNames: Record<StatusCode, string> = {\n [statusCodes.notRunYet]: 'not-run',\n [statusCodes.passed]: 'passed',\n [statusCodes.failed]: 'failed',\n [statusCodes.aborted]: 'aborted',\n [statusCodes.couldNotRun]: 'could-not-run'\n}\n\nexport function resetStatusFile(config: FinalConfig): void {\n writeStatusFile(config, statusCodes.notRunYet, 'no run has finished yet')\n}\n\nexport function writeStatusFile(\n config: FinalConfig,\n code: StatusCode,\n description: string,\n details: string[] = [],\n durationMs?: number\n): void {\n write(config, [\n `${code} - ${description}`,\n localTime(new Date()),\n ...details,\n ...(durationMs === undefined) ? [] : [`${durationMs.toLocaleString()}ms`]\n ].join('\\n') + '\\n')\n}\n\n// local time, so the file reads the way the terminal beside it does, with the offset so a\n// reader elsewhere can still place it\nfunction localTime(date: Date): string {\n const pad = (value: number): string => String(value).padStart(2, '0')\n // getTimezoneOffset() counts minutes behind UTC, so the sign is the other way round\n const offsetMinutes = -date.getTimezoneOffset()\n const offset = `${(offsetMinutes < 0) ? '-' : '+'}`\n + `${pad(Math.floor(Math.abs(offsetMinutes) / 60))}:${pad(Math.abs(offsetMinutes) % 60)}`\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n + ` ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`\n + ` ${offset}`\n}\n\nfunction write(config: FinalConfig, contents: string): void {\n const statusFile = config.watch.statusFile\n if (typeof statusFile !== 'string' || statusFile === '') return\n\n const location = path.resolve(process.cwd(), statusFile)\n // written via a temp file and renamed, so a poller never reads a half written status\n const tempLocation = `${location}.${process.pid}.tmp`\n try {\n fs.mkdirSync(path.dirname(location), { recursive: true })\n fs.writeFileSync(tempLocation, contents)\n fs.renameSync(tempLocation, location)\n } catch (error) {\n // never let the status file take the run down with it\n log(chalk.mediumred(\n `[${packageName}] Could not write status file ${location}: ${String(error)}`\n ))\n try { fs.rmSync(tempLocation, { force: true }) } catch { /* nothing more to do */ }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stopSignal.js","sourceRoot":"","sources":["../../../src/cli/lib/stopSignal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stopSignal.js","sourceRoot":"","sources":["../../../src/cli/lib/stopSignal.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,cAAc;IAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AAC7B,CAAC;AAED,2FAA2F;AAC3F,mBAAmB;AACnB,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,IAAgB,EAAE,MAAe;IACjF,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM;QAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;AACtD,CAAC","sourcesContent":["\nimport type { FinalConfig } from '../../types.js'\n\n\n// Shared by one run, so the file, describe and test loops can all see that something has\n// failed and stop starting new work. Deliberately a signal the loops *check* rather than an\n// exception: breaking out leaves every afterEach/teardown to unwind as it normally would.\nexport interface StopSignal {\n stopped: boolean\n}\n\nexport function makeStopSignal(): StopSignal {\n return { stopped: false }\n}\n\n// `failed` covers all three: a test file that would not load, a describe that threw, and a\n// test that failed\nexport function stopIfFailFast(config: FinalConfig, stop: StopSignal, failed: boolean): void {\n if (config.failFast && failed) stop.stopped = true\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeProfier.js","sourceRoot":"","sources":["../../../src/cli/lib/timeProfier.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timeProfier.js","sourceRoot":"","sources":["../../../src/cli/lib/timeProfier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAGnD,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAA;AAE/E,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAA","sourcesContent":["\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { showTimeProfiling } from '../../config.js'\n\n\nconst { timeProfile, timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport { timeProfile, timeProfileAsync }\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateConfig.js","sourceRoot":"","sources":["../../../src/cli/lib/validateConfig.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validateConfig.js","sourceRoot":"","sources":["../../../src/cli/lib/validateConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGhD,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,SAAiB;IACjE,MAAM,GAAG,GAAG,SAAS,IAAI,OAAO,CAAA;IAEhC,SAAS,OAAO,CAAC,OAAe;QAC5B,GAAG,CAAC,OAAO,CAAC,CAAA;QACZ,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,+CAA+C,CAAC,CAAA;IAC5D,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;QACnF,OAAO,CAAC,+EAA+E,CAAC,CAAA;IAC5F,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,SAAS,KAAK,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,SAAS,KAAK,YAAY,EAAE,CAAC;QAC3F,OAAO,CAAC,mFAAmF,CAAC,CAAA;IAChG,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;QACnF,OAAO,CAAC,+EAA+E,CAAC,CAAA;IAC5F,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACzD,OAAO,CAAC,qEAAqE,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAA;IAC1C,IAAI,UAAU,KAAK,KAAK,IAAI,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,EAAE,CAAC,EAAE,CAAC;QAChF,OAAO,CAAC,sEAAsE,CAAC,CAAA;IACnF,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,CAAC,sDAAsD,CAAC,CAAA;IACnE,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACzD,OAAO,CAAC,qEAAqE,CAAC,CAAA;IAClF,CAAC;AACL,CAAC","sourcesContent":["\nimport type { FinalConfig, OutFn } from '../../types.js'\nimport { out as mainOut } from '../../output.js'\n\n\nexport function validateConfig(config: FinalConfig, customOut?: OutFn): void {\n const out = customOut ?? mainOut\n\n function doError(message: string): never {\n out(message)\n throw new Error(message)\n }\n\n if (config.execution === undefined) {\n doError('Config error, config.execution is not defined')\n }\n\n if (config.execution.files !== 'parallel' && config.execution.files !== 'sequential') {\n doError('Config error, config.execution.files should be \\'parallel\\' or \\'sequential\\'')\n }\n\n if (config.execution.describes !== 'parallel' && config.execution.describes !== 'sequential') {\n doError('Config error, config.execution.describes should be \\'parallel\\' or \\'sequential\\'')\n }\n\n if (config.execution.tests !== 'parallel' && config.execution.tests !== 'sequential') {\n doError('Config error, config.execution.tests should be \\'parallel\\' or \\'sequential\\'')\n }\n\n if (typeof config.watch.ttyActionsOnKeypress !== 'boolean') {\n doError('Config error, config.watch.ttyActionsOnKeypress should be a boolean')\n }\n\n const statusFile = config.watch.statusFile\n if (statusFile !== false && (typeof statusFile !== 'string' || statusFile === '')) {\n doError('Config error, config.watch.statusFile should be false or a file path')\n }\n\n if (typeof config.watch.agent !== 'boolean') {\n doError('Config error, config.watch.agent should be a boolean')\n }\n\n if (typeof config.watch.dependencyEvaluation !== 'boolean') {\n doError('Config error, config.watch.dependencyEvaluation should be a boolean')\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchFilesAndRunTests.js","sourceRoot":"","sources":["../../../src/cli/lib/watchFilesAndRunTests.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watchFilesAndRunTests.js","sourceRoot":"","sources":["../../../src/cli/lib/watchFilesAndRunTests.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,IAAI,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAE7G,6GAA6G","sourcesContent":["\nexport { watchFilesAndRunTestsNodeWatch as watchFilesAndRunTests } from './watchFilesAndRunTestsNodeWatch.js'\n\n//export { watchFilesAndRunTestsChokidar as watchFilesAndRunTests } from './watchFilesAndRunTestsChokidar.js'\n"]}
|
|
@@ -24,9 +24,9 @@ export {};
|
|
|
24
24
|
// watchRunState: ReRunManageState,
|
|
25
25
|
// customOut?: OutFn,
|
|
26
26
|
// executionFilters: TestExecutionFilters = {}
|
|
27
|
-
// ): Promise<
|
|
27
|
+
// ): Promise<FSWatcher> {
|
|
28
28
|
// const projectDir = process.cwd()
|
|
29
|
-
//
|
|
29
|
+
// return timeProfileAsync('start watching', async () => {
|
|
30
30
|
// let changedFiles: Array<[string, string]> = []
|
|
31
31
|
// let timeout: ReturnType<typeof setTimeout> | null = null
|
|
32
32
|
// const testFilter = (file: string): boolean => {
|
|
@@ -39,7 +39,7 @@ export {};
|
|
|
39
39
|
// )
|
|
40
40
|
// }
|
|
41
41
|
// // start watching
|
|
42
|
-
//
|
|
42
|
+
// return watchFilesChokidar(config, watchEvent)
|
|
43
43
|
// function watchEvent(filename: string, event: string): void {
|
|
44
44
|
// debug('chokidar watch event', filename, event)
|
|
45
45
|
// // remove dep tree for any tests that are deleted, avoiding trying to run it later
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchFilesAndRunTestsChokidar.js","sourceRoot":"","sources":["../../../src/cli/lib/watchFilesAndRunTestsChokidar.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watchFilesAndRunTestsChokidar.js","sourceRoot":"","sources":["../../../src/cli/lib/watchFilesAndRunTestsChokidar.ts"],"names":[],"mappings":"AACA,sEAAsE;AACtE,sDAAsD;AACtD,8CAA8C;AAC9C,oCAAoC;AACpC,8CAA8C;AAC9C,oDAAoD;;AAEpD,2CAA2C;AAC3C,iEAAiE;AACjE,uDAAuD;AACvD,+DAA+D;AAC/D,uCAAuC;AACvC,4DAA4D;AAE5D,kGAAkG;AAClG,4DAA4D;AAC5D,mDAAmD;AAEnD,qEAAqE;AAErE,uDAAuD;AACvD,2BAA2B;AAC3B,2BAA2B;AAC3B,wCAAwC;AACxC,8BAA8B;AAC9B,8DAA8D;AAC9D,uCAAuC;AACvC,yBAAyB;AACzB,kDAAkD;AAClD,0BAA0B;AAC1B,uCAAuC;AAEvC,8DAA8D;AAC9D,yDAAyD;AACzD,mEAAmE;AAEnE,0DAA0D;AAC1D,mEAAmE;AACnE,0EAA0E;AAC1E,uBAAuB;AACvB,uDAAuD;AACvD,mDAAmD;AACnD,4EAA4E;AAC5E,oBAAoB;AACpB,YAAY;AAEZ,4BAA4B;AAC5B,wDAAwD;AAExD,uEAAuE;AACvE,6DAA6D;AAE7D,iGAAiG;AACjG,uEAAuE;AACvE,mDAAmD;AACnD,mDAAmD;AACnD,gBAAgB;AAEhB,yCAAyC;AACzC,8DAA8D;AAE9D,+CAA+C;AAC/C,mDAAmD;AAEnD,6FAA6F;AAC7F,6BAA6B;AAC7B,wCAAwC;AACxC,gBAAgB;AAEhB,2CAA2C;AAC3C,8EAA8E;AAC9E,2DAA2D;AAC3D,4BAA4B;AAC5B,qDAAqD;AACrD,qDAAqD;AACrD,0EAA0E;AAC1E,mDAAmD;AACnD,sDAAsD;AACtD,kIAAkI;AAClI,uGAAuG;AACvG,gEAAgE;AAChE,uDAAuD;AACvD,6FAA6F;AAC7F,+EAA+E;AAC/E,2DAA2D;AAC3D,wCAAwC;AACxC,oCAAoC;AACpC,gCAAgC;AAChC,+DAA+D;AAC/D,sDAAsD;AACtD,6FAA6F;AAC7F,2EAA2E;AAC3E,+HAA+H;AAC/H,sEAAsE;AACtE,oDAAoD;AACpD,oCAAoC;AACpC,gCAAgC;AAChC,4BAA4B;AAE5B,4CAA4C;AAE5C,gDAAgD;AAEhD,8CAA8C;AAC9C,mGAAmG;AACnG,wDAAwD;AAExD,wDAAwD;AACxD,sEAAsE;AACtE,6FAA6F;AAE7F,gFAAgF;AAChF,4FAA4F;AAC5F,6DAA6D;AAE7D,+DAA+D;AAC/D,0DAA0D;AAE1D,uEAAuE;AACvE,8CAA8C;AAC9C,8CAA8C;AAC9C,oDAAoD;AACpD,iDAAiD;AACjD,qDAAqD;AACrD,iDAAiD;AACjD,uDAAuD;AACvD,oCAAoC;AACpC,iEAAiE;AACjE,iCAAiC;AACjC,4BAA4B;AAC5B,oCAAoC;AACpC,wDAAwD;AACxD,wBAAwB;AACxB,qBAAqB;AACrB,qBAAqB;AACrB,kCAAkC;AAElC,wDAAwD;AACxD,0CAA0C;AAC1C,2EAA2E;AAC3E,yDAAyD;AACzD,yEAAyE;AACzE,+CAA+C;AAC/C,YAAY;AACZ,SAAS;AAET,0FAA0F;AAC1F,uFAAuF;AACvF,qFAAqF;AACrF,4CAA4C;AAC5C,IAAI","sourcesContent":["\n// import { createTimeProfiler } from '../../packages/timeProfiler.js'\n// import { showTimeProfiling } from '../../config.js'\n// import chalk from '../../packages/chalk.js'\n// import minimatch from 'minimatch'\n// import slash from '../../packages/slash.js'\n// import { out, log, debug } from '../../output.js'\n\n// import { runTests } from './runTests.js'\n// import { buildDependencyTree } from './buildDependencyTree.js'\n// import { globArgCombine } from './globArgCombine.js'\n// import { watchFilesChokidar } from './watchFilesChokidar.js'\n// import { filter } from './filter.js'\n// import { remove as arrayRemove } from 'sxy-lib/arrays.js'\n\n// import type { FinalConfig, DependencyTrees, OutFn, TestExecutionFilters } from '../../types.js'\n// import { ReRunManageState } from './makeWatchRunState.js'\n// import { ReRunManager } from './reRunManager.js'\n\n// const { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\n// export async function watchFilesAndRunTestsChokidar(\n// config: FinalConfig,\n// testFiles: string[],\n// dependencyTrees: DependencyTrees,\n// failingTests: string[],\n// reRunManager: ReRunManager, // still needs to be incopr\n// watchRunState: ReRunManageState,\n// customOut?: OutFn,\n// executionFilters: TestExecutionFilters = {}\n// ): Promise<FSWatcher> {\n// const projectDir = process.cwd()\n\n// return timeProfileAsync('start watching', async () => {\n// let changedFiles: Array<[string, string]> = []\n// let timeout: ReturnType<typeof setTimeout> | null = null\n\n// const testFilter = (file: string): boolean => {\n// return minimatch(file, globArgCombine(config.tests))\n// && !minimatch(file, globArgCombine(config.testsIgnore))\n// && (\n// config.testsFilter === undefined\n// || config.testsFilter === ''\n// || filter(config.testsBase, config.testsFilter, file)\n// )\n// }\n\n// // start watching\n// return watchFilesChokidar(config, watchEvent)\n\n// function watchEvent(filename: string, event: string): void {\n// debug('chokidar watch event', filename, event)\n\n// // remove dep tree for any tests that are deleted, avoiding trying to run it later\n// if (event === 'remove' && filename in dependencyTrees) {\n// arrayRemove(testFiles, filename)\n// delete dependencyTrees[filename]\n// }\n\n// // info on the event found\n// out(chalk.grey`change: ${filename} (${event})`)\n\n// // add the file to changed files\n// changedFiles.push([filename, event])\n\n// // wait 100ms after any change before processing, to avoid multiple execution?\n// if (timeout) {\n// clearTimeout(timeout)\n// }\n\n// timeout = setTimeout(() => {\n// void timeProfileAsync('handle changed files', async () => {\n// debug('changed files', changedFiles)\n// try {\n// // build related test list\n// const tests: string[] = []\n// for (const [file, fileEvent] of changedFiles) {\n// debug('check', file)\n// debug('1 tests', tests)\n// if (fileEvent !== 'remove') { // only check if it's a test if it exists (has not just been removed)\n// if (testFilter(file)) { // it is a test file itself, add to run list\n// debug('its a test', file)\n// tests.push(file)\n// if (!(file in dependencyTrees)) { // if its a new test\n// debug('try to add a new test', file)\n// addNewTest(file)\n// }\n// }\n// }\n// debug('dtrees', dependencyTrees)\n// debug('2 tests', tests)\n// for (const f of Object.getOwnPropertyNames(dependencyTrees)) {\n// debug('dep tree', f, dependencyTrees[f])\n// if (dependencyTrees[f]?.some(dep => dep === file) === true) { // a test depends on this file\n// debug('its a dependency', file)\n// tests.push(f)\n// }\n// }\n// }\n\n// changedFiles = []\n\n// debug('tests', tests)\n\n// if (tests.length) {\n// await timeProfileAsync('run tests related to changes', async () => {\n// debug('tests', tests)\n\n// debug('tests', tests)\n// debug('failingTests', failingTests)\n// debug('reRunFailingTests', config.watch.reRunFailingTests)\n\n// const toTest = config.watch.reRunFailingTests\n// ? [...new Set([...tests, ...failingTests])].reverse()\n// : [...tests].reverse()\n\n// debug('run tests on change')\n// debug('toTest', toTest)\n\n// watchRunState.currentRun = runTests(\n// config,\n// toTest,\n// failingTests,\n// 'refresh',\n// watchRunState,\n// customOut,\n// executionFilters\n// )\n// await watchRunState.currentRun\n// })\n// }\n// } catch (e) {\n// log('watch handler error', e)\n// }\n// })\n// }, 33)\n// } // end of watch event\n\n// function addNewTest(testFile: string): void {\n// debug('new test', testFile)\n// const dependencyTree = buildDependencyTree(config, testFile)\n// dependencyTrees[testFile] = dependencyTree\n// .map(file => slash(file).slice(projectDir.length + 1))\n// .filter(f => f !== testFile)\n// }\n// })\n\n// // NOTE: \"watching...\" is intentionally NOT printed here. watch() already emits it,\n// // tied to a real milestone (the initial test run finishing, or no tests found).\n// // Printing it again here produced a duplicate \"watching...\" on every startup.\n// // out(chalk.brightblue`watching...`)\n// }\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { FinalConfig, DependencyTrees, OutFn
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import type { FinalConfig, DependencyTrees, OutFn } from '../../types.js';
|
|
2
|
+
import type { TestExecutionFilters } from '../cliTypes.js';
|
|
3
|
+
import type { ReRunManager } from './reRunManager.js';
|
|
4
|
+
import type { StopFn } from '../watch.js';
|
|
5
|
+
export declare function watchFilesAndRunTestsNodeWatch(config: FinalConfig, dependencyTrees: DependencyTrees, failingTests: string[], reRunManager: ReRunManager, customOut?: OutFn, executionFilters?: TestExecutionFilters): Promise<StopFn>;
|
|
4
6
|
//# sourceMappingURL=watchFilesAndRunTestsNodeWatch.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { createTimeProfiler } from '../../packages/timeProfiler.js';
|
|
2
|
-
import { showTimeProfiling } from '../../config.js';
|
|
3
|
-
import chalk from '../../packages/chalk.js';
|
|
4
1
|
import minimatch from 'minimatch';
|
|
2
|
+
import chalk from '../../packages/chalk.js';
|
|
5
3
|
import slash from '../../packages/slash.js';
|
|
4
|
+
import { createTimeProfiler } from '../../packages/timeProfiler.js';
|
|
5
|
+
import { showTimeProfiling } from '../../config.js';
|
|
6
6
|
import { out as mainOut, log, debug } from '../../output.js';
|
|
7
7
|
import { agentChange } from './agentReport.js';
|
|
8
8
|
import { runTests } from './runTests.js';
|
|
@@ -11,7 +11,7 @@ import { globArgCombine } from './globArgCombine.js';
|
|
|
11
11
|
import { addBasePath } from './addBasePath.js';
|
|
12
12
|
import { watchFilesNodeWatch } from './watchFilesNodeWatch.js';
|
|
13
13
|
import { filter } from './filter.js';
|
|
14
|
-
const { timeProfileAsync } = createTimeProfiler(showTimeProfiling);
|
|
14
|
+
const { timeProfile, timeProfileAsync } = createTimeProfiler(showTimeProfiling);
|
|
15
15
|
export async function watchFilesAndRunTestsNodeWatch(config,
|
|
16
16
|
//testFiles: Set<string>,
|
|
17
17
|
dependencyTrees, failingTests, reRunManager,
|
|
@@ -20,7 +20,7 @@ customOut, executionFilters = {}) {
|
|
|
20
20
|
const projectDir = process.cwd();
|
|
21
21
|
// agent mode passes a sink here, so its own change lines are the only ones printed
|
|
22
22
|
const out = customOut ?? mainOut;
|
|
23
|
-
|
|
23
|
+
return timeProfileAsync('init watching', async () => {
|
|
24
24
|
debug('failingTests', failingTests);
|
|
25
25
|
const testsGlobs = addBasePath(config.testsBase, config.tests);
|
|
26
26
|
const testsIgnoreGlobs = addBasePath(config.testsBase, config.testsIgnore);
|
|
@@ -38,7 +38,13 @@ customOut, executionFilters = {}) {
|
|
|
38
38
|
out('No config.watch.watchFilesBase provided, defaulting to \'.\'');
|
|
39
39
|
config.watch.watchFilesBase = '.';
|
|
40
40
|
}
|
|
41
|
-
await watchFilesNodeWatch(config, watchEvent);
|
|
41
|
+
const watcher = await watchFilesNodeWatch(config, watchEvent);
|
|
42
|
+
return () => {
|
|
43
|
+
watcher.close();
|
|
44
|
+
// a change seen just before stopping would otherwise still run its tests
|
|
45
|
+
if (timeout)
|
|
46
|
+
clearTimeout(timeout);
|
|
47
|
+
};
|
|
42
48
|
function watchEvent(filename, event) {
|
|
43
49
|
debug('handle watch event ', filename, event);
|
|
44
50
|
filename = slash(filename);
|
|
@@ -59,12 +65,13 @@ customOut, executionFilters = {}) {
|
|
|
59
65
|
agentChange(config, filename, event);
|
|
60
66
|
// add the file to changed files
|
|
61
67
|
changedFiles.push([filename, event]);
|
|
62
|
-
//
|
|
68
|
+
// 33ms debounce
|
|
69
|
+
const debounceMs = 33;
|
|
63
70
|
if (timeout) {
|
|
64
71
|
clearTimeout(timeout);
|
|
65
72
|
}
|
|
66
73
|
timeout = setTimeout(() => {
|
|
67
|
-
|
|
74
|
+
timeProfile('handle changed files', () => {
|
|
68
75
|
debug('changedFiles', changedFiles);
|
|
69
76
|
try {
|
|
70
77
|
// build related test list
|
|
@@ -112,7 +119,7 @@ customOut, executionFilters = {}) {
|
|
|
112
119
|
changedFiles = [];
|
|
113
120
|
debug('tests', tests);
|
|
114
121
|
if (tests.size > 0) {
|
|
115
|
-
|
|
122
|
+
timeProfile('build list of files to test and request a run', () => {
|
|
116
123
|
debug('tests', tests);
|
|
117
124
|
debug('reRunFailingTests', config.watch.reRunFailingTests);
|
|
118
125
|
// changes accumulate here because an 'auto' request made while a
|
|
@@ -120,7 +127,7 @@ customOut, executionFilters = {}) {
|
|
|
120
127
|
// edited in the meantime still has to be covered
|
|
121
128
|
reRunManager.state.untestedFiles
|
|
122
129
|
= reRunManager.state.untestedFiles.union(tests);
|
|
123
|
-
reRunManager.requestRun('auto', () => {
|
|
130
|
+
void reRunManager.requestRun('auto', () => {
|
|
124
131
|
// resolved when the run actually starts, not when it is
|
|
125
132
|
// queued, so a coalesced request picks up the later edits
|
|
126
133
|
const toTest = (config.watch.reRunFailingTests)
|
|
@@ -141,7 +148,7 @@ customOut, executionFilters = {}) {
|
|
|
141
148
|
log('watch handler error', e);
|
|
142
149
|
}
|
|
143
150
|
});
|
|
144
|
-
},
|
|
151
|
+
}, debounceMs);
|
|
145
152
|
} // end of watch event
|
|
146
153
|
function addNewTest(testFile) {
|
|
147
154
|
debug('new test', testFile);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchFilesAndRunTestsNodeWatch.js","sourceRoot":"","sources":["../../../src/cli/lib/watchFilesAndRunTestsNodeWatch.ts"],"names":[],"mappings":"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","sourcesContent":["import { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { showTimeProfiling } from '../../config.js'\nimport chalk from '../../packages/chalk.js'\nimport minimatch from 'minimatch'\nimport slash from '../../packages/slash.js'\nimport { out as mainOut, log, debug } from '../../output.js'\n\nimport { agentChange } from './agentReport.js'\nimport { runTests } from './runTests.js'\nimport { buildDependencyTree } from './buildDependencyTree.js'\nimport { globArgCombine } from './globArgCombine.js'\nimport { addBasePath } from './addBasePath.js'\nimport { watchFilesNodeWatch } from './watchFilesNodeWatch.js'\nimport { filter } from './filter.js'\nimport { remove as arrayRemove } from 'sxy-lib/arrays.js'\n\nimport type { FinalConfig, DependencyTrees, OutFn, TestExecutionFilters } from '../../types.js'\nimport { ReRunManageState } from './makeWatchRunState.js'\nimport { ReRunManager } from './reRunManager.js'\nimport { inspect } from 'util'\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport async function watchFilesAndRunTestsNodeWatch(\n config: FinalConfig,\n //testFiles: Set<string>,\n dependencyTrees: DependencyTrees,\n failingTests: string[],\n reRunManager: ReRunManager,\n //watchRunState: WatchRunState,\n customOut?: OutFn,\n executionFilters: TestExecutionFilters = {}\n): Promise<void> {\n const projectDir = process.cwd()\n // agent mode passes a sink here, so its own change lines are the only ones printed\n const out = customOut ?? mainOut\n\n await timeProfileAsync('init watching', async () => {\n debug('failingTests', failingTests)\n\n const testsGlobs = addBasePath(config.testsBase, config.tests)\n const testsIgnoreGlobs = addBasePath(config.testsBase, config.testsIgnore)\n\n // indentify a test file\n const testFilter = (file: string): boolean => {\n return minimatch(file, globArgCombine(testsGlobs))\n && !minimatch(file, globArgCombine(testsIgnoreGlobs))\n && (\n config.testsFilter === undefined\n || config.testsFilter === ''\n || filter(config.testsBase, config.testsFilter, file)\n )\n }\n\n let changedFiles: Array<[string, string]> = []\n let timeout: ReturnType<typeof setTimeout> | null = null\n\n if (config.watch.watchFilesBase === '') {\n out('No config.watch.watchFilesBase provided, defaulting to \\'.\\'')\n config.watch.watchFilesBase = '.'\n }\n\n await watchFilesNodeWatch(config, watchEvent)\n\n function watchEvent(filename: string, event: string): void {\n debug('handle watch event ', filename, event)\n\n filename = slash(filename)\n\n // remove dep tree for any tests that are deleted, avoiding trying to run it later\n if (event === 'remove') {\n debug('removing test', filename)\n if (filename in dependencyTrees) {\n reRunManager.state.allTestFiles.delete(filename)\n delete dependencyTrees[filename]\n } else if (!config.watch.dependencyEvaluation) {\n // without trees there is nothing to look the file up in\n reRunManager.state.allTestFiles.delete(filename)\n }\n }\n\n // info on the event found\n out(chalk.grey`change: ${filename} (${event})`)\n agentChange(config, filename, event)\n\n // add the file to changed files\n changedFiles.push([filename, event])\n\n // wait 100ms after any change before processing, to avoid multiple execution?\n if (timeout) {\n clearTimeout(timeout)\n }\n\n timeout = setTimeout(() => {\n void timeProfileAsync('handle changed files', async () => {\n debug('changedFiles', changedFiles)\n try {\n // build related test list\n //const tests: string[] = []\n const tests = new Set<string>\n for (const [file, fileEvent] of changedFiles) {\n debug('check', file)\n debug('1 tests', tests)\n if (fileEvent !== 'remove') { // only check if it's a test if it exists (has not just been removed)\n if (testFilter(file)) { // it is a test file itself, add to run list\n debug('its a test', file)\n //tests.push(file)\n tests.add(file)\n if (config.watch.dependencyEvaluation) {\n if (!(file in dependencyTrees)) { // if its a new test\n debug('try to add a new test', file)\n addNewTest(file)\n }\n } else {\n // no trees to record it in, so this is what makes a\n // newly created test part of the run set\n reRunManager.state.allTestFiles.add(file)\n }\n }\n }\n\n // with evaluation off there is nothing to map the change through:\n // any watched file could affect any test, so run the lot\n if (!config.watch.dependencyEvaluation) {\n for (const f of reRunManager.state.allTestFiles) tests.add(f)\n continue\n }\n\n debug('dtrees', dependencyTrees)\n debug('2 tests', tests)\n for (const f of Object.getOwnPropertyNames(dependencyTrees)) {\n debug('dep tree', f, dependencyTrees[f])\n if (dependencyTrees[f]?.some(dep => dep === file) === true) { // a test depends on this file\n debug('its a dependency', file)\n //tests.push(f)\n tests.add(f)\n }\n }\n }\n\n changedFiles = []\n\n debug('tests', tests)\n\n if (tests.size > 0) {\n await timeProfileAsync('build list of files to test and request a run', async () => {\n debug('tests', tests)\n debug('reRunFailingTests', config.watch.reRunFailingTests)\n\n // changes accumulate here because an 'auto' request made while a\n // run is in flight is coalesced into the queued one - everything\n // edited in the meantime still has to be covered\n reRunManager.state.untestedFiles\n = reRunManager.state.untestedFiles.union(tests)\n\n reRunManager.requestRun(\n 'auto',\n () => {\n // resolved when the run actually starts, not when it is\n // queued, so a coalesced request picks up the later edits\n const toTest = (config.watch.reRunFailingTests)\n ? reRunManager.state.untestedFiles\n .union(reRunManager.state.failedTestFiles)\n : new Set(reRunManager.state.untestedFiles)\n\n // consumed by this run - without this they are retested\n // on every later run for the rest of the session\n reRunManager.state.untestedFiles = new Set()\n\n debug('run tests on change')\n debug('toTest', toTest)\n\n return runTests(\n config,\n toTest,\n reRunManager,\n { limit: -1 },\n 'refresh',\n customOut,\n executionFilters\n )\n }\n )\n })\n }\n } catch (e) {\n log('watch handler error', e)\n }\n })\n }, 33)\n } // end of watch event\n\n function addNewTest(testFile: string): void {\n debug('new test', testFile)\n const dependencyTree = buildDependencyTree(config, testFile)\n dependencyTrees[testFile] = dependencyTree\n .map(file => slash(file).slice(projectDir.length + 1))\n .filter(f => f !== testFile)\n }\n })\n\n // NOTE: \"watching...\" is intentionally NOT printed here. watch() already emits it,\n // tied to a real milestone (the initial test run finishing, or no tests found).\n // Printing it again here produced a duplicate \"watching...\" on every startup.\n // out(chalk.brightblue`watching...`)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"watchFilesAndRunTestsNodeWatch.js","sourceRoot":"","sources":["../../../src/cli/lib/watchFilesAndRunTestsNodeWatch.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport minimatch from 'minimatch'\n\nimport type { FinalConfig, DependencyTrees, OutFn } from '../../types.js'\nimport type { TestExecutionFilters } from '../cliTypes.js'\nimport type { ReRunManager } from './reRunManager.js'\nimport type { StopFn } from '../watch.js'\nimport chalk from '../../packages/chalk.js'\nimport slash from '../../packages/slash.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { showTimeProfiling } from '../../config.js'\nimport { out as mainOut, log, debug } from '../../output.js'\nimport { agentChange } from './agentReport.js'\nimport { runTests } from './runTests.js'\nimport { buildDependencyTree } from './buildDependencyTree.js'\nimport { globArgCombine } from './globArgCombine.js'\nimport { addBasePath } from './addBasePath.js'\nimport { watchFilesNodeWatch } from './watchFilesNodeWatch.js'\nimport { filter } from './filter.js'\n\n\nconst { timeProfile, timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport async function watchFilesAndRunTestsNodeWatch(\n config: FinalConfig,\n //testFiles: Set<string>,\n dependencyTrees: DependencyTrees,\n failingTests: string[],\n reRunManager: ReRunManager,\n //watchRunState: WatchRunState,\n customOut?: OutFn,\n executionFilters: TestExecutionFilters = {}\n): Promise<StopFn> {\n const projectDir = process.cwd()\n // agent mode passes a sink here, so its own change lines are the only ones printed\n const out = customOut ?? mainOut\n\n return timeProfileAsync('init watching', async () => {\n debug('failingTests', failingTests)\n\n const testsGlobs = addBasePath(config.testsBase, config.tests)\n const testsIgnoreGlobs = addBasePath(config.testsBase, config.testsIgnore)\n\n // indentify a test file\n const testFilter = (file: string): boolean => {\n return minimatch(file, globArgCombine(testsGlobs))\n && !minimatch(file, globArgCombine(testsIgnoreGlobs))\n && (\n config.testsFilter === undefined\n || config.testsFilter === ''\n || filter(config.testsBase, config.testsFilter, file)\n )\n }\n\n let changedFiles: Array<[string, string]> = []\n let timeout: ReturnType<typeof setTimeout> | null = null\n\n if (config.watch.watchFilesBase === '') {\n out('No config.watch.watchFilesBase provided, defaulting to \\'.\\'')\n config.watch.watchFilesBase = '.'\n }\n\n const watcher = await watchFilesNodeWatch(config, watchEvent)\n return () => {\n watcher.close()\n // a change seen just before stopping would otherwise still run its tests\n if (timeout) clearTimeout(timeout)\n }\n\n function watchEvent(filename: string, event: string): void {\n debug('handle watch event ', filename, event)\n\n filename = slash(filename)\n\n // remove dep tree for any tests that are deleted, avoiding trying to run it later\n if (event === 'remove') {\n debug('removing test', filename)\n if (filename in dependencyTrees) {\n reRunManager.state.allTestFiles.delete(filename)\n delete dependencyTrees[filename]\n } else if (!config.watch.dependencyEvaluation) {\n // without trees there is nothing to look the file up in\n reRunManager.state.allTestFiles.delete(filename)\n }\n }\n\n // info on the event found\n out(chalk.grey`change: ${filename} (${event})`)\n agentChange(config, filename, event)\n\n // add the file to changed files\n changedFiles.push([filename, event])\n\n // 33ms debounce\n const debounceMs = 33\n if (timeout) {\n clearTimeout(timeout)\n }\n timeout = setTimeout(() => {\n timeProfile('handle changed files', () => {\n debug('changedFiles', changedFiles)\n try {\n // build related test list\n //const tests: string[] = []\n const tests = new Set<string>\n for (const [file, fileEvent] of changedFiles) {\n debug('check', file)\n debug('1 tests', tests)\n if (fileEvent !== 'remove') { // only check if it's a test if it exists (has not just been removed)\n if (testFilter(file)) { // it is a test file itself, add to run list\n debug('its a test', file)\n //tests.push(file)\n tests.add(file)\n if (config.watch.dependencyEvaluation) {\n if (!(file in dependencyTrees)) { // if its a new test\n debug('try to add a new test', file)\n addNewTest(file)\n }\n } else {\n // no trees to record it in, so this is what makes a\n // newly created test part of the run set\n reRunManager.state.allTestFiles.add(file)\n }\n }\n }\n\n // with evaluation off there is nothing to map the change through:\n // any watched file could affect any test, so run the lot\n if (!config.watch.dependencyEvaluation) {\n for (const f of reRunManager.state.allTestFiles) tests.add(f)\n continue\n }\n\n debug('dtrees', dependencyTrees)\n debug('2 tests', tests)\n for (const f of Object.getOwnPropertyNames(dependencyTrees)) {\n debug('dep tree', f, dependencyTrees[f])\n if (dependencyTrees[f]?.some(dep => dep === file) === true) { // a test depends on this file\n debug('its a dependency', file)\n //tests.push(f)\n tests.add(f)\n }\n }\n }\n\n changedFiles = []\n\n debug('tests', tests)\n\n if (tests.size > 0) {\n timeProfile('build list of files to test and request a run',\n () => {\n debug('tests', tests)\n debug('reRunFailingTests', config.watch.reRunFailingTests)\n\n // changes accumulate here because an 'auto' request made while a\n // run is in flight is coalesced into the queued one - everything\n // edited in the meantime still has to be covered\n reRunManager.state.untestedFiles\n = reRunManager.state.untestedFiles.union(tests)\n\n void reRunManager.requestRun(\n 'auto',\n () => {\n // resolved when the run actually starts, not when it is\n // queued, so a coalesced request picks up the later edits\n const toTest = (config.watch.reRunFailingTests)\n ? reRunManager.state.untestedFiles\n .union(reRunManager.state.failedTestFiles)\n : new Set(reRunManager.state.untestedFiles)\n\n // consumed by this run - without this they are retested\n // on every later run for the rest of the session\n reRunManager.state.untestedFiles = new Set()\n\n debug('run tests on change')\n debug('toTest', toTest)\n\n return runTests(\n config,\n toTest,\n reRunManager,\n { limit: -1 },\n 'refresh',\n customOut,\n executionFilters\n )\n }\n )\n }\n )\n }\n } catch (e) {\n log('watch handler error', e)\n }\n })\n }, debounceMs)\n } // end of watch event\n\n function addNewTest(testFile: string): void {\n debug('new test', testFile)\n const dependencyTree = buildDependencyTree(config, testFile)\n dependencyTrees[testFile] = dependencyTree\n .map(file => slash(file).slice(projectDir.length + 1))\n .filter(f => f !== testFile)\n }\n })\n\n // NOTE: \"watching...\" is intentionally NOT printed here. watch() already emits it,\n // tied to a real milestone (the initial test run finishing, or no tests found).\n // Printing it again here produced a duplicate \"watching...\" on every startup.\n // out(chalk.brightblue`watching...`)\n}\n"]}
|