sxy-test-runner 2.4.16 → 2.4.17

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.
@@ -8,6 +8,7 @@ export type TestFile = {
8
8
  meta?: FileMeta;
9
9
  error?: string | false;
10
10
  logs?: unknown[][];
11
+ loadTime?: number;
11
12
  };
12
13
  export declare function loadTestFile(config: FinalConfig, testFile: string, refresh?: 'refresh' | 'cached'): Promise<TestFile>;
13
14
  //# sourceMappingURL=loadTestFile.d.ts.map
@@ -42,6 +42,7 @@ export async function loadTestFile(config, testFile, refresh = 'refresh') {
42
42
  const test = { file: testFile };
43
43
  //// capture console.log output
44
44
  const logs = [];
45
+ const loadStart = performance.now();
45
46
  await captureLogs(logs, async () => {
46
47
  try {
47
48
  await import(importUrl);
@@ -53,6 +54,9 @@ export async function loadTestFile(config, testFile, refresh = 'refresh') {
53
54
  test.error = `Error loading file\n${String(e)}`;
54
55
  }
55
56
  });
57
+ // a cached load shares modules with earlier files, so its time says little about this one
58
+ if (refresh === 'refresh')
59
+ test.loadTime = Math.round(performance.now() - loadStart);
56
60
  const sourceFile = mappedSourceFile(importUrl);
57
61
  if (sourceFile !== undefined)
58
62
  test.sourceFile = sourceFile;
@@ -1 +1 @@
1
- {"version":3,"file":"loadTestFile.js","sourceRoot":"","sources":["../../../src/cli/lib/loadTestFile.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { existsSync } from 'node:fs'\nimport { findSourceMap } from 'node:module'\nimport { join, relative } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport type { Describe, FinalConfig } from '../../types.js'\nimport type { FileMeta } from '../../meta.js'\nimport chalk from '../../packages/chalk.js'\nimport slash from '../../packages/slash.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport '../../packages/esmReload.js' // registers the test module reload hook\nimport { showTimeProfiling } from '../../config.js'\nimport { debug } from '../../output.js'\nimport { captureLogs } from './consoleCapture.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport type TestFile = {\n file: string\n // project relative, from the file's source map\n sourceFile?: string\n describes?: Describe[]\n meta?: FileMeta\n error?: string | false\n logs?: unknown[][]\n}\n\nlet loading: Promise<TestFile> | null = null\n\nlet importIteration = 1\n\n// reads the map Node already parsed for stack traces, which is keyed by the exact import URL\nfunction mappedSourceFile(moduleUrl: string): string | undefined {\n const sources = findSourceMap(moduleUrl)?.payload.sources\n const source = sources?.length === 1 ? sources[0] : undefined\n if (source === undefined || !source.startsWith('file:')) return undefined\n const sourcePath = fileURLToPath(source)\n if (!existsSync(sourcePath)) return undefined\n return slash(relative(process.cwd(), sourcePath))\n}\n\nexport async function loadTestFile(\n config: FinalConfig,\n testFile: string,\n refresh: 'refresh' | 'cached' = 'refresh'\n): Promise<TestFile> {\n if (loading !== null) {\n debug(chalk.yellow`loadTestFile - another file is loading - waiting for it to finish`)\n await loading\n debug(chalk.yellow`previous file complete - will now load the file`)\n }\n\n const loadPromise = timeProfileAsync(`load test ${testFile}`, async () => {\n const projectDir = process.cwd()\n\n global.__sxy_test_runner__ = {\n describes: [],\n describeCounter: 1\n }\n\n const testFileFullUrl = pathToFileURL(join(projectDir, testFile)).href\n const importUrl = refresh === 'refresh'\n ? testFileFullUrl + `?sxyt-instance=${importIteration++}`\n : testFileFullUrl\n\n const test: TestFile = { file: testFile }\n\n //// capture console.log output\n const logs: unknown[][] = []\n await captureLogs(logs, async () => {\n try {\n await import(importUrl)\n test.describes = global.__sxy_test_runner__?.describes ?? []\n test.meta = global.__sxy_test_runner__?.fileMeta\n test.error = false\n } catch (e) {\n test.error = `Error loading file\\n${String(e)}`\n }\n })\n const sourceFile = mappedSourceFile(importUrl)\n if (sourceFile !== undefined) test.sourceFile = sourceFile\n test.logs = logs\n ////\n\n return test\n })\n\n loading = loadPromise\n\n return await loadPromise\n}\n"]}
1
+ {"version":3,"file":"loadTestFile.js","sourceRoot":"","sources":["../../../src/cli/lib/loadTestFile.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { existsSync } from 'node:fs'\nimport { findSourceMap } from 'node:module'\nimport { join, relative } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\n\nimport type { Describe, FinalConfig } from '../../types.js'\nimport type { FileMeta } from '../../meta.js'\nimport chalk from '../../packages/chalk.js'\nimport slash from '../../packages/slash.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport '../../packages/esmReload.js' // registers the test module reload hook\nimport { showTimeProfiling } from '../../config.js'\nimport { debug } from '../../output.js'\nimport { captureLogs } from './consoleCapture.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport type TestFile = {\n file: string\n // project relative, from the file's source map\n sourceFile?: string\n describes?: Describe[]\n meta?: FileMeta\n error?: string | false\n logs?: unknown[][]\n // ms spent importing the file and its module graph\n loadTime?: number\n}\n\nlet loading: Promise<TestFile> | null = null\n\nlet importIteration = 1\n\n// reads the map Node already parsed for stack traces, which is keyed by the exact import URL\nfunction mappedSourceFile(moduleUrl: string): string | undefined {\n const sources = findSourceMap(moduleUrl)?.payload.sources\n const source = sources?.length === 1 ? sources[0] : undefined\n if (source === undefined || !source.startsWith('file:')) return undefined\n const sourcePath = fileURLToPath(source)\n if (!existsSync(sourcePath)) return undefined\n return slash(relative(process.cwd(), sourcePath))\n}\n\nexport async function loadTestFile(\n config: FinalConfig,\n testFile: string,\n refresh: 'refresh' | 'cached' = 'refresh'\n): Promise<TestFile> {\n if (loading !== null) {\n debug(chalk.yellow`loadTestFile - another file is loading - waiting for it to finish`)\n await loading\n debug(chalk.yellow`previous file complete - will now load the file`)\n }\n\n const loadPromise = timeProfileAsync(`load test ${testFile}`, async () => {\n const projectDir = process.cwd()\n\n global.__sxy_test_runner__ = {\n describes: [],\n describeCounter: 1\n }\n\n const testFileFullUrl = pathToFileURL(join(projectDir, testFile)).href\n const importUrl = refresh === 'refresh'\n ? testFileFullUrl + `?sxyt-instance=${importIteration++}`\n : testFileFullUrl\n\n const test: TestFile = { file: testFile }\n\n //// capture console.log output\n const logs: unknown[][] = []\n const loadStart = performance.now()\n await captureLogs(logs, async () => {\n try {\n await import(importUrl)\n test.describes = global.__sxy_test_runner__?.describes ?? []\n test.meta = global.__sxy_test_runner__?.fileMeta\n test.error = false\n } catch (e) {\n test.error = `Error loading file\\n${String(e)}`\n }\n })\n // a cached load shares modules with earlier files, so its time says little about this one\n if (refresh === 'refresh') test.loadTime = Math.round(performance.now() - loadStart)\n const sourceFile = mappedSourceFile(importUrl)\n if (sourceFile !== undefined) test.sourceFile = sourceFile\n test.logs = logs\n ////\n\n return test\n })\n\n loading = loadPromise\n\n return await loadPromise\n}\n"]}
@@ -13,6 +13,8 @@ export type DescribeResultsSummary = {
13
13
  export type TestResult = {
14
14
  file: string;
15
15
  sourceFile?: string;
16
+ time?: number;
17
+ loadTime?: number;
16
18
  success: boolean | null;
17
19
  describeResults: DescribeResult[];
18
20
  describeResultsSummary: DescribeResultsSummary;
@@ -9,6 +9,7 @@ const { timeProfileAsync } = createTimeProfiler(showTimeProfiling);
9
9
  export function runTest(config, test, filters = {}, stop = makeStopSignal()) {
10
10
  return timeProfileAsync(`run test ${test.file}`, async () => {
11
11
  debug('test', test);
12
+ const runStart = performance.now();
12
13
  // run before test file
13
14
  const fileExports = {};
14
15
  await configBeforeEachFile(config, fileExports);
@@ -61,6 +62,10 @@ export function runTest(config, test, filters = {}, stop = makeStopSignal()) {
61
62
  };
62
63
  // run after test
63
64
  await configAfterEachFile(config, fileExports);
65
+ if (test.loadTime !== undefined) {
66
+ testResults.loadTime = test.loadTime;
67
+ testResults.time = test.loadTime + Math.round(performance.now() - runStart);
68
+ }
64
69
  return testResults;
65
70
  });
66
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runTest.js","sourceRoot":"","sources":["../../../src/cli/lib/runTest.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport type {\n FinalConfig, TaskExports\n} from '../../types.js'\nimport type { TestFile } from './loadTestFile.js'\nimport type { TestExecutionFilters } from '../cliTypes.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { debug } from '../../output.js'\nimport { showTimeProfiling } from '../../config.js'\nimport { runTasks } from './runTasks.js'\nimport { addExports } from './addExports.js'\nimport { runDescribe, type DescribeResult } from './runDescribe.js'\nimport { makeStopSignal, type StopSignal } from './stopSignal.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport type DescribeResultsSummary = {\n total: number\n passes: number\n invalid: number\n itsTotal: number\n itsPasses: number\n}\nexport type TestResult = {\n file: string\n sourceFile?: string\n success: boolean | null\n describeResults: DescribeResult[]\n describeResultsSummary: DescribeResultsSummary\n logs: unknown[][]\n}\n\nexport function runTest(\n config: FinalConfig,\n test: TestFile,\n filters: TestExecutionFilters = {},\n stop: StopSignal = makeStopSignal()\n): Promise<TestResult> {\n return timeProfileAsync(`run test ${test.file}`, async () => {\n debug('test', test)\n\n // run before test file\n const fileExports: TaskExports = {}\n await configBeforeEachFile(config, fileExports)\n\n // meta() rejects a meta naming neither key, so the else branch can only be a\n // sequentialDescribes one\n const parallelOverride = test.meta === undefined\n ? undefined\n : 'parallelDescribes' in test.meta ? test.meta.parallelDescribes : !test.meta.sequentialDescribes\n\n const isParallel = parallelOverride ?? config.execution.describes === 'parallel'\n\n const runDescribePromises: Array<Promise<DescribeResult>> = []\n\n for (const describe of test.describes ?? []) {\n // a failure in an earlier describe leaves the rest of the file unrun\n if (stop.stopped) break\n\n if (\n filters.describe !== undefined\n && !describe.thing.toLowerCase().includes(filters.describe.toLowerCase())\n ) continue\n\n const describePromise = runDescribe(config, describe, filters.it, stop)\n runDescribePromises.push(describePromise)\n if (!isParallel) await describePromise\n }\n\n let describeResults = await Promise.all(runDescribePromises)\n if (filters.it !== undefined) {\n describeResults = describeResults.filter(result => (\n result.itResults.length > 0 || result.error !== undefined\n ))\n }\n\n const describeResultsSummary: DescribeResultsSummary = {\n total: 0,\n passes: 0,\n invalid: 0,\n itsTotal: 0,\n itsPasses: 0\n }\n\n for (const describeResult of describeResults) {\n describeResultsSummary.total += +(describeResult.success !== null)\n describeResultsSummary.passes += +(describeResult.success ?? false)\n describeResultsSummary.invalid += +(describeResult.success === null)\n describeResultsSummary.itsTotal += describeResult.itResultsSummary.total\n describeResultsSummary.itsPasses += describeResult.itResultsSummary.passes\n }\n\n const testResults: TestResult = {\n file: test.file,\n ...(test.sourceFile !== undefined && { sourceFile: test.sourceFile }),\n success: (describeResultsSummary.total > 0)\n ? describeResultsSummary.total === describeResultsSummary.passes\n : null,\n describeResults,\n describeResultsSummary,\n logs: test.logs ?? []\n }\n\n // run after test\n await configAfterEachFile(config, fileExports)\n\n return testResults\n })\n}\n\nasync function configBeforeEachFile(config: FinalConfig, exports: TaskExports): Promise<void> {\n if (config.beforeEachFile !== undefined) {\n const theExports = await runTasks(config.beforeEachFile, undefined, 'beforeEachFile')\n if (theExports) addExports(exports, theExports, 'beforeEachFile')\n }\n}\n\nasync function configAfterEachFile(config: FinalConfig, exports: TaskExports): Promise<void> {\n if (config.afterEachFile !== undefined) {\n await runTasks(config.afterEachFile, exports, 'afterEachFile')\n }\n}\n"]}
1
+ {"version":3,"file":"runTest.js","sourceRoot":"","sources":["../../../src/cli/lib/runTest.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport type {\n FinalConfig, TaskExports\n} from '../../types.js'\nimport type { TestFile } from './loadTestFile.js'\nimport type { TestExecutionFilters } from '../cliTypes.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { debug } from '../../output.js'\nimport { showTimeProfiling } from '../../config.js'\nimport { runTasks } from './runTasks.js'\nimport { addExports } from './addExports.js'\nimport { runDescribe, type DescribeResult } from './runDescribe.js'\nimport { makeStopSignal, type StopSignal } from './stopSignal.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport type DescribeResultsSummary = {\n total: number\n passes: number\n invalid: number\n itsTotal: number\n itsPasses: number\n}\nexport type TestResult = {\n file: string\n sourceFile?: string\n // ms for the whole file, module loading included\n time?: number\n loadTime?: number\n success: boolean | null\n describeResults: DescribeResult[]\n describeResultsSummary: DescribeResultsSummary\n logs: unknown[][]\n}\n\nexport function runTest(\n config: FinalConfig,\n test: TestFile,\n filters: TestExecutionFilters = {},\n stop: StopSignal = makeStopSignal()\n): Promise<TestResult> {\n return timeProfileAsync(`run test ${test.file}`, async () => {\n debug('test', test)\n const runStart = performance.now()\n\n // run before test file\n const fileExports: TaskExports = {}\n await configBeforeEachFile(config, fileExports)\n\n // meta() rejects a meta naming neither key, so the else branch can only be a\n // sequentialDescribes one\n const parallelOverride = test.meta === undefined\n ? undefined\n : 'parallelDescribes' in test.meta ? test.meta.parallelDescribes : !test.meta.sequentialDescribes\n\n const isParallel = parallelOverride ?? config.execution.describes === 'parallel'\n\n const runDescribePromises: Array<Promise<DescribeResult>> = []\n\n for (const describe of test.describes ?? []) {\n // a failure in an earlier describe leaves the rest of the file unrun\n if (stop.stopped) break\n\n if (\n filters.describe !== undefined\n && !describe.thing.toLowerCase().includes(filters.describe.toLowerCase())\n ) continue\n\n const describePromise = runDescribe(config, describe, filters.it, stop)\n runDescribePromises.push(describePromise)\n if (!isParallel) await describePromise\n }\n\n let describeResults = await Promise.all(runDescribePromises)\n if (filters.it !== undefined) {\n describeResults = describeResults.filter(result => (\n result.itResults.length > 0 || result.error !== undefined\n ))\n }\n\n const describeResultsSummary: DescribeResultsSummary = {\n total: 0,\n passes: 0,\n invalid: 0,\n itsTotal: 0,\n itsPasses: 0\n }\n\n for (const describeResult of describeResults) {\n describeResultsSummary.total += +(describeResult.success !== null)\n describeResultsSummary.passes += +(describeResult.success ?? false)\n describeResultsSummary.invalid += +(describeResult.success === null)\n describeResultsSummary.itsTotal += describeResult.itResultsSummary.total\n describeResultsSummary.itsPasses += describeResult.itResultsSummary.passes\n }\n\n const testResults: TestResult = {\n file: test.file,\n ...(test.sourceFile !== undefined && { sourceFile: test.sourceFile }),\n success: (describeResultsSummary.total > 0)\n ? describeResultsSummary.total === describeResultsSummary.passes\n : null,\n describeResults,\n describeResultsSummary,\n logs: test.logs ?? []\n }\n\n // run after test\n await configAfterEachFile(config, fileExports)\n\n if (test.loadTime !== undefined) {\n testResults.loadTime = test.loadTime\n testResults.time = test.loadTime + Math.round(performance.now() - runStart)\n }\n\n return testResults\n })\n}\n\nasync function configBeforeEachFile(config: FinalConfig, exports: TaskExports): Promise<void> {\n if (config.beforeEachFile !== undefined) {\n const theExports = await runTasks(config.beforeEachFile, undefined, 'beforeEachFile')\n if (theExports) addExports(exports, theExports, 'beforeEachFile')\n }\n}\n\nasync function configAfterEachFile(config: FinalConfig, exports: TaskExports): Promise<void> {\n if (config.afterEachFile !== undefined) {\n await runTasks(config.afterEachFile, exports, 'afterEachFile')\n }\n}\n"]}
@@ -42,7 +42,9 @@ export async function showTestResult(config, testResult, customOut) {
42
42
  const gap = config.compact ? () => { } : () => { out(); };
43
43
  await timeProfileAsync('show test result', () => {
44
44
  out();
45
- out(chalk.grey `File ${testResult.sourceFile ?? testResult.file}`);
45
+ const fileTime = (testResult.time === undefined) ? '' : ` ${testResult.time.toLocaleString()}ms`
46
+ + ((testResult.loadTime === undefined) ? '' : ` (${testResult.loadTime.toLocaleString()}ms module re-loading)`);
47
+ out(chalk.grey `File ${testResult.sourceFile ?? testResult.file}${fileTime}`);
46
48
  const indent = ' ';
47
49
  if (testResult.logs.length > 0) {
48
50
  gap();
@@ -1 +1 @@
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 // compact keeps only the blank line that separates files\n const gap = config.compact ? () => {} : () => { out() }\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 gap()\n out(chalk.grey`console.logs:`)\n testResult.logs.forEach(log => {\n out(...log)\n })\n gap()\n }\n\n if (testResult.describeResults.length === 0) {\n out('No describes')\n gap()\n }\n\n let first = true\n\n for (const describeResult of testResult.describeResults) {\n if (!first) gap()\n first = false\n\n out(chalk.lightgrey`${describeResult.counter}) describing ` + chalk.brightblue(describeResult.thing)\n + chalk.grey` ${describeResult.time.toLocaleString()}ms`)\n if (describeResult.itResults.length === 0 && !('error' in describeResult)) out(`${indent}No tests`)\n gap()\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 gap()\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 gap()\n out(chalk.grey(display(describeError.stack)))\n }\n } else {\n out(chalk.mediumred(`${indent}${display(describeError)}`))\n }\n gap()\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 gap()\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 gap()\n out(chalk.grey(display(err.stack)))\n }\n } else {\n out(chalk.mediumred(\n `${spacer}${display(err)}`\n ))\n }\n }\n }\n\n gap()\n if (itResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n itResult.logs.forEach(log => {\n out(...log)\n })\n gap()\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 // compact keeps only the blank line that separates files\n const gap = config.compact ? () => {} : () => { out() }\n\n await timeProfileAsync('show test result', () => {\n out()\n const fileTime = (testResult.time === undefined) ? '' : ` ${testResult.time.toLocaleString()}ms`\n + ((testResult.loadTime === undefined) ? '' : ` (${testResult.loadTime.toLocaleString()}ms module re-loading)`)\n out(chalk.grey`File ${testResult.sourceFile ?? testResult.file}${fileTime}`)\n\n const indent = ' '\n\n if (testResult.logs.length > 0) {\n gap()\n out(chalk.grey`console.logs:`)\n testResult.logs.forEach(log => {\n out(...log)\n })\n gap()\n }\n\n if (testResult.describeResults.length === 0) {\n out('No describes')\n gap()\n }\n\n let first = true\n\n for (const describeResult of testResult.describeResults) {\n if (!first) gap()\n first = false\n\n out(chalk.lightgrey`${describeResult.counter}) describing ` + chalk.brightblue(describeResult.thing)\n + chalk.grey` ${describeResult.time.toLocaleString()}ms`)\n if (describeResult.itResults.length === 0 && !('error' in describeResult)) out(`${indent}No tests`)\n gap()\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 gap()\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 gap()\n out(chalk.grey(display(describeError.stack)))\n }\n } else {\n out(chalk.mediumred(`${indent}${display(describeError)}`))\n }\n gap()\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 gap()\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 gap()\n out(chalk.grey(display(err.stack)))\n }\n } else {\n out(chalk.mediumred(\n `${spacer}${display(err)}`\n ))\n }\n }\n }\n\n gap()\n if (itResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n itResult.logs.forEach(log => {\n out(...log)\n })\n gap()\n }\n }\n }\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sxy-test-runner",
3
- "version": "2.4.16",
3
+ "version": "2.4.17",
4
4
  "license": "MIT",
5
5
  "homepage": "https://github.com/RobertSandiford/sxy-test-runner",
6
6
  "repository": {