@japa/runner 3.1.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +8 -4
  2. package/build/{chunk-OBDV3O36.js → chunk-OGQDXVXY.js} +1 -1
  3. package/build/{chunk-PHC5CJQG.js → chunk-PLH254PF.js} +21 -16
  4. package/build/chunk-PLH254PF.js.map +1 -0
  5. package/build/{chunk-BFNOUWI5.js → chunk-VDZGMJWM.js} +6 -6
  6. package/build/chunk-VDZGMJWM.js.map +1 -0
  7. package/build/{chunk-NVI2OU43.js → chunk-ZBQV333W.js} +15 -6
  8. package/build/chunk-ZBQV333W.js.map +1 -0
  9. package/build/factories/{create_diverse_tests.d.ts → create_dummy_tests.d.ts} +1 -1
  10. package/build/factories/main.d.ts +1 -1
  11. package/build/factories/main.js +28 -8
  12. package/build/factories/main.js.map +1 -1
  13. package/build/factories/runner.d.ts +4 -0
  14. package/build/index.d.ts +3 -0
  15. package/build/index.js +27 -10
  16. package/build/index.js.map +1 -1
  17. package/build/modules/core/main.d.ts +10 -3
  18. package/build/modules/core/main.js +2 -2
  19. package/build/modules/core/reporters/base.d.ts +1 -1
  20. package/build/modules/core/types.d.ts +0 -1
  21. package/build/src/config_manager.d.ts +1 -1
  22. package/build/src/debug.d.ts +0 -1
  23. package/build/src/exceptions_manager.d.ts +1 -1
  24. package/build/src/files_manager.d.ts +0 -1
  25. package/build/src/helpers.d.ts +1 -0
  26. package/build/src/planner.d.ts +0 -1
  27. package/build/src/reporters/main.js +3 -3
  28. package/build/src/types.d.ts +2 -1
  29. package/build/src/types.js +1 -1
  30. package/build/src/types.js.map +1 -1
  31. package/package.json +75 -72
  32. package/build/chunk-BFNOUWI5.js.map +0 -1
  33. package/build/chunk-NVI2OU43.js.map +0 -1
  34. package/build/chunk-PHC5CJQG.js.map +0 -1
  35. /package/build/{chunk-OBDV3O36.js.map → chunk-OGQDXVXY.js.map} +0 -0
package/README.md CHANGED
@@ -1,9 +1,13 @@
1
1
  # @japa/runner
2
- > An API first tests runner for Node.js
2
+ > A simple yet powerful testing framework for Node.js
3
3
 
4
4
  [![github-actions-image]][github-actions-url] [![npm-image]][npm-url] [![license-image]][license-url] [![typescript-image]][typescript-url]
5
5
 
6
- Japa is an API first testing framework. It focuses only on testing Node.js (backend) applications, thus resulting in a fast, small, and a simple tests runner.
6
+ Japa comes with everything you need to test your backend applications. Be it writing JSON API tests using an Open API schema or writing browser tests using Playwright.
7
+
8
+ Unlike other testing frameworks born out of the frontend ecosystem, Japa focuses only on testing backend applications and libraries. Therefore, Japa is **simpler**, **faster**, and **bloatware free**.
9
+
10
+ Japa
7
11
 
8
12
  #### 💁 Please visit https://japa.dev for documentation
9
13
 
