@japa/runner 4.3.1 → 4.4.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.
@@ -1,234 +1,191 @@
1
- import {
2
- CliParser,
3
- ConfigManager,
4
- GlobalHooks,
5
- Planner,
6
- createTest,
7
- createTestGroup
8
- } from "../chunk-Y57JXJ7G.js";
9
- import "../chunk-U3BSXCEH.js";
10
- import {
11
- Emitter,
12
- Runner,
13
- Suite
14
- } from "../chunk-PCBL2VZP.js";
15
- import "../chunk-2KG3PWR4.js";
16
-
17
- // factories/runner.ts
18
- import { fileURLToPath } from "url";
1
+ import { a as GlobalHooks, i as CliParser, n as createTestGroup, o as Planner, r as ConfigManager, t as createTest } from "../create_test-CuTGNCAf.js";
2
+ import { c as Suite, i as Emitter, s as Runner } from "../helpers-BlHaYYTh.js";
3
+ import "../main-CB1nhl6c.js";
4
+ import { fileURLToPath } from "node:url";
5
+ import assert from "node:assert";
19
6
  var RunnerFactory = class {
20
- #emitter = new Emitter();
21
- #config;
22
- #cliArgs;
23
- #file = fileURLToPath(import.meta.url);
24
- #bail = false;
25
- get #refiner() {
26
- return this.#config.refiner;
27
- }
28
- /**
29
- * Registers plugins
30
- */
31
- async #registerPlugins(runner2) {
32
- for (let plugin of this.#config.plugins) {
33
- await plugin({
34
- config: this.#config,
35
- runner: runner2,
36
- emitter: this.#emitter,
37
- cliArgs: this.#cliArgs
38
- });
39
- }
40
- }
41
- /**
42
- * Configure runner
43
- */
44
- configure(config, argv) {
45
- this.#cliArgs = new CliParser().parse(argv || []);
46
- this.#config = new ConfigManager(config, this.#cliArgs).hydrate();
47
- return this;
48
- }
49
- /**
50
- * Define a custom emitter instance to use
51
- */
52
- useEmitter(emitter) {
53
- this.#emitter = emitter;
54
- return this;
55
- }
56
- /**
57
- * Run a test using the runner
58
- */
59
- async runTest(title, callback) {
60
- return this.runSuites((emitter, refiner, file) => {
61
- const defaultSuite = new Suite("default", emitter, refiner);
62
- createTest(title, emitter, refiner, {
63
- suite: defaultSuite,
64
- file
65
- }).run(callback);
66
- return [defaultSuite];
67
- });
68
- }
69
- /**
70
- * Enable/disable the bail mode
71
- */
72
- bail(toggle = true) {
73
- this.#bail = toggle;
74
- return this;
75
- }
76
- /**
77
- * Run dummy tests. You might use
78
- */
79
- async runSuites(suites) {
80
- const runner2 = new Runner(this.#emitter);
81
- runner2.bail(this.#bail);
82
- await this.#registerPlugins(runner2);
83
- const { config, reporters, refinerFilters } = await new Planner(this.#config).plan();
84
- const globalHooks = new GlobalHooks();
85
- globalHooks.apply(config);
86
- reporters.forEach((reporter) => {
87
- runner2.registerReporter(reporter);
88
- });
89
- refinerFilters.forEach((filter) => {
90
- config.refiner.add(filter.layer, filter.filters);
91
- });
92
- suites(this.#emitter, this.#refiner, this.#file).forEach((suite) => runner2.add(suite));
93
- await globalHooks.setup(runner2);
94
- await runner2.start();
95
- await runner2.exec();
96
- await runner2.end();
97
- await globalHooks.teardown(null, runner2);
98
- return runner2.getSummary();
99
- }
7
+ #emitter = new Emitter();
8
+ #config;
9
+ #cliArgs;
10
+ #file = fileURLToPath(import.meta.url);
11
+ #bail = false;
12
+ get #refiner() {
13
+ return this.#config.refiner;
14
+ }
15
+ async #registerPlugins(runner$1) {
16
+ for (let plugin of this.#config.plugins) await plugin({
17
+ config: this.#config,
18
+ runner: runner$1,
19
+ emitter: this.#emitter,
20
+ cliArgs: this.#cliArgs
21
+ });
22
+ }
23
+ configure(config, argv) {
24
+ this.#cliArgs = new CliParser().parse(argv || []);
25
+ this.#config = new ConfigManager(config, this.#cliArgs).hydrate();
26
+ return this;
27
+ }
28
+ useEmitter(emitter) {
29
+ this.#emitter = emitter;
30
+ return this;
31
+ }
32
+ async runTest(title, callback) {
33
+ return this.runSuites((emitter, refiner, file) => {
34
+ const defaultSuite = new Suite("default", emitter, refiner);
35
+ const debuggingError = /* @__PURE__ */ new Error();
36
+ createTest(title, emitter, refiner, debuggingError, {
37
+ suite: defaultSuite,
38
+ file
39
+ }).run(callback, debuggingError);
40
+ return [defaultSuite];
41
+ });
42
+ }
43
+ bail(toggle = true) {
44
+ this.#bail = toggle;
45
+ return this;
46
+ }
47
+ async runSuites(suites) {
48
+ const runner$1 = new Runner(this.#emitter);
49
+ runner$1.bail(this.#bail);
50
+ await this.#registerPlugins(runner$1);
51
+ const { config, reporters, refinerFilters } = await new Planner(this.#config).plan();
52
+ const globalHooks = new GlobalHooks();
53
+ globalHooks.apply(config);
54
+ reporters.forEach((reporter) => {
55
+ runner$1.registerReporter(reporter);
56
+ });
57
+ refinerFilters.forEach((filter) => {
58
+ config.refiner.add(filter.layer, filter.filters);
59
+ });
60
+ suites(this.#emitter, this.#refiner, this.#file).forEach((suite) => runner$1.add(suite));
61
+ await globalHooks.setup(runner$1);
62
+ await runner$1.start();
63
+ await runner$1.exec();
64
+ await runner$1.end();
65
+ await globalHooks.teardown(null, runner$1);
66
+ return runner$1.getSummary();
67
+ }
100
68
  };
101
-
102
- // factories/create_dummy_tests.ts
103
- import assert from "assert";
104
69
  function createUnitTestsSuite(emitter, refiner, file) {
105
- const suite = new Suite("unit", emitter, refiner);
106
- const group = createTestGroup("Maths#add", emitter, refiner, {
107
- suite,
108
- file
109
- });
110
- createTest("A top level test inside a suite", emitter, refiner, {
111
- suite,
112
- file
113
- }).run(() => {
114
- });
115
- createTest("add two numbers", emitter, refiner, { group, file }).run(() => {
116
- assert.equal(2 + 2, 4);
117
- });
118
- createTest("add three numbers", emitter, refiner, {
119
- group,
120
- file
121
- }).run(() => {
122
- assert.equal(2 + 2 + 2, 6);
123
- });
124
- createTest("add group of numbers", emitter, refiner, { group, file });
125
- createTest("use math.js lib", emitter, refiner, { group, file }).skip(
126
- true,
127
- "Library work pending"
128
- );
129
- createTest("add multiple numbers", emitter, refiner, {
130
- file,
131
- group
132
- }).run(() => {
133
- assert.equal(2 + 2 + 2 + 2, 6);
134
- });
135
- createTest("add floating numbers", emitter, refiner, { group, file }).run(() => {
136
- assert.equal(2 + 2.2 + 2.1, 6);
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");
141
- createTest("A test with an error that is not an AssertionError", emitter, refiner, {
142
- group,
143
- file
144
- }).run(() => {
145
- throw new Error("This is an error");
146
- });
147
- return suite;
70
+ const suite = new Suite("unit", emitter, refiner);
71
+ const group = createTestGroup("Maths#add", emitter, refiner, {
72
+ suite,
73
+ file
74
+ });
75
+ createTest("A top level test inside a suite", emitter, refiner, /* @__PURE__ */ new Error(), {
76
+ suite,
77
+ file
78
+ }).run(() => {});
79
+ createTest("add two numbers", emitter, refiner, /* @__PURE__ */ new Error(), {
80
+ group,
81
+ file
82
+ }).run(() => {
83
+ assert.equal(4, 4);
84
+ });
85
+ createTest("add three numbers", emitter, refiner, /* @__PURE__ */ new Error(), {
86
+ group,
87
+ file
88
+ }).run(() => {
89
+ assert.equal(6, 6);
90
+ });
91
+ createTest("add group of numbers", emitter, refiner, /* @__PURE__ */ new Error(), {
92
+ group,
93
+ file
94
+ });
95
+ createTest("use math.js lib", emitter, refiner, /* @__PURE__ */ new Error(), {
96
+ group,
97
+ file
98
+ }).skip(true, "Library work pending");
99
+ createTest("add multiple numbers", emitter, refiner, /* @__PURE__ */ new Error(), {
100
+ file,
101
+ group
102
+ }).run(() => {
103
+ assert.equal(8, 6);
104
+ });
105
+ createTest("add floating numbers", emitter, refiner, /* @__PURE__ */ new Error(), {
106
+ group,
107
+ file
108
+ }).run(() => {
109
+ assert.equal(6.300000000000001, 6);
110
+ }).fails("Have to add support for floating numbers");
111
+ createTest("regression test that is passing", emitter, refiner, /* @__PURE__ */ new Error(), {
112
+ group,
113
+ file
114
+ }).run(() => {
115
+ assert.equal(6.300000000000001, 6.300000000000001);
116
+ }).fails("Have to add support for floating numbers");
117
+ createTest("A test with an error that is not an AssertionError", emitter, refiner, /* @__PURE__ */ new Error(), {
118
+ group,
119
+ file
120
+ }).run(() => {
121
+ throw new Error("This is an error");
122
+ });
123
+ return suite;
148
124
  }
149
125
  function createFunctionalTestsSuite(emitter, refiner, file) {
150
- const suite = new Suite("functional", emitter, refiner);
151
- const group = createTestGroup("Users/store", emitter, refiner, {
152
- suite,
153
- file
154
- });
155
- createTest("Validate user data", emitter, refiner, {
156
- group,
157
- file
158
- }).run(() => {
159
- });
160
- createTest("Disallow duplicate emails", emitter, refiner, {
161
- group,
162
- file
163
- }).run(() => {
164
- });
165
- createTest("Disallow duplicate emails across tenants", emitter, refiner, {
166
- group,
167
- file
168
- }).run(() => {
169
- const users = ["", ""];
170
- assert.equal(users.length, 1);
171
- });
172
- createTest("Normalize email before persisting it", emitter, refiner, {
173
- group,
174
- file
175
- }).skip(true, "Have to build a normalizer");
176
- createTest("Send email verification mail", emitter, refiner, {
177
- group,
178
- file
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
- });
188
- const usersListGroup = createTestGroup("Users/list", emitter, refiner, {
189
- suite,
190
- file
191
- });
192
- usersListGroup.setup(() => {
193
- throw new Error("Unable to cleanup database");
194
- });
195
- createTest("A test that will never run because the group hooks fails", emitter, refiner, {
196
- group: usersListGroup
197
- });
198
- createTest("A top level test inside functional suite", emitter, refiner, {
199
- suite,
200
- file
201
- }).run(() => {
202
- });
203
- return suite;
126
+ const suite = new Suite("functional", emitter, refiner);
127
+ const group = createTestGroup("Users/store", emitter, refiner, {
128
+ suite,
129
+ file
130
+ });
131
+ createTest("Validate user data", emitter, refiner, /* @__PURE__ */ new Error(), {
132
+ group,
133
+ file
134
+ }).run(() => {});
135
+ createTest("Disallow duplicate emails", emitter, refiner, /* @__PURE__ */ new Error(), {
136
+ group,
137
+ file
138
+ }).run(() => {});
139
+ createTest("Disallow duplicate emails across tenants", emitter, refiner, /* @__PURE__ */ new Error(), {
140
+ group,
141
+ file
142
+ }).run(() => {
143
+ assert.equal(2, 1);
144
+ });
145
+ createTest("Normalize email before persisting it", emitter, refiner, /* @__PURE__ */ new Error(), {
146
+ group,
147
+ file
148
+ }).skip(true, "Have to build a normalizer");
149
+ createTest("Send email verification mail", emitter, refiner, /* @__PURE__ */ new Error(), {
150
+ group,
151
+ file
152
+ });
153
+ createTest("Test that times out", emitter, refiner, /* @__PURE__ */ new Error(), {
154
+ group,
155
+ file
156
+ }).run(() => {
157
+ return new Promise((resolve) => {
158
+ setTimeout(resolve, 2100);
159
+ });
160
+ });
161
+ const usersListGroup = createTestGroup("Users/list", emitter, refiner, {
162
+ suite,
163
+ file
164
+ });
165
+ usersListGroup.setup(() => {
166
+ throw new Error("Unable to cleanup database");
167
+ });
168
+ createTest("A test that will never run because the group hooks fails", emitter, refiner, /* @__PURE__ */ new Error(), { group: usersListGroup });
169
+ createTest("A top level test inside functional suite", emitter, refiner, /* @__PURE__ */ new Error(), {
170
+ suite,
171
+ file
172
+ }).run(() => {});
173
+ return suite;
204
174
  }
205
175
  function createDummyTests(emitter, refiner, file) {
206
- return [
207
- createUnitTestsSuite(emitter, refiner, file),
208
- createFunctionalTestsSuite(emitter, refiner, file)
209
- ];
176
+ return [createUnitTestsSuite(emitter, refiner, file), createFunctionalTestsSuite(emitter, refiner, file)];
210
177
  }
211
-
212
- // factories/main.ts
213
- var runner = () => new RunnerFactory();
214
- var syncReporter = {
215
- name: "sync",
216
- handler(r, emitter) {
217
- emitter.on("runner:end", function() {
218
- const summary = r.getSummary();
219
- if (summary.hasError) {
220
- if (summary.failureTree[0].errors.length) {
221
- throw summary.failureTree[0].errors[0].error;
222
- }
223
- if (summary.failureTree[0].children[0].errors.length) {
224
- throw summary.failureTree[0].children[0].errors[0].error;
225
- }
226
- }
227
- });
228
- }
229
- };
230
- export {
231
- createDummyTests,
232
- runner,
233
- syncReporter
178
+ const runner = () => new RunnerFactory();
179
+ const syncReporter = {
180
+ name: "sync",
181
+ handler(r, emitter) {
182
+ emitter.on("runner:end", function() {
183
+ const summary = r.getSummary();
184
+ if (summary.hasError) {
185
+ if (summary.failureTree[0].errors.length) throw summary.failureTree[0].errors[0].error;
186
+ if (summary.failureTree[0].children[0].errors.length) throw summary.failureTree[0].children[0].errors[0].error;
187
+ }
188
+ });
189
+ }
234
190
  };
191
+ export { createDummyTests, runner, syncReporter };
@@ -1,4 +1,4 @@
1
- import { Suite, Emitter, TestContext, Refiner } from '../modules/core/main.js';
1
+ import { Suite, Emitter, type TestContext, type Refiner } from '../modules/core/main.js';
2
2
  import type { Config, TestExecutor, RunnerSummary } from '../src/types.js';
3
3
  /**
4
4
  * Runner factory exposes the API to run dummy suites, groups and tests.
@@ -0,0 +1,241 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { ErrorsPrinter } from "@japa/errors-printer";
3
+ import { inspect } from "node:util";
4
+ import string from "@poppinss/string";
5
+ import useColors from "@poppinss/colors";
6
+ import supportsColor from "supports-color";
7
+ import { parse } from "error-stack-parser-es";
8
+ import { Emitter, Group, Refiner, Runner, Suite, Test, TestContext } from "@japa/core";
9
+ import { AssertionError } from "node:assert";
10
+ var BaseReporter = class {
11
+ runner;
12
+ currentFileName;
13
+ currentSuiteName;
14
+ currentGroupName;
15
+ options;
16
+ constructor(options = {}) {
17
+ this.options = Object.assign({ stackLinesCount: 2 }, options);
18
+ }
19
+ printAggregates(summary) {
20
+ const tests = [];
21
+ if (summary.aggregates.passed) tests.push(colors.green(`${summary.aggregates.passed} passed`));
22
+ if (summary.aggregates.failed) tests.push(colors.red(`${summary.aggregates.failed} failed`));
23
+ if (summary.aggregates.todo) tests.push(colors.cyan(`${summary.aggregates.todo} todo`));
24
+ if (summary.aggregates.skipped) tests.push(colors.yellow(`${summary.aggregates.skipped} skipped`));
25
+ if (summary.aggregates.regression) tests.push(colors.magenta(`${summary.aggregates.regression} regression`));
26
+ this.runner.summaryBuilder.use(() => {
27
+ return [{
28
+ key: colors.dim("Tests"),
29
+ value: `${tests.join(", ")} ${colors.dim(`(${summary.aggregates.total})`)}`
30
+ }, {
31
+ key: colors.dim("Time"),
32
+ value: colors.dim(string.milliseconds.format(summary.duration))
33
+ }];
34
+ });
35
+ console.log(this.runner.summaryBuilder.build().join("\n"));
36
+ }
37
+ aggregateErrors(summary) {
38
+ const errorsList = [];
39
+ summary.failureTree.forEach((suite) => {
40
+ suite.errors.forEach((error) => errorsList.push({
41
+ title: suite.name,
42
+ ...error
43
+ }));
44
+ suite.children.forEach((testOrGroup) => {
45
+ if (testOrGroup.type === "test") {
46
+ testOrGroup.errors.forEach((error) => {
47
+ errorsList.push({
48
+ title: `${suite.name} / ${testOrGroup.title}`,
49
+ ...error
50
+ });
51
+ });
52
+ return;
53
+ }
54
+ testOrGroup.errors.forEach((error) => {
55
+ errorsList.push({
56
+ title: testOrGroup.name,
57
+ ...error
58
+ });
59
+ });
60
+ testOrGroup.children.forEach((test) => {
61
+ test.errors.forEach((error) => {
62
+ errorsList.push({
63
+ title: `${testOrGroup.name} / ${test.title}`,
64
+ ...error
65
+ });
66
+ });
67
+ });
68
+ });
69
+ });
70
+ return errorsList;
71
+ }
72
+ async printErrors(summary) {
73
+ if (!summary.failureTree.length) return;
74
+ const errorPrinter = new ErrorsPrinter({ framesMaxLimit: this.options.framesMaxLimit });
75
+ errorPrinter.printSectionHeader("ERRORS");
76
+ await errorPrinter.printErrors(this.aggregateErrors(summary));
77
+ }
78
+ onTestStart(_) {}
79
+ onTestEnd(_) {}
80
+ onGroupStart(_) {}
81
+ onGroupEnd(_) {}
82
+ onSuiteStart(_) {}
83
+ onSuiteEnd(_) {}
84
+ async start(_) {}
85
+ async end(_) {}
86
+ async printSummary(summary) {
87
+ await this.printErrors(summary);
88
+ console.log("");
89
+ if (summary.aggregates.total === 0 && !summary.hasError) {
90
+ console.log(colors.bgYellow().black(" NO TESTS EXECUTED "));
91
+ return;
92
+ }
93
+ if (summary.hasError) console.log(colors.bgRed().black(" FAILED "));
94
+ else console.log(colors.bgGreen().black(" PASSED "));
95
+ console.log("");
96
+ this.printAggregates(summary);
97
+ }
98
+ boot(runner, emitter) {
99
+ this.runner = runner;
100
+ emitter.on("test:start", (payload) => {
101
+ this.currentFileName = payload.meta.fileName;
102
+ this.onTestStart(payload);
103
+ });
104
+ emitter.on("test:end", (payload) => {
105
+ this.onTestEnd(payload);
106
+ });
107
+ emitter.on("group:start", (payload) => {
108
+ this.currentGroupName = payload.title;
109
+ this.currentFileName = payload.meta.fileName;
110
+ this.onGroupStart(payload);
111
+ });
112
+ emitter.on("group:end", (payload) => {
113
+ this.currentGroupName = void 0;
114
+ this.onGroupEnd(payload);
115
+ });
116
+ emitter.on("suite:start", (payload) => {
117
+ this.currentSuiteName = payload.name;
118
+ this.onSuiteStart(payload);
119
+ });
120
+ emitter.on("suite:end", (payload) => {
121
+ this.currentSuiteName = void 0;
122
+ this.onSuiteEnd(payload);
123
+ });
124
+ emitter.on("runner:start", async (payload) => {
125
+ await this.start(payload);
126
+ });
127
+ emitter.on("runner:end", async (payload) => {
128
+ await this.end(payload);
129
+ });
130
+ }
131
+ };
132
+ var TestContext$1 = class extends TestContext {
133
+ constructor(test) {
134
+ super();
135
+ this.test = test;
136
+ this.cleanup = (cleanupCallback) => {
137
+ test.cleanup(cleanupCallback);
138
+ };
139
+ }
140
+ };
141
+ var Test$1 = class extends Test {
142
+ static executedCallbacks = [];
143
+ static executingCallbacks = [];
144
+ throws(message, errorConstructor) {
145
+ const errorInPoint = new AssertionError({});
146
+ const existingExecutor = this.options.executor;
147
+ if (!existingExecutor) throw new Error("Cannot use \"test.throws\" method without a test callback");
148
+ this.options.executor = async (...args) => {
149
+ let raisedException;
150
+ try {
151
+ await existingExecutor(...args);
152
+ } catch (error) {
153
+ raisedException = error;
154
+ }
155
+ if (!raisedException) {
156
+ errorInPoint.message = "Expected test to throw an exception";
157
+ throw errorInPoint;
158
+ }
159
+ if (errorConstructor && !(raisedException instanceof errorConstructor)) {
160
+ errorInPoint.message = `Expected test to throw "${inspect(errorConstructor)}"`;
161
+ throw errorInPoint;
162
+ }
163
+ const exceptionMessage = raisedException.message;
164
+ if (!exceptionMessage || typeof exceptionMessage !== "string") {
165
+ errorInPoint.message = "Expected test to throw an exception with message property";
166
+ throw errorInPoint;
167
+ }
168
+ if (typeof message === "string") {
169
+ if (exceptionMessage !== message) {
170
+ errorInPoint.message = `Expected test to throw "${message}". Instead received "${raisedException.message}"`;
171
+ errorInPoint.actual = raisedException.message;
172
+ errorInPoint.expected = message;
173
+ throw errorInPoint;
174
+ }
175
+ return;
176
+ }
177
+ if (!message.test(exceptionMessage)) {
178
+ errorInPoint.message = `Expected test error to match "${message}" regular expression`;
179
+ throw errorInPoint;
180
+ }
181
+ };
182
+ return this;
183
+ }
184
+ };
185
+ var Group$1 = class extends Group {};
186
+ var Suite$1 = class extends Suite {};
187
+ var Runner$1 = class extends Runner {};
188
+ const colors = supportsColor.stdout ? useColors.ansi() : useColors.silent();
189
+ const icons = process.platform === "win32" && !process.env.WT_SESSION ? {
190
+ tick: "√",
191
+ cross: "×",
192
+ bullet: "*",
193
+ nodejs: "♦",
194
+ pointer: ">",
195
+ info: "i",
196
+ warning: "‼",
197
+ branch: " -",
198
+ squareSmallFilled: "[█]"
199
+ } : {
200
+ tick: "✔",
201
+ cross: "✖",
202
+ bullet: "●",
203
+ nodejs: "⬢",
204
+ pointer: "❯",
205
+ info: "ℹ",
206
+ warning: "⚠",
207
+ branch: "└──",
208
+ squareSmallFilled: "◼"
209
+ };
210
+ function formatPinnedTest(test) {
211
+ let fileName = "";
212
+ let line = 0;
213
+ let column = 0;
214
+ try {
215
+ test.options.meta.abort("Finding pinned test location");
216
+ } catch (error) {
217
+ const frame = parse(error).find((f) => f.fileName && f.lineNumber !== void 0 && f.columnNumber !== void 0 && !f.fileName.includes("node:") && !f.fileName.includes("ext:") && !f.fileName.includes("node_modules/"));
218
+ if (frame) {
219
+ fileName = frame.fileName.startsWith("file:") ? string.toUnixSlash(fileURLToPath(frame.fileName)) : string.toUnixSlash(frame.fileName);
220
+ line = frame.lineNumber;
221
+ column = frame.columnNumber;
222
+ }
223
+ }
224
+ return `${colors.yellow(` ⁃ ${test.title}`)}\n${colors.dim(` ${fileName}:${line}:${column}`)}`;
225
+ }
226
+ function printPinnedTests(runner) {
227
+ let pinnedTests = [];
228
+ runner.suites.forEach((suite) => {
229
+ suite.stack.forEach((testOrGroup) => {
230
+ if (testOrGroup instanceof Group$1) testOrGroup.tests.forEach(($test) => {
231
+ if ($test.isPinned) pinnedTests.push(formatPinnedTest($test));
232
+ });
233
+ else if (testOrGroup.isPinned) pinnedTests.push(formatPinnedTest(testOrGroup));
234
+ });
235
+ });
236
+ if (pinnedTests.length) {
237
+ console.log(colors.bgYellow().black(` ${pinnedTests.length} pinned test(s) found `));
238
+ pinnedTests.forEach((row) => console.log(row));
239
+ } else console.log(colors.bgYellow().black(` No pinned tests found `));
240
+ }
241
+ export { Group$1 as a, Suite$1 as c, BaseReporter as d, Emitter as i, Test$1 as l, icons as n, Refiner as o, printPinnedTests as r, Runner$1 as s, colors as t, TestContext$1 as u };
package/build/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { TestExecutor } from '@japa/core/types';
2
2
  import type { Config } from './src/types.js';
3
- import { Group, Test, TestContext } from './modules/core/main.js';
3
+ import { type Group, type Test, type TestContext } from './modules/core/main.js';
4
4
  type OmitFirstArg<F> = F extends [_: any, ...args: infer R] ? R : never;
5
5
  /**
6
6
  * Create a Japa test. Defining a test without the callback