@japa/runner 2.5.1 → 3.0.0-1

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 (69) hide show
  1. package/LICENSE.md +1 -1
  2. package/build/factories/main.d.ts +3 -0
  3. package/build/factories/main.d.ts.map +1 -0
  4. package/build/factories/main.js +2 -0
  5. package/build/factories/runner.d.ts +10 -0
  6. package/build/factories/runner.d.ts.map +1 -0
  7. package/build/factories/runner.js +155 -0
  8. package/build/index.d.ts +8 -29
  9. package/build/index.js +93 -466
  10. package/build/modules/core/main.d.ts +29 -0
  11. package/build/modules/core/main.d.ts.map +1 -0
  12. package/build/modules/core/main.js +68 -0
  13. package/build/modules/core/reporters/base.d.ts +21 -0
  14. package/build/modules/core/reporters/base.d.ts.map +1 -0
  15. package/build/modules/core/reporters/base.js +136 -0
  16. package/build/modules/core/types.d.ts +6 -0
  17. package/build/modules/core/types.d.ts.map +1 -0
  18. package/build/modules/core/types.js +1 -0
  19. package/build/src/cli_parser.d.ts +6 -0
  20. package/build/src/cli_parser.d.ts.map +1 -0
  21. package/build/src/cli_parser.js +49 -0
  22. package/build/src/config_manager.d.ts +7 -0
  23. package/build/src/config_manager.d.ts.map +1 -0
  24. package/build/src/config_manager.js +115 -0
  25. package/build/src/create_test.d.ts +16 -0
  26. package/build/src/create_test.d.ts.map +1 -0
  27. package/build/src/create_test.js +33 -0
  28. package/build/src/debug.d.ts +2 -1
  29. package/build/src/debug.d.ts.map +1 -0
  30. package/build/src/debug.js +2 -12
  31. package/build/src/exceptions_manager.d.ts +7 -0
  32. package/build/src/exceptions_manager.d.ts.map +1 -0
  33. package/build/src/exceptions_manager.js +58 -0
  34. package/build/src/files_manager.d.ts +7 -0
  35. package/build/src/files_manager.d.ts.map +1 -0
  36. package/build/src/files_manager.js +28 -0
  37. package/build/src/helpers.d.ts +23 -0
  38. package/build/src/helpers.d.ts.map +1 -0
  39. package/build/src/helpers.js +2 -0
  40. package/build/src/hooks.d.ts +9 -0
  41. package/build/src/hooks.d.ts.map +1 -0
  42. package/build/src/hooks.js +26 -0
  43. package/build/src/planner.d.ts +18 -0
  44. package/build/src/planner.d.ts.map +1 -0
  45. package/build/src/planner.js +67 -0
  46. package/build/src/plugins/retry.d.ts +8 -0
  47. package/build/src/plugins/retry.d.ts.map +1 -0
  48. package/build/src/plugins/retry.js +42 -0
  49. package/build/src/reporters/dot.d.ts +7 -0
  50. package/build/src/reporters/dot.d.ts.map +1 -0
  51. package/build/src/reporters/dot.js +24 -0
  52. package/build/src/reporters/main.d.ts +5 -0
  53. package/build/src/reporters/main.d.ts.map +1 -0
  54. package/build/src/reporters/main.js +21 -0
  55. package/build/src/reporters/ndjson.d.ts +12 -0
  56. package/build/src/reporters/ndjson.d.ts.map +1 -0
  57. package/build/src/reporters/ndjson.js +61 -0
  58. package/build/src/reporters/spec.d.ts +11 -0
  59. package/build/src/reporters/spec.d.ts.map +1 -0
  60. package/build/src/reporters/spec.js +103 -0
  61. package/build/src/types.d.ts +48 -49
  62. package/build/src/types.d.ts.map +1 -0
  63. package/build/src/types.js +1 -10
  64. package/build/src/validator.d.ts +11 -0
  65. package/build/src/validator.d.ts.map +1 -0
  66. package/build/src/validator.js +46 -0
  67. package/package.json +78 -83
  68. package/build/src/core/main.d.ts +0 -49
  69. package/build/src/core/main.js +0 -87