@@ -12,9 +16,9 @@ Japa is an API first testing framework. It focuses only on testing Node.js (back
12
16
 
13
17
  ![](https://raw.githubusercontent.com/thetutlage/static/main/sponsorkit/sponsors.png)
14
18
 
15
- [github-actions-image]: https://img.shields.io/github/actions/workflow/status/japa/runner/test.yml?style=for-the-badge "github-actions"
19
+ [github-actions-image]: https://img.shields.io/github/actions/workflow/status/japa/runner/checks.yml?style=for-the-badge "github-actions"
16
20
 
17
- [github-actions-url]: https://github.com/japa/runner/actions/workflows/test.yml
21
+ [github-actions-url]: https://github.com/japa/runner/actions/workflows/checks.yml
18
22
 
19
23
  [npm-image]: https://img.shields.io/npm/v/@japa/runner.svg?style=for-the-badge&logo=npm
20
24
  [npm-url]: https://npmjs.org/package/@japa/runner "npm"
@@ -15,4 +15,4 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
15
15
  export {
16
16
  __reExport
17
17
  };
18
- //# sourceMappingURL=chunk-OBDV3O36.js.map
18
+ //# sourceMappingURL=chunk-OGQDXVXY.js.map
@@ -2,7 +2,7 @@ import {
2
2
  BaseReporter,
3
3
  colors,
4
4
  icons
5
- } from "./chunk-BFNOUWI5.js";
5
+ } from "./chunk-VDZGMJWM.js";
6
6
 
7
7
  // src/reporters/dot.ts
8
8
  var DotReporter = class extends BaseReporter {
@@ -13,10 +13,12 @@ var DotReporter = class extends BaseReporter {
13
13
  let output = "";
14
14
  if (payload.isTodo) {
15
15
  output = colors.cyan(icons.info);
16
- } else if (payload.hasError || payload.isFailing) {
17
- output = payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross);
16
+ } else if (payload.hasError) {
17
+ output = colors.red(icons.cross);
18
18
  } else if (payload.isSkipped) {
19
19
  output = colors.yellow(icons.bullet);
20
+ } else if (payload.isFailing) {
21
+ output = colors.magenta(icons.squareSmallFilled);
20
22
  } else {
21
23
  output = colors.green(icons.tick);
22
24
  }
@@ -47,15 +49,15 @@ var SpecReporter = class extends BaseReporter {
47
49
  if (payload.isTodo) {
48
50
  return colors.cyan(icons.info);
49
51
  }
50
- if (payload.isFailing) {
51
- return payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross);
52
- }
53
52
  if (payload.hasError) {
54
53
  return colors.red(icons.cross);
55
54
  }
56
55
  if (payload.isSkipped) {
57
56
  return colors.yellow(icons.bullet);
58
57
  }
58
+ if (payload.isFailing) {
59
+ return colors.magenta(icons.squareSmallFilled);
60
+ }
59
61
  return colors.green(icons.tick);
60
62
  }
61
63
  /**
@@ -66,15 +68,15 @@ var SpecReporter = class extends BaseReporter {
66
68
  if (payload.isTodo) {
67
69
  return colors.blue(message);
68
70
  }
69
- if (payload.isFailing) {
70
- return payload.hasError ? colors.magenta(message) : colors.red(message);
71
- }
72
71
  if (payload.hasError) {
73
72
  return colors.red(message);
74
73
  }
75
74
  if (payload.isSkipped) {
76
75
  return colors.yellow(message);
77
76
  }
77
+ if (payload.isFailing) {
78
+ return colors.magenta(message);
79
+ }
78
80
  return colors.grey(message);
79
81
  }
80
82
  /**
@@ -82,20 +84,21 @@ var SpecReporter = class extends BaseReporter {
82
84
  */
83
85
  #getSubText(payload) {
84
86
  if (payload.isSkipped && payload.skipReason) {
85
- return colors.yellow(payload.skipReason);
87
+ return colors.dim(`${icons.branch} ${colors.italic(payload.skipReason)}`);
86
88
  }
87
89
  if (!payload.isFailing) {
88
90
  return;
89
91
  }
90
- if (!payload.hasError) {
91
- return colors.magenta(`Test marked with ".fails()" must finish with an error`);
92
+ if (payload.hasError) {
93
+ const message = payload.errors.find((error) => error.phase === "test")?.error.message ?? `Test marked with ".fails()" must finish with an error`;
94
+ return colors.dim(`${icons.branch} ${colors.italic(message)}`);
92
95
  }
93
96
  if (payload.failReason) {
94
- return colors.magenta(payload.failReason);
97
+ return colors.dim(`${icons.branch} ${colors.italic(payload.failReason)}`);
95
98
  }
96
99
  const testErrorMessage = payload.errors.find((error) => error.phase === "test");
97
100
  if (testErrorMessage && testErrorMessage.error) {
98
- return colors.magenta(testErrorMessage.error.message);
101
+ return colors.dim(`${icons.branch} ${colors.italic(testErrorMessage.error.message)}`);
99
102
  }
100
103
  }
101
104
  /**
@@ -217,7 +220,9 @@ var NdJSONReporter = class extends BaseReporter {
217
220
  console.log(
218
221
  JSON.stringify({
219
222
  event: "suite:end",
220
- ...payload
223
+ name: payload.name,
224
+ hasError: payload.hasError,
225
+ errors: this.#serializeErrors(payload.errors)
221
226
  })
222
227
  );
223
228
  }
@@ -259,4 +264,4 @@ export {
259
264
  dot,
260
265
  ndjson
261
266
  };
262
- //# sourceMappingURL=chunk-PHC5CJQG.js.map
267
+ //# sourceMappingURL=chunk-PLH254PF.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) {\n output = colors.red(icons.cross)\n } else if (payload.isSkipped) {\n output = colors.yellow(icons.bullet)\n } else if (payload.isFailing) {\n output = colors.magenta(icons.squareSmallFilled)\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.hasError) {\n return colors.red(icons.cross)\n }\n\n if (payload.isSkipped) {\n return colors.yellow(icons.bullet)\n }\n\n if (payload.isFailing) {\n return colors.magenta(icons.squareSmallFilled)\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.hasError) {\n return colors.red(message)\n }\n\n if (payload.isSkipped) {\n return colors.yellow(message)\n }\n\n if (payload.isFailing) {\n return colors.magenta(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.dim(`${icons.branch} ${colors.italic(payload.skipReason)}`)\n }\n\n if (!payload.isFailing) {\n return\n }\n\n if (payload.hasError) {\n const message =\n payload.errors.find((error) => error.phase === 'test')?.error.message ??\n `Test marked with \".fails()\" must finish with an error`\n\n return colors.dim(`${icons.branch} ${colors.italic(message)}`)\n }\n\n if (payload.failReason) {\n return colors.dim(`${icons.branch} ${colors.italic(payload.failReason)}`)\n }\n\n const testErrorMessage = payload.errors.find((error) => error.phase === 'test')\n if (testErrorMessage && testErrorMessage.error) {\n return colors.dim(`${icons.branch} ${colors.italic(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(\n errors: TestEndNode['errors'] | GroupEndNode['errors'] | SuiteEndNode['errors']\n ) {\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 name: payload.name,\n hasError: payload.hasError,\n errors: this.#serializeErrors(payload.errors),\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"]}
@@ -13,6 +13,7 @@ import { AssertionError } from "node:assert";
13
13
 
14
14
  // modules/core/reporters/base.ts
15
15
  import ms from "ms";
16
+ import { ErrorsPrinter } from "@japa/errors-printer";
16
17
 
17
18
  // src/helpers.ts
18
19
  import useColors from "@poppinss/colors";
@@ -26,6 +27,7 @@ var icons = process.platform === "win32" && !process.env.WT_SESSION ? {
26
27
  pointer: ">",
27
28
  info: "i",
28
29
  warning: "\u203C",
30
+ branch: " -",
29
31
  squareSmallFilled: "[\u2588]"
30
32
  } : {
31
33
  tick: "\u2714",
@@ -35,11 +37,11 @@ var icons = process.platform === "win32" && !process.env.WT_SESSION ? {
35
37
  pointer: "\u276F",
36
38
  info: "\u2139",
37
39
  warning: "\u26A0",
40
+ branch: "\u2514\u2500\u2500",
38
41
  squareSmallFilled: "\u25FC"
39
42
  };
40
43
 
41
44
  // modules/core/reporters/base.ts
42
- import { ErrorsPrinter } from "@japa/errors-printer";
43
45
  var BaseReporter = class {
44
46
  #options;
45
47
  runner;
@@ -126,7 +128,6 @@ var BaseReporter = class {
126
128
  return;
127
129
  }
128
130
  const errorPrinter = new ErrorsPrinter({
129
- stackLinesCount: this.#options.stackLinesCount,
130
131
  framesMaxLimit: this.#options.framesMaxLimit
131
132
  });
132
133
  errorPrinter.printSectionHeader("ERRORS");
@@ -227,9 +228,8 @@ var Test = class extends BaseTest {
227
228
  */
228
229
  static executingCallbacks = [];
229
230
  /**
230
- * Assert the test callback throws an exception when a certain
231
- * error message and optionally is an instance of a given
232
- * Error class.
231
+ * Assert the test throws an exception with a certain error message
232
+ * and optionally is an instance of a given Error class.
233
233
  */
234
234
  throws(message, errorConstructor) {
235
235
  const errorInPoint = new AssertionError({});
@@ -293,4 +293,4 @@ export {
293
293
  Suite,
294
294
  Runner
295
295
  };
296
- //# sourceMappingURL=chunk-BFNOUWI5.js.map
296
+ //# sourceMappingURL=chunk-VDZGMJWM.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 /**\n * Assert the test throws an exception with a certain error message\n * and optionally is an instance of a given Error class.\n */\n throws(message: string | RegExp, errorConstructor?: any): this\n }\n interface TestContext {\n /**\n * Register a cleanup function that runs after the test finishes\n * successfully or with an error.\n */\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 throws an exception with a certain error message\n * and optionally is an instance of a given 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 { ErrorsPrinter } from '@japa/errors-printer'\n\nimport { Emitter, Runner } from '../main.js'\nimport { colors } from '../../../src/helpers.js'\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'\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 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 branch: ' -',\n squareSmallFilled: '[█]',\n }\n : {\n tick: '✔',\n cross: '✖',\n bullet: '●',\n nodejs: '⬢',\n pointer: '❯',\n info: 'ℹ',\n warning: '⚠',\n branch: '└──',\n squareSmallFilled: '◼',\n }\n"],"mappings":"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","names":[]}
@@ -2,14 +2,14 @@ import {
2
2
  dot,
3
3
  ndjson,
4
4
  spec
5
- } from "./chunk-PHC5CJQG.js";
5
+ } from "./chunk-PLH254PF.js";
6
6
  import {
7
7
  Group,
8
8
  Refiner,
9
9
  Test,
10
10
  TestContext,
11
11
  colors
12
- } from "./chunk-BFNOUWI5.js";
12
+ } from "./chunk-VDZGMJWM.js";
13
13
 
