@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/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,3 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
15
15
  export {
16
16
  __reExport
17
17
  };
18
- //# sourceMappingURL=chunk-OBDV3O36.js.map
@@ -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,13 +37,12 @@ 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
- #options;
45
46
  runner;
46
47
  /**
47
48
  * Path to the file for which the tests are getting executed
@@ -55,13 +56,14 @@ var BaseReporter = class {
55
56
  * Group for which the tests are getting executed
56
57
  */
57
58
  currentGroupName;
59
+ options;
58
60
  constructor(options = {}) {
59
- this.#options = Object.assign({ stackLinesCount: 2 }, options);
61
+ this.options = Object.assign({ stackLinesCount: 2 }, options);
60
62
  }
61
63
  /**
62
64
  * Pretty prints the aggregates
63
65
  */
64
- #printAggregates(summary) {
66
+ printAggregates(summary) {
65
67
  const tests = [];
66
68
  if (summary.aggregates.passed) {
67
69
  tests.push(colors.green(`${summary.aggregates.passed} passed`));
@@ -95,7 +97,7 @@ var BaseReporter = class {
95
97
  /**
96
98
  * Aggregates errors tree to a flat array
97
99
  */
98
- #aggregateErrors(summary) {
100
+ aggregateErrors(summary) {
99
101
  const errorsList = [];
100
102
  summary.failureTree.forEach((suite) => {
101
103
  suite.errors.forEach((error) => errorsList.push({ title: suite.name, ...error }));
@@ -121,16 +123,15 @@ var BaseReporter = class {
121
123
  /**
122
124
  * Pretty print errors
123
125
  */
124
- async #printErrors(summary) {
126
+ async printErrors(summary) {
125
127
  if (!summary.failureTree.length) {
126
128
  return;
127
129
  }
128
130
  const errorPrinter = new ErrorsPrinter({
129
- stackLinesCount: this.#options.stackLinesCount,
130
- framesMaxLimit: this.#options.framesMaxLimit
131
+ framesMaxLimit: this.options.framesMaxLimit
131
132
  });
132
133
  errorPrinter.printSectionHeader("ERRORS");
133
- await errorPrinter.printErrors(this.#aggregateErrors(summary));
134
+ await errorPrinter.printErrors(this.aggregateErrors(summary));
134
135
  }
135
136
  /**
136
137
  * Handlers to capture events
@@ -155,7 +156,7 @@ var BaseReporter = class {
155
156
  * Print tests summary
156
157
  */
157
158
  async printSummary(summary) {
158
- await this.#printErrors(summary);
159
+ await this.printErrors(summary);
159
160
  console.log("");
160
161
  if (summary.aggregates.total === 0 && !summary.hasError) {
161
162
  console.log(colors.bgYellow().black(" NO TESTS EXECUTED "));
@@ -167,7 +168,7 @@ var BaseReporter = class {
167
168
  console.log(colors.bgGreen().black(" PASSED "));
168
169
  }
169
170
  console.log("");
170
- this.#printAggregates(summary);
171
+ this.printAggregates(summary);
171
172
  }
172
173
  /**
173
174
  * Invoked by the tests runner when tests are about to start
@@ -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,3 @@ export {
293
293
  Suite,
294
294
  Runner
295
295
  };
296
- //# sourceMappingURL=chunk-BFNOUWI5.js.map
@@ -2,7 +2,7 @@ import {
2
2
  BaseReporter,
3
3
  colors,
4
4
  icons
5
- } from "./chunk-BFNOUWI5.js";
5
+ } from "./chunk-CYGUHLQ7.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
  }
@@ -234,6 +239,80 @@ var NdJSONReporter = class extends BaseReporter {
234
239
  }
235
240
  };
236
241
 
242
+ // src/reporters/github.ts
243
+ import slash from "slash";
244
+ import { relative as relative3 } from "node:path";
245
+ import { stripVTControlCharacters } from "node:util";
246
+ import { ErrorsPrinter } from "@japa/errors-printer";
247
+ var GithubReporter = class extends BaseReporter {
248
+ /**
249
+ * Performs string escape on annotation message as per
250
+ * https://github.com/actions/toolkit/blob/f1d9b4b985e6f0f728b4b766db73498403fd5ca3/packages/core/src/command.ts#L80-L85
251
+ */
252
+ escapeMessage(value) {
253
+ return value.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A");
254
+ }
255
+ /**
256
+ * Performs string escape on annotation properties as per
257
+ * https://github.com/actions/toolkit/blob/f1d9b4b985e6f0f728b4b766db73498403fd5ca3/packages/core/src/command.ts#L80-L85
258
+ */
259
+ escapeProperty(value) {
260
+ return value.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A").replace(/:/g, "%3A").replace(/,/g, "%2C");
261
+ }
262
+ /**
263
+ * Formats the message as per the Github annotations spec.
264
+ * https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message
265
+ */
266
+ formatMessage({
267
+ command,
268
+ properties,
269
+ message
270
+ }) {
271
+ let result = `::${command}`;
272
+ Object.entries(properties).forEach(([k, v], i) => {
273
+ result += i === 0 ? " " : ",";
274
+ result += `${k}=${this.escapeProperty(v)}`;
275
+ });
276
+ result += `::${this.escapeMessage(message)}`;
277
+ return result;
278
+ }
279
+ /**
280
+ * Prints Github annotation for a given error
281
+ */
282
+ async getErrorAnnotation(printer, error) {
283
+ const parsedError = await printer.parseError(error.error);
284
+ if (!("frames" in parsedError)) {
285
+ return;
286
+ }
287
+ const mainFrame = parsedError.frames.find((frame) => frame.type === "app");
288
+ if (!mainFrame) {
289
+ return;
290
+ }
291
+ return this.formatMessage({
292
+ command: "error",
293
+ properties: {
294
+ file: slash(relative3(process.cwd(), mainFrame.fileName)),
295
+ title: error.title,
296
+ line: String(mainFrame.lineNumber),
297
+ column: String(mainFrame.columnNumber)
298
+ },
299
+ message: stripVTControlCharacters(parsedError.message)
300
+ });
301
+ }
302
+ async end() {
303
+ const summary = this.runner.getSummary();
304
+ const errorsList = this.aggregateErrors(summary);
305
+ const errorPrinter = new ErrorsPrinter(this.options);
306
+ for (let error of errorsList) {
307
+ const formatted = await this.getErrorAnnotation(errorPrinter, error);
308
+ if (formatted) {
309
+ console.log(`
310
+ ${formatted}`);
311
+ }
312
+ }
313
+ }
314
+ };
315
+
237
316
  // src/reporters/main.ts
238
317
  var spec = (options) => {
239
318
  return {
@@ -253,10 +332,16 @@ var ndjson = (options) => {
253
332
  handler: (...args) => new NdJSONReporter(options).boot(...args)
254
333
  };
255
334
  };
335
+ var github = (options) => {
336
+ return {
337
+ name: "github",
338
+ handler: (...args) => new GithubReporter(options).boot(...args)
339
+ };
340
+ };
256
341
 
257
342
  export {
258
343
  spec,
259
344
  dot,
260
- ndjson
345
+ ndjson,
346
+ github
261
347
  };
262
- //# sourceMappingURL=chunk-PHC5CJQG.js.map
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  dot,
3
+ github,
3
4
  ndjson,
4
5
  spec
5
- } from "./chunk-PHC5CJQG.js";
6
+ } from "./chunk-DPWXK7IV.js";
6
7
  import {
7
8
  Group,
8
9
  Refiner,
9
10
  Test,
10
11
  TestContext,
11
12
  colors
12
- } from "./chunk-BFNOUWI5.js";
13
+ } from "./chunk-CYGUHLQ7.js";
13
14
 
14
15
  // src/debug.ts
15
16
  import { debuglog } from "node:util";
@@ -259,11 +260,12 @@ var GlobalHooks = class {
259
260
  // src/cli_parser.ts
260
261
  import getopts from "getopts";
261
262
  var OPTIONS = {
262
- string: ["tests", "groups", "tags", "files", "timeout", "retries", "reporters", "failed"],
263
- boolean: ["help", "matchAll", "failed"],
263
+ string: ["tests", "groups", "tags", "files", "timeout", "retries", "reporters", "bailLayer"],
264
+ boolean: ["help", "matchAll", "failed", "bail"],
264
265
  alias: {
265
266
  forceExit: "force-exit",
266
267
  matchAll: "match-all",
268
+ bailLayer: "bail-layer",
267
269
  help: "h"
268
270
  }
269
271
  };
@@ -273,12 +275,15 @@ ${colors.yellow("@japa/runner v2.3.0")}
273
275
  ${colors.green("--tests")} ${colors.dim("Filter tests by the test title")}
274
276
  ${colors.green("--groups")} ${colors.dim("Filter tests by the group title")}
275
277
  ${colors.green("--tags")} ${colors.dim("Filter tests by tags")}
278
+ ${colors.green("--match-all")} ${colors.dim("Run tests that matches all the supplied tags")}
276
279
  ${colors.green("--files")} ${colors.dim("Filter tests by the file name")}
277
280
  ${colors.green("--force-exit")} ${colors.dim("Forcefully exit the process")}
278
281
  ${colors.green("--timeout")} ${colors.dim("Define default timeout for all tests")}
279
282
  ${colors.green("--retries")} ${colors.dim("Define default retries for all tests")}
280
283
  ${colors.green("--reporters")} ${colors.dim("Activate one or more test reporters")}
281
284
  ${colors.green("--failed")} ${colors.dim("Run tests failed during the last run")}
285
+ ${colors.green("--bail")} ${colors.dim("Exit early when a test fails")}
286
+ ${colors.green("--bail-layer")} ${colors.dim('Specify at which layer to enable the bail mode. Can be "group" or "suite"')}
282
287
  ${colors.green("-h, --help")} ${colors.dim("View help")}
283
288
 
284
289
  ${colors.yellow("Examples:")}
@@ -289,13 +294,18 @@ ${colors.dim("node bin/test.js --force-exit")}
289
294
  ${colors.dim('node bin/test.js --files="user"')}
290
295
  ${colors.dim('node bin/test.js --files="functional/user"')}
291
296
  ${colors.dim('node bin/test.js --files="unit/user"')}
297
+ ${colors.dim("node bin/test.js --failed")}
298
+ ${colors.dim("node bin/test.js --bail")}
299
+ ${colors.dim("node bin/test.js --bail=group")}
292
300
 
293
301
  ${colors.yellow("Notes:")}
294
302
  - 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.
303
+ tests by group title and then apply the tests filter.
296
304
  - The timeout defined on test object takes precedence over the ${colors.green("--timeout")} flag.
297
305
  - The retries defined on test object takes precedence over the ${colors.green("--retries")} flag.
298
306
  - The ${colors.green("--files")} flag checks for the file names ending with the filter substring.
307
+ - The ${colors.green("--tags")} filter runs tests that has one or more of the supplied tags.
308
+ - You can use the ${colors.green("--match-all")} flag to run tests that has all the supplied tags.
299
309
  `;
300
310
  var CliParser = class {
301
311
  /**
@@ -322,8 +332,8 @@ var DEFAULTS = {
322
332
  forceExit: false,
323
333
  plugins: [],
324
334
  reporters: {
325
- activated: ["spec"],
326
- list: [spec(), ndjson(), dot()]
335
+ activated: ["spec"].concat(process.env.GITHUB_ACTIONS === "true" ? ["github"] : []),
336
+ list: [spec(), ndjson(), dot(), github()]
327
337
  },
328
338
  importer: (filePath) => import(filePath.href),
329
339
  configureSuite: () => {
@@ -501,4 +511,3 @@ export {
501
511
  createTest,
502
512
  createTestGroup
503
513
  };
504
- //# sourceMappingURL=chunk-NVI2OU43.js.map
@@ -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-WEAHCEFK.js";
9
+ import "../chunk-DPWXK7IV.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-CYGUHLQ7.js";
15
+ import "../chunk-2KG3PWR4.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,8 +228,7 @@ var syncReporter = {
208
228
  }
209
229
  };
210
230
  export {
211
- createDiverseTests,
231
+ createDummyTests,
212
232
  runner,
213
233
  syncReporter
214
234
  };
215
- //# sourceMappingURL=main.js.map
@@ -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
  */
package/build/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { TestExecutor } from '@japa/core/types';
2
2
  import type { Config } from './src/types.js';
3
3
  import { Group, Test, TestContext } from './modules/core/main.js';
4
+ type OmitFirstArg<F> = F extends [_: any, ...args: infer R] ? R : never;
4
5
  /**
5
6
  * Create a Japa test. Defining a test without the callback
6
7
  * will create a todo test.
@@ -8,6 +9,7 @@ import { Group, Test, TestContext } from './modules/core/main.js';
8
9
  export declare function test(title: string, callback?: TestExecutor<TestContext, undefined>): Test<undefined>;
9
10
  export declare namespace test {
10
11
  var group: (title: string, callback: (group: Group) => void) => void;
12
+ var macro: <T extends (test: Test, ...args: any[]) => any>(callback: T) => (...args: OmitFirstArg<Parameters<T>>) => ReturnType<T>;
11
13
  }
12
14
  /**
13
15
  * Get the test of currently running test
@@ -31,3 +33,4 @@ export declare function configure(options: Config): void;
31
33
  * files behind the scenes
32
34
  */
33
35
  export declare function run(): Promise<void>;
36
+ export {};