@@ -0,0 +1,68 @@
1
+ import { Emitter, Refiner, Test as BaseTest, Suite as BaseSuite, Group as BaseGroup, Runner as BaseRunner, TestContext as BaseTestContext, } from '@japa/core';
2
+ import { inspect } from 'node:util';
3
+ import { AssertionError } from 'node:assert';
4
+ import { BaseReporter } from './reporters/base.js';
5
+ export { Emitter, Refiner, BaseReporter };
6
+ export class TestContext extends BaseTestContext {
7
+ test;
8
+ constructor(test) {
9
+ super();
10
+ this.test = test;
11
+ this.cleanup = (cleanupCallback) => {
12
+ test.cleanup(cleanupCallback);
13
+ };
14
+ }
15
+ }
16
+ export class Test extends BaseTest {
17
+ static executedCallbacks = [];
18
+ static executingCallbacks = [];
19
+ throws(message, errorConstructor) {
20
+ const errorInPoint = new AssertionError({});
21
+ const existingExecutor = this.options.executor;
22
+ if (!existingExecutor) {
23
+ throw new Error('Cannot use "test.throws" method without a test callback');
24
+ }
25
+ this.options.executor = async (...args) => {
26
+ let raisedException;
27
+ try {
28
+ await existingExecutor(...args);
29
+ }
30
+ catch (error) {
31
+ raisedException = error;
32
+ }
33
+ if (!raisedException) {
34
+ errorInPoint.message = 'Expected test to throw an exception';
35
+ throw errorInPoint;
36
+ }
37
+ if (errorConstructor && !(raisedException instanceof errorConstructor)) {
38
+ errorInPoint.message = `Expected test to throw "${inspect(errorConstructor)}"`;
39
+ throw errorInPoint;
40
+ }
41
+ const exceptionMessage = raisedException.message;
42
+ if (!exceptionMessage || typeof exceptionMessage !== 'string') {
43
+ errorInPoint.message = 'Expected test to throw an exception with message property';
44
+ throw errorInPoint;
45
+ }
46
+ if (typeof message === 'string') {
47
+ if (exceptionMessage !== message) {
48
+ errorInPoint.message = `Expected test to throw "${message}". Instead received "${raisedException.message}"`;
49
+ errorInPoint.actual = raisedException.message;
50
+ errorInPoint.expected = message;
51
+ throw errorInPoint;
52
+ }
53
+ return;
54
+ }
55
+ if (!message.test(exceptionMessage)) {
56
+ errorInPoint.message = `Expected test error to match "${message}" regular expression`;
57
+ throw errorInPoint;
58
+ }
59
+ };
60
+ return this;
61
+ }
62
+ }
63
+ export class Group extends BaseGroup {
64
+ }
65
+ export class Suite extends BaseSuite {
66
+ }
67
+ export class Runner extends BaseRunner {
68
+ }
@@ -0,0 +1,21 @@
1
+ import type { TestEndNode, SuiteEndNode, GroupEndNode, TestStartNode, RunnerSummary, RunnerEndNode, GroupStartNode, SuiteStartNode, RunnerStartNode, BaseReporterOptions } from '../types.js';
2
+ import { Emitter, Runner } from '../main.js';
3
+ export declare abstract class BaseReporter {
4
+ #private;
5
+ runner?: Runner;
6
+ currentFileName?: string;
7
+ currentSuiteName?: string;
8
+ currentGroupName?: string;
9
+ constructor(options?: BaseReporterOptions);
10
+ protected onTestStart(_: TestStartNode): void;
11
+ protected onTestEnd(_: TestEndNode): void;
12
+ protected onGroupStart(_: GroupStartNode): void;
13
+ protected onGroupEnd(_: GroupEndNode): void;
14
+ protected onSuiteStart(_: SuiteStartNode): void;
15
+ protected onSuiteEnd(_: SuiteEndNode): void;
16
+ protected start(_: RunnerStartNode): Promise<void>;
17
+ protected end(_: RunnerEndNode): Promise<void>;
18
+ protected printSummary(summary: RunnerSummary): Promise<void>;
19
+ boot(runner: Runner, emitter: Emitter): void;
20
+ }
21
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../modules/core/reporters/base.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAO5C,8BAAsB,YAAY;;IAEhC,MAAM,CAAC,EAAE,MAAM,CAAA;IAKf,eAAe,CAAC,EAAE,MAAM,CAAA;IAKxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAKzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;gBAEb,OAAO,GAAE,mBAAwB;IAsG7C,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI;IAC7C,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW;IAElC,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,cAAc;IACxC,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY;IAEpC,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,cAAc;IACxC,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY;cAEpB,KAAK,CAAC,CAAC,EAAE,eAAe;cACxB,GAAG,CAAC,CAAC,EAAE,aAAa;cAKpB,YAAY,CAAC,OAAO,EAAE,aAAa;IAqBnD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;CAyCtC"}
@@ -0,0 +1,136 @@
1
+ import ms from 'ms';
2
+ import colors from '@poppinss/colors';
3
+ import { ErrorsPrinter } from '@japa/errors-printer';
4
+ const ansi = colors.ansi();
5
+ export class BaseReporter {
6
+ #options;
7
+ runner;
8
+ currentFileName;
9
+ currentSuiteName;
10
+ currentGroupName;
11
+ constructor(options = {}) {
12
+ this.#options = Object.assign({ stackLinesCount: 2 }, options);
13
+ }
14
+ #printAggregates(summary) {
15
+ const tests = [];
16
+ if (summary.aggregates.passed) {
17
+ tests.push(ansi.green(`${summary.aggregates.passed} passed`));
18
+ }
19
+ if (summary.aggregates.failed) {
20
+ tests.push(ansi.red(`${summary.aggregates.failed} failed`));
21
+ }
22
+ if (summary.aggregates.todo) {
23
+ tests.push(ansi.cyan(`${summary.aggregates.todo} todo`));
24
+ }
25
+ if (summary.aggregates.skipped) {
26
+ tests.push(ansi.yellow(`${summary.aggregates.skipped} skipped`));
27
+ }
28
+ if (summary.aggregates.regression) {
29
+ tests.push(ansi.magenta(`${summary.aggregates.regression} regression`));
30
+ }
31
+ this.runner.summaryBuilder.use(() => {
32
+ return [
33
+ {
34
+ key: ansi.dim('Tests'),
35
+ value: `${tests.join(', ')} ${ansi.dim(`(${summary.aggregates.total})`)}`,
36
+ },
37
+ {
38
+ key: ansi.dim('Time'),
39
+ value: ansi.dim(ms(summary.duration)),
40
+ },
41
+ ];
42
+ });
43
+ console.log(this.runner.summaryBuilder.build().join('\n'));
44
+ }
45
+ #aggregateErrors(summary) {
46
+ const errorsList = [];
47
+ summary.failureTree.forEach((suite) => {
48
+ suite.errors.forEach((error) => errorsList.push({ title: suite.name, ...error }));
49
+ suite.children.forEach((testOrGroup) => {
50
+ if (testOrGroup.type === 'test') {
51
+ testOrGroup.errors.forEach((error) => {
52
+ errorsList.push({ title: `${suite.name} / ${testOrGroup.title}`, ...error });
53
+ });
54
+ return;
55
+ }
56
+ testOrGroup.errors.forEach((error) => {
57
+ errorsList.push({ title: testOrGroup.name, ...error });
58
+ });
59
+ testOrGroup.children.forEach((test) => {
60
+ test.errors.forEach((error) => {
61
+ errorsList.push({ title: `${testOrGroup.name} / ${test.title}`, ...error });
62
+ });
63
+ });
64
+ });
65
+ });
66
+ return errorsList;
67
+ }
68
+ async #printErrors(summary) {
69
+ if (!summary.failureTree.length) {
70
+ return;
71
+ }
72
+ const errorPrinter = new ErrorsPrinter({
73
+ stackLinesCount: this.#options.stackLinesCount,
74
+ framesMaxLimit: this.#options.framesMaxLimit,
75
+ });
76
+ errorPrinter.printSectionHeader('ERRORS');
77
+ await errorPrinter.printErrors(this.#aggregateErrors(summary));
78
+ }
79
+ onTestStart(_) { }
80
+ onTestEnd(_) { }
81
+ onGroupStart(_) { }
82
+ onGroupEnd(_) { }
83
+ onSuiteStart(_) { }
84
+ onSuiteEnd(_) { }
85
+ async start(_) { }
86
+ async end(_) { }
87
+ async printSummary(summary) {
88
+ await this.#printErrors(summary);
89
+ console.log('');
90
+ if (summary.aggregates.total === 0 && !summary.hasError) {
91
+ console.log(ansi.bgYellow().black(' NO TESTS EXECUTED '));
92
+ return;
93
+ }
94
+ if (summary.hasError) {
95
+ console.log(ansi.bgRed().black(' FAILED '));
96
+ }
97
+ else {
98
+ console.log(ansi.bgGreen().black(' PASSED '));
99
+ }
100
+ console.log('');
101
+ this.#printAggregates(summary);
102
+ }
103
+ boot(runner, emitter) {
104
+ this.runner = runner;
105
+ emitter.on('test:start', (payload) => {
106
+ this.currentFileName = payload.meta.fileName;
107
+ this.onTestStart(payload);
108
+ });
109
+ emitter.on('test:end', (payload) => {
110
+ this.onTestEnd(payload);
111
+ });
112
+ emitter.on('group:start', (payload) => {
113
+ this.currentGroupName = payload.title;
114
+ this.currentFileName = payload.meta.fileName;
115
+ this.onGroupStart(payload);
116
+ });
117
+ emitter.on('group:end', (payload) => {
118
+ this.currentGroupName = undefined;
119
+ this.onGroupEnd(payload);
120
+ });
121
+ emitter.on('suite:start', (payload) => {
122
+ this.currentSuiteName = payload.name;
123
+ this.onSuiteStart(payload);
124
+ });
125
+ emitter.on('suite:end', (payload) => {
126
+ this.currentSuiteName = undefined;
127
+ this.onSuiteEnd(payload);
128
+ });
129
+ emitter.on('runner:start', async (payload) => {
130
+ await this.start(payload);
131
+ });
132
+ emitter.on('runner:end', async (payload) => {
133
+ await this.end(payload);
134
+ });
135
+ }
136
+ }
@@ -0,0 +1,6 @@
1
+ export * from '@japa/core/types';
2
+ export type BaseReporterOptions = {
3
+ stackLinesCount?: number;
4
+ framesMaxLimit?: number;
5
+ };
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../modules/core/types.ts"],"names":[],"mappings":"AASA,cAAc,kBAAkB,CAAA;AAEhC,MAAM,MAAM,mBAAmB,GAAG;IAChC,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA"}
@@ -0,0 +1 @@
1
+ export * from '@japa/core/types';
@@ -0,0 +1,6 @@
1
+ import type { CLIArgs } from './types.js';
2
+ export declare class CliParser {
3
+ parse(argv: string[]): CLIArgs;
4
+ getHelp(): string;
5
+ }
6
+ //# sourceMappingURL=cli_parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli_parser.d.ts","sourceRoot":"","sources":["../../src/cli_parser.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAsDzC,qBAAa,SAAS;IAIpB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO;IAO9B,OAAO;CAGR"}
@@ -0,0 +1,49 @@
1
+ import getopts from 'getopts';
2
+ import colors from '@poppinss/colors';
3
+ const ansi = colors.ansi();
4
+ const OPTIONS = {
5
+ string: ['tests', 'groups', 'tags', 'files', 'timeout', 'retries', 'reporter'],
6
+ boolean: ['help', 'matchAll'],
7
+ alias: {
8
+ forceExit: 'force-exit',
9
+ matchAll: 'match-all',
10
+ help: 'h',
11
+ },
12
+ };
13
+ const GET_HELP = () => `
14
+ ${ansi.yellow('@japa/runner v2.3.0')}
15
+
16
+ ${ansi.green('--tests')} ${ansi.dim('Filter tests by the test title')}
17
+ ${ansi.green('--groups')} ${ansi.dim('Filter tests by the group title')}
18
+ ${ansi.green('--tags')} ${ansi.dim('Filter tests by tags')}
19
+ ${ansi.green('--files')} ${ansi.dim('Filter tests by the file name')}
20
+ ${ansi.green('--force-exit')} ${ansi.dim('Forcefully exit the process')}
21
+ ${ansi.green('--timeout')} ${ansi.dim('Define default timeout for all tests')}
22
+ ${ansi.green('--retries')} ${ansi.dim('Define default retries for all tests')}
23
+ ${ansi.green('--reporter')} ${ansi.dim('Activate one or more test reporters')}
24
+ ${ansi.green('-h, --help')} ${ansi.dim('View help')}
25
+
26
+ ${ansi.yellow('Examples:')}
27
+ ${ansi.dim('node bin/test.js --tags="@github"')}
28
+ ${ansi.dim('node bin/test.js --tags="~@github"')}
29
+ ${ansi.dim('node bin/test.js --tags="@github,@slow,@integration" --match-all')}
30
+ ${ansi.dim('node bin/test.js --force-exit')}
31
+ ${ansi.dim('node bin/test.js --files="user"')}
32
+ ${ansi.dim('node bin/test.js --files="functional/user"')}
33
+ ${ansi.dim('node bin/test.js --files="unit/user"')}
34
+
35
+ ${ansi.yellow('Notes:')}
36
+ - When groups and tests filters are applied together. We will first filter the
37
+ tests by group title and then apply the tests title filter.
38
+ - The timeout defined on test object takes precedence over the ${ansi.green('--timeout')} flag.
39
+ - The retries defined on test object takes precedence over the ${ansi.green('--retries')} flag.
40
+ - The ${ansi.green('--files')} flag checks for the file names ending with the filter substring.
41
+ `;
42
+ export class CliParser {
43
+ parse(argv) {
44
+ return getopts(argv, OPTIONS);
45
+ }
46
+ getHelp() {
47
+ return GET_HELP();
48
+ }
49
+ }
@@ -0,0 +1,7 @@
1
+ import type { CLIArgs, Config } from './types.js';
2
+ export declare class ConfigManager {
3
+ #private;
4
+ constructor(config: Config, cliArgs: CLIArgs);
5
+ hydrate(): Required<Config>;
6
+ }
7
+ //# sourceMappingURL=config_manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config_manager.d.ts","sourceRoot":"","sources":["../../src/config_manager.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAW,MAAM,YAAY,CAAA;AA0B1D,qBAAa,aAAa;;gBAIZ,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAsF5C,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC;CAoD5B"}
@@ -0,0 +1,115 @@
1
+ import debug from './debug.js';
2
+ import { spec } from './reporters/main.js';
3
+ import { Refiner } from '../modules/core/main.js';
4
+ const DEFAULTS = {
5
+ files: [],
6
+ timeout: 2000,
7
+ retries: 0,
8
+ forceExit: false,
9
+ plugins: [],
10
+ reporters: {
11
+ activated: ['spec'],
12
+ list: [spec()],
13
+ },
14
+ importer: (filePath) => import(filePath.href),
15
+ configureSuite: () => { },
16
+ };
17
+ export class ConfigManager {
18
+ #config;
19
+ #cliArgs;
20
+ constructor(config, cliArgs) {
21
+ this.#config = config;
22
+ this.#cliArgs = cliArgs;
23
+ }
24
+ #processAsArray(value) {
25
+ return Array.isArray(value) ? value : value.split(',').map((item) => item.trim());
26
+ }
27
+ #getCLIFilters() {
28
+ const filters = {};
29
+ if (this.#cliArgs.tags) {
30
+ filters.tags = this.#processAsArray(this.#cliArgs.tags);
31
+ }
32
+ if (this.#cliArgs.tests) {
33
+ filters.tests = this.#processAsArray(this.#cliArgs.tests);
34
+ }
35
+ if (this.#cliArgs.files) {
36
+ filters.files = this.#processAsArray(this.#cliArgs.files);
37
+ }
38
+ if (this.#cliArgs.groups) {
39
+ filters.groups = this.#processAsArray(this.#cliArgs.groups);
40
+ }
41
+ if (this.#cliArgs._ && this.#cliArgs._.length) {
42
+ filters.suites = this.#processAsArray(this.#cliArgs._);
43
+ }
44
+ return filters;
45
+ }
46
+ #getCLITimeout() {
47
+ if (this.#cliArgs.timeout) {
48
+ const value = Number(this.#cliArgs.timeout);
49
+ if (!Number.isNaN(value)) {
50
+ return value;
51
+ }
52
+ }
53
+ }
54
+ #getCLIRetries() {
55
+ if (this.#cliArgs.retries) {
56
+ const value = Number(this.#cliArgs.retries);
57
+ if (!Number.isNaN(value)) {
58
+ return value;
59
+ }
60
+ }
61
+ }
62
+ #getCLIForceExit() {
63
+ if (this.#cliArgs.forceExit) {
64
+ return true;
65
+ }
66
+ }
67
+ #getCLIReporters() {
68
+ if (this.#cliArgs.reporter) {
69
+ return this.#processAsArray(this.#cliArgs.reporter);
70
+ }
71
+ }
72
+ hydrate() {
73
+ const cliFilters = this.#getCLIFilters();
74
+ const cliRetries = this.#getCLIRetries();
75
+ const cliTimeout = this.#getCLITimeout();
76
+ const cliReporters = this.#getCLIReporters();
77
+ const cliForceExit = this.#getCLIForceExit();
78
+ debug('filters applied using CLI flags %O', cliFilters);
79
+ const baseConfig = {
80
+ cwd: this.#config.cwd ?? process.cwd(),
81
+ filters: Object.assign({}, this.#config.filters ?? {}, cliFilters),
82
+ importer: this.#config.importer ?? DEFAULTS.importer,
83
+ refiner: this.#config.refiner ?? new Refiner(),
84
+ retries: cliRetries ?? this.#config.retries ?? DEFAULTS.retries,
85
+ timeout: cliTimeout ?? this.#config.timeout ?? DEFAULTS.timeout,
86
+ plugins: this.#config.plugins ?? DEFAULTS.plugins,
87
+ forceExit: cliForceExit ?? this.#config.forceExit ?? DEFAULTS.forceExit,
88
+ reporters: this.#config.reporters ?? DEFAULTS.reporters,
89
+ configureSuite: this.#config.configureSuite ?? DEFAULTS.configureSuite,
90
+ setup: this.#config.setup || [],
91
+ teardown: this.#config.teardown || [],
92
+ };
93
+ if (cliReporters) {
94
+ baseConfig.reporters.activated = cliReporters;
95
+ }
96
+ if ('files' in this.#config) {
97
+ return {
98
+ files: this.#config.files,
99
+ ...baseConfig,
100
+ };
101
+ }
102
+ return {
103
+ suites: this.#config.suites.map((suite) => {
104
+ return {
105
+ name: suite.name,
106
+ files: suite.files,
107
+ timeout: cliTimeout ?? suite.timeout ?? baseConfig.timeout,
108
+ retries: cliRetries ?? suite.retries ?? baseConfig.retries,
109
+ configure: suite.configure,
110
+ };
111
+ }),
112
+ ...baseConfig,
113
+ };
114
+ }
115
+ }
@@ -0,0 +1,16 @@
1
+ import { Emitter, Group, Refiner, Suite, Test } from '../modules/core/main.js';
2
+ export declare function createTest(title: string, emitter: Emitter, refiner: Refiner, options: {
3
+ group?: Group;
4
+ suite?: Suite;
5
+ file?: string;
6
+ timeout?: number;
7
+ retries?: number;
8
+ }): Test<undefined>;
9
+ export declare function createTestGroup(title: string, emitter: Emitter, refiner: Refiner, options: {
10
+ group?: Group;
11
+ suite?: Suite;
12
+ file?: string;
13
+ timeout?: number;
14
+ retries?: number;
15
+ }): Group;
16
+ //# sourceMappingURL=create_test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create_test.d.ts","sourceRoot":"","sources":["../../src/create_test.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAe,MAAM,yBAAyB,CAAA;AAU3F,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,mBAwBF;AAKD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,SAeF"}
@@ -0,0 +1,33 @@
1
+ import { Group, Test, TestContext } from '../modules/core/main.js';
2
+ const contextBuilder = (testInstance) => new TestContext(testInstance);
3
+ export function createTest(title, emitter, refiner, options) {
4
+ const testInstance = new Test(title, contextBuilder, emitter, refiner, options.group);
5
+ testInstance.options.meta.suite = options.suite;
6
+ testInstance.options.meta.group = options.group;
7
+ testInstance.options.meta.fileName = options.file;
8
+ if (options.timeout !== undefined) {
9
+ testInstance.timeout(options.timeout);
10
+ }
11
+ if (options.retries !== undefined) {
12
+ testInstance.retry(options.retries);
13
+ }
14
+ if (options.group) {
15
+ options.group.add(testInstance);
16
+ }
17
+ else if (options.suite) {
18
+ options.suite.add(testInstance);
19
+ }
20
+ return testInstance;
21
+ }
22
+ export function createTestGroup(title, emitter, refiner, options) {
23
+ if (options.group) {
24
+ throw new Error('Nested groups are not supported by Japa');
25
+ }
26
+ const group = new Group(title, emitter, refiner);
27
+ group.options.meta.suite = options.suite;
28
+ group.options.meta.fileName = options.file;
29
+ if (options.suite) {
30
+ options.suite.add(group);
31
+ }
32
+ return group;
33
+ }
@@ -1,3 +1,4 @@
1
- /// <reference types="node" />
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
2
  declare const _default: import("util").DebugLogger;