14
14
  // src/debug.ts
15
15
  import { debuglog } from "node:util";
@@ -259,11 +259,12 @@ var GlobalHooks = class {
259
259
  // src/cli_parser.ts
260
260
  import getopts from "getopts";
261
261
  var OPTIONS = {
262
- string: ["tests", "groups", "tags", "files", "timeout", "retries", "reporters", "failed"],
263
- boolean: ["help", "matchAll", "failed"],
262
+ string: ["tests", "groups", "tags", "files", "timeout", "retries", "reporters", "bailLayer"],
263
+ boolean: ["help", "matchAll", "failed", "bail"],
264
264
  alias: {
265
265
  forceExit: "force-exit",
266
266
  matchAll: "match-all",
267
+ bailLayer: "bail-layer",
267
268
  help: "h"
268
269
  }
269
270
  };
@@ -273,12 +274,15 @@ ${colors.yellow("@japa/runner v2.3.0")}
273
274
  ${colors.green("--tests")} ${colors.dim("Filter tests by the test title")}
274
275
  ${colors.green("--groups")} ${colors.dim("Filter tests by the group title")}
275
276
  ${colors.green("--tags")} ${colors.dim("Filter tests by tags")}
277
+ ${colors.green("--match-all")} ${colors.dim("Run tests that matches all the supplied tags")}
276
278
  ${colors.green("--files")} ${colors.dim("Filter tests by the file name")}
277
279
  ${colors.green("--force-exit")} ${colors.dim("Forcefully exit the process")}
278
280
  ${colors.green("--timeout")} ${colors.dim("Define default timeout for all tests")}
279
281
  ${colors.green("--retries")} ${colors.dim("Define default retries for all tests")}
280
282
  ${colors.green("--reporters")} ${colors.dim("Activate one or more test reporters")}
281
283
  ${colors.green("--failed")} ${colors.dim("Run tests failed during the last run")}
284
+ ${colors.green("--bail")} ${colors.dim("Exit early when a test fails")}
285
+ ${colors.green("--bail-layer")} ${colors.dim('Specify at which layer to enable the bail mode. Can be "group" or "suite"')}
282
286
  ${colors.green("-h, --help")} ${colors.dim("View help")}
283
287
 
284
288
  ${colors.yellow("Examples:")}
@@ -289,13 +293,18 @@ ${colors.dim("node bin/test.js --force-exit")}
289
293
  ${colors.dim('node bin/test.js --files="user"')}
290
294
  ${colors.dim('node bin/test.js --files="functional/user"')}
291
295
  ${colors.dim('node bin/test.js --files="unit/user"')}
296
+ ${colors.dim("node bin/test.js --failed")}
297
+ ${colors.dim("node bin/test.js --bail")}
298
+ ${colors.dim("node bin/test.js --bail=group")}
292
299
 
293
300
  ${colors.yellow("Notes:")}
294
301
  - When groups and tests filters are applied together. We will first filter the
295
- tests by group title and then apply the tests title filter.
302
+ tests by group title and then apply the tests filter.
296
303
  - The timeout defined on test object takes precedence over the ${colors.green("--timeout")} flag.
297
304
  - The retries defined on test object takes precedence over the ${colors.green("--retries")} flag.
298
305
  - The ${colors.green("--files")} flag checks for the file names ending with the filter substring.
306
+ - The ${colors.green("--tags")} filter runs tests that has one or more of the supplied tags.
307
+ - You can use the ${colors.green("--match-all")} flag to run tests that has all the supplied tags.
299
308
  `;
300
309
  var CliParser = class {
301
310
  /**
@@ -501,4 +510,4 @@ export {
501
510
  createTest,
502
511
  createTestGroup
503
512
  };
504
- //# sourceMappingURL=chunk-NVI2OU43.js.map
513
+ //# sourceMappingURL=chunk-ZBQV333W.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', 'bailLayer'],\n boolean: ['help', 'matchAll', 'failed', 'bail'],\n alias: {\n forceExit: 'force-exit',\n matchAll: 'match-all',\n bailLayer: 'bail-layer',\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('--match-all')} ${colors.dim('Run tests that matches all the supplied 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('--bail')} ${colors.dim('Exit early when a test fails')}\n${colors.green('--bail-layer')} ${colors.dim('Specify at which layer to enable the bail mode. Can be \"group\" or \"suite\"')}\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${colors.dim('node bin/test.js --failed')}\n${colors.dim('node bin/test.js --bail')}\n${colors.dim('node bin/test.js --bail=group')}\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 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- The ${colors.green('--tags')} filter runs tests that has one or more of the supplied tags.\n- You can use the ${colors.green('--match-all')} flag to run tests that has all the supplied tags.\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 with the 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":[]}
@@ -3,4 +3,4 @@ import { Suite, Emitter, Refiner } from '../modules/core/main.js';
3
3
  * Returns an array of suites with dummy tests reproducting
4
4
  * different test behavior
5
5
  */
6
- export declare function createDiverseTests(emitter: Emitter, refiner: Refiner, file?: string): Suite[];
6
+ export declare function createDummyTests(emitter: Emitter, refiner: Refiner, file?: string): Suite[];
@@ -4,5 +4,5 @@ import { RunnerFactory } from './runner.js';
4
4
  * Create an instance of the runner factory
5
5
  */
6
6
  export declare const runner: () => RunnerFactory;
7
- export { createDiverseTests } from './create_diverse_tests.js';
7
+ export { createDummyTests } from './create_dummy_tests.js';
8
8
  export declare const syncReporter: ReporterContract;
@@ -5,14 +5,14 @@ import {
5
5
  Planner,
6
6
  createTest,
7
7
  createTestGroup
8
- } from "../chunk-NVI2OU43.js";
9
- import "../chunk-PHC5CJQG.js";
8
+ } from "../chunk-ZBQV333W.js";
9
+ import "../chunk-PLH254PF.js";
10
10
  import {
11
11
  Emitter,
12
12
  Runner,
13
13
  Suite
14
- } from "../chunk-BFNOUWI5.js";
15
- import "../chunk-OBDV3O36.js";
14
+ } from "../chunk-VDZGMJWM.js";
15
+ import "../chunk-OGQDXVXY.js";
16
16
 
17
17
  // factories/runner.ts
18
18
  import { fileURLToPath } from "node:url";
@@ -21,6 +21,7 @@ var RunnerFactory = class {
21
21
  #config;
22
22
  #cliArgs;
23
23
  #file = fileURLToPath(import.meta.url);
24
+ #bail = false;
24
25
  get #refiner() {
25
26
  return this.#config.refiner;
26
27
  }
@@ -65,11 +66,19 @@ var RunnerFactory = class {
65
66
  return [defaultSuite];
66
67
  });
67
68
  }
69
+ /**
70
+ * Enable/disable the bail mode
71
+ */
72
+ bail(toggle = true) {
73
+ this.#bail = toggle;
74
+ return this;
75
+ }
68
76
  /**
69
77
  * Run dummy tests. You might use
70
78
  */
71
79
  async runSuites(suites) {
72
80
  const runner2 = new Runner(this.#emitter);
81
+ runner2.bail(this.#bail);
73
82
  await this.#registerPlugins(runner2);
74
83
  const { config, reporters, refinerFilters } = await new Planner(this.#config).plan();
75
84
  const globalHooks = new GlobalHooks();
@@ -90,7 +99,7 @@ var RunnerFactory = class {
90
99
  }
91
100
  };
92
101
 
93
- // factories/create_diverse_tests.ts
102
+ // factories/create_dummy_tests.ts
94
103
  import assert from "node:assert";
95
104
  function createUnitTestsSuite(emitter, refiner, file) {
96
105
  const suite = new Suite("unit", emitter, refiner);
@@ -126,6 +135,9 @@ function createUnitTestsSuite(emitter, refiner, file) {
126
135
  createTest("add floating numbers", emitter, refiner, { group, file }).run(() => {
127
136
  assert.equal(2 + 2.2 + 2.1, 6);
128
137
  }).fails("Have to add support for floating numbers");
138
+ createTest("regression test that is passing", emitter, refiner, { group, file }).run(() => {
139
+ assert.equal(2 + 2.2 + 2.1, 2 + 2.2 + 2.1);
140
+ }).fails("Have to add support for floating numbers");
129
141
  createTest("A test with an error that is not an AssertionError", emitter, refiner, {
130
142
  group,
131
143
  file
@@ -165,6 +177,14 @@ function createFunctionalTestsSuite(emitter, refiner, file) {
165
177
  group,
166
178
  file
167
179
  });
180
+ createTest("Test that times out", emitter, refiner, {
181
+ group,
182
+ file
183
+ }).run(() => {
184
+ return new Promise((resolve) => {
185
+ setTimeout(resolve, 2100);
186
+ });
187
+ });
168
188
  const usersListGroup = createTestGroup("Users/list", emitter, refiner, {
169
189
  suite,
170
190
  file
@@ -172,7 +192,7 @@ function createFunctionalTestsSuite(emitter, refiner, file) {
172
192
  usersListGroup.setup(() => {
173
193
  throw new Error("Unable to cleanup database");
174
194
  });
175
- createTest("A test that will never because the group hooks fails", emitter, refiner, {
195
+ createTest("A test that will never run because the group hooks fails", emitter, refiner, {
176
196
  group: usersListGroup
177
197
  });
178
198
  createTest("A top level test inside functional suite", emitter, refiner, {
@@ -182,7 +202,7 @@ function createFunctionalTestsSuite(emitter, refiner, file) {
182
202
  });
183
203
  return suite;
184
204
  }
185
- function createDiverseTests(emitter, refiner, file) {
205
+ function createDummyTests(emitter, refiner, file) {
186
206
  return [
187
207
  createUnitTestsSuite(emitter, refiner, file),
188
208
  createFunctionalTestsSuite(emitter, refiner, file)
@@ -208,7 +228,7 @@ var syncReporter = {
208
228
  }
209
229
  };
210
230
  export {
211
- createDiverseTests,
231
+ createDummyTests,
212
232
  runner,
213
233
  syncReporter
214
234
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../factories/runner.ts","../../factories/create_diverse_tests.ts","../../factories/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 { fileURLToPath } from 'node:url'\n\nimport { Planner } from '../src/planner.js'\nimport { GlobalHooks } from '../src/hooks.js'\nimport { CliParser } from '../src/cli_parser.js'\nimport { createTest } from '../src/create_test.js'\nimport { ConfigManager } from '../src/config_manager.js'\nimport { Suite, Runner, Emitter, TestContext, Refiner } from '../modules/core/main.js'\nimport type {\n Config,\n CLIArgs,\n TestExecutor,\n RunnerSummary,\n NormalizedConfig,\n} from '../src/types.js'\n\n/**\n * Runner factory exposes the API to run dummy suites, groups and tests.\n * You might want to use the factory for testing reporters and\n * plugins usage\n */\nexport class RunnerFactory {\n #emitter = new Emitter()\n #config?: NormalizedConfig\n #cliArgs?: CLIArgs\n #file = fileURLToPath(import.meta.url)\n\n get #refiner() {\n return this.#config!.refiner\n }\n\n /**\n * Registers plugins\n */\n async #registerPlugins(runner: Runner) {\n for (let plugin of this.#config!.plugins) {\n await plugin({\n config: this.#config!,\n runner,\n emitter: this.#emitter,\n cliArgs: this.#cliArgs!,\n })\n }\n }\n\n /**\n * Configure runner\n */\n configure(config: Config, argv?: string[]) {\n this.#cliArgs = new CliParser().parse(argv || [])\n this.#config = new ConfigManager(config, this.#cliArgs).hydrate()\n return this\n }\n\n /**\n * Define a custom emitter instance to use\n */\n useEmitter(emitter: Emitter) {\n this.#emitter = emitter\n return this\n }\n\n /**\n * Run a test using the runner\n */\n async runTest(\n title: string,\n callback: TestExecutor<TestContext, undefined>\n ): Promise<RunnerSummary> {\n return this.runSuites((emitter, refiner, file) => {\n const defaultSuite = new Suite('default', emitter, refiner)\n\n createTest(title, emitter, refiner, {\n suite: defaultSuite,\n file: file,\n }).run(callback)\n\n return [defaultSuite]\n })\n }\n\n /**\n * Run dummy tests. You might use\n */\n async runSuites(\n suites: (emitter: Emitter, refiner: Refiner, file?: string) => Suite[]\n ): Promise<RunnerSummary> {\n const runner = new Runner(this.#emitter)\n await this.#registerPlugins(runner)\n\n const { config, reporters, refinerFilters } = await new Planner(this.#config!).plan()\n const globalHooks = new GlobalHooks()\n globalHooks.apply(config)\n\n reporters.forEach((reporter) => {\n runner.registerReporter(reporter)\n })\n\n refinerFilters.forEach((filter) => {\n config.refiner.add(filter.layer, filter.filters)\n })\n\n suites(this.#emitter, this.#refiner, this.#file).forEach((suite) => runner.add(suite))\n\n await globalHooks.setup(runner)\n await runner.start()\n await runner.exec()\n await runner.end()\n await globalHooks.teardown(null, runner)\n\n return runner.getSummary()\n }\n}\n","import assert from 'node:assert'\nimport { Suite, Emitter, Refiner } from '../modules/core/main.js'\nimport { createTest, createTestGroup } from '../src/create_test.js'\n\n/**\n * Creates a unit tests suite with bunch of dummy tests\n * reproducing different tests behavior\n */\nfunction createUnitTestsSuite(emitter: Emitter, refiner: Refiner, file?: string) {\n const suite = new Suite('unit', emitter, refiner)\n const group = createTestGroup('Maths#add', emitter, refiner, {\n suite,\n file,\n })\n\n createTest('A top level test inside a suite', emitter, refiner, {\n suite,\n file,\n }).run(() => {})\n\n createTest('add two numbers', emitter, refiner, { group, file }).run(() => {\n assert.equal(2 + 2, 4)\n })\n createTest('add three numbers', emitter, refiner, {\n group,\n file,\n }).run(() => {\n assert.equal(2 + 2 + 2, 6)\n })\n\n createTest('add group of numbers', emitter, refiner, { group, file })\n createTest('use math.js lib', emitter, refiner, { group, file }).skip(\n true,\n 'Library work pending'\n )\n createTest('add multiple numbers', emitter, refiner, {\n file,\n group,\n }).run(() => {\n assert.equal(2 + 2 + 2 + 2, 6)\n })\n createTest('add floating numbers', emitter, refiner, { group, file })\n .run(() => {\n assert.equal(2 + 2.2 + 2.1, 6)\n })\n .fails('Have to add support for floating numbers')\n createTest('A test with an error that is not an AssertionError', emitter, refiner, {\n group,\n file,\n }).run(() => {\n throw new Error('This is an error')\n })\n\n return suite\n}\n\n/**\n * Creates a unit functional suite with bunch of dummy tests\n * reproducing different tests behavior\n */\nfunction createFunctionalTestsSuite(emitter: Emitter, refiner: Refiner, file?: string) {\n const suite = new Suite('functional', emitter, refiner)\n\n const group = createTestGroup('Users/store', emitter, refiner, {\n suite,\n file: file,\n })\n createTest('Validate user data', emitter, refiner, {\n group,\n file: file,\n }).run(() => {})\n createTest('Disallow duplicate emails', emitter, refiner, {\n group,\n file: file,\n }).run(() => {})\n createTest('Disallow duplicate emails across tenants', emitter, refiner, {\n group,\n file: file,\n }).run(() => {\n const users = ['', '']\n assert.equal(users.length, 1)\n })\n createTest('Normalize email before persisting it', emitter, refiner, {\n group,\n file: file,\n }).skip(true, 'Have to build a normalizer')\n createTest('Send email verification mail', emitter, refiner, {\n group,\n file: file,\n })\n\n const usersListGroup = createTestGroup('Users/list', emitter, refiner, {\n suite,\n file: file,\n })\n usersListGroup.setup(() => {\n throw new Error('Unable to cleanup database')\n })\n createTest('A test that will never because the group hooks fails', emitter, refiner, {\n group: usersListGroup,\n })\n\n createTest('A top level test inside functional suite', emitter, refiner, {\n suite,\n file: file,\n }).run(() => {})\n\n return suite\n}\n\n/**\n * Returns an array of suites with dummy tests reproducting\n * different test behavior\n */\nexport function createDiverseTests(emitter: Emitter, refiner: Refiner, file?: string): Suite[] {\n return [\n createUnitTestsSuite(emitter, refiner, file),\n createFunctionalTestsSuite(emitter, refiner, file),\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 { ReporterContract } from '../src/types.js'\nimport { RunnerFactory } from './runner.js'\n\n/**\n * Create an instance of the runner factory\n */\nexport const runner = () => new RunnerFactory()\nexport { createDiverseTests } from './create_diverse_tests.js'\nexport const syncReporter: ReporterContract = {\n name: 'sync',\n handler(r, emitter) {\n emitter.on('runner:end', function () {\n const summary = r.getSummary()\n if (summary.hasError) {\n if (summary.failureTree[0].errors.length) {\n throw summary.failureTree[0].errors[0].error\n }\n if (summary.failureTree[0].children[0].errors.length) {\n throw summary.failureTree[0].children[0].errors[0].error\n }\n }\n })\n },\n}\n"],"mappings":"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","names":["runner"]}
1
+ {"version":3,"sources":["../../factories/runner.ts","../../factories/create_dummy_tests.ts","../../factories/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 { fileURLToPath } from 'node:url'\n\nimport { Planner } from '../src/planner.js'\nimport { GlobalHooks } from '../src/hooks.js'\nimport { CliParser } from '../src/cli_parser.js'\nimport { createTest } from '../src/create_test.js'\nimport { ConfigManager } from '../src/config_manager.js'\nimport { Suite, Runner, Emitter, TestContext, Refiner } from '../modules/core/main.js'\nimport type {\n Config,\n CLIArgs,\n TestExecutor,\n RunnerSummary,\n NormalizedConfig,\n} from '../src/types.js'\n\n/**\n * Runner factory exposes the API to run dummy suites, groups and tests.\n * You might want to use the factory for testing reporters and\n * plugins usage\n */\nexport class RunnerFactory {\n #emitter = new Emitter()\n #config?: NormalizedConfig\n #cliArgs?: CLIArgs\n #file = fileURLToPath(import.meta.url)\n #bail: boolean = false\n\n get #refiner() {\n return this.#config!.refiner\n }\n\n /**\n * Registers plugins\n */\n async #registerPlugins(runner: Runner) {\n for (let plugin of this.#config!.plugins) {\n await plugin({\n config: this.#config!,\n runner,\n emitter: this.#emitter,\n cliArgs: this.#cliArgs!,\n })\n }\n }\n\n /**\n * Configure runner\n */\n configure(config: Config, argv?: string[]) {\n this.#cliArgs = new CliParser().parse(argv || [])\n this.#config = new ConfigManager(config, this.#cliArgs).hydrate()\n return this\n }\n\n /**\n * Define a custom emitter instance to use\n */\n useEmitter(emitter: Emitter) {\n this.#emitter = emitter\n return this\n }\n\n /**\n * Run a test using the runner\n */\n async runTest(\n title: string,\n callback: TestExecutor<TestContext, undefined>\n ): Promise<RunnerSummary> {\n return this.runSuites((emitter, refiner, file) => {\n const defaultSuite = new Suite('default', emitter, refiner)\n\n createTest(title, emitter, refiner, {\n suite: defaultSuite,\n file: file,\n }).run(callback)\n\n return [defaultSuite]\n })\n }\n\n /**\n * Enable/disable the bail mode\n */\n bail(toggle: boolean = true) {\n this.#bail = toggle\n return this\n }\n\n /**\n * Run dummy tests. You might use\n */\n async runSuites(\n suites: (emitter: Emitter, refiner: Refiner, file?: string) => Suite[]\n ): Promise<RunnerSummary> {\n const runner = new Runner(this.#emitter)\n runner.bail(this.#bail)\n\n await this.#registerPlugins(runner)\n\n const { config, reporters, refinerFilters } = await new Planner(this.#config!).plan()\n const globalHooks = new GlobalHooks()\n globalHooks.apply(config)\n\n reporters.forEach((reporter) => {\n runner.registerReporter(reporter)\n })\n\n refinerFilters.forEach((filter) => {\n config.refiner.add(filter.layer, filter.filters)\n })\n\n suites(this.#emitter, this.#refiner, this.#file).forEach((suite) => runner.add(suite))\n\n await globalHooks.setup(runner)\n await runner.start()\n await runner.exec()\n await runner.end()\n await globalHooks.teardown(null, runner)\n\n return runner.getSummary()\n }\n}\n","import assert from 'node:assert'\nimport { Suite, Emitter, Refiner } from '../modules/core/main.js'\nimport { createTest, createTestGroup } from '../src/create_test.js'\n\n/**\n * Creates a unit tests suite with bunch of dummy tests\n * reproducing different tests behavior\n */\nfunction createUnitTestsSuite(emitter: Emitter, refiner: Refiner, file?: string) {\n const suite = new Suite('unit', emitter, refiner)\n const group = createTestGroup('Maths#add', emitter, refiner, {\n suite,\n file,\n })\n\n createTest('A top level test inside a suite', emitter, refiner, {\n suite,\n file,\n }).run(() => {})\n\n createTest('add two numbers', emitter, refiner, { group, file }).run(() => {\n assert.equal(2 + 2, 4)\n })\n createTest('add three numbers', emitter, refiner, {\n group,\n file,\n }).run(() => {\n assert.equal(2 + 2 + 2, 6)\n })\n\n createTest('add group of numbers', emitter, refiner, { group, file })\n createTest('use math.js lib', emitter, refiner, { group, file }).skip(\n true,\n 'Library work pending'\n )\n createTest('add multiple numbers', emitter, refiner, {\n file,\n group,\n }).run(() => {\n assert.equal(2 + 2 + 2 + 2, 6)\n })\n createTest('add floating numbers', emitter, refiner, { group, file })\n .run(() => {\n assert.equal(2 + 2.2 + 2.1, 6)\n })\n .fails('Have to add support for floating numbers')\n\n createTest('regression test that is passing', emitter, refiner, { group, file })\n .run(() => {\n assert.equal(2 + 2.2 + 2.1, 2 + 2.2 + 2.1)\n })\n .fails('Have to add support for floating numbers')\n\n createTest('A test with an error that is not an AssertionError', emitter, refiner, {\n group,\n file,\n }).run(() => {\n throw new Error('This is an error')\n })\n\n return suite\n}\n\n/**\n * Creates a unit functional suite with bunch of dummy tests\n * reproducing different tests behavior\n */\nfunction createFunctionalTestsSuite(emitter: Emitter, refiner: Refiner, file?: string) {\n const suite = new Suite('functional', emitter, refiner)\n\n const group = createTestGroup('Users/store', emitter, refiner, {\n suite,\n file: file,\n })\n createTest('Validate user data', emitter, refiner, {\n group,\n file: file,\n }).run(() => {})\n createTest('Disallow duplicate emails', emitter, refiner, {\n group,\n file: file,\n }).run(() => {})\n createTest('Disallow duplicate emails across tenants', emitter, refiner, {\n group,\n file: file,\n }).run(() => {\n const users = ['', '']\n assert.equal(users.length, 1)\n })\n createTest('Normalize email before persisting it', emitter, refiner, {\n group,\n file: file,\n }).skip(true, 'Have to build a normalizer')\n createTest('Send email verification mail', emitter, refiner, {\n group,\n file: file,\n })\n\n createTest('Test that times out', emitter, refiner, {\n group,\n file: file,\n }).run(() => {\n return new Promise((resolve) => {\n setTimeout(resolve, 2100)\n })\n })\n\n const usersListGroup = createTestGroup('Users/list', emitter, refiner, {\n suite,\n file: file,\n })\n usersListGroup.setup(() => {\n throw new Error('Unable to cleanup database')\n })\n createTest('A test that will never run because the group hooks fails', emitter, refiner, {\n group: usersListGroup,\n })\n\n createTest('A top level test inside functional suite', emitter, refiner, {\n suite,\n file: file,\n }).run(() => {})\n\n return suite\n}\n\n/**\n * Returns an array of suites with dummy tests reproducting\n * different test behavior\n */\nexport function createDummyTests(emitter: Emitter, refiner: Refiner, file?: string): Suite[] {\n return [\n createUnitTestsSuite(emitter, refiner, file),\n createFunctionalTestsSuite(emitter, refiner, file),\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 { ReporterContract } from '../src/types.js'\nimport { RunnerFactory } from './runner.js'\n\n/**\n * Create an instance of the runner factory\n */\nexport const runner = () => new RunnerFactory()\nexport { createDummyTests } from './create_dummy_tests.js'\nexport const syncReporter: ReporterContract = {\n name: 'sync',\n handler(r, emitter) {\n emitter.on('runner:end', function () {\n const summary = r.getSummary()\n if (summary.hasError) {\n if (summary.failureTree[0].errors.length) {\n throw summary.failureTree[0].errors[0].error\n }\n if (summary.failureTree[0].children[0].errors.length) {\n throw summary.failureTree[0].children[0].errors[0].error\n }\n }\n })\n },\n}\n"],"mappings":"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","names":["runner"]}
@@ -19,6 +19,10 @@ export declare class RunnerFactory {
19
19
  * Run a test using the runner
20
20
  */
21
21
  runTest(title: string, callback: TestExecutor<TestContext, undefined>): Promise<RunnerSummary>;
22
+ /**
23
+ * Enable/disable the bail mode
24
+ */
25
+ bail(toggle?: boolean): this;
22
26
  /**
23
27
  * Run dummy tests. You might use
24
28
  */