@japa/runner 3.1.2 → 3.1.4

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.
@@ -13,9 +13,33 @@ import { AssertionError } from "node:assert";
13
13
 
14
14
  // modules/core/reporters/base.ts
15
15
  import ms from "ms";
16
- import colors from "@poppinss/colors";
16
+
17
+ // src/helpers.ts
18
+ import useColors from "@poppinss/colors";
19
+ import supportsColor from "supports-color";
20
+ var colors = supportsColor.stdout ? useColors.ansi() : useColors.silent();
21
+ var icons = process.platform === "win32" && !process.env.WT_SESSION ? {
22
+ tick: "\u221A",
23
+ cross: "\xD7",
24
+ bullet: "*",
25
+ nodejs: "\u2666",
26
+ pointer: ">",
27
+ info: "i",
28
+ warning: "\u203C",
29
+ squareSmallFilled: "[\u2588]"
30
+ } : {
31
+ tick: "\u2714",
32
+ cross: "\u2716",
33
+ bullet: "\u25CF",
34
+ nodejs: "\u2B22",
35
+ pointer: "\u276F",
36
+ info: "\u2139",
37
+ warning: "\u26A0",
38
+ squareSmallFilled: "\u25FC"
39
+ };
40
+
41
+ // modules/core/reporters/base.ts
17
42
  import { ErrorsPrinter } from "@japa/errors-printer";
