@japa/runner 3.1.4 → 4.1.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 (36) hide show
  1. package/README.md +8 -4
  2. package/build/{chunk-OBDV3O36.js → chunk-2KG3PWR4.js} +0 -1
  3. package/build/{chunk-BFNOUWI5.js → chunk-CYGUHLQ7.js} +14 -15
  4. package/build/{chunk-PHC5CJQG.js → chunk-DPWXK7IV.js} +102 -17
  5. package/build/{chunk-NVI2OU43.js → chunk-WEAHCEFK.js} +17 -8
  6. package/build/factories/{create_diverse_tests.d.ts → create_dummy_tests.d.ts} +1 -1
  7. package/build/factories/main.d.ts +1 -1
  8. package/build/factories/main.js +28 -9
  9. package/build/factories/runner.d.ts +4 -0
  10. package/build/index.d.ts +3 -0
  11. package/build/index.js +27 -11
  12. package/build/modules/core/main.d.ts +10 -3
  13. package/build/modules/core/main.js +2 -3
  14. package/build/modules/core/reporters/base.d.ts +18 -2
  15. package/build/modules/core/types.d.ts +0 -1
  16. package/build/src/config_manager.d.ts +1 -1
  17. package/build/src/debug.d.ts +0 -1
  18. package/build/src/exceptions_manager.d.ts +1 -1
  19. package/build/src/files_manager.d.ts +0 -1
  20. package/build/src/helpers.d.ts +1 -0
  21. package/build/src/planner.d.ts +0 -1
  22. package/build/src/reporters/github.d.ts +35 -0
  23. package/build/src/reporters/main.d.ts +4 -0
  24. package/build/src/reporters/main.js +5 -4
  25. package/build/src/types.d.ts +2 -1
  26. package/build/src/types.js +1 -2
  27. package/package.json +77 -74
  28. package/build/chunk-BFNOUWI5.js.map +0 -1
  29. package/build/chunk-NVI2OU43.js.map +0 -1
  30. package/build/chunk-OBDV3O36.js.map +0 -1
  31. package/build/chunk-PHC5CJQG.js.map +0 -1
  32. package/build/factories/main.js.map +0 -1
  33. package/build/index.js.map +0 -1
  34. package/build/modules/core/main.js.map +0 -1
  35. package/build/src/reporters/main.js.map +0 -1
  36. package/build/src/types.js.map +0 -1
package/build/index.js CHANGED
@@ -7,15 +7,15 @@ import {
7
7
  createTestGroup,
8
8
  debug_default,
9
9
  validator_default
10
- } from "./chunk-NVI2OU43.js";
11
- import "./chunk-PHC5CJQG.js";
10
+ } from "./chunk-WEAHCEFK.js";
11
+ import "./chunk-DPWXK7IV.js";
12
12
  import {
13
13
  Emitter,
14
14
  Runner,
15
15
  Suite,
16
16
  colors
17
- } from "./chunk-BFNOUWI5.js";
18
- import "./chunk-OBDV3O36.js";
17
+ } from "./chunk-CYGUHLQ7.js";
18
+ import "./chunk-2KG3PWR4.js";
19
19
 
20
20
  // index.ts
21
21
  import { fileURLToPath } from "node:url";
@@ -104,11 +104,11 @@ var ExceptionsManager = class {
104
104
  }
105
105
  });
106
106
  }
107
- async flow() {
108
- if (this.#state === "flowing") {
107
+ async report() {
108
+ if (this.#state === "reporting") {
109
109
  return;
110
110
  }
111
- this.#state = "flowing";
111
+ this.#state = "reporting";
112
112
  if (this.#exceptionsBuffer.length) {
113
113
  let exceptionsCount = this.#exceptionsBuffer.length;
114
114
  let exceptionsIndex = this.#exceptionsBuffer.length;
@@ -150,7 +150,7 @@ function test(title, callback) {
150
150
  };
151
151
  });
152
152
  if (callback) {
153
- testInstance.run(callback);
153
+ testInstance.run(callback, new Error());
154
154
  }
155
155
  return testInstance;
156
156
  }
@@ -162,9 +162,20 @@ test.group = function(title, callback) {
162
162
  runnerConfig.refiner,
163
163
  executionPlanState
164
164
  );
165
+ if (cliArgs.bail && cliArgs.bailLayer === "group") {
166
+ executionPlanState.group.bail(true);
167
+ }
165
168
  callback(executionPlanState.group);
166
169
  executionPlanState.group = void 0;
167
170
  };