3
3
  export default _default;
4
+ //# sourceMappingURL=debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/debug.ts"],"names":[],"mappings":";;AAUA,wBAAsC"}
@@ -1,12 +1,2 @@
1
- "use strict";
2
- /*
3
- * @japa/runner
4
- *
5
- * (c) Japa.dev
6
- *
7
- * For the full copyright and license information, please view the LICENSE
8
- * file that was distributed with this source code.
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- const util_1 = require("util");
12
- exports.default = (0, util_1.debuglog)('japa:runner');
1
+ import { debuglog } from 'node:util';
2
+ export default debuglog('japa:runner');
@@ -0,0 +1,7 @@
1
+ export declare class ExceptionsManager {
2
+ #private;
3
+ hasErrors: boolean;
4
+ monitor(): void;
5
+ flow(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=exceptions_manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions_manager.d.ts","sourceRoot":"","sources":["../../src/exceptions_manager.ts"],"names":[],"mappings":"AAeA,qBAAa,iBAAiB;;IAM5B,SAAS,EAAE,OAAO,CAAQ;IAW1B,OAAO;IAwBD,IAAI;CAmCX"}
@@ -0,0 +1,58 @@
1
+ import { ErrorsPrinter } from '@japa/errors-printer';
2
+ export class ExceptionsManager {
3
+ #exceptionsBuffer = [];
4
+ #rejectionsBuffer = [];
5
+ #state = 'watching';
6
+ #errorsPrinter = new ErrorsPrinter({ stackLinesCount: 2, framesMaxLimit: 4 });
7
+ hasErrors = false;
8
+ monitor() {
9
+ process.on('uncaughtException', async (error) => {
10
+ this.hasErrors = true;
11
+ if (this.#state === 'watching') {
12
+ this.#exceptionsBuffer.push(error);
13
+ }
14
+ else {
15
+ this.#errorsPrinter.printSectionBorder('[Unhandled Error]');
16
+ await this.#errorsPrinter.printError(error);
17
+ process.exitCode = 1;
18
+ }
19
+ });
20
+ process.on('unhandledRejection', async (error) => {
21
+ this.hasErrors = true;
22
+ if (this.#state === 'watching') {
23
+ this.#rejectionsBuffer.push(error);
24
+ }
25
+ else {
26
+ this.#errorsPrinter.printSectionBorder('[Unhandled Rejection]');
27
+ await this.#errorsPrinter.printError(error);
28
+ process.exitCode = 1;
29
+ }
30
+ });
31
+ }
32
+ async flow() {
33
+ if (this.#state === 'flowing') {
34
+ return;
35
+ }
36
+ this.#state = 'flowing';
37
+ if (this.#exceptionsBuffer.length) {
38
+ let exceptionsCount = this.#exceptionsBuffer.length;
39
+ let exceptionsIndex = this.#exceptionsBuffer.length;
40
+ this.#errorsPrinter.printSectionHeader('Unhandled Errors');
41
+ for (let exception of this.#exceptionsBuffer) {
42
+ await this.#errorsPrinter.printError(exception);
43
+ this.#errorsPrinter.printSectionBorder(`[${++exceptionsIndex}/${exceptionsCount}]`);
44
+ }
45
+ this.#exceptionsBuffer = [];
46
+ }
47
+ if (this.#rejectionsBuffer.length) {
48
+ let rejectionsCount = this.#exceptionsBuffer.length;
49
+ let rejectionsIndex = this.#exceptionsBuffer.length;
50
+ this.#errorsPrinter.printSectionBorder('Unhandled Rejections');
51
+ for (let rejection of this.#rejectionsBuffer) {
52
+ await this.#errorsPrinter.printError(rejection);
53
+ this.#errorsPrinter.printSectionBorder(`[${++rejectionsIndex}/${rejectionsCount}]`);
54
+ }
55
+ this.#rejectionsBuffer = [];
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,7 @@
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
+ import type { TestFiles } from './types.js';
3
+ export declare class FilesManager {
4
+ getFiles(cwd: string, files: TestFiles): Promise<URL[]>;
5
+ grep(files: URL[], filters: string[]): URL[];
6
+ }
7
+ //# sourceMappingURL=files_manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files_manager.d.ts","sourceRoot":"","sources":["../../src/files_manager.ts"],"names":[],"mappings":";AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAY3C,qBAAa,YAAY;IAKjB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAiB7D,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE;CAY7C"}
@@ -0,0 +1,28 @@
1
+ import { sep } from 'node:path';
2
+ import fastGlob from 'fast-glob';
3
+ import { pathToFileURL } from 'node:url';
4
+ const FILE_SUFFIX_EXPRESSION = /(\.spec|\.test)?\.[js|ts|jsx|tsx|mjs|mts|cjs|cts]+$/;
5
+ export class FilesManager {
6
+ async getFiles(cwd, files) {
7
+ if (Array.isArray(files) || typeof files === 'string') {
8
+ const testFiles = await fastGlob(files, {
9
+ absolute: true,
10
+ onlyFiles: true,
11
+ cwd: cwd,
12
+ });
13
+ return testFiles.map((file) => pathToFileURL(file));
14
+ }
15
+ return await files();
16
+ }
17
+ grep(files, filters) {
18
+ return files.filter((file) => {
19
+ return !!filters.find((filter) => {
20
+ const filterSegments = filter.split('/').reverse();
21
+ const fileSegments = file.pathname.replace(FILE_SUFFIX_EXPRESSION, '').split(sep).reverse();
22
+ return filterSegments.every((segment, index) => {
23
+ return fileSegments[index] && (segment === '*' || fileSegments[index].endsWith(segment));
24
+ });
25
+ });
26
+ });
27
+ }
28
+ }
@@ -0,0 +1,23 @@
1
+ declare const _default: {
2
+ colors: import("@poppinss/colors/types").Colors;
3
+ logger: import("@poppinss/cliui").Logger;
4
+ table: (tableOptions?: Partial<import("@poppinss/cliui/types").TableOptions> | undefined) => import("@poppinss/cliui").Table;
5
+ tasks: (tasksOptions?: Partial<import("@poppinss/cliui/types").TaskManagerOptions> | undefined) => import("@poppinss/cliui").TaskManager;
6
+ icons: {
7
+ tick: string;
8
+ cross: string;
9
+ bullet: string;
10
+ nodejs: string;
11
+ pointer: string;
12
+ info: string;
13
+ warning: string;
14
+ squareSmallFilled: string;
15
+ };
16
+ sticker: () => import("@poppinss/cliui").Instructions;
17
+ instructions: () => import("@poppinss/cliui").Instructions;
18
+ switchMode(modeToUse: "raw" | "silent" | "normal"): void;
19
+ useRenderer(rendererToUse: import("@poppinss/cliui/types").RendererContract): void;
20
+ useColors(colorsToUse: import("@poppinss/colors/types").Colors): void;
21
+ };
22
+ export default _default;
23
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAUA,wBAAsB"}
@@ -0,0 +1,2 @@
1
+ import { cliui } from '@poppinss/cliui';
2
+ export default cliui();