18
- var ansi = colors.ansi();
19
43
  var BaseReporter = class {
20
44
  #options;
21
45
  runner;
@@ -40,29 +64,29 @@ var BaseReporter = class {
40
64
  #printAggregates(summary) {
41
65
  const tests = [];
42
66
  if (summary.aggregates.passed) {
43
- tests.push(ansi.green(`${summary.aggregates.passed} passed`));
67
+ tests.push(colors.green(`${summary.aggregates.passed} passed`));
44
68
  }
45
69
  if (summary.aggregates.failed) {
46
- tests.push(ansi.red(`${summary.aggregates.failed} failed`));
70
+ tests.push(colors.red(`${summary.aggregates.failed} failed`));
47
71
  }
48
72
  if (summary.aggregates.todo) {
49
- tests.push(ansi.cyan(`${summary.aggregates.todo} todo`));
73
+ tests.push(colors.cyan(`${summary.aggregates.todo} todo`));
50
74
  }
51
75
  if (summary.aggregates.skipped) {
52
- tests.push(ansi.yellow(`${summary.aggregates.skipped} skipped`));
76
+ tests.push(colors.yellow(`${summary.aggregates.skipped} skipped`));
53
77
  }
54
78
  if (summary.aggregates.regression) {
55
- tests.push(ansi.magenta(`${summary.aggregates.regression} regression`));
79
+ tests.push(colors.magenta(`${summary.aggregates.regression} regression`));
56
80
  }
57
81
  this.runner.summaryBuilder.use(() => {
58
82
  return [
59
83
  {
60
- key: ansi.dim("Tests"),
61
- value: `${tests.join(", ")} ${ansi.dim(`(${summary.aggregates.total})`)}`
84
+ key: colors.dim("Tests"),
85
+ value: `${tests.join(", ")} ${colors.dim(`(${summary.aggregates.total})`)}`
62
86
  },
63
87
  {
64
- key: ansi.dim("Time"),
65
- value: ansi.dim(ms(summary.duration))
88
+ key: colors.dim("Time"),
89
+ value: colors.dim(ms(summary.duration))
66
90
  }
67
91
  ];
68
92
  });
@@ -134,13 +158,13 @@ var BaseReporter = class {
134
158
  await this.#printErrors(summary);
135
159
  console.log("");
136
160
  if (summary.aggregates.total === 0 && !summary.hasError) {
137
- console.log(ansi.bgYellow().black(" NO TESTS EXECUTED "));
161
+ console.log(colors.bgYellow().black(" NO TESTS EXECUTED "));
138
162
  return;
139
163
  }
140
164
  if (summary.hasError) {
141
- console.log(ansi.bgRed().black(" FAILED "));
165
+ console.log(colors.bgRed().black(" FAILED "));
142
166
  } else {
143
- console.log(ansi.bgGreen().black(" PASSED "));
167
+ console.log(colors.bgGreen().black(" PASSED "));
144
168
  }
145
169
  console.log("");
146
170
  this.#printAggregates(summary);
@@ -258,6 +282,8 @@ var Runner = class extends BaseRunner {
258
282
  };
259
283
 
260
284
  export {
285
+ colors,
286
+ icons,
261
287
  BaseReporter,
262
288
  Emitter,
263
289
  Refiner,
@@ -267,4 +293,4 @@ export {
267
293
  Suite,
268
294
  Runner
269
295
  };
270
- //# sourceMappingURL=chunk-PKOB3ULJ.js.map
296
+ //# sourceMappingURL=chunk-BFNOUWI5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../modules/core/main.ts","../modules/core/reporters/base.ts","../src/helpers.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport {\n Emitter,\n Refiner,\n Test as BaseTest,\n Suite as BaseSuite,\n Group as BaseGroup,\n Runner as BaseRunner,\n TestContext as BaseTestContext,\n} from '@japa/core'\nimport { inspect } from 'node:util'\nimport { AssertionError } from 'node:assert'\nimport { BaseReporter } from './reporters/base.js'\nimport type { DataSetNode, TestHooksCleanupHandler } from './types.js'\n\ndeclare module '@japa/core' {\n interface Test<Context extends Record<any, any>, TestData extends DataSetNode = undefined> {\n throws(message: string | RegExp, errorConstructor?: any): this\n }\n interface TestContext {\n cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void\n }\n}\n\nexport { Emitter, Refiner, BaseReporter }\n\n/**\n * Test context carries context data for a given test.\n */\nexport class TestContext extends BaseTestContext {\n /**\n * Register a cleanup function that runs after the test finishes\n * successfully or with an error.\n */\n declare cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void\n\n constructor(public test: Test) {\n super()\n this.cleanup = (cleanupCallback: TestHooksCleanupHandler<TestContext>) => {\n test.cleanup(cleanupCallback)\n }\n }\n}\n\n/**\n * Test class represents an individual test and exposes API to tweak\n * its runtime behavior.\n */\nexport class Test<TestData extends DataSetNode = undefined> extends BaseTest<\n TestContext,\n TestData\n> {\n /**\n * @inheritdoc\n */\n static executedCallbacks = []\n\n /**\n * @inheritdoc\n */\n static executingCallbacks = []\n\n /**\n * Assert the test callback throws an exception when a certain\n * error message and optionally is an instance of a given\n * Error class.\n */\n throws(message: string | RegExp, errorConstructor?: any) {\n const errorInPoint = new AssertionError({})\n const existingExecutor = this.options.executor\n if (!existingExecutor) {\n throw new Error('Cannot use \"test.throws\" method without a test callback')\n }\n\n /**\n * Overwriting existing callback\n */\n this.options.executor = async (...args: [any, any, any]) => {\n let raisedException: any\n try {\n await existingExecutor(...args)\n } catch (error) {\n raisedException = error\n }\n\n /**\n * Notify no exception has been raised\n */\n if (!raisedException) {\n errorInPoint.message = 'Expected test to throw an exception'\n throw errorInPoint\n }\n\n /**\n * Constructor mis-match\n */\n if (errorConstructor && !(raisedException instanceof errorConstructor)) {\n errorInPoint.message = `Expected test to throw \"${inspect(errorConstructor)}\"`\n throw errorInPoint\n }\n\n /**\n * Error does not have a message property\n */\n const exceptionMessage: unknown = raisedException.message\n if (!exceptionMessage || typeof exceptionMessage !== 'string') {\n errorInPoint.message = 'Expected test to throw an exception with message property'\n throw errorInPoint\n }\n\n /**\n * Message does not match\n */\n if (typeof message === 'string') {\n if (exceptionMessage !== message) {\n errorInPoint.message = `Expected test to throw \"${message}\". Instead received \"${raisedException.message}\"`\n errorInPoint.actual = raisedException.message\n errorInPoint.expected = message\n throw errorInPoint\n }\n return\n }\n\n if (!message.test(exceptionMessage)) {\n errorInPoint.message = `Expected test error to match \"${message}\" regular expression`\n throw errorInPoint\n }\n }\n\n return this\n }\n}\n\n/**\n * TestGroup is used to bulk configure a collection of tests and\n * define lifecycle hooks for them\n */\nexport class Group extends BaseGroup<TestContext> {}\n\n/**\n * A suite is a collection of tests created around a given\n * testing type. For example: A suite for unit tests, a\n * suite for functional tests and so on.\n */\nexport class Suite extends BaseSuite<TestContext> {}\n\n/**\n * Runner class is used to execute the tests\n */\nexport class Runner extends BaseRunner<TestContext> {}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport ms from 'ms'\nimport { colors } from '../../../src/helpers.js'\nimport { ErrorsPrinter } from '@japa/errors-printer'\n\nimport type {\n TestEndNode,\n SuiteEndNode,\n GroupEndNode,\n TestStartNode,\n RunnerSummary,\n RunnerEndNode,\n GroupStartNode,\n SuiteStartNode,\n RunnerStartNode,\n BaseReporterOptions,\n} from '../types.js'\nimport { Emitter, Runner } from '../main.js'\n\n/**\n * Base reporter to build custom reporters on top of\n */\nexport abstract class BaseReporter {\n #options: BaseReporterOptions\n runner?: Runner\n\n /**\n * Path to the file for which the tests are getting executed\n */\n currentFileName?: string\n\n /**\n * Suite for which the tests are getting executed\n */\n currentSuiteName?: string\n\n /**\n * Group for which the tests are getting executed\n */\n currentGroupName?: string\n\n constructor(options: BaseReporterOptions = {}) {\n this.#options = Object.assign({ stackLinesCount: 2 }, options)\n }\n\n /**\n * Pretty prints the aggregates\n */\n #printAggregates(summary: RunnerSummary) {\n const tests: string[] = []\n\n /**\n * Set value for tests row\n */\n if (summary.aggregates.passed) {\n tests.push(colors.green(`${summary.aggregates.passed} passed`))\n }\n if (summary.aggregates.failed) {\n tests.push(colors.red(`${summary.aggregates.failed} failed`))\n }\n if (summary.aggregates.todo) {\n tests.push(colors.cyan(`${summary.aggregates.todo} todo`))\n }\n if (summary.aggregates.skipped) {\n tests.push(colors.yellow(`${summary.aggregates.skipped} skipped`))\n }\n if (summary.aggregates.regression) {\n tests.push(colors.magenta(`${summary.aggregates.regression} regression`))\n }\n\n this.runner!.summaryBuilder.use(() => {\n return [\n {\n key: colors.dim('Tests'),\n value: `${tests.join(', ')} ${colors.dim(`(${summary.aggregates.total})`)}`,\n },\n {\n key: colors.dim('Time'),\n value: colors.dim(ms(summary.duration)),\n },\n ]\n })\n\n console.log(this.runner!.summaryBuilder.build().join('\\n'))\n }\n\n /**\n * Aggregates errors tree to a flat array\n */\n #aggregateErrors(summary: RunnerSummary) {\n const errorsList: { phase: string; title: string; error: Error }[] = []\n\n summary.failureTree.forEach((suite) => {\n suite.errors.forEach((error) => errorsList.push({ title: suite.name, ...error }))\n\n suite.children.forEach((testOrGroup) => {\n /**\n * Suite child is a test\n */\n if (testOrGroup.type === 'test') {\n testOrGroup.errors.forEach((error) => {\n errorsList.push({ title: `${suite.name} / ${testOrGroup.title}`, ...error })\n })\n return\n }\n\n /**\n * Suite child is a group\n */\n testOrGroup.errors.forEach((error) => {\n errorsList.push({ title: testOrGroup.name, ...error })\n })\n testOrGroup.children.forEach((test) => {\n test.errors.forEach((error) => {\n errorsList.push({ title: `${testOrGroup.name} / ${test.title}`, ...error })\n })\n })\n })\n })\n\n return errorsList\n }\n\n /**\n * Pretty print errors\n */\n async #printErrors(summary: RunnerSummary) {\n if (!summary.failureTree.length) {\n return\n }\n\n const errorPrinter = new ErrorsPrinter({\n stackLinesCount: this.#options.stackLinesCount,\n framesMaxLimit: this.#options.framesMaxLimit,\n })\n\n errorPrinter.printSectionHeader('ERRORS')\n await errorPrinter.printErrors(this.#aggregateErrors(summary))\n }\n\n /**\n * Handlers to capture events\n */\n protected onTestStart(_: TestStartNode): void {}\n protected onTestEnd(_: TestEndNode) {}\n\n protected onGroupStart(_: GroupStartNode) {}\n protected onGroupEnd(_: GroupEndNode) {}\n\n protected onSuiteStart(_: SuiteStartNode) {}\n protected onSuiteEnd(_: SuiteEndNode) {}\n\n protected async start(_: RunnerStartNode) {}\n protected async end(_: RunnerEndNode) {}\n\n /**\n * Print tests summary\n */\n protected async printSummary(summary: RunnerSummary) {\n await this.#printErrors(summary)\n\n console.log('')\n if (summary.aggregates.total === 0 && !summary.hasError) {\n console.log(colors.bgYellow().black(' NO TESTS EXECUTED '))\n return\n }\n\n if (summary.hasError) {\n console.log(colors.bgRed().black(' FAILED '))\n } else {\n console.log(colors.bgGreen().black(' PASSED '))\n }\n console.log('')\n this.#printAggregates(summary)\n }\n\n /**\n * Invoked by the tests runner when tests are about to start\n */\n boot(runner: Runner, emitter: Emitter) {\n this.runner = runner\n\n emitter.on('test:start', (payload) => {\n this.currentFileName = payload.meta.fileName\n this.onTestStart(payload)\n })\n\n emitter.on('test:end', (payload) => {\n this.onTestEnd(payload)\n })\n\n emitter.on('group:start', (payload) => {\n this.currentGroupName = payload.title\n this.currentFileName = payload.meta.fileName\n this.onGroupStart(payload)\n })\n\n emitter.on('group:end', (payload) => {\n this.currentGroupName = undefined\n this.onGroupEnd(payload)\n })\n\n emitter.on('suite:start', (payload) => {\n this.currentSuiteName = payload.name\n this.onSuiteStart(payload)\n })\n\n emitter.on('suite:end', (payload) => {\n this.currentSuiteName = undefined\n this.onSuiteEnd(payload)\n })\n\n emitter.on('runner:start', async (payload) => {\n await this.start(payload)\n })\n\n emitter.on('runner:end', async (payload) => {\n await this.end(payload)\n })\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport useColors from '@poppinss/colors'\nimport supportsColor from 'supports-color'\nimport { Colors } from '@poppinss/colors/types'\n\nexport const colors: Colors = supportsColor.stdout ? useColors.ansi() : useColors.silent()\n\n/**\n * A collection of platform specific icons\n */\nexport const icons =\n process.platform === 'win32' && !process.env.WT_SESSION\n ? {\n tick: '√',\n cross: '×',\n bullet: '*',\n nodejs: '♦',\n pointer: '>',\n info: 'i',\n warning: '‼',\n squareSmallFilled: '[█]',\n }\n : {\n tick: '✔',\n cross: '✖',\n bullet: '●',\n nodejs: '⬢',\n pointer: '❯',\n info: 'ℹ',\n warning: '⚠',\n squareSmallFilled: '◼',\n }\n"],"mappings":"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","names":[]}
@@ -2,13 +2,14 @@ import {
2
2
  dot,
3
3
  ndjson,
4
4
  spec
5
- } from "./chunk-6IZE72CL.js";
5
+ } from "./chunk-PHC5CJQG.js";
6
6
  import {
7
7
  Group,
8
8
  Refiner,
9
9
  Test,
10
- TestContext
11
- } from "./chunk-PKOB3ULJ.js";
10
+ TestContext,
11
+ colors
12
+ } from "./chunk-BFNOUWI5.js";
12
13
 
13
14
  // src/debug.ts
14
15
  import { debuglog } from "node:util";
@@ -257,8 +258,6 @@ var GlobalHooks = class {
257
258
 
258
259
  // src/cli_parser.ts
259
260
  import getopts from "getopts";
260
- import colors from "@poppinss/colors";
261
- var ansi = colors.ansi();
262
261
  var OPTIONS = {
263
262
  string: ["tests", "groups", "tags", "files", "timeout", "retries", "reporters", "failed"],
264
263
  boolean: ["help", "matchAll", "failed"],
@@ -269,34 +268,34 @@ var OPTIONS = {
269
268
  }
270
269
  };
271
270
  var GET_HELP = () => `
272
- ${ansi.yellow("@japa/runner v2.3.0")}
271
+ ${colors.yellow("@japa/runner v2.3.0")}
273
272
 
274
- ${ansi.green("--tests")} ${ansi.dim("Filter tests by the test title")}
275
- ${ansi.green("--groups")} ${ansi.dim("Filter tests by the group title")}
276
- ${ansi.green("--tags")} ${ansi.dim("Filter tests by tags")}
277
- ${ansi.green("--files")} ${ansi.dim("Filter tests by the file name")}
278
- ${ansi.green("--force-exit")} ${ansi.dim("Forcefully exit the process")}
279
- ${ansi.green("--timeout")} ${ansi.dim("Define default timeout for all tests")}
280
- ${ansi.green("--retries")} ${ansi.dim("Define default retries for all tests")}
281
- ${ansi.green("--reporters")} ${ansi.dim("Activate one or more test reporters")}
282
- ${ansi.green("--failed")} ${ansi.dim("Run tests failed during the last run")}
283
- ${ansi.green("-h, --help")} ${ansi.dim("View help")}
273
+ ${colors.green("--tests")} ${colors.dim("Filter tests by the test title")}
274
+ ${colors.green("--groups")} ${colors.dim("Filter tests by the group title")}
275
+ ${colors.green("--tags")} ${colors.dim("Filter tests by tags")}
276
+ ${colors.green("--files")} ${colors.dim("Filter tests by the file name")}
277
+ ${colors.green("--force-exit")} ${colors.dim("Forcefully exit the process")}
278
+ ${colors.green("--timeout")} ${colors.dim("Define default timeout for all tests")}
279
+ ${colors.green("--retries")} ${colors.dim("Define default retries for all tests")}
280
+ ${colors.green("--reporters")} ${colors.dim("Activate one or more test reporters")}
281
+ ${colors.green("--failed")} ${colors.dim("Run tests failed during the last run")}
282
+ ${colors.green("-h, --help")} ${colors.dim("View help")}
284
283
 
285
- ${ansi.yellow("Examples:")}
286
- ${ansi.dim('node bin/test.js --tags="@github"')}
287
- ${ansi.dim('node bin/test.js --tags="~@github"')}
288
- ${ansi.dim('node bin/test.js --tags="@github,@slow,@integration" --match-all')}
289
- ${ansi.dim("node bin/test.js --force-exit")}
290
- ${ansi.dim('node bin/test.js --files="user"')}
291
- ${ansi.dim('node bin/test.js --files="functional/user"')}
292
- ${ansi.dim('node bin/test.js --files="unit/user"')}
284
+ ${colors.yellow("Examples:")}
285
+ ${colors.dim('node bin/test.js --tags="@github"')}
286
+ ${colors.dim('node bin/test.js --tags="~@github"')}
287
+ ${colors.dim('node bin/test.js --tags="@github,@slow,@integration" --match-all')}
288
+ ${colors.dim("node bin/test.js --force-exit")}
289
+ ${colors.dim('node bin/test.js --files="user"')}
290
+ ${colors.dim('node bin/test.js --files="functional/user"')}
291
+ ${colors.dim('node bin/test.js --files="unit/user"')}
293
292
 
294
- ${ansi.yellow("Notes:")}
293
+ ${colors.yellow("Notes:")}
295
294
  - When groups and tests filters are applied together. We will first filter the
296
295
  tests by group title and then apply the tests title filter.
297
- - The timeout defined on test object takes precedence over the ${ansi.green("--timeout")} flag.
298
- - The retries defined on test object takes precedence over the ${ansi.green("--retries")} flag.
299
- - The ${ansi.green("--files")} flag checks for the file names ending with the filter substring.
296
+ - The timeout defined on test object takes precedence over the ${colors.green("--timeout")} flag.
297
+ - The retries defined on test object takes precedence over the ${colors.green("--retries")} flag.
298
+ - The ${colors.green("--files")} flag checks for the file names ending with the filter substring.
300
299
  `;
301
300
  var CliParser = class {
302
301
  /**
@@ -502,4 +501,4 @@ export {
502
501
  createTest,
503
502
  createTestGroup
504
503
  };
505
- //# sourceMappingURL=chunk-PSL75GNC.js.map
504
+ //# sourceMappingURL=chunk-NVI2OU43.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/debug.ts","../src/validator.ts","../src/files_manager.ts","../src/planner.ts","../src/hooks.ts","../src/cli_parser.ts","../src/config_manager.ts","../src/create_test.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { debuglog } from 'node:util'\nexport default debuglog('japa:runner')\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { NormalizedConfig } from './types.js'\n\n/**\n * Validator encapsulates the validations to perform before running\n * the tests\n */\nclass Validator {\n /**\n * Ensures the japa is configured. Otherwise raises an exception\n */\n ensureIsConfigured(config: NormalizedConfig | undefined) {\n if (!config) {\n throw new Error(\n `Cannot run tests. Make sure to call \"configure\" method before the \"run\" method`\n )\n }\n }\n\n /**\n * Ensures the japa is in planning phase\n */\n ensureIsInPlanningPhase(phase: 'idle' | 'planning' | 'executing') {\n if (phase !== 'planning') {\n throw new Error(\n `Cannot import japa test file directly. It must be imported by calling the \"japa.run\" method`\n )\n }\n }\n\n /**\n * Ensures the suites filter uses a subset of the user configured suites.\n */\n validateSuitesFilter(config: NormalizedConfig) {\n /**\n * Do not perform any validation if no filters are applied\n * in the first place\n */\n if (!config.filters.suites || !config.filters.suites.length) {\n return\n }\n\n /**\n * Notify user they have applied the suites filter but forgot to define\n * suites\n */\n if (!('suites' in config) || !config.suites.length) {\n throw new Error(`Cannot apply suites filter. You have not configured any test suites`)\n }\n\n const suites = config.suites.map(({ name }) => name)\n\n /**\n * Find unknown suites and report the error\n */\n const unknownSuites = config.filters.suites.filter((suite) => !suites.includes(suite))\n if (unknownSuites.length) {\n throw new Error(`Cannot apply suites filter. \"${unknownSuites[0]}\" suite is not configured`)\n }\n }\n\n /**\n * Ensure there are unique suites\n */\n validateSuitesForUniqueness(config: NormalizedConfig) {\n if (!('suites' in config)) {\n return\n }\n\n const suites: Set<string> = new Set()\n config.suites.forEach(({ name }) => {\n if (suites.has(name)) {\n throw new Error(`Duplicate suite \"${name}\"`)\n }\n suites.add(name)\n })\n\n suites.clear()\n }\n\n /**\n * Ensure the activated reporters are in the list of defined\n * reporters\n */\n validateActivatedReporters(config: NormalizedConfig) {\n const reportersList = config.reporters.list.map(({ name }) => name)\n const unknownReporters = config.reporters.activated.filter(\n (name) => !reportersList.includes(name)\n )\n\n if (unknownReporters.length) {\n throw new Error(\n `Invalid reporter \"${unknownReporters[0]}\". Make sure to register it first inside the \"reporters.list\" array`\n )\n }\n }\n}\n\nexport default new Validator()\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport slash from 'slash'\nimport fastGlob from 'fast-glob'\nimport { pathToFileURL } from 'node:url'\nimport type { TestFiles } from './types.js'\n\n/**\n * The expression to remove file extension and optionally\n * .spec|.test from the test file name\n */\nconst FILE_SUFFIX_EXPRESSION = /(\\.spec|\\.test)?\\.[js|ts|jsx|tsx|mjs|mts|cjs|cts]+$/\n\n/**\n * Files manager exposes the API to collect, filter and import test\n * files based upon the config\n */\nexport class FilesManager {\n /**\n * Returns a collection of files from the user defined\n * glob or the implementation function\n */\n async getFiles(cwd: string, files: TestFiles, excludes: string[]): Promise<URL[]> {\n if (Array.isArray(files) || typeof files === 'string') {\n const testFiles = await fastGlob(files, {\n absolute: true,\n onlyFiles: true,\n cwd: cwd,\n ignore: excludes,\n })\n return testFiles.map((file) => pathToFileURL(file))\n }\n\n return await files()\n }\n\n /**\n * Applies file name filter on a collection of file\n * URLs\n */\n grep(files: URL[], filters: string[]): URL[] {\n return files.filter((file) => {\n const filename = slash(file.pathname)\n const filenameWithoutTestSuffix = filename.replace(FILE_SUFFIX_EXPRESSION, '')\n\n return !!filters.find((filter) => {\n if (filename.endsWith(filter)) {\n return true\n }\n\n const filterSegments = filter.split('/').reverse()\n const fileSegments = filenameWithoutTestSuffix.split('/').reverse()\n\n return filterSegments.every((segment, index) => {\n return fileSegments[index] && (segment === '*' || fileSegments[index].endsWith(segment))\n })\n })\n })\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport validator from './validator.js'\nimport { FilesManager } from './files_manager.js'\nimport type { NamedReporterContract, NormalizedConfig, TestFiles, TestSuite } from './types.js'\n\n/**\n * The tests planner is used to plan the tests by doing all\n * the heavy lifting of executing plugins, registering\n * reporters, filtering tests and so on.\n */\nexport class Planner {\n #config: NormalizedConfig\n #fileManager = new FilesManager()\n\n constructor(config: NormalizedConfig) {\n validator.validateActivatedReporters(config!)\n validator.validateSuitesFilter(config!)\n validator.validateSuitesForUniqueness(config!)\n this.#config = config\n }\n\n /**\n * Returns a list of reporters based upon the activated\n * reporters list.\n */\n #getActivatedReporters(): NamedReporterContract[] {\n return this.#config.reporters.activated.map((activated) => {\n return this.#config.reporters.list.find(({ name }) => activated === name)!\n })\n }\n\n /**\n * A generic method to collect files from the user defined\n * files glob and apply the files filter\n */\n async #collectFiles(files: TestFiles) {\n let filesURLs = await this.#fileManager.getFiles(this.#config.cwd, files, this.#config.exclude)\n if (this.#config.filters.files && this.#config.filters.files.length) {\n filesURLs = this.#fileManager.grep(filesURLs, this.#config.filters.files)\n }\n\n return filesURLs\n }\n\n /**\n * Returns a collection of suites and their associated\n * test files by applying all the filters\n */\n async #getSuites(): Promise<(TestSuite & { filesURLs: URL[] })[]> {\n let suites: (TestSuite & { filesURLs: URL[] })[] = []\n let suitesFilters = this.#config.filters.suites || []\n\n if ('files' in this.#config) {\n suites.push({\n name: 'default',\n files: this.#config.files,\n timeout: this.#config.timeout,\n retries: this.#config.retries,\n filesURLs: await this.#collectFiles(this.#config.files),\n })\n }\n\n if ('suites' in this.#config) {\n for (let suite of this.#config.suites) {\n if (!suitesFilters.length || suitesFilters.includes(suite.name)) {\n suites.push({\n ...suite,\n filesURLs: await this.#collectFiles(suite.files),\n })\n }\n }\n }\n\n return suites\n }\n\n /**\n * Returns a list of filters to the passed to the refiner\n */\n #getRefinerFilters() {\n return Object.keys(this.#config.filters).reduce(\n (result, layer) => {\n if (layer === 'tests' || layer === 'tags' || layer === 'groups') {\n result.push({ layer, filters: this.#config.filters[layer]! })\n }\n return result\n },\n [] as { layer: 'tags' | 'tests' | 'groups'; filters: string[] }[]\n )\n }\n\n /**\n * Creates a plan for running the tests\n */\n async plan() {\n const suites = await this.#getSuites()\n const reporters = this.#getActivatedReporters()\n const refinerFilters = this.#getRefinerFilters()\n return {\n reporters,\n suites,\n refinerFilters,\n config: this.#config,\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport Hooks from '@poppinss/hooks'\nimport type { Runner as HooksRunner } from '@poppinss/hooks/types'\n\nimport { Runner } from '../modules/core/main.js'\nimport type { HooksEvents, SetupHookState, NormalizedConfig, TeardownHookState } from './types.js'\n\n/**\n * Exposes API for working with global hooks\n */\nexport class GlobalHooks {\n #hooks = new Hooks<HooksEvents>()\n #setupRunner: HooksRunner<SetupHookState[0], SetupHookState[1]> | undefined\n #teardownRunner: HooksRunner<TeardownHookState[0], TeardownHookState[1]> | undefined\n\n /**\n * Apply hooks from the config\n */\n apply(config: NormalizedConfig) {\n config.setup.forEach((hook) => this.#hooks.add('setup', hook))\n config.teardown.forEach((hook) => this.#hooks.add('teardown', hook))\n }\n\n /**\n * Perform setup\n */\n async setup(runner: Runner) {\n this.#setupRunner = this.#hooks.runner('setup')\n this.#teardownRunner = this.#hooks.runner('teardown')\n await this.#setupRunner.run(runner)\n }\n\n /**\n * Perform cleanup\n */\n async teardown(error: Error | null, runner: Runner) {\n if (this.#setupRunner) {\n await this.#setupRunner.cleanup(error, runner)\n }\n if (this.#teardownRunner) {\n if (!error) {\n await this.#teardownRunner.run(runner)\n }\n await this.#teardownRunner.cleanup(error, runner)\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n// @ts-ignore-error\nimport getopts from 'getopts'\nimport { colors } from './helpers.js'\nimport type { CLIArgs } from './types.js'\n\n/**\n * Known commandline options. The user can still define additional flags and they\n * will be parsed aswell, but without any normalization\n */\nconst OPTIONS = {\n string: ['tests', 'groups', 'tags', 'files', 'timeout', 'retries', 'reporters', 'failed'],\n boolean: ['help', 'matchAll', 'failed'],\n alias: {\n forceExit: 'force-exit',\n matchAll: 'match-all',\n help: 'h',\n },\n}\n\n/**\n * Help string to display when the `--help flag is used`\n */\nconst GET_HELP = () => `\n${colors.yellow('@japa/runner v2.3.0')}\n\n${colors.green('--tests')} ${colors.dim('Filter tests by the test title')}\n${colors.green('--groups')} ${colors.dim('Filter tests by the group title')}\n${colors.green('--tags')} ${colors.dim('Filter tests by tags')}\n${colors.green('--files')} ${colors.dim('Filter tests by the file name')}\n${colors.green('--force-exit')} ${colors.dim('Forcefully exit the process')}\n${colors.green('--timeout')} ${colors.dim('Define default timeout for all tests')}\n${colors.green('--retries')} ${colors.dim('Define default retries for all tests')}\n${colors.green('--reporters')} ${colors.dim('Activate one or more test reporters')}\n${colors.green('--failed')} ${colors.dim('Run tests failed during the last run')}\n${colors.green('-h, --help')} ${colors.dim('View help')}\n\n${colors.yellow('Examples:')}\n${colors.dim('node bin/test.js --tags=\"@github\"')}\n${colors.dim('node bin/test.js --tags=\"~@github\"')}\n${colors.dim('node bin/test.js --tags=\"@github,@slow,@integration\" --match-all')}\n${colors.dim('node bin/test.js --force-exit')}\n${colors.dim('node bin/test.js --files=\"user\"')}\n${colors.dim('node bin/test.js --files=\"functional/user\"')}\n${colors.dim('node bin/test.js --files=\"unit/user\"')}\n\n${colors.yellow('Notes:')}\n- When groups and tests filters are applied together. We will first filter the\n tests by group title and then apply the tests title filter.\n- The timeout defined on test object takes precedence over the ${colors.green('--timeout')} flag.\n- The retries defined on test object takes precedence over the ${colors.green('--retries')} flag.\n- The ${colors.green('--files')} flag checks for the file names ending with the filter substring.\n`\n\n/**\n * CLI Parser is used to parse the commandline argument\n */\nexport class CliParser {\n /**\n * Parses command-line arguments\n */\n parse(argv: string[]): CLIArgs {\n return getopts(argv, OPTIONS)\n }\n\n /**\n * Returns the help string\n */\n getHelp() {\n return GET_HELP()\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport debug from './debug.js'\nimport { Refiner } from '../modules/core/main.js'\nimport { dot, ndjson, spec } from './reporters/main.js'\nimport type { CLIArgs, Config, Filters, NormalizedBaseConfig, NormalizedConfig } from './types.js'\n\nexport const NOOP = () => {}\n\n/**\n * Defaults to use for configuration\n */\nconst DEFAULTS = {\n files: [],\n timeout: 2000,\n retries: 0,\n forceExit: false,\n plugins: [],\n reporters: {\n activated: ['spec'],\n list: [spec(), ndjson(), dot()],\n },\n importer: (filePath) => import(filePath.href),\n configureSuite: () => {},\n} satisfies Config\n\n/**\n * Config manager is used to hydrate the configuration by merging\n * the defaults, user defined config and the command line\n * flags.\n *\n * The command line flags have the upmost priority\n */\nexport class ConfigManager {\n #config: Config\n #cliArgs: CLIArgs\n\n constructor(config: Config, cliArgs: CLIArgs) {\n this.#config = config\n this.#cliArgs = cliArgs\n }\n\n /**\n * Processes a CLI argument and converts it to an\n * array of strings\n */\n #processAsArray(value: string | string[], splitByComma: boolean): string[] {\n return Array.isArray(value)\n ? value\n : splitByComma\n ? value.split(',').map((item: string) => item.trim())\n : [value]\n }\n\n /**\n * Returns a copy of filters based upon the CLI\n * arguments.\n */\n #getCLIFilters(): Filters {\n const filters: Filters = {}\n\n if (this.#cliArgs.tags) {\n filters.tags = this.#processAsArray(this.#cliArgs.tags, true)\n }\n if (this.#cliArgs.tests) {\n filters.tests = this.#processAsArray(this.#cliArgs.tests, false)\n }\n if (this.#cliArgs.files) {\n filters.files = this.#processAsArray(this.#cliArgs.files, true)\n }\n if (this.#cliArgs.groups) {\n filters.groups = this.#processAsArray(this.#cliArgs.groups, false)\n }\n if (this.#cliArgs._ && this.#cliArgs._.length) {\n filters.suites = this.#processAsArray(this.#cliArgs._, true)\n }\n\n return filters\n }\n\n /**\n * Returns the timeout from the CLI args\n */\n #getCLITimeout(): number | undefined {\n if (this.#cliArgs.timeout) {\n const value = Number(this.#cliArgs.timeout)\n if (!Number.isNaN(value)) {\n return value\n }\n }\n }\n\n /**\n * Returns the retries from the CLI args\n */\n #getCLIRetries(): number | undefined {\n if (this.#cliArgs.retries) {\n const value = Number(this.#cliArgs.retries)\n if (!Number.isNaN(value)) {\n return value\n }\n }\n }\n\n /**\n * Returns the forceExit property from the CLI args\n */\n #getCLIForceExit(): boolean | undefined {\n if (this.#cliArgs.forceExit) {\n return true\n }\n }\n\n /**\n * Returns reporters selected using the commandline\n * --reporter flag\n */\n #getCLIReporters(): string[] | undefined {\n if (this.#cliArgs.reporters) {\n return this.#processAsArray(this.#cliArgs.reporters, true)\n }\n }\n\n /**\n * Hydrates the config with user defined options and the\n * command-line flags.\n */\n hydrate(): NormalizedConfig {\n const cliFilters = this.#getCLIFilters()\n const cliRetries = this.#getCLIRetries()\n const cliTimeout = this.#getCLITimeout()\n const cliReporters = this.#getCLIReporters()\n const cliForceExit = this.#getCLIForceExit()\n\n debug('filters applied using CLI flags %O', cliFilters)\n\n const baseConfig: NormalizedBaseConfig = {\n cwd: this.#config.cwd ?? process.cwd(),\n exclude: this.#config.exclude || ['node_modules/**', '.git/**', 'coverage/**'],\n filters: Object.assign({}, this.#config.filters ?? {}, cliFilters),\n importer: this.#config.importer ?? DEFAULTS.importer,\n refiner: this.#config.refiner ?? new Refiner(),\n retries: cliRetries ?? this.#config.retries ?? DEFAULTS.retries,\n timeout: cliTimeout ?? this.#config.timeout ?? DEFAULTS.timeout,\n plugins: this.#config.plugins ?? DEFAULTS.plugins,\n forceExit: cliForceExit ?? this.#config.forceExit ?? DEFAULTS.forceExit,\n reporters: this.#config.reporters\n ? {\n activated: this.#config.reporters.activated,\n list: this.#config.reporters.list || DEFAULTS.reporters.list,\n }\n : DEFAULTS.reporters,\n configureSuite: this.#config.configureSuite ?? DEFAULTS.configureSuite,\n setup: this.#config.setup || [],\n teardown: this.#config.teardown || [],\n }\n\n /**\n * Overwrite activated reporters when defined using CLI\n * flag\n */\n if (cliReporters) {\n baseConfig.reporters.activated = cliReporters\n }\n\n if ('files' in this.#config) {\n return {\n files: this.#config.files,\n ...baseConfig,\n }\n }\n\n return {\n suites: this.#config.suites.map((suite) => {\n return {\n name: suite.name,\n files: suite.files,\n timeout: cliTimeout ?? suite.timeout ?? baseConfig.timeout,\n retries: cliRetries ?? suite.retries ?? baseConfig.retries,\n configure: suite.configure || NOOP,\n }\n }),\n ...baseConfig,\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { Emitter, Group, Refiner, Suite, Test, TestContext } from '../modules/core/main.js'\n\n/**\n * Function to create the test context for the test\n */\nconst contextBuilder = (testInstance: Test<any>) => new TestContext(testInstance)\n\n/**\n * Create a new instance of the Test\n */\nexport function createTest(\n title: string,\n emitter: Emitter,\n refiner: Refiner,\n options: {\n group?: Group\n suite?: Suite\n file?: string\n timeout?: number\n retries?: number\n }\n) {\n const testInstance = new Test<undefined>(title, contextBuilder, emitter, refiner, options.group)\n testInstance.options.meta.suite = options.suite\n testInstance.options.meta.group = options.group\n testInstance.options.meta.fileName = options.file\n\n if (options.timeout !== undefined) {\n testInstance.timeout(options.timeout)\n }\n if (options.retries !== undefined) {\n testInstance.retry(options.retries)\n }\n\n /**\n * Register test as a child either with the group or the suite\n */\n if (options.group) {\n options.group.add(testInstance)\n } else if (options.suite) {\n options.suite.add(testInstance)\n }\n\n return testInstance\n}\n\n/**\n * Create a new instance of the Group\n */\nexport function createTestGroup(\n title: string,\n emitter: Emitter,\n refiner: Refiner,\n options: {\n group?: Group\n suite?: Suite\n file?: string\n timeout?: number\n retries?: number\n }\n) {\n if (options.group) {\n throw new Error('Nested groups are not supported by Japa')\n }\n\n const group = new Group(title, emitter, refiner)\n group.options.meta.suite = options.suite\n group.options.meta.fileName = options.file\n\n if (options.suite) {\n options.suite.add(group)\n }\n\n return group\n}\n"],"mappings":"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","names":[]}
@@ -1,29 +1,8 @@
1
1
  import {
2
- BaseReporter
3
- } from "./chunk-PKOB3ULJ.js";
4
-
5
- // src/helpers.ts
6
- import useColors from "@poppinss/colors";
7
- var colors = useColors.ansi();
8
- var icons = process.platform === "win32" && !process.env.WT_SESSION ? {
9
- tick: "\u221A",
10
- cross: "\xD7",
11
- bullet: "*",
12
- nodejs: "\u2666",
13
- pointer: ">",
14
- info: "i",
15
- warning: "\u203C",
16
- squareSmallFilled: "[\u2588]"
17
- } : {
18
- tick: "\u2714",
19
- cross: "\u2716",
20
- bullet: "\u25CF",
21
- nodejs: "\u2B22",
22
- pointer: "\u276F",
23
- info: "\u2139",
24
- warning: "\u26A0",
25
- squareSmallFilled: "\u25FC"
26
- };
2
+ BaseReporter,
3
+ colors,
4
+ icons
5
+ } from "./chunk-BFNOUWI5.js";
27
6
 
28
7
  // src/reporters/dot.ts
29
8
  var DotReporter = class extends BaseReporter {
@@ -276,9 +255,8 @@ var ndjson = (options) => {
276
255
  };
277
256
 
278
257
  export {
279
- colors,
280
258
  spec,
281
259
  dot,
282
260
  ndjson
283
261
  };
284
- //# sourceMappingURL=chunk-6IZE72CL.js.map
262
+ //# sourceMappingURL=chunk-PHC5CJQG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/reporters/dot.ts","../src/reporters/spec.ts","../src/reporters/ndjson.ts","../src/reporters/main.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { colors, icons } from '../helpers.js'\nimport type { TestEndNode } from '../../modules/core/types.js'\nimport { BaseReporter } from '../../modules/core/reporters/base.js'\n\n/**\n * Minimal reporter that prints each test as an icon.\n */\nexport class DotReporter extends BaseReporter {\n /**\n * When a test ended\n */\n protected onTestEnd(payload: TestEndNode) {\n let output = ''\n if (payload.isTodo) {\n output = colors.cyan(icons.info)\n } else if (payload.hasError || payload.isFailing) {\n output = payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross)\n } else if (payload.isSkipped) {\n output = colors.yellow(icons.bullet)\n } else {\n output = colors.green(icons.tick)\n }\n\n process.stdout.write(`${output}`)\n }\n\n /**\n * When test runner ended\n */\n protected async end() {\n console.log('')\n await this.printSummary(this.runner!.getSummary())\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport ms from 'ms'\nimport { relative } from 'node:path'\n\nimport { colors, icons } from '../helpers.js'\nimport { BaseReporter } from '../../modules/core/main.js'\nimport { GroupStartNode, TestEndNode } from '../../modules/core/types.js'\n\n/**\n * Pretty prints the tests on the console\n */\nexport class SpecReporter extends BaseReporter {\n /**\n * Tracking if the first event we get is for a test without any parent group\n * We need this to decide the display style for tests without groups.\n */\n #isFirstLoneTest = true\n\n /**\n * Returns the icon for the test\n */\n #getTestIcon(payload: TestEndNode) {\n if (payload.isTodo) {\n return colors.cyan(icons.info)\n }\n\n if (payload.isFailing) {\n return payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross)\n }\n\n if (payload.hasError) {\n return colors.red(icons.cross)\n }\n\n if (payload.isSkipped) {\n return colors.yellow(icons.bullet)\n }\n\n return colors.green(icons.tick)\n }\n\n /**\n * Returns the test message\n */\n #getTestMessage(payload: TestEndNode) {\n const message = payload.title.expanded\n\n if (payload.isTodo) {\n return colors.blue(message)\n }\n\n if (payload.isFailing) {\n return payload.hasError ? colors.magenta(message) : colors.red(message)\n }\n\n if (payload.hasError) {\n return colors.red(message)\n }\n\n if (payload.isSkipped) {\n return colors.yellow(message)\n }\n\n return colors.grey(message)\n }\n\n /**\n * Returns the subtext message for the test\n */\n #getSubText(payload: TestEndNode): string | undefined {\n if (payload.isSkipped && payload.skipReason) {\n return colors.yellow(payload.skipReason)\n }\n\n if (!payload.isFailing) {\n return\n }\n\n if (!payload.hasError) {\n return colors.magenta(`Test marked with \".fails()\" must finish with an error`)\n }\n\n if (payload.failReason) {\n return colors.magenta(payload.failReason)\n }\n\n const testErrorMessage = payload.errors.find((error) => error.phase === 'test')\n if (testErrorMessage && testErrorMessage.error) {\n return colors.magenta(testErrorMessage.error.message)\n }\n }\n\n /**\n * Returns the filename relative from the current working dir\n */\n #getRelativeFilename(fileName: string) {\n return relative(process.cwd(), fileName)\n }\n\n /**\n * Prints the test details\n */\n #printTest(payload: TestEndNode) {\n const icon = this.#getTestIcon(payload)\n const message = this.#getTestMessage(payload)\n const prefix = payload.isPinned ? colors.yellow('[PINNED] ') : ''\n const indentation = this.currentFileName || this.currentGroupName ? ' ' : ''\n const duration = colors.dim(`(${ms(Number(payload.duration.toFixed(2)))})`)\n const retries =\n payload.retryAttempt && payload.retryAttempt > 1\n ? colors.dim(`(x${payload.retryAttempt}) `)\n : ''\n\n let subText = this.#getSubText(payload)\n subText = subText ? `\\n${indentation} ${subText}` : ''\n\n console.log(`${indentation}${icon} ${prefix}${retries}${message} ${duration}${subText}`)\n }\n\n /**\n * Prints the group name\n */\n #printGroup(payload: GroupStartNode) {\n const title =\n this.currentSuiteName !== 'default'\n ? `${this.currentSuiteName} / ${payload.title}`\n : payload.title\n\n const suffix = this.currentFileName\n ? colors.dim(` (${this.#getRelativeFilename(this.currentFileName)})`)\n : ''\n\n console.log(`\\n${title}${suffix}`)\n }\n\n protected onTestStart(): void {\n /**\n * Display the filename when\n *\n * - The filename exists\n * - The test is not under a group\n * - Test is first in a sequence\n */\n if (this.currentFileName && this.#isFirstLoneTest) {\n console.log(`\\n${colors.dim(this.#getRelativeFilename(this.currentFileName))}`)\n }\n this.#isFirstLoneTest = false\n }\n\n protected onTestEnd(payload: TestEndNode): void {\n this.#printTest(payload)\n }\n\n protected onGroupStart(payload: GroupStartNode): void {\n /**\n * When a group starts, we mark the upcoming test as NOT a\n * lone test\n */\n this.#isFirstLoneTest = false\n this.#printGroup(payload)\n }\n\n protected onGroupEnd(): void {\n /**\n * When the group ends we assume that the next test can\n * be out of the group, hence a lone test.\n *\n * If this assumption is false, then the `onGroupStart` method\n * will toggle the boolean\n */\n this.#isFirstLoneTest = true\n }\n\n protected async end() {\n const summary = this.runner!.getSummary()\n await this.printSummary(summary)\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { relative } from 'node:path'\nimport { serializeError } from 'serialize-error'\n\nimport { BaseReporter } from '../../modules/core/main.js'\nimport type {\n TestEndNode,\n SuiteEndNode,\n GroupEndNode,\n SuiteStartNode,\n GroupStartNode,\n} from '../../modules/core/types.js'\n\n/**\n * Prints tests progress as JSON. Each event is emitted\n * independently\n */\nexport class NdJSONReporter extends BaseReporter {\n /**\n * Returns the filename relative from the current working dir\n */\n #getRelativeFilename(fileName: string) {\n return relative(process.cwd(), fileName)\n }\n\n /**\n * Serialize errors to JSON\n */\n #serializeErrors(errors: TestEndNode['errors']) {\n return errors.map((error) => ({\n phase: error.phase,\n error: serializeError(error.error),\n }))\n }\n\n protected onTestEnd(payload: TestEndNode): void {\n console.log(\n JSON.stringify({\n event: 'test:end',\n filePath: this.currentFileName,\n relativePath: this.currentFileName\n ? this.#getRelativeFilename(this.currentFileName)\n : undefined,\n title: payload.title,\n duration: payload.duration,\n failReason: payload.failReason,\n isFailing: payload.isFailing,\n skipReason: payload.skipReason,\n isSkipped: payload.isSkipped,\n isTodo: payload.isTodo,\n isPinned: payload.isPinned,\n retryAttempt: payload.retryAttempt,\n retries: payload.retries,\n errors: this.#serializeErrors(payload.errors),\n })\n )\n }\n\n protected onGroupStart(payload: GroupStartNode): void {\n console.log(\n JSON.stringify({\n event: 'group:start',\n title: payload.title,\n })\n )\n }\n\n protected onGroupEnd(payload: GroupEndNode): void {\n JSON.stringify({\n event: 'group:end',\n title: payload.title,\n errors: this.#serializeErrors(payload.errors),\n })\n }\n\n protected onSuiteStart(payload: SuiteStartNode): void {\n console.log(\n JSON.stringify({\n event: 'suite:start',\n ...payload,\n })\n )\n }\n\n protected onSuiteEnd(payload: SuiteEndNode): void {\n console.log(\n JSON.stringify({\n event: 'suite:end',\n ...payload,\n })\n )\n }\n\n protected async end() {\n const summary = this.runner!.getSummary()\n console.log(\n JSON.stringify({\n aggregates: summary.aggregates,\n duration: summary.duration,\n failedTestsTitles: summary.failedTestsTitles,\n hasError: summary.hasError,\n })\n )\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { DotReporter } from './dot.js'\nimport { SpecReporter } from './spec.js'\nimport { NdJSONReporter } from './ndjson.js'\nimport type { BaseReporterOptions, NamedReporterContract } from '../types.js'\n\n/**\n * Create an instance of the spec reporter\n */\nexport const spec: (options?: BaseReporterOptions) => NamedReporterContract = (options) => {\n return {\n name: 'spec',\n handler: (...args) => new SpecReporter(options).boot(...args),\n }\n}\n\n/**\n * Create an instance of the dot reporter\n */\nexport const dot: (options?: BaseReporterOptions) => NamedReporterContract = (options) => {\n return {\n name: 'dot',\n handler: (...args) => new DotReporter(options).boot(...args),\n }\n}\n\n/**\n * Create an instance of the ndjson reporter\n */\nexport const ndjson: (options?: BaseReporterOptions) => NamedReporterContract = (options) => {\n return {\n name: 'ndjson',\n handler: (...args) => new NdJSONReporter(options).boot(...args),\n }\n}\n"],"mappings":";;;;;;;AAgBO,IAAM,cAAN,cAA0B,aAAa;AAAA;AAAA;AAAA;AAAA,EAIlC,UAAU,SAAsB;AACxC,QAAI,SAAS;AACb,QAAI,QAAQ,QAAQ;AAClB,eAAS,OAAO,KAAK,MAAM,IAAI;AAAA,IACjC,WAAW,QAAQ,YAAY,QAAQ,WAAW;AAChD,eAAS,QAAQ,WAAW,OAAO,QAAQ,MAAM,iBAAiB,IAAI,OAAO,IAAI,MAAM,KAAK;AAAA,IAC9F,WAAW,QAAQ,WAAW;AAC5B,eAAS,OAAO,OAAO,MAAM,MAAM;AAAA,IACrC,OAAO;AACL,eAAS,OAAO,MAAM,MAAM,IAAI;AAAA,IAClC;AAEA,YAAQ,OAAO,MAAM,GAAG,MAAM,EAAE;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,MAAM;AACpB,YAAQ,IAAI,EAAE;AACd,UAAM,KAAK,aAAa,KAAK,OAAQ,WAAW,CAAC;AAAA,EACnD;AACF;;;ACjCA,OAAO,QAAQ;AACf,SAAS,gBAAgB;AASlB,IAAM,eAAN,cAA2B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAK7C,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAKnB,aAAa,SAAsB;AACjC,QAAI,QAAQ,QAAQ;AAClB,aAAO,OAAO,KAAK,MAAM,IAAI;AAAA,IAC/B;AAEA,QAAI,QAAQ,WAAW;AACrB,aAAO,QAAQ,WAAW,OAAO,QAAQ,MAAM,iBAAiB,IAAI,OAAO,IAAI,MAAM,KAAK;AAAA,IAC5F;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,OAAO,IAAI,MAAM,KAAK;AAAA,IAC/B;AAEA,QAAI,QAAQ,WAAW;AACrB,aAAO,OAAO,OAAO,MAAM,MAAM;AAAA,IACnC;AAEA,WAAO,OAAO,MAAM,MAAM,IAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,SAAsB;AACpC,UAAM,UAAU,QAAQ,MAAM;AAE9B,QAAI,QAAQ,QAAQ;AAClB,aAAO,OAAO,KAAK,OAAO;AAAA,IAC5B;AAEA,QAAI,QAAQ,WAAW;AACrB,aAAO,QAAQ,WAAW,OAAO,QAAQ,OAAO,IAAI,OAAO,IAAI,OAAO;AAAA,IACxE;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,OAAO,IAAI,OAAO;AAAA,IAC3B;AAEA,QAAI,QAAQ,WAAW;AACrB,aAAO,OAAO,OAAO,OAAO;AAAA,IAC9B;AAEA,WAAO,OAAO,KAAK,OAAO;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,SAA0C;AACpD,QAAI,QAAQ,aAAa,QAAQ,YAAY;AAC3C,aAAO,OAAO,OAAO,QAAQ,UAAU;AAAA,IACzC;AAEA,QAAI,CAAC,QAAQ,WAAW;AACtB;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,UAAU;AACrB,aAAO,OAAO,QAAQ,uDAAuD;AAAA,IAC/E;AAEA,QAAI,QAAQ,YAAY;AACtB,aAAO,OAAO,QAAQ,QAAQ,UAAU;AAAA,IAC1C;AAEA,UAAM,mBAAmB,QAAQ,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,MAAM;AAC9E,QAAI,oBAAoB,iBAAiB,OAAO;AAC9C,aAAO,OAAO,QAAQ,iBAAiB,MAAM,OAAO;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,UAAkB;AACrC,WAAO,SAAS,QAAQ,IAAI,GAAG,QAAQ;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,SAAsB;AAC/B,UAAM,OAAO,KAAK,aAAa,OAAO;AACtC,UAAM,UAAU,KAAK,gBAAgB,OAAO;AAC5C,UAAM,SAAS,QAAQ,WAAW,OAAO,OAAO,WAAW,IAAI;AAC/D,UAAM,cAAc,KAAK,mBAAmB,KAAK,mBAAmB,OAAO;AAC3E,UAAM,WAAW,OAAO,IAAI,IAAI,GAAG,OAAO,QAAQ,SAAS,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG;AAC1E,UAAM,UACJ,QAAQ,gBAAgB,QAAQ,eAAe,IAC3C,OAAO,IAAI,KAAK,QAAQ,YAAY,IAAI,IACxC;AAEN,QAAI,UAAU,KAAK,YAAY,OAAO;AACtC,cAAU,UAAU;AAAA,EAAK,WAAW,KAAK,OAAO,KAAK;AAErD,YAAQ,IAAI,GAAG,WAAW,GAAG,IAAI,IAAI,MAAM,GAAG,OAAO,GAAG,OAAO,IAAI,QAAQ,GAAG,OAAO,EAAE;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,SAAyB;AACnC,UAAM,QACJ,KAAK,qBAAqB,YACtB,GAAG,KAAK,gBAAgB,MAAM,QAAQ,KAAK,KAC3C,QAAQ;AAEd,UAAM,SAAS,KAAK,kBAChB,OAAO,IAAI,KAAK,KAAK,qBAAqB,KAAK,eAAe,CAAC,GAAG,IAClE;AAEJ,YAAQ,IAAI;AAAA,EAAK,KAAK,GAAG,MAAM,EAAE;AAAA,EACnC;AAAA,EAEU,cAAoB;AAQ5B,QAAI,KAAK,mBAAmB,KAAK,kBAAkB;AACjD,cAAQ,IAAI;AAAA,EAAK,OAAO,IAAI,KAAK,qBAAqB,KAAK,eAAe,CAAC,CAAC,EAAE;AAAA,IAChF;AACA,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEU,UAAU,SAA4B;AAC9C,SAAK,WAAW,OAAO;AAAA,EACzB;AAAA,EAEU,aAAa,SAA+B;AAKpD,SAAK,mBAAmB;AACxB,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA,EAEU,aAAmB;AAQ3B,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,MAAgB,MAAM;AACpB,UAAM,UAAU,KAAK,OAAQ,WAAW;AACxC,UAAM,KAAK,aAAa,OAAO;AAAA,EACjC;AACF;;;AChLA,SAAS,YAAAA,iBAAgB;AACzB,SAAS,sBAAsB;AAexB,IAAM,iBAAN,cAA6B,aAAa;AAAA;AAAA;AAAA;AAAA,EAI/C,qBAAqB,UAAkB;AACrC,WAAOC,UAAS,QAAQ,IAAI,GAAG,QAAQ;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,QAA+B;AAC9C,WAAO,OAAO,IAAI,CAAC,WAAW;AAAA,MAC5B,OAAO,MAAM;AAAA,MACb,OAAO,eAAe,MAAM,KAAK;AAAA,IACnC,EAAE;AAAA,EACJ;AAAA,EAEU,UAAU,SAA4B;AAC9C,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,UAAU,KAAK;AAAA,QACf,cAAc,KAAK,kBACf,KAAK,qBAAqB,KAAK,eAAe,IAC9C;AAAA,QACJ,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,QAClB,YAAY,QAAQ;AAAA,QACpB,WAAW,QAAQ;AAAA,QACnB,YAAY,QAAQ;AAAA,QACpB,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,QAClB,cAAc,QAAQ;AAAA,QACtB,SAAS,QAAQ;AAAA,QACjB,QAAQ,KAAK,iBAAiB,QAAQ,MAAM;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEU,aAAa,SAA+B;AACpD,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEU,WAAW,SAA6B;AAChD,SAAK,UAAU;AAAA,MACb,OAAO;AAAA,MACP,OAAO,QAAQ;AAAA,MACf,QAAQ,KAAK,iBAAiB,QAAQ,MAAM;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA,EAEU,aAAa,SAA+B;AACpD,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEU,WAAW,SAA6B;AAChD,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAgB,MAAM;AACpB,UAAM,UAAU,KAAK,OAAQ,WAAW;AACxC,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,YAAY,QAAQ;AAAA,QACpB,UAAU,QAAQ;AAAA,QAClB,mBAAmB,QAAQ;AAAA,QAC3B,UAAU,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC/FO,IAAM,OAAiE,CAAC,YAAY;AACzF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,IAAI,SAAS,IAAI,aAAa,OAAO,EAAE,KAAK,GAAG,IAAI;AAAA,EAC9D;AACF;AAKO,IAAM,MAAgE,CAAC,YAAY;AACxF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,IAAI,SAAS,IAAI,YAAY,OAAO,EAAE,KAAK,GAAG,IAAI;AAAA,EAC7D;AACF;AAKO,IAAM,SAAmE,CAAC,YAAY;AAC3F,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,IAAI,SAAS,IAAI,eAAe,OAAO,EAAE,KAAK,GAAG,IAAI;AAAA,EAChE;AACF;","names":["relative","relative"]}
@@ -5,13 +5,13 @@ import {
5
5
  Planner,
6
6
  createTest,
7
7
  createTestGroup
8
- } from "../chunk-PSL75GNC.js";
9
- import "../chunk-6IZE72CL.js";
8
+ } from "../chunk-NVI2OU43.js";
9
+ import "../chunk-PHC5CJQG.js";
10
10
  import {
11
11
  Emitter,
12
12
  Runner,
13
13
  Suite
14
- } from "../chunk-PKOB3ULJ.js";
14
+ } from "../chunk-BFNOUWI5.js";
15
15
  import "../chunk-OBDV3O36.js";
16
16
 
17
17
  // factories/runner.ts
package/build/index.js CHANGED
@@ -7,15 +7,14 @@ import {
7
7
  createTestGroup,
8
8
  debug_default,
9
9
  validator_default
10
- } from "./chunk-PSL75GNC.js";
11
- import {
12
- colors
13
- } from "./chunk-6IZE72CL.js";
10
+ } from "./chunk-NVI2OU43.js";
11
+ import "./chunk-PHC5CJQG.js";
14
12
  import {
15
13
  Emitter,
16
14
  Runner,
17
- Suite
18
- } from "./chunk-PKOB3ULJ.js";
15
+ Suite,
16
+ colors
17
+ } from "./chunk-BFNOUWI5.js";
19
18
  import "./chunk-OBDV3O36.js";
20
19
 
21
20
  // index.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts","../src/plugins/retry.ts","../src/exceptions_manager.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { fileURLToPath } from 'node:url'\nimport { ErrorsPrinter } from '@japa/errors-printer'\nimport type { TestExecutor } from '@japa/core/types'\n\nimport debug from './src/debug.js'\nimport validator from './src/validator.js'\nimport { Planner } from './src/planner.js'\nimport { GlobalHooks } from './src/hooks.js'\nimport { CliParser } from './src/cli_parser.js'\nimport { retryPlugin } from './src/plugins/retry.js'\nimport { ConfigManager } from './src/config_manager.js'\nimport { ExceptionsManager } from './src/exceptions_manager.js'\nimport { createTest, createTestGroup } from './src/create_test.js'\nimport type { CLIArgs, Config, NormalizedConfig } from './src/types.js'\nimport { Emitter, Group, Runner, Suite, Test, TestContext } from './modules/core/main.js'\n\n/**\n * Global emitter instance used by the test\n */\nconst emitter = new Emitter()\n\n/**\n * The current active test\n */\nlet activeTest: Test<any> | undefined\n\n/**\n * Parsed commandline arguments\n */\nlet cliArgs: CLIArgs = {}\n\n/**\n * Hydrated config\n */\nlet runnerConfig: NormalizedConfig | undefined\n\n/**\n * The state refers to the phase where we configure suites and import\n * test files. We stick this metadata to the test instance one can\n * later reference within the test.\n */\nconst executionPlanState: {\n phase: 'idle' | 'planning' | 'executing'\n file?: string\n suite?: Suite\n group?: Group\n timeout?: number\n retries?: number\n} = {\n phase: 'idle',\n}\n\n/**\n * Create a Japa test. Defining a test without the callback\n * will create a todo test.\n */\nexport function test(title: string, callback?: TestExecutor<TestContext, undefined>) {\n validator.ensureIsInPlanningPhase(executionPlanState.phase)\n\n const testInstance = createTest(title, emitter, runnerConfig!.refiner, executionPlanState)\n testInstance.setup((t) => {\n activeTest = t\n return () => {\n activeTest = undefined\n }\n })\n\n if (callback) {\n testInstance.run(callback)\n }\n\n return testInstance\n}\n\n/**\n * Create a Japa test group\n */\ntest.group = function (title: string, callback: (group: Group) => void) {\n validator.ensureIsInPlanningPhase(executionPlanState.phase)\n\n executionPlanState.group = createTestGroup(\n title,\n emitter,\n runnerConfig!.refiner,\n executionPlanState\n )\n callback(executionPlanState.group)\n executionPlanState.group = undefined\n}\n\n/**\n * Get the test of currently running test\n */\nexport function getActiveTest() {\n return activeTest\n}\n\n/**\n * Make Japa process command line arguments. Later the parsed output\n * will be used by Japa to compute the configuration\n */\nexport function processCLIArgs(argv: string[]) {\n cliArgs = new CliParser().parse(argv)\n}\n\n/**\n * Configure the tests runner with inline configuration. You must\n * call configure method before the run method.\n *\n * Do note: The CLI flags will overwrite the options provided\n * to the configure method.\n */\nexport function configure(options: Config) {\n runnerConfig = new ConfigManager(options, cliArgs).hydrate()\n}\n\n/**\n * Execute Japa tests. Calling this function will import the test\n * files behind the scenes\n */\nexport async function run() {\n /**\n * Display help when help flag is used\n */\n if (cliArgs.help) {\n console.log(new CliParser().getHelp())\n return\n }\n\n validator.ensureIsConfigured(runnerConfig)\n\n executionPlanState.phase = 'planning'\n const runner = new Runner(emitter)\n const globalHooks = new GlobalHooks()\n const exceptionsManager = new ExceptionsManager()\n\n try {\n /**\n * Executing the retry plugin as the first thing\n */\n await retryPlugin({ config: runnerConfig!, runner, emitter, cliArgs })\n\n /**\n * Step 1: Executing plugins before creating a plan, so that it can mutate\n * the config\n */\n for (let plugin of runnerConfig!.plugins) {\n debug('executing \"%s\" plugin', plugin.name || 'anonymous')\n await plugin({ runner, emitter, cliArgs, config: runnerConfig! })\n }\n\n /**\n * Step 2: Creating an execution plan. The output is the result of\n * applying all the filters and validations.\n */\n const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig!).plan()\n\n /**\n * Step 3: Registering reporters and filters with the runner\n */\n reporters.forEach((reporter) => {\n debug('registering \"%s\" reporter', reporter.name)\n runner.registerReporter(reporter)\n })\n refinerFilters.forEach((filter) => {\n debug('apply %s filters \"%O\" ', filter.layer, filter.filters)\n config.refiner.add(filter.layer, filter.filters)\n })\n config.refiner.matchAllTags(cliArgs.matchAll ?? false)\n runner.onSuite(config.configureSuite)\n\n /**\n * Step 4: Running the setup hooks\n */\n debug('executing global hooks')\n globalHooks.apply(config)\n await globalHooks.setup(runner)\n\n /**\n * Step 5: Register suites and import test files\n */\n for (let suite of suites) {\n /**\n * Creating and configuring the suite\n */\n executionPlanState.suite = new Suite(suite.name, emitter, config.refiner)\n executionPlanState.retries = suite.retries\n executionPlanState.timeout = suite.timeout\n if (typeof suite.configure === 'function') {\n suite.configure(executionPlanState.suite)\n }\n runner.add(executionPlanState.suite)\n\n /**\n * Importing suite files\n */\n for (let fileURL of suite.filesURLs) {\n executionPlanState.file = fileURLToPath(fileURL)\n debug('importing test file %s', executionPlanState.file)\n await config.importer(fileURL)\n }\n\n /**\n * Resetting global state\n */\n executionPlanState.suite = undefined\n }\n\n /**\n * Onto execution phase\n */\n executionPlanState.phase = 'executing'\n\n /**\n * Monitor for unhandled erorrs and rejections\n */\n exceptionsManager.monitor()\n\n await runner.start()\n await runner.exec()\n\n await globalHooks.teardown(null, runner)\n await runner.end()\n\n /**\n * Print unhandled errors\n */\n await exceptionsManager.flow()\n\n const summary = runner.getSummary()\n if (summary.hasError || exceptionsManager.hasErrors) {\n process.exitCode = 1\n }\n if (config.forceExit) {\n process.exit()\n }\n } catch (error) {\n await globalHooks.teardown(error, runner)\n const printer = new ErrorsPrinter()\n await printer.printError(error)\n\n /**\n * Print unhandled errors in case the code inside\n * the try block never got triggered\n */\n await exceptionsManager.flow()\n\n process.exitCode = 1\n if (runnerConfig!.forceExit) {\n process.exit()\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { join } from 'node:path'\nimport findCacheDirectory from 'find-cache-dir'\nimport { mkdir, readFile, unlink, writeFile } from 'node:fs/promises'\n\nimport { colors } from '../helpers.js'\nimport type { PluginFn } from '../types.js'\n\n/**\n * Paths to the cache directory and the summary file\n */\nconst CACHE_DIR = findCacheDirectory({ name: '@japa/runner' })\nconst SUMMARY_FILE = CACHE_DIR ? join(CACHE_DIR, 'summary.json') : undefined\n\n/**\n * Returns an object with the title of the tests failed during\n * the last run.\n */\nexport async function getFailedTests(): Promise<{ tests?: string[] }> {\n try {\n const summary = await readFile(SUMMARY_FILE!, 'utf-8')\n return JSON.parse(summary)\n } catch (error) {\n if (error.code === 'ENOENT') {\n return {}\n }\n throw new Error('Unable to read failed tests cache file', { cause: error })\n }\n}\n\n/**\n * Writes failing tests to the cache directory\n */\nexport async function cacheFailedTests(tests: string[]) {\n await mkdir(CACHE_DIR!, { recursive: true })\n await writeFile(SUMMARY_FILE!, JSON.stringify({ tests: tests }))\n}\n\n/**\n * Clears the cache dir\n */\nexport async function clearCache() {\n await unlink(SUMMARY_FILE!)\n}\n\n/**\n * Exposes the API to run failing tests using the \"failed\" CLI flag.\n */\nexport const retryPlugin: PluginFn = async function retry({ config, cliArgs }) {\n if (!SUMMARY_FILE) {\n return\n }\n\n config.teardown.push(async (runner) => {\n const summary = runner.getSummary()\n await cacheFailedTests(summary.failedTestsTitles)\n })\n\n if (cliArgs.failed) {\n try {\n const { tests } = await getFailedTests()\n if (!tests || !tests.length) {\n console.log(colors.bgYellow().black(' No failing tests found. Running all the tests '))\n return\n }\n config.filters.tests = tests\n } catch (error) {\n console.log(colors.bgRed().black(' Unable to read failed tests. Running all the tests '))\n console.log(colors.red(error))\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { ErrorsPrinter } from '@japa/errors-printer'\n\n/**\n * Handles uncaught exceptions and prints them to the\n * console\n */\nexport class ExceptionsManager {\n #exceptionsBuffer: any[] = []\n #rejectionsBuffer: any[] = []\n #state: 'watching' | 'flowing' = 'watching'\n #errorsPrinter = new ErrorsPrinter({ stackLinesCount: 2, framesMaxLimit: 4 })\n\n hasErrors: boolean = false\n\n /**\n * Monitors unhandled exceptions and rejections. The exceptions\n * are stacked in a buffer, so that we do not clutter the\n * tests output and once the tests are over, we will\n * print them to the console.\n *\n * In case the tests are completed, we will print errors as they\n * happen.\n */\n monitor() {\n process.on('uncaughtException', async (error) => {\n this.hasErrors = true\n if (this.#state === 'watching') {\n this.#exceptionsBuffer.push(error)\n } else {\n this.#errorsPrinter.printSectionBorder('[Unhandled Error]')\n await this.#errorsPrinter.printError(error)\n process.exitCode = 1\n }\n })\n\n process.on('unhandledRejection', async (error) => {\n this.hasErrors = true\n if (this.#state === 'watching') {\n this.#rejectionsBuffer.push(error)\n } else {\n this.#errorsPrinter.printSectionBorder('[Unhandled Rejection]')\n await this.#errorsPrinter.printError(error)\n process.exitCode = 1\n }\n })\n }\n\n async flow() {\n if (this.#state === 'flowing') {\n return\n }\n\n this.#state = 'flowing'\n\n /**\n * Print exceptions\n */\n if (this.#exceptionsBuffer.length) {\n let exceptionsCount = this.#exceptionsBuffer.length\n let exceptionsIndex = this.#exceptionsBuffer.length\n this.#errorsPrinter.printSectionHeader('Unhandled Errors')\n for (let exception of this.#exceptionsBuffer) {\n await this.#errorsPrinter.printError(exception)\n this.#errorsPrinter.printSectionBorder(`[${++exceptionsIndex}/${exceptionsCount}]`)\n }\n this.#exceptionsBuffer = []\n }\n\n /**\n * Print rejections\n */\n if (this.#rejectionsBuffer.length) {\n let rejectionsCount = this.#exceptionsBuffer.length\n let rejectionsIndex = this.#exceptionsBuffer.length\n this.#errorsPrinter.printSectionBorder('Unhandled Rejections')\n for (let rejection of this.#rejectionsBuffer) {\n await this.#errorsPrinter.printError(rejection)\n this.#errorsPrinter.printSectionBorder(`[${++rejectionsIndex}/${rejectionsCount}]`)\n }\n this.#rejectionsBuffer = []\n }\n }\n}\n"],"mappings":"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","names":["ErrorsPrinter","cliArgs","ErrorsPrinter"]}
1
+ {"version":3,"sources":["../index.ts","../src/plugins/retry.ts","../src/exceptions_manager.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { fileURLToPath } from 'node:url'\nimport { ErrorsPrinter } from '@japa/errors-printer'\nimport type { TestExecutor } from '@japa/core/types'\n\nimport debug from './src/debug.js'\nimport validator from './src/validator.js'\nimport { Planner } from './src/planner.js'\nimport { GlobalHooks } from './src/hooks.js'\nimport { CliParser } from './src/cli_parser.js'\nimport { retryPlugin } from './src/plugins/retry.js'\nimport { ConfigManager } from './src/config_manager.js'\nimport { ExceptionsManager } from './src/exceptions_manager.js'\nimport { createTest, createTestGroup } from './src/create_test.js'\nimport type { CLIArgs, Config, NormalizedConfig } from './src/types.js'\nimport { Emitter, Group, Runner, Suite, Test, TestContext } from './modules/core/main.js'\n\n/**\n * Global emitter instance used by the test\n */\nconst emitter = new Emitter()\n\n/**\n * The current active test\n */\nlet activeTest: Test<any> | undefined\n\n/**\n * Parsed commandline arguments\n */\nlet cliArgs: CLIArgs = {}\n\n/**\n * Hydrated config\n */\nlet runnerConfig: NormalizedConfig | undefined\n\n/**\n * The state refers to the phase where we configure suites and import\n * test files. We stick this metadata to the test instance one can\n * later reference within the test.\n */\nconst executionPlanState: {\n phase: 'idle' | 'planning' | 'executing'\n file?: string\n suite?: Suite\n group?: Group\n timeout?: number\n retries?: number\n} = {\n phase: 'idle',\n}\n\n/**\n * Create a Japa test. Defining a test without the callback\n * will create a todo test.\n */\nexport function test(title: string, callback?: TestExecutor<TestContext, undefined>) {\n validator.ensureIsInPlanningPhase(executionPlanState.phase)\n\n const testInstance = createTest(title, emitter, runnerConfig!.refiner, executionPlanState)\n testInstance.setup((t) => {\n activeTest = t\n return () => {\n activeTest = undefined\n }\n })\n\n if (callback) {\n testInstance.run(callback)\n }\n\n return testInstance\n}\n\n/**\n * Create a Japa test group\n */\ntest.group = function (title: string, callback: (group: Group) => void) {\n validator.ensureIsInPlanningPhase(executionPlanState.phase)\n\n executionPlanState.group = createTestGroup(\n title,\n emitter,\n runnerConfig!.refiner,\n executionPlanState\n )\n callback(executionPlanState.group)\n executionPlanState.group = undefined\n}\n\n/**\n * Get the test of currently running test\n */\nexport function getActiveTest() {\n return activeTest\n}\n\n/**\n * Make Japa process command line arguments. Later the parsed output\n * will be used by Japa to compute the configuration\n */\nexport function processCLIArgs(argv: string[]) {\n cliArgs = new CliParser().parse(argv)\n}\n\n/**\n * Configure the tests runner with inline configuration. You must\n * call configure method before the run method.\n *\n * Do note: The CLI flags will overwrite the options provided\n * to the configure method.\n */\nexport function configure(options: Config) {\n runnerConfig = new ConfigManager(options, cliArgs).hydrate()\n}\n\n/**\n * Execute Japa tests. Calling this function will import the test\n * files behind the scenes\n */\nexport async function run() {\n /**\n * Display help when help flag is used\n */\n if (cliArgs.help) {\n console.log(new CliParser().getHelp())\n return\n }\n\n validator.ensureIsConfigured(runnerConfig)\n\n executionPlanState.phase = 'planning'\n const runner = new Runner(emitter)\n const globalHooks = new GlobalHooks()\n const exceptionsManager = new ExceptionsManager()\n\n try {\n /**\n * Executing the retry plugin as the first thing\n */\n await retryPlugin({ config: runnerConfig!, runner, emitter, cliArgs })\n\n /**\n * Step 1: Executing plugins before creating a plan, so that it can mutate\n * the config\n */\n for (let plugin of runnerConfig!.plugins) {\n debug('executing \"%s\" plugin', plugin.name || 'anonymous')\n await plugin({ runner, emitter, cliArgs, config: runnerConfig! })\n }\n\n /**\n * Step 2: Creating an execution plan. The output is the result of\n * applying all the filters and validations.\n */\n const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig!).plan()\n\n /**\n * Step 3: Registering reporters and filters with the runner\n */\n reporters.forEach((reporter) => {\n debug('registering \"%s\" reporter', reporter.name)\n runner.registerReporter(reporter)\n })\n refinerFilters.forEach((filter) => {\n debug('apply %s filters \"%O\" ', filter.layer, filter.filters)\n config.refiner.add(filter.layer, filter.filters)\n })\n config.refiner.matchAllTags(cliArgs.matchAll ?? false)\n runner.onSuite(config.configureSuite)\n\n /**\n * Step 4: Running the setup hooks\n */\n debug('executing global hooks')\n globalHooks.apply(config)\n await globalHooks.setup(runner)\n\n /**\n * Step 5: Register suites and import test files\n */\n for (let suite of suites) {\n /**\n * Creating and configuring the suite\n */\n executionPlanState.suite = new Suite(suite.name, emitter, config.refiner)\n executionPlanState.retries = suite.retries\n executionPlanState.timeout = suite.timeout\n if (typeof suite.configure === 'function') {\n suite.configure(executionPlanState.suite)\n }\n runner.add(executionPlanState.suite)\n\n /**\n * Importing suite files\n */\n for (let fileURL of suite.filesURLs) {\n executionPlanState.file = fileURLToPath(fileURL)\n debug('importing test file %s', executionPlanState.file)\n await config.importer(fileURL)\n }\n\n /**\n * Resetting global state\n */\n executionPlanState.suite = undefined\n }\n\n /**\n * Onto execution phase\n */\n executionPlanState.phase = 'executing'\n\n /**\n * Monitor for unhandled erorrs and rejections\n */\n exceptionsManager.monitor()\n\n await runner.start()\n await runner.exec()\n\n await globalHooks.teardown(null, runner)\n await runner.end()\n\n /**\n * Print unhandled errors\n */\n await exceptionsManager.flow()\n\n const summary = runner.getSummary()\n if (summary.hasError || exceptionsManager.hasErrors) {\n process.exitCode = 1\n }\n if (config.forceExit) {\n process.exit()\n }\n } catch (error) {\n await globalHooks.teardown(error, runner)\n const printer = new ErrorsPrinter()\n await printer.printError(error)\n\n /**\n * Print unhandled errors in case the code inside\n * the try block never got triggered\n */\n await exceptionsManager.flow()\n\n process.exitCode = 1\n if (runnerConfig!.forceExit) {\n process.exit()\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { join } from 'node:path'\nimport findCacheDirectory from 'find-cache-dir'\nimport { mkdir, readFile, unlink, writeFile } from 'node:fs/promises'\n\nimport { colors } from '../helpers.js'\nimport type { PluginFn } from '../types.js'\n\n/**\n * Paths to the cache directory and the summary file\n */\nconst CACHE_DIR = findCacheDirectory({ name: '@japa/runner' })\nconst SUMMARY_FILE = CACHE_DIR ? join(CACHE_DIR, 'summary.json') : undefined\n\n/**\n * Returns an object with the title of the tests failed during\n * the last run.\n */\nexport async function getFailedTests(): Promise<{ tests?: string[] }> {\n try {\n const summary = await readFile(SUMMARY_FILE!, 'utf-8')\n return JSON.parse(summary)\n } catch (error) {\n if (error.code === 'ENOENT') {\n return {}\n }\n throw new Error('Unable to read failed tests cache file', { cause: error })\n }\n}\n\n/**\n * Writes failing tests to the cache directory\n */\nexport async function cacheFailedTests(tests: string[]) {\n await mkdir(CACHE_DIR!, { recursive: true })\n await writeFile(SUMMARY_FILE!, JSON.stringify({ tests: tests }))\n}\n\n/**\n * Clears the cache dir\n */\nexport async function clearCache() {\n await unlink(SUMMARY_FILE!)\n}\n\n/**\n * Exposes the API to run failing tests using the \"failed\" CLI flag.\n */\nexport const retryPlugin: PluginFn = async function retry({ config, cliArgs }) {\n if (!SUMMARY_FILE) {\n return\n }\n\n config.teardown.push(async (runner) => {\n const summary = runner.getSummary()\n await cacheFailedTests(summary.failedTestsTitles)\n })\n\n if (cliArgs.failed) {\n try {\n const { tests } = await getFailedTests()\n if (!tests || !tests.length) {\n console.log(colors.bgYellow().black(' No failing tests found. Running all the tests '))\n return\n }\n config.filters.tests = tests\n } catch (error) {\n console.log(colors.bgRed().black(' Unable to read failed tests. Running all the tests '))\n console.log(colors.red(error))\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { ErrorsPrinter } from '@japa/errors-printer'\n\n/**\n * Handles uncaught exceptions and prints them to the\n * console\n */\nexport class ExceptionsManager {\n #exceptionsBuffer: any[] = []\n #rejectionsBuffer: any[] = []\n #state: 'watching' | 'flowing' = 'watching'\n #errorsPrinter = new ErrorsPrinter({ stackLinesCount: 2, framesMaxLimit: 4 })\n\n hasErrors: boolean = false\n\n /**\n * Monitors unhandled exceptions and rejections. The exceptions\n * are stacked in a buffer, so that we do not clutter the\n * tests output and once the tests are over, we will\n * print them to the console.\n *\n * In case the tests are completed, we will print errors as they\n * happen.\n */\n monitor() {\n process.on('uncaughtException', async (error) => {\n this.hasErrors = true\n if (this.#state === 'watching') {\n this.#exceptionsBuffer.push(error)\n } else {\n this.#errorsPrinter.printSectionBorder('[Unhandled Error]')\n await this.#errorsPrinter.printError(error)\n process.exitCode = 1\n }\n })\n\n process.on('unhandledRejection', async (error) => {\n this.hasErrors = true\n if (this.#state === 'watching') {\n this.#rejectionsBuffer.push(error)\n } else {\n this.#errorsPrinter.printSectionBorder('[Unhandled Rejection]')\n await this.#errorsPrinter.printError(error)\n process.exitCode = 1\n }\n })\n }\n\n async flow() {\n if (this.#state === 'flowing') {\n return\n }\n\n this.#state = 'flowing'\n\n /**\n * Print exceptions\n */\n if (this.#exceptionsBuffer.length) {\n let exceptionsCount = this.#exceptionsBuffer.length\n let exceptionsIndex = this.#exceptionsBuffer.length\n this.#errorsPrinter.printSectionHeader('Unhandled Errors')\n for (let exception of this.#exceptionsBuffer) {\n await this.#errorsPrinter.printError(exception)\n this.#errorsPrinter.printSectionBorder(`[${++exceptionsIndex}/${exceptionsCount}]`)\n }\n this.#exceptionsBuffer = []\n }\n\n /**\n * Print rejections\n */\n if (this.#rejectionsBuffer.length) {\n let rejectionsCount = this.#exceptionsBuffer.length\n let rejectionsIndex = this.#exceptionsBuffer.length\n this.#errorsPrinter.printSectionBorder('Unhandled Rejections')\n for (let rejection of this.#rejectionsBuffer) {\n await this.#errorsPrinter.printError(rejection)\n this.#errorsPrinter.printSectionBorder(`[${++rejectionsIndex}/${rejectionsCount}]`)\n }\n this.#rejectionsBuffer = []\n }\n }\n}\n"],"mappings":"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","names":["ErrorsPrinter","cliArgs","ErrorsPrinter"]}
@@ -7,7 +7,7 @@ import {
7
7
  Suite,
8
8
  Test,
9
9
  TestContext
10
- } from "../../chunk-PKOB3ULJ.js";
10
+ } from "../../chunk-BFNOUWI5.js";
11
11
  import "../../chunk-OBDV3O36.js";
12
12
  export {
13
13
  BaseReporter,
@@ -2,8 +2,8 @@ import {
2
2
  dot,
3
3
  ndjson,
4
4
  spec
5
- } from "../../chunk-6IZE72CL.js";
6
- import "../../chunk-PKOB3ULJ.js";
5
+ } from "../../chunk-PHC5CJQG.js";
6
+ import "../../chunk-BFNOUWI5.js";
7
7
  import "../../chunk-OBDV3O36.js";
8
8
  export {
9
9
  dot,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@japa/runner",
3
3
  "description": "Runner for Japa testing framework",
4
- "version": "3.1.2",
4
+ "version": "3.1.4",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
7
7
  },
@@ -65,7 +65,7 @@
65
65
  },
66
66
  "dependencies": {
67
67
  "@japa/core": "^9.0.1",
68
- "@japa/errors-printer": "^3.0.3",
68
+ "@japa/errors-printer": "^3.0.4",
69
69
  "@poppinss/colors": "^4.1.3",
70
70
  "@poppinss/hooks": "^7.2.3",
71
71
  "fast-glob": "^3.3.2",
@@ -73,7 +73,8 @@
73
73
  "getopts": "^2.3.0",
74
74
  "ms": "^2.1.3",
75
75
  "serialize-error": "^11.0.3",
76
- "slash": "^5.1.0"
76
+ "slash": "^5.1.0",
77
+ "supports-color": "^9.4.0"
77
78
  },
78
79
  "author": "virk,japa",
79
80
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/helpers.ts","../src/reporters/dot.ts","../src/reporters/spec.ts","../src/reporters/ndjson.ts","../src/reporters/main.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport useColors from '@poppinss/colors'\nimport { Colors } from '@poppinss/colors/types'\n\nexport const colors: Colors = useColors.ansi()\n\n/**\n * A collection of platform specific icons\n */\nexport const icons =\n process.platform === 'win32' && !process.env.WT_SESSION\n ? {\n tick: '√',\n cross: '×',\n bullet: '*',\n nodejs: '♦',\n pointer: '>',\n info: 'i',\n warning: '‼',\n squareSmallFilled: '[█]',\n }\n : {\n tick: '✔',\n cross: '✖',\n bullet: '●',\n nodejs: '⬢',\n pointer: '❯',\n info: 'ℹ',\n warning: '⚠',\n squareSmallFilled: '◼',\n }\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { colors, icons } from '../helpers.js'\nimport type { TestEndNode } from '../../modules/core/types.js'\nimport { BaseReporter } from '../../modules/core/reporters/base.js'\n\n/**\n * Minimal reporter that prints each test as an icon.\n */\nexport class DotReporter extends BaseReporter {\n /**\n * When a test ended\n */\n protected onTestEnd(payload: TestEndNode) {\n let output = ''\n if (payload.isTodo) {\n output = colors.cyan(icons.info)\n } else if (payload.hasError || payload.isFailing) {\n output = payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross)\n } else if (payload.isSkipped) {\n output = colors.yellow(icons.bullet)\n } else {\n output = colors.green(icons.tick)\n }\n\n process.stdout.write(`${output}`)\n }\n\n /**\n * When test runner ended\n */\n protected async end() {\n console.log('')\n await this.printSummary(this.runner!.getSummary())\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport ms from 'ms'\nimport { relative } from 'node:path'\n\nimport { colors, icons } from '../helpers.js'\nimport { BaseReporter } from '../../modules/core/main.js'\nimport { GroupStartNode, TestEndNode } from '../../modules/core/types.js'\n\n/**\n * Pretty prints the tests on the console\n */\nexport class SpecReporter extends BaseReporter {\n /**\n * Tracking if the first event we get is for a test without any parent group\n * We need this to decide the display style for tests without groups.\n */\n #isFirstLoneTest = true\n\n /**\n * Returns the icon for the test\n */\n #getTestIcon(payload: TestEndNode) {\n if (payload.isTodo) {\n return colors.cyan(icons.info)\n }\n\n if (payload.isFailing) {\n return payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross)\n }\n\n if (payload.hasError) {\n return colors.red(icons.cross)\n }\n\n if (payload.isSkipped) {\n return colors.yellow(icons.bullet)\n }\n\n return colors.green(icons.tick)\n }\n\n /**\n * Returns the test message\n */\n #getTestMessage(payload: TestEndNode) {\n const message = payload.title.expanded\n\n if (payload.isTodo) {\n return colors.blue(message)\n }\n\n if (payload.isFailing) {\n return payload.hasError ? colors.magenta(message) : colors.red(message)\n }\n\n if (payload.hasError) {\n return colors.red(message)\n }\n\n if (payload.isSkipped) {\n return colors.yellow(message)\n }\n\n return colors.grey(message)\n }\n\n /**\n * Returns the subtext message for the test\n */\n #getSubText(payload: TestEndNode): string | undefined {\n if (payload.isSkipped && payload.skipReason) {\n return colors.yellow(payload.skipReason)\n }\n\n if (!payload.isFailing) {\n return\n }\n\n if (!payload.hasError) {\n return colors.magenta(`Test marked with \".fails()\" must finish with an error`)\n }\n\n if (payload.failReason) {\n return colors.magenta(payload.failReason)\n }\n\n const testErrorMessage = payload.errors.find((error) => error.phase === 'test')\n if (testErrorMessage && testErrorMessage.error) {\n return colors.magenta(testErrorMessage.error.message)\n }\n }\n\n /**\n * Returns the filename relative from the current working dir\n */\n #getRelativeFilename(fileName: string) {\n return relative(process.cwd(), fileName)\n }\n\n /**\n * Prints the test details\n */\n #printTest(payload: TestEndNode) {\n const icon = this.#getTestIcon(payload)\n const message = this.#getTestMessage(payload)\n const prefix = payload.isPinned ? colors.yellow('[PINNED] ') : ''\n const indentation = this.currentFileName || this.currentGroupName ? ' ' : ''\n const duration = colors.dim(`(${ms(Number(payload.duration.toFixed(2)))})`)\n const retries =\n payload.retryAttempt && payload.retryAttempt > 1\n ? colors.dim(`(x${payload.retryAttempt}) `)\n : ''\n\n let subText = this.#getSubText(payload)\n subText = subText ? `\\n${indentation} ${subText}` : ''\n\n console.log(`${indentation}${icon} ${prefix}${retries}${message} ${duration}${subText}`)\n }\n\n /**\n * Prints the group name\n */\n #printGroup(payload: GroupStartNode) {\n const title =\n this.currentSuiteName !== 'default'\n ? `${this.currentSuiteName} / ${payload.title}`\n : payload.title\n\n const suffix = this.currentFileName\n ? colors.dim(` (${this.#getRelativeFilename(this.currentFileName)})`)\n : ''\n\n console.log(`\\n${title}${suffix}`)\n }\n\n protected onTestStart(): void {\n /**\n * Display the filename when\n *\n * - The filename exists\n * - The test is not under a group\n * - Test is first in a sequence\n */\n if (this.currentFileName && this.#isFirstLoneTest) {\n console.log(`\\n${colors.dim(this.#getRelativeFilename(this.currentFileName))}`)\n }\n this.#isFirstLoneTest = false\n }\n\n protected onTestEnd(payload: TestEndNode): void {\n this.#printTest(payload)\n }\n\n protected onGroupStart(payload: GroupStartNode): void {\n /**\n * When a group starts, we mark the upcoming test as NOT a\n * lone test\n */\n this.#isFirstLoneTest = false\n this.#printGroup(payload)\n }\n\n protected onGroupEnd(): void {\n /**\n * When the group ends we assume that the next test can\n * be out of the group, hence a lone test.\n *\n * If this assumption is false, then the `onGroupStart` method\n * will toggle the boolean\n */\n this.#isFirstLoneTest = true\n }\n\n protected async end() {\n const summary = this.runner!.getSummary()\n await this.printSummary(summary)\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { relative } from 'node:path'\nimport { serializeError } from 'serialize-error'\n\nimport { BaseReporter } from '../../modules/core/main.js'\nimport type {\n TestEndNode,\n SuiteEndNode,\n GroupEndNode,\n SuiteStartNode,\n GroupStartNode,\n} from '../../modules/core/types.js'\n\n/**\n * Prints tests progress as JSON. Each event is emitted\n * independently\n */\nexport class NdJSONReporter extends BaseReporter {\n /**\n * Returns the filename relative from the current working dir\n */\n #getRelativeFilename(fileName: string) {\n return relative(process.cwd(), fileName)\n }\n\n /**\n * Serialize errors to JSON\n */\n #serializeErrors(errors: TestEndNode['errors']) {\n return errors.map((error) => ({\n phase: error.phase,\n error: serializeError(error.error),\n }))\n }\n\n protected onTestEnd(payload: TestEndNode): void {\n console.log(\n JSON.stringify({\n event: 'test:end',\n filePath: this.currentFileName,\n relativePath: this.currentFileName\n ? this.#getRelativeFilename(this.currentFileName)\n : undefined,\n title: payload.title,\n duration: payload.duration,\n failReason: payload.failReason,\n isFailing: payload.isFailing,\n skipReason: payload.skipReason,\n isSkipped: payload.isSkipped,\n isTodo: payload.isTodo,\n isPinned: payload.isPinned,\n retryAttempt: payload.retryAttempt,\n retries: payload.retries,\n errors: this.#serializeErrors(payload.errors),\n })\n )\n }\n\n protected onGroupStart(payload: GroupStartNode): void {\n console.log(\n JSON.stringify({\n event: 'group:start',\n title: payload.title,\n })\n )\n }\n\n protected onGroupEnd(payload: GroupEndNode): void {\n JSON.stringify({\n event: 'group:end',\n title: payload.title,\n errors: this.#serializeErrors(payload.errors),\n })\n }\n\n protected onSuiteStart(payload: SuiteStartNode): void {\n console.log(\n JSON.stringify({\n event: 'suite:start',\n ...payload,\n })\n )\n }\n\n protected onSuiteEnd(payload: SuiteEndNode): void {\n console.log(\n JSON.stringify({\n event: 'suite:end',\n ...payload,\n })\n )\n }\n\n protected async end() {\n const summary = this.runner!.getSummary()\n console.log(\n JSON.stringify({\n aggregates: summary.aggregates,\n duration: summary.duration,\n failedTestsTitles: summary.failedTestsTitles,\n hasError: summary.hasError,\n })\n )\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { DotReporter } from './dot.js'\nimport { SpecReporter } from './spec.js'\nimport { NdJSONReporter } from './ndjson.js'\nimport type { BaseReporterOptions, NamedReporterContract } from '../types.js'\n\n/**\n * Create an instance of the spec reporter\n */\nexport const spec: (options?: BaseReporterOptions) => NamedReporterContract = (options) => {\n return {\n name: 'spec',\n handler: (...args) => new SpecReporter(options).boot(...args),\n }\n}\n\n/**\n * Create an instance of the dot reporter\n */\nexport const dot: (options?: BaseReporterOptions) => NamedReporterContract = (options) => {\n return {\n name: 'dot',\n handler: (...args) => new DotReporter(options).boot(...args),\n }\n}\n\n/**\n * Create an instance of the ndjson reporter\n */\nexport const ndjson: (options?: BaseReporterOptions) => NamedReporterContract = (options) => {\n return {\n name: 'ndjson',\n handler: (...args) => new NdJSONReporter(options).boot(...args),\n }\n}\n"],"mappings":"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","names":["relative","relative"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../modules/core/main.ts","../modules/core/reporters/base.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport {\n Emitter,\n Refiner,\n Test as BaseTest,\n Suite as BaseSuite,\n Group as BaseGroup,\n Runner as BaseRunner,\n TestContext as BaseTestContext,\n} from '@japa/core'\nimport { inspect } from 'node:util'\nimport { AssertionError } from 'node:assert'\nimport { BaseReporter } from './reporters/base.js'\nimport type { DataSetNode, TestHooksCleanupHandler } from './types.js'\n\ndeclare module '@japa/core' {\n interface Test<Context extends Record<any, any>, TestData extends DataSetNode = undefined> {\n throws(message: string | RegExp, errorConstructor?: any): this\n }\n interface TestContext {\n cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void\n }\n}\n\nexport { Emitter, Refiner, BaseReporter }\n\n/**\n * Test context carries context data for a given test.\n */\nexport class TestContext extends BaseTestContext {\n /**\n * Register a cleanup function that runs after the test finishes\n * successfully or with an error.\n */\n declare cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void\n\n constructor(public test: Test) {\n super()\n this.cleanup = (cleanupCallback: TestHooksCleanupHandler<TestContext>) => {\n test.cleanup(cleanupCallback)\n }\n }\n}\n\n/**\n * Test class represents an individual test and exposes API to tweak\n * its runtime behavior.\n */\nexport class Test<TestData extends DataSetNode = undefined> extends BaseTest<\n TestContext,\n TestData\n> {\n /**\n * @inheritdoc\n */\n static executedCallbacks = []\n\n /**\n * @inheritdoc\n */\n static executingCallbacks = []\n\n /**\n * Assert the test callback throws an exception when a certain\n * error message and optionally is an instance of a given\n * Error class.\n */\n throws(message: string | RegExp, errorConstructor?: any) {\n const errorInPoint = new AssertionError({})\n const existingExecutor = this.options.executor\n if (!existingExecutor) {\n throw new Error('Cannot use \"test.throws\" method without a test callback')\n }\n\n /**\n * Overwriting existing callback\n */\n this.options.executor = async (...args: [any, any, any]) => {\n let raisedException: any\n try {\n await existingExecutor(...args)\n } catch (error) {\n raisedException = error\n }\n\n /**\n * Notify no exception has been raised\n */\n if (!raisedException) {\n errorInPoint.message = 'Expected test to throw an exception'\n throw errorInPoint\n }\n\n /**\n * Constructor mis-match\n */\n if (errorConstructor && !(raisedException instanceof errorConstructor)) {\n errorInPoint.message = `Expected test to throw \"${inspect(errorConstructor)}\"`\n throw errorInPoint\n }\n\n /**\n * Error does not have a message property\n */\n const exceptionMessage: unknown = raisedException.message\n if (!exceptionMessage || typeof exceptionMessage !== 'string') {\n errorInPoint.message = 'Expected test to throw an exception with message property'\n throw errorInPoint\n }\n\n /**\n * Message does not match\n */\n if (typeof message === 'string') {\n if (exceptionMessage !== message) {\n errorInPoint.message = `Expected test to throw \"${message}\". Instead received \"${raisedException.message}\"`\n errorInPoint.actual = raisedException.message\n errorInPoint.expected = message\n throw errorInPoint\n }\n return\n }\n\n if (!message.test(exceptionMessage)) {\n errorInPoint.message = `Expected test error to match \"${message}\" regular expression`\n throw errorInPoint\n }\n }\n\n return this\n }\n}\n\n/**\n * TestGroup is used to bulk configure a collection of tests and\n * define lifecycle hooks for them\n */\nexport class Group extends BaseGroup<TestContext> {}\n\n/**\n * A suite is a collection of tests created around a given\n * testing type. For example: A suite for unit tests, a\n * suite for functional tests and so on.\n */\nexport class Suite extends BaseSuite<TestContext> {}\n\n/**\n * Runner class is used to execute the tests\n */\nexport class Runner extends BaseRunner<TestContext> {}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport ms from 'ms'\nimport colors from '@poppinss/colors'\nimport { ErrorsPrinter } from '@japa/errors-printer'\n\nimport type {\n TestEndNode,\n SuiteEndNode,\n GroupEndNode,\n TestStartNode,\n RunnerSummary,\n RunnerEndNode,\n GroupStartNode,\n SuiteStartNode,\n RunnerStartNode,\n BaseReporterOptions,\n} from '../types.js'\nimport { Emitter, Runner } from '../main.js'\n\nconst ansi = colors.ansi()\n\n/**\n * Base reporter to build custom reporters on top of\n */\nexport abstract class BaseReporter {\n #options: BaseReporterOptions\n runner?: Runner\n\n /**\n * Path to the file for which the tests are getting executed\n */\n currentFileName?: string\n\n /**\n * Suite for which the tests are getting executed\n */\n currentSuiteName?: string\n\n /**\n * Group for which the tests are getting executed\n */\n currentGroupName?: string\n\n constructor(options: BaseReporterOptions = {}) {\n this.#options = Object.assign({ stackLinesCount: 2 }, options)\n }\n\n /**\n * Pretty prints the aggregates\n */\n #printAggregates(summary: RunnerSummary) {\n const tests: string[] = []\n\n /**\n * Set value for tests row\n */\n if (summary.aggregates.passed) {\n tests.push(ansi.green(`${summary.aggregates.passed} passed`))\n }\n if (summary.aggregates.failed) {\n tests.push(ansi.red(`${summary.aggregates.failed} failed`))\n }\n if (summary.aggregates.todo) {\n tests.push(ansi.cyan(`${summary.aggregates.todo} todo`))\n }\n if (summary.aggregates.skipped) {\n tests.push(ansi.yellow(`${summary.aggregates.skipped} skipped`))\n }\n if (summary.aggregates.regression) {\n tests.push(ansi.magenta(`${summary.aggregates.regression} regression`))\n }\n\n this.runner!.summaryBuilder.use(() => {\n return [\n {\n key: ansi.dim('Tests'),\n value: `${tests.join(', ')} ${ansi.dim(`(${summary.aggregates.total})`)}`,\n },\n {\n key: ansi.dim('Time'),\n value: ansi.dim(ms(summary.duration)),\n },\n ]\n })\n\n console.log(this.runner!.summaryBuilder.build().join('\\n'))\n }\n\n /**\n * Aggregates errors tree to a flat array\n */\n #aggregateErrors(summary: RunnerSummary) {\n const errorsList: { phase: string; title: string; error: Error }[] = []\n\n summary.failureTree.forEach((suite) => {\n suite.errors.forEach((error) => errorsList.push({ title: suite.name, ...error }))\n\n suite.children.forEach((testOrGroup) => {\n /**\n * Suite child is a test\n */\n if (testOrGroup.type === 'test') {\n testOrGroup.errors.forEach((error) => {\n errorsList.push({ title: `${suite.name} / ${testOrGroup.title}`, ...error })\n })\n return\n }\n\n /**\n * Suite child is a group\n */\n testOrGroup.errors.forEach((error) => {\n errorsList.push({ title: testOrGroup.name, ...error })\n })\n testOrGroup.children.forEach((test) => {\n test.errors.forEach((error) => {\n errorsList.push({ title: `${testOrGroup.name} / ${test.title}`, ...error })\n })\n })\n })\n })\n\n return errorsList\n }\n\n /**\n * Pretty print errors\n */\n async #printErrors(summary: RunnerSummary) {\n if (!summary.failureTree.length) {\n return\n }\n\n const errorPrinter = new ErrorsPrinter({\n stackLinesCount: this.#options.stackLinesCount,\n framesMaxLimit: this.#options.framesMaxLimit,\n })\n\n errorPrinter.printSectionHeader('ERRORS')\n await errorPrinter.printErrors(this.#aggregateErrors(summary))\n }\n\n /**\n * Handlers to capture events\n */\n protected onTestStart(_: TestStartNode): void {}\n protected onTestEnd(_: TestEndNode) {}\n\n protected onGroupStart(_: GroupStartNode) {}\n protected onGroupEnd(_: GroupEndNode) {}\n\n protected onSuiteStart(_: SuiteStartNode) {}\n protected onSuiteEnd(_: SuiteEndNode) {}\n\n protected async start(_: RunnerStartNode) {}\n protected async end(_: RunnerEndNode) {}\n\n /**\n * Print tests summary\n */\n protected async printSummary(summary: RunnerSummary) {\n await this.#printErrors(summary)\n\n console.log('')\n if (summary.aggregates.total === 0 && !summary.hasError) {\n console.log(ansi.bgYellow().black(' NO TESTS EXECUTED '))\n return\n }\n\n if (summary.hasError) {\n console.log(ansi.bgRed().black(' FAILED '))\n } else {\n console.log(ansi.bgGreen().black(' PASSED '))\n }\n console.log('')\n this.#printAggregates(summary)\n }\n\n /**\n * Invoked by the tests runner when tests are about to start\n */\n boot(runner: Runner, emitter: Emitter) {\n this.runner = runner\n\n emitter.on('test:start', (payload) => {\n this.currentFileName = payload.meta.fileName\n this.onTestStart(payload)\n })\n\n emitter.on('test:end', (payload) => {\n this.onTestEnd(payload)\n })\n\n emitter.on('group:start', (payload) => {\n this.currentGroupName = payload.title\n this.currentFileName = payload.meta.fileName\n this.onGroupStart(payload)\n })\n\n emitter.on('group:end', (payload) => {\n this.currentGroupName = undefined\n this.onGroupEnd(payload)\n })\n\n emitter.on('suite:start', (payload) => {\n this.currentSuiteName = payload.name\n this.onSuiteStart(payload)\n })\n\n emitter.on('suite:end', (payload) => {\n this.currentSuiteName = undefined\n this.onSuiteEnd(payload)\n })\n\n emitter.on('runner:start', async (payload) => {\n await this.start(payload)\n })\n\n emitter.on('runner:end', async (payload) => {\n await this.end(payload)\n })\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/debug.ts","../src/validator.ts","../src/files_manager.ts","../src/planner.ts","../src/hooks.ts","../src/cli_parser.ts","../src/config_manager.ts","../src/create_test.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { debuglog } from 'node:util'\nexport default debuglog('japa:runner')\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { NormalizedConfig } from './types.js'\n\n/**\n * Validator encapsulates the validations to perform before running\n * the tests\n */\nclass Validator {\n /**\n * Ensures the japa is configured. Otherwise raises an exception\n */\n ensureIsConfigured(config: NormalizedConfig | undefined) {\n if (!config) {\n throw new Error(\n `Cannot run tests. Make sure to call \"configure\" method before the \"run\" method`\n )\n }\n }\n\n /**\n * Ensures the japa is in planning phase\n */\n ensureIsInPlanningPhase(phase: 'idle' | 'planning' | 'executing') {\n if (phase !== 'planning') {\n throw new Error(\n `Cannot import japa test file directly. It must be imported by calling the \"japa.run\" method`\n )\n }\n }\n\n /**\n * Ensures the suites filter uses a subset of the user configured suites.\n */\n validateSuitesFilter(config: NormalizedConfig) {\n /**\n * Do not perform any validation if no filters are applied\n * in the first place\n */\n if (!config.filters.suites || !config.filters.suites.length) {\n return\n }\n\n /**\n * Notify user they have applied the suites filter but forgot to define\n * suites\n */\n if (!('suites' in config) || !config.suites.length) {\n throw new Error(`Cannot apply suites filter. You have not configured any test suites`)\n }\n\n const suites = config.suites.map(({ name }) => name)\n\n /**\n * Find unknown suites and report the error\n */\n const unknownSuites = config.filters.suites.filter((suite) => !suites.includes(suite))\n if (unknownSuites.length) {\n throw new Error(`Cannot apply suites filter. \"${unknownSuites[0]}\" suite is not configured`)\n }\n }\n\n /**\n * Ensure there are unique suites\n */\n validateSuitesForUniqueness(config: NormalizedConfig) {\n if (!('suites' in config)) {\n return\n }\n\n const suites: Set<string> = new Set()\n config.suites.forEach(({ name }) => {\n if (suites.has(name)) {\n throw new Error(`Duplicate suite \"${name}\"`)\n }\n suites.add(name)\n })\n\n suites.clear()\n }\n\n /**\n * Ensure the activated reporters are in the list of defined\n * reporters\n */\n validateActivatedReporters(config: NormalizedConfig) {\n const reportersList = config.reporters.list.map(({ name }) => name)\n const unknownReporters = config.reporters.activated.filter(\n (name) => !reportersList.includes(name)\n )\n\n if (unknownReporters.length) {\n throw new Error(\n `Invalid reporter \"${unknownReporters[0]}\". Make sure to register it first inside the \"reporters.list\" array`\n )\n }\n }\n}\n\nexport default new Validator()\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport slash from 'slash'\nimport fastGlob from 'fast-glob'\nimport { pathToFileURL } from 'node:url'\nimport type { TestFiles } from './types.js'\n\n/**\n * The expression to remove file extension and optionally\n * .spec|.test from the test file name\n */\nconst FILE_SUFFIX_EXPRESSION = /(\\.spec|\\.test)?\\.[js|ts|jsx|tsx|mjs|mts|cjs|cts]+$/\n\n/**\n * Files manager exposes the API to collect, filter and import test\n * files based upon the config\n */\nexport class FilesManager {\n /**\n * Returns a collection of files from the user defined\n * glob or the implementation function\n */\n async getFiles(cwd: string, files: TestFiles, excludes: string[]): Promise<URL[]> {\n if (Array.isArray(files) || typeof files === 'string') {\n const testFiles = await fastGlob(files, {\n absolute: true,\n onlyFiles: true,\n cwd: cwd,\n ignore: excludes,\n })\n return testFiles.map((file) => pathToFileURL(file))\n }\n\n return await files()\n }\n\n /**\n * Applies file name filter on a collection of file\n * URLs\n */\n grep(files: URL[], filters: string[]): URL[] {\n return files.filter((file) => {\n const filename = slash(file.pathname)\n const filenameWithoutTestSuffix = filename.replace(FILE_SUFFIX_EXPRESSION, '')\n\n return !!filters.find((filter) => {\n if (filename.endsWith(filter)) {\n return true\n }\n\n const filterSegments = filter.split('/').reverse()\n const fileSegments = filenameWithoutTestSuffix.split('/').reverse()\n\n return filterSegments.every((segment, index) => {\n return fileSegments[index] && (segment === '*' || fileSegments[index].endsWith(segment))\n })\n })\n })\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport validator from './validator.js'\nimport { FilesManager } from './files_manager.js'\nimport type { NamedReporterContract, NormalizedConfig, TestFiles, TestSuite } from './types.js'\n\n/**\n * The tests planner is used to plan the tests by doing all\n * the heavy lifting of executing plugins, registering\n * reporters, filtering tests and so on.\n */\nexport class Planner {\n #config: NormalizedConfig\n #fileManager = new FilesManager()\n\n constructor(config: NormalizedConfig) {\n validator.validateActivatedReporters(config!)\n validator.validateSuitesFilter(config!)\n validator.validateSuitesForUniqueness(config!)\n this.#config = config\n }\n\n /**\n * Returns a list of reporters based upon the activated\n * reporters list.\n */\n #getActivatedReporters(): NamedReporterContract[] {\n return this.#config.reporters.activated.map((activated) => {\n return this.#config.reporters.list.find(({ name }) => activated === name)!\n })\n }\n\n /**\n * A generic method to collect files from the user defined\n * files glob and apply the files filter\n */\n async #collectFiles(files: TestFiles) {\n let filesURLs = await this.#fileManager.getFiles(this.#config.cwd, files, this.#config.exclude)\n if (this.#config.filters.files && this.#config.filters.files.length) {\n filesURLs = this.#fileManager.grep(filesURLs, this.#config.filters.files)\n }\n\n return filesURLs\n }\n\n /**\n * Returns a collection of suites and their associated\n * test files by applying all the filters\n */\n async #getSuites(): Promise<(TestSuite & { filesURLs: URL[] })[]> {\n let suites: (TestSuite & { filesURLs: URL[] })[] = []\n let suitesFilters = this.#config.filters.suites || []\n\n if ('files' in this.#config) {\n suites.push({\n name: 'default',\n files: this.#config.files,\n timeout: this.#config.timeout,\n retries: this.#config.retries,\n filesURLs: await this.#collectFiles(this.#config.files),\n })\n }\n\n if ('suites' in this.#config) {\n for (let suite of this.#config.suites) {\n if (!suitesFilters.length || suitesFilters.includes(suite.name)) {\n suites.push({\n ...suite,\n filesURLs: await this.#collectFiles(suite.files),\n })\n }\n }\n }\n\n return suites\n }\n\n /**\n * Returns a list of filters to the passed to the refiner\n */\n #getRefinerFilters() {\n return Object.keys(this.#config.filters).reduce(\n (result, layer) => {\n if (layer === 'tests' || layer === 'tags' || layer === 'groups') {\n result.push({ layer, filters: this.#config.filters[layer]! })\n }\n return result\n },\n [] as { layer: 'tags' | 'tests' | 'groups'; filters: string[] }[]\n )\n }\n\n /**\n * Creates a plan for running the tests\n */\n async plan() {\n const suites = await this.#getSuites()\n const reporters = this.#getActivatedReporters()\n const refinerFilters = this.#getRefinerFilters()\n return {\n reporters,\n suites,\n refinerFilters,\n config: this.#config,\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport Hooks from '@poppinss/hooks'\nimport type { Runner as HooksRunner } from '@poppinss/hooks/types'\n\nimport { Runner } from '../modules/core/main.js'\nimport type { HooksEvents, SetupHookState, NormalizedConfig, TeardownHookState } from './types.js'\n\n/**\n * Exposes API for working with global hooks\n */\nexport class GlobalHooks {\n #hooks = new Hooks<HooksEvents>()\n #setupRunner: HooksRunner<SetupHookState[0], SetupHookState[1]> | undefined\n #teardownRunner: HooksRunner<TeardownHookState[0], TeardownHookState[1]> | undefined\n\n /**\n * Apply hooks from the config\n */\n apply(config: NormalizedConfig) {\n config.setup.forEach((hook) => this.#hooks.add('setup', hook))\n config.teardown.forEach((hook) => this.#hooks.add('teardown', hook))\n }\n\n /**\n * Perform setup\n */\n async setup(runner: Runner) {\n this.#setupRunner = this.#hooks.runner('setup')\n this.#teardownRunner = this.#hooks.runner('teardown')\n await this.#setupRunner.run(runner)\n }\n\n /**\n * Perform cleanup\n */\n async teardown(error: Error | null, runner: Runner) {\n if (this.#setupRunner) {\n await this.#setupRunner.cleanup(error, runner)\n }\n if (this.#teardownRunner) {\n if (!error) {\n await this.#teardownRunner.run(runner)\n }\n await this.#teardownRunner.cleanup(error, runner)\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\n// @ts-ignore-error\nimport getopts from 'getopts'\nimport colors from '@poppinss/colors'\nimport type { CLIArgs } from './types.js'\n\nconst ansi = colors.ansi()\n\n/**\n * Known commandline options. The user can still define additional flags and they\n * will be parsed aswell, but without any normalization\n */\nconst OPTIONS = {\n string: ['tests', 'groups', 'tags', 'files', 'timeout', 'retries', 'reporters', 'failed'],\n boolean: ['help', 'matchAll', 'failed'],\n alias: {\n forceExit: 'force-exit',\n matchAll: 'match-all',\n help: 'h',\n },\n}\n\n/**\n * Help string to display when the `--help flag is used`\n */\nconst GET_HELP = () => `\n${ansi.yellow('@japa/runner v2.3.0')}\n\n${ansi.green('--tests')} ${ansi.dim('Filter tests by the test title')}\n${ansi.green('--groups')} ${ansi.dim('Filter tests by the group title')}\n${ansi.green('--tags')} ${ansi.dim('Filter tests by tags')}\n${ansi.green('--files')} ${ansi.dim('Filter tests by the file name')}\n${ansi.green('--force-exit')} ${ansi.dim('Forcefully exit the process')}\n${ansi.green('--timeout')} ${ansi.dim('Define default timeout for all tests')}\n${ansi.green('--retries')} ${ansi.dim('Define default retries for all tests')}\n${ansi.green('--reporters')} ${ansi.dim('Activate one or more test reporters')}\n${ansi.green('--failed')} ${ansi.dim('Run tests failed during the last run')}\n${ansi.green('-h, --help')} ${ansi.dim('View help')}\n\n${ansi.yellow('Examples:')}\n${ansi.dim('node bin/test.js --tags=\"@github\"')}\n${ansi.dim('node bin/test.js --tags=\"~@github\"')}\n${ansi.dim('node bin/test.js --tags=\"@github,@slow,@integration\" --match-all')}\n${ansi.dim('node bin/test.js --force-exit')}\n${ansi.dim('node bin/test.js --files=\"user\"')}\n${ansi.dim('node bin/test.js --files=\"functional/user\"')}\n${ansi.dim('node bin/test.js --files=\"unit/user\"')}\n\n${ansi.yellow('Notes:')}\n- When groups and tests filters are applied together. We will first filter the\n tests by group title and then apply the tests title filter.\n- The timeout defined on test object takes precedence over the ${ansi.green('--timeout')} flag.\n- The retries defined on test object takes precedence over the ${ansi.green('--retries')} flag.\n- The ${ansi.green('--files')} flag checks for the file names ending with the filter substring.\n`\n\n/**\n * CLI Parser is used to parse the commandline argument\n */\nexport class CliParser {\n /**\n * Parses command-line arguments\n */\n parse(argv: string[]): CLIArgs {\n return getopts(argv, OPTIONS)\n }\n\n /**\n * Returns the help string\n */\n getHelp() {\n return GET_HELP()\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport debug from './debug.js'\nimport { Refiner } from '../modules/core/main.js'\nimport { dot, ndjson, spec } from './reporters/main.js'\nimport type { CLIArgs, Config, Filters, NormalizedBaseConfig, NormalizedConfig } from './types.js'\n\nexport const NOOP = () => {}\n\n/**\n * Defaults to use for configuration\n */\nconst DEFAULTS = {\n files: [],\n timeout: 2000,\n retries: 0,\n forceExit: false,\n plugins: [],\n reporters: {\n activated: ['spec'],\n list: [spec(), ndjson(), dot()],\n },\n importer: (filePath) => import(filePath.href),\n configureSuite: () => {},\n} satisfies Config\n\n/**\n * Config manager is used to hydrate the configuration by merging\n * the defaults, user defined config and the command line\n * flags.\n *\n * The command line flags have the upmost priority\n */\nexport class ConfigManager {\n #config: Config\n #cliArgs: CLIArgs\n\n constructor(config: Config, cliArgs: CLIArgs) {\n this.#config = config\n this.#cliArgs = cliArgs\n }\n\n /**\n * Processes a CLI argument and converts it to an\n * array of strings\n */\n #processAsArray(value: string | string[], splitByComma: boolean): string[] {\n return Array.isArray(value)\n ? value\n : splitByComma\n ? value.split(',').map((item: string) => item.trim())\n : [value]\n }\n\n /**\n * Returns a copy of filters based upon the CLI\n * arguments.\n */\n #getCLIFilters(): Filters {\n const filters: Filters = {}\n\n if (this.#cliArgs.tags) {\n filters.tags = this.#processAsArray(this.#cliArgs.tags, true)\n }\n if (this.#cliArgs.tests) {\n filters.tests = this.#processAsArray(this.#cliArgs.tests, false)\n }\n if (this.#cliArgs.files) {\n filters.files = this.#processAsArray(this.#cliArgs.files, true)\n }\n if (this.#cliArgs.groups) {\n filters.groups = this.#processAsArray(this.#cliArgs.groups, false)\n }\n if (this.#cliArgs._ && this.#cliArgs._.length) {\n filters.suites = this.#processAsArray(this.#cliArgs._, true)\n }\n\n return filters\n }\n\n /**\n * Returns the timeout from the CLI args\n */\n #getCLITimeout(): number | undefined {\n if (this.#cliArgs.timeout) {\n const value = Number(this.#cliArgs.timeout)\n if (!Number.isNaN(value)) {\n return value\n }\n }\n }\n\n /**\n * Returns the retries from the CLI args\n */\n #getCLIRetries(): number | undefined {\n if (this.#cliArgs.retries) {\n const value = Number(this.#cliArgs.retries)\n if (!Number.isNaN(value)) {\n return value\n }\n }\n }\n\n /**\n * Returns the forceExit property from the CLI args\n */\n #getCLIForceExit(): boolean | undefined {\n if (this.#cliArgs.forceExit) {\n return true\n }\n }\n\n /**\n * Returns reporters selected using the commandline\n * --reporter flag\n */\n #getCLIReporters(): string[] | undefined {\n if (this.#cliArgs.reporters) {\n return this.#processAsArray(this.#cliArgs.reporters, true)\n }\n }\n\n /**\n * Hydrates the config with user defined options and the\n * command-line flags.\n */\n hydrate(): NormalizedConfig {\n const cliFilters = this.#getCLIFilters()\n const cliRetries = this.#getCLIRetries()\n const cliTimeout = this.#getCLITimeout()\n const cliReporters = this.#getCLIReporters()\n const cliForceExit = this.#getCLIForceExit()\n\n debug('filters applied using CLI flags %O', cliFilters)\n\n const baseConfig: NormalizedBaseConfig = {\n cwd: this.#config.cwd ?? process.cwd(),\n exclude: this.#config.exclude || ['node_modules/**', '.git/**', 'coverage/**'],\n filters: Object.assign({}, this.#config.filters ?? {}, cliFilters),\n importer: this.#config.importer ?? DEFAULTS.importer,\n refiner: this.#config.refiner ?? new Refiner(),\n retries: cliRetries ?? this.#config.retries ?? DEFAULTS.retries,\n timeout: cliTimeout ?? this.#config.timeout ?? DEFAULTS.timeout,\n plugins: this.#config.plugins ?? DEFAULTS.plugins,\n forceExit: cliForceExit ?? this.#config.forceExit ?? DEFAULTS.forceExit,\n reporters: this.#config.reporters\n ? {\n activated: this.#config.reporters.activated,\n list: this.#config.reporters.list || DEFAULTS.reporters.list,\n }\n : DEFAULTS.reporters,\n configureSuite: this.#config.configureSuite ?? DEFAULTS.configureSuite,\n setup: this.#config.setup || [],\n teardown: this.#config.teardown || [],\n }\n\n /**\n * Overwrite activated reporters when defined using CLI\n * flag\n */\n if (cliReporters) {\n baseConfig.reporters.activated = cliReporters\n }\n\n if ('files' in this.#config) {\n return {\n files: this.#config.files,\n ...baseConfig,\n }\n }\n\n return {\n suites: this.#config.suites.map((suite) => {\n return {\n name: suite.name,\n files: suite.files,\n timeout: cliTimeout ?? suite.timeout ?? baseConfig.timeout,\n retries: cliRetries ?? suite.retries ?? baseConfig.retries,\n configure: suite.configure || NOOP,\n }\n }),\n ...baseConfig,\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { Emitter, Group, Refiner, Suite, Test, TestContext } from '../modules/core/main.js'\n\n/**\n * Function to create the test context for the test\n */\nconst contextBuilder = (testInstance: Test<any>) => new TestContext(testInstance)\n\n/**\n * Create a new instance of the Test\n */\nexport function createTest(\n title: string,\n emitter: Emitter,\n refiner: Refiner,\n options: {\n group?: Group\n suite?: Suite\n file?: string\n timeout?: number\n retries?: number\n }\n) {\n const testInstance = new Test<undefined>(title, contextBuilder, emitter, refiner, options.group)\n testInstance.options.meta.suite = options.suite\n testInstance.options.meta.group = options.group\n testInstance.options.meta.fileName = options.file\n\n if (options.timeout !== undefined) {\n testInstance.timeout(options.timeout)\n }\n if (options.retries !== undefined) {\n testInstance.retry(options.retries)\n }\n\n /**\n * Register test as a child either with the group or the suite\n */\n if (options.group) {\n options.group.add(testInstance)\n } else if (options.suite) {\n options.suite.add(testInstance)\n }\n\n return testInstance\n}\n\n/**\n * Create a new instance of the Group\n */\nexport function createTestGroup(\n title: string,\n emitter: Emitter,\n refiner: Refiner,\n options: {\n group?: Group\n suite?: Suite\n file?: string\n timeout?: number\n retries?: number\n }\n) {\n if (options.group) {\n throw new Error('Nested groups are not supported by Japa')\n }\n\n const group = new Group(title, emitter, refiner)\n group.options.meta.suite = options.suite\n group.options.meta.fileName = options.file\n\n if (options.suite) {\n options.suite.add(group)\n }\n\n return group\n}\n"],"mappings":"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","names":[]}