171
+ test.macro = function(callback) {
172
+ return (...args) => {
173
+ if (!activeTest) {
174
+ throw new Error("Cannot invoke macro outside of the test callback");
175
+ }
176
+ return callback(activeTest, ...args);
177
+ };
178
+ };
168
179
  function getActiveTest() {
169
180
  return activeTest;
170
181
  }
@@ -182,6 +193,9 @@ async function run() {
182
193
  validator_default.ensureIsConfigured(runnerConfig);
183
194
  executionPlanState.phase = "planning";
184
195
  const runner = new Runner(emitter);
196
+ if (cliArgs.bail && cliArgs.bailLayer === "") {
197
+ runner.bail(true);
198
+ }
185
199
  const globalHooks = new GlobalHooks();
186
200
  const exceptionsManager = new ExceptionsManager();
187
201
  try {
@@ -211,6 +225,9 @@ async function run() {
211
225
  if (typeof suite.configure === "function") {
212
226
  suite.configure(executionPlanState.suite);
213
227
  }
228
+ if (cliArgs.bail && cliArgs.bailLayer === "suite") {
229
+ executionPlanState.suite.bail(true);
230
+ }
214
231
  runner.add(executionPlanState.suite);
215
232
  for (let fileURL of suite.filesURLs) {
216
233
  executionPlanState.file = fileURLToPath(fileURL);
@@ -225,7 +242,7 @@ async function run() {
225
242
  await runner.exec();
226
243
  await globalHooks.teardown(null, runner);
227
244
  await runner.end();
228
- await exceptionsManager.flow();
245
+ await exceptionsManager.report();
229
246
  const summary = runner.getSummary();
230
247
  if (summary.hasError || exceptionsManager.hasErrors) {
231
248
  process.exitCode = 1;
@@ -237,7 +254,7 @@ async function run() {
237
254
  await globalHooks.teardown(error, runner);
238
255
  const printer = new ErrorsPrinter2();
239
256
  await printer.printError(error);
240
- await exceptionsManager.flow();
257
+ await exceptionsManager.report();
241
258
  process.exitCode = 1;
242
259
  if (runnerConfig.forceExit) {
243
260
  process.exit();
@@ -251,4 +268,3 @@ export {
251
268
  run,
252
269
  test
253
270
  };
254
- //# sourceMappingURL=index.js.map
@@ -3,9 +3,17 @@ import { BaseReporter } from './reporters/base.js';
3
3
  import type { DataSetNode, TestHooksCleanupHandler } from './types.js';
4
4
  declare module '@japa/core' {
5
5
  interface Test<Context extends Record<any, any>, TestData extends DataSetNode = undefined> {
6
+ /**
7
+ * Assert the test throws an exception with a certain error message
8
+ * and optionally is an instance of a given Error class.
9
+ */
6
10
  throws(message: string | RegExp, errorConstructor?: any): this;
7
11
  }
8
12
  interface TestContext {
13
+ /**
14
+ * Register a cleanup function that runs after the test finishes
15
+ * successfully or with an error.
16
+ */
9
17
  cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void;
10
18
  }
11
19
  }
@@ -36,9 +44,8 @@ export declare class Test<TestData extends DataSetNode = undefined> extends Base
36
44
  */
37
45
  static executingCallbacks: never[];
38
46
  /**
39
- * Assert the test callback throws an exception when a certain
40
- * error message and optionally is an instance of a given
41
- * Error class.
47
+ * Assert the test throws an exception with a certain error message
48
+ * and optionally is an instance of a given Error class.
42
49
  */
43
50
  throws(message: string | RegExp, errorConstructor?: any): this;
44
51
  }
@@ -7,8 +7,8 @@ import {
7
7
  Suite,
8
8
  Test,
9
9
  TestContext
10
- } from "../../chunk-BFNOUWI5.js";
11
- import "../../chunk-OBDV3O36.js";
10
+ } from "../../chunk-CYGUHLQ7.js";
11
+ import "../../chunk-2KG3PWR4.js";
12
12
  export {
13
13
  BaseReporter,
14
14
  Emitter,
@@ -19,4 +19,3 @@ export {
19
19
  Test,
20
20
  TestContext
21
21
  };
22
- //# sourceMappingURL=main.js.map
@@ -1,10 +1,9 @@
1
- import type { TestEndNode, SuiteEndNode, GroupEndNode, TestStartNode, RunnerSummary, RunnerEndNode, GroupStartNode, SuiteStartNode, RunnerStartNode, BaseReporterOptions } from '../types.js';
2
1
  import { Emitter, Runner } from '../main.js';
2
+ import type { TestEndNode, SuiteEndNode, GroupEndNode, TestStartNode, RunnerSummary, RunnerEndNode, GroupStartNode, SuiteStartNode, RunnerStartNode, BaseReporterOptions } from '../types.js';
3
3
  /**
4
4
  * Base reporter to build custom reporters on top of
5
5
  */
6
6
  export declare abstract class BaseReporter {
7
- #private;
8
7
  runner?: Runner;
9
8
  /**
10
9
  * Path to the file for which the tests are getting executed
@@ -18,7 +17,24 @@ export declare abstract class BaseReporter {
18
17
  * Group for which the tests are getting executed
19
18
  */
20
19
  currentGroupName?: string;
20
+ protected options: BaseReporterOptions;
21
21
  constructor(options?: BaseReporterOptions);
22
+ /**
23
+ * Pretty prints the aggregates
24
+ */
25
+ protected printAggregates(summary: RunnerSummary): void;
26
+ /**
27
+ * Aggregates errors tree to a flat array
28
+ */
29
+ protected aggregateErrors(summary: RunnerSummary): {
30
+ phase: string;
31
+ title: string;
32
+ error: Error;
33
+ }[];
34
+ /**
35
+ * Pretty print errors
36
+ */
37
+ protected printErrors(summary: RunnerSummary): Promise<void>;
22
38
  /**
23
39
  * Handlers to capture events
24
40
  */
@@ -1,5 +1,4 @@
1
1
  export * from '@japa/core/types';
2
2
  export type BaseReporterOptions = {
3
- stackLinesCount?: number;
4
3
  framesMaxLimit?: number;
5
4
  };
@@ -2,7 +2,7 @@ import type { CLIArgs, Config, NormalizedConfig } from './types.js';
2
2
  export declare const NOOP: () => void;
3
3
  /**
4
4
  * Config manager is used to hydrate the configuration by merging
5
- * the defaults, user defined config and the command line
5
+ * the defaults with the user defined config and the command line
6
6
  * flags.
7
7
  *
8
8
  * The command line flags have the upmost priority
@@ -1,3 +1,2 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  declare const _default: import("util").DebugLogger;
3
2
  export default _default;
@@ -15,5 +15,5 @@ export declare class ExceptionsManager {
15
15
  * happen.
16
16
  */
17
17
  monitor(): void;
18
- flow(): Promise<void>;
18
+ report(): Promise<void>;
19
19
  }
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { TestFiles } from './types.js';
3
2
  /**
4
3
  * Files manager exposes the API to collect, filter and import test
@@ -11,5 +11,6 @@ export declare const icons: {
11
11
  pointer: string;
12
12
  info: string;
13
13
  warning: string;
14
+ branch: string;
14
15
  squareSmallFilled: string;
15
16
  };
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { NamedReporterContract, NormalizedConfig, TestSuite } from './types.js';
3
2
  /**
4
3
  * The tests planner is used to plan the tests by doing all
@@ -0,0 +1,35 @@
1
+ import { ErrorsPrinter } from '@japa/errors-printer';
2
+ import { BaseReporter } from '../../modules/core/main.js';
3
+ /**
4
+ * Prints annotations when executing tests within Github actions
5
+ */
6
+ export declare class GithubReporter extends BaseReporter {
7
+ /**
8
+ * Performs string escape on annotation message as per
9
+ * https://github.com/actions/toolkit/blob/f1d9b4b985e6f0f728b4b766db73498403fd5ca3/packages/core/src/command.ts#L80-L85
10
+ */
11
+ protected escapeMessage(value: string): string;
12
+ /**
13
+ * Performs string escape on annotation properties as per
14
+ * https://github.com/actions/toolkit/blob/f1d9b4b985e6f0f728b4b766db73498403fd5ca3/packages/core/src/command.ts#L80-L85
15
+ */
16
+ protected escapeProperty(value: string): string;
17
+ /**
18
+ * Formats the message as per the Github annotations spec.
19
+ * https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message
20
+ */
21
+ protected formatMessage({ command, properties, message, }: {
22
+ command: string;
23
+ properties: Record<string, string>;
24
+ message: string;
25
+ }): string;
26
+ /**
27
+ * Prints Github annotation for a given error
28
+ */
29
+ getErrorAnnotation(printer: ErrorsPrinter, error: {
30
+ phase: string;
31
+ title: string;
32
+ error: Error;
33
+ }): Promise<string | undefined>;
34
+ end(): Promise<void>;
35
+ }
@@ -11,3 +11,7 @@ export declare const dot: (options?: BaseReporterOptions) => NamedReporterContra
11
11
  * Create an instance of the ndjson reporter
12
12
  */
13
13
  export declare const ndjson: (options?: BaseReporterOptions) => NamedReporterContract;
14
+ /**
15
+ * Create an instance of the github reporter
16
+ */
17
+ export declare const github: (options?: BaseReporterOptions) => NamedReporterContract;
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  dot,
3
+ github,
3
4
  ndjson,
4
5
  spec
5
- } from "../../chunk-PHC5CJQG.js";
6
- import "../../chunk-BFNOUWI5.js";
7
- import "../../chunk-OBDV3O36.js";
6
+ } from "../../chunk-DPWXK7IV.js";
7
+ import "../../chunk-CYGUHLQ7.js";
8
+ import "../../chunk-2KG3PWR4.js";
8
9
  export {
9
10
  dot,
11
+ github,
10
12
  ndjson,
11
13
  spec
12
14
  };
13
- //# sourceMappingURL=main.js.map
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { HookHandler } from '@poppinss/hooks/types';
3
2
  import type { Emitter, Refiner, Runner, Suite } from '../modules/core/main.js';
4
3
  import type { FilteringOptions, NamedReporterContract } from '../modules/core/types.js';
@@ -36,6 +35,8 @@ export type CLIArgs = {
36
35
  failed?: boolean;
37
36
  help?: boolean;
38
37
  matchAll?: boolean;
38
+ bail?: boolean;
39
+ bailLayer?: string;
39
40
  } & Record<string, string | string[] | boolean>;
40
41
  /**
41
42
  * Set of filters you can apply to run only specific tests
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __reExport
3
- } from "../chunk-OBDV3O36.js";
3
+ } from "../chunk-2KG3PWR4.js";
4
4
 
5
5
  // src/types.ts
6
6
  var types_exports2 = {};
@@ -12,4 +12,3 @@ import * as types_star from "@japa/core/types";
12
12
 
13
13
  // src/types.ts
14
14
  __reExport(types_exports2, types_exports);
15
- //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@japa/runner",
3
- "description": "Runner for Japa testing framework",
4
- "version": "3.1.4",
3
+ "description": "A simple yet powerful testing framework for Node.js",
4
+ "version": "4.1.0",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
7
7
  },
@@ -10,8 +10,7 @@
10
10
  "files": [
11
11
  "build",
12
12
  "!build/examples",
13
- "!build/tests",
14
- "!build/tests_helpers"
13
+ "!build/tests"
15
14
  ],
16
15
  "exports": {
17
16
  ".": "./build/index.js",
@@ -23,61 +22,55 @@
23
22
  "scripts": {
24
23
  "pretest": "npm run lint",
25
24
  "test": "cross-env NODE_DEBUG=japa:runner c8 npm run quick:test",
26
- "quick:test": "glob -c \"node --enable-source-maps --loader=ts-node/esm --test-reporter=spec --test\" \"tests/*.spec.ts\"",
27
- "clean": "del-cli build",
25
+ "lint": "eslint .",
26
+ "format": "prettier --write .",
28
27
  "typecheck": "tsc --noEmit",
28
+ "clean": "del-cli build",
29
29
  "precompile": "npm run lint && npm run clean",
30
30
  "compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
31
31
  "build": "npm run compile",
32
- "release": "np",
33
- "prepublishOnly": "npm run build",
34
- "lint": "eslint . --ext=.ts",
35
- "format": "prettier --write .",
36
32
  "version": "npm run build",
37
- "sync-labels": "github-label-sync --labels .github/labels.json japa/runner"
33
+ "prepublishOnly": "npm run build",
34
+ "release": "release-it",
35
+ "quick:test": "glob -c \"node --import=ts-node-maintained/register/esm --enable-source-maps --test-reporter=spec --test\" \"tests/*.spec.ts\""
38
36
  },
39
37
  "devDependencies": {
40
- "@adonisjs/eslint-config": "^1.3.0",
41
- "@adonisjs/prettier-config": "^1.3.0",
42
- "@adonisjs/tsconfig": "^1.3.0",
43
- "@commitlint/cli": "^19.2.1",
44
- "@commitlint/config-conventional": "^19.1.0",
45
- "@swc/core": "^1.4.11",
46
- "@types/chai": "^4.3.14",
38
+ "@adonisjs/eslint-config": "^2.0.0-beta.7",
39
+ "@adonisjs/prettier-config": "^1.4.0",
40
+ "@adonisjs/tsconfig": "^1.4.0",
41
+ "@release-it/conventional-changelog": "^10.0.0",
42
+ "@swc/core": "^1.10.4",
43
+ "@types/chai": "^5.0.1",
47
44
  "@types/chai-subset": "^1.3.5",
48
- "@types/find-cache-dir": "^5.0.0",
45
+ "@types/find-cache-dir": "^5.0.2",
49
46
  "@types/ms": "^0.7.34",
50
- "@types/node": "^20.11.30",
51
- "c8": "^9.1.0",
52
- "chai": "^5.1.0",
47
+ "@types/node": "^22.10.5",
48
+ "c8": "^10.1.3",
49
+ "chai": "^5.1.2",
53
50
  "chai-subset": "^1.6.0",
54
51
  "cross-env": "^7.0.3",
55
- "del-cli": "^5.1.0",
56
- "eslint": "^8.57.0",
57
- "github-label-sync": "^2.3.1",
58
- "glob": "^10.3.12",
59
- "husky": "^9.0.11",
60
- "np": "^10.0.2",
61
- "prettier": "^3.2.5",
62
- "ts-node": "^10.9.2",
63
- "tsup": "^8.0.2",
64
- "typescript": "^5.4.3"
52
+ "del-cli": "^6.0.0",
53
+ "eslint": "^9.17.0",
54
+ "glob": "^11.0.0",
55
+ "prettier": "^3.4.2",
56
+ "release-it": "^18.1.1",
57
+ "ts-node-maintained": "^10.9.4",
58
+ "tsup": "^8.3.5",
59
+ "typescript": "^5.7.3"
65
60
  },
66
61
  "dependencies": {
67
- "@japa/core": "^9.0.1",
68
- "@japa/errors-printer": "^3.0.4",
69
- "@poppinss/colors": "^4.1.3",
70
- "@poppinss/hooks": "^7.2.3",
71
- "fast-glob": "^3.3.2",
62
+ "@japa/core": "^10.3.0",
63
+ "@japa/errors-printer": "^4.1.0",
64
+ "@poppinss/colors": "^4.1.4",
65
+ "@poppinss/hooks": "^7.2.5",
66
+ "fast-glob": "^3.3.3",
72
67
  "find-cache-dir": "^5.0.0",
73
68
  "getopts": "^2.3.0",
74
69
  "ms": "^2.1.3",
75
- "serialize-error": "^11.0.3",
70
+ "serialize-error": "^12.0.0",
76
71
  "slash": "^5.1.0",
77
- "supports-color": "^9.4.0"
72
+ "supports-color": "^10.0.0"
78
73
  },
79
- "author": "virk,japa",
80
- "license": "MIT",
81
74
  "homepage": "https://github.com/japa/runner#readme",
82
75
  "repository": {
83
76
  "type": "git",
@@ -91,27 +84,50 @@
91
84
  "tests",
92
85
  "test-runner"
93
86
  ],
94
- "directories": {
95
- "test": "test"
96
- },
97
- "eslintConfig": {
98
- "extends": "@adonisjs/eslint-config/package"
99
- },
100
- "prettier": "@adonisjs/prettier-config",
101
- "commitlint": {
102
- "extends": [
103
- "@commitlint/config-conventional"
104
- ]
105
- },
87
+ "author": "Harminder Virk <virk@adonisjs.com>",
88
+ "license": "MIT",
106
89
  "publishConfig": {
107
90
  "access": "public",
108
- "tag": "latest"
91
+ "provenance": true
109
92
  },
110
- "np": {
111
- "message": "chore(release): %s",
112
- "tag": "latest",
113
- "branch": "main",
114
- "anyBranch": false
93
+ "tsup": {
94
+ "entry": [
95
+ "./index.ts",
96
+ "./src/types.ts",
97
+ "./src/reporters/main.ts",
98
+ "./factories/main.ts",
99
+ "./modules/core/main.ts"
100
+ ],
101
+ "outDir": "./build",
102
+ "clean": true,
103
+ "format": "esm",
104
+ "dts": false,
105
+ "sourcemap": false,
106
+ "target": "esnext"
107
+ },
108
+ "release-it": {
109
+ "git": {
110
+ "requireCleanWorkingDir": true,
111
+ "requireUpstream": true,
112
+ "commitMessage": "chore(release): ${version}",
113
+ "tagAnnotation": "v${version}",
114
+ "push": true,
115
+ "tagName": "v${version}"
116
+ },
117
+ "github": {
118
+ "release": true
119
+ },
120
+ "npm": {
121
+ "publish": true,
122
+ "skipChecks": true
123
+ },
124
+ "plugins": {
125
+ "@release-it/conventional-changelog": {
126
+ "preset": {
127
+ "name": "angular"
128
+ }
129
+ }
130
+ }
115
131
  },
116
132
  "c8": {
117
133
  "reporter": [
@@ -121,24 +137,11 @@
121
137
  "exclude": [
122
138
  "tests/**",
123
139
  "tests_helpers/**",
140
+ "build/**",
124
141
  "factories/**",
125
142
  "modules/core/**",
126
143
  "src/reporters/**"
127
144
  ]
128
145
  },
129
- "tsup": {
130
- "entry": [
131
- "./index.ts",
132
- "./src/types.ts",
133
- "./src/reporters/main.ts",
134
- "./factories/main.ts",
135
- "./modules/core/main.ts"
136
- ],
137
- "outDir": "./build",
138
- "clean": true,
139
- "format": "esm",
140
- "dts": false,
141
- "sourcemap": true,
142
- "target": "esnext"
143
- }
146
+ "prettier": "@adonisjs/prettier-config"
144
147
  }
@@ -1 +0,0 @@
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":[]}