@epicat/toon-reporter 0.0.6 → 0.0.8
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.
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +49 -23
- package/dist/playwright.d.mts +0 -1
- package/dist/playwright.mjs +1 -4
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -5,13 +5,12 @@ import { Reporter, TestRunEndReason, Vitest } from "vitest/node";
|
|
|
5
5
|
interface ToonReporterOptions {
|
|
6
6
|
outputFile?: string;
|
|
7
7
|
color?: boolean;
|
|
8
|
-
/**
|
|
8
|
+
/** When true, shows all files and all coverage metrics. When false (default), only shows files with gaps and only metrics < 100% */
|
|
9
9
|
verbose?: boolean;
|
|
10
10
|
/** @internal Used for testing to capture output */
|
|
11
11
|
_captureOutput?: (output: string) => void;
|
|
12
12
|
}
|
|
13
13
|
declare class ToonReporter implements Reporter {
|
|
14
|
-
start: number;
|
|
15
14
|
ctx: Vitest;
|
|
16
15
|
options: ToonReporterOptions;
|
|
17
16
|
private useColor;
|
|
@@ -25,6 +24,7 @@ declare class ToonReporter implements Reporter {
|
|
|
25
24
|
private parseErrorLocation;
|
|
26
25
|
private parseExpectedGot;
|
|
27
26
|
private formatErrorMessage;
|
|
27
|
+
private buildReportForModules;
|
|
28
28
|
onTestRunEnd(testModules: ReadonlyArray<any>, _unhandledErrors: ReadonlyArray<SerializedError>, _reason: TestRunEndReason): Promise<void>;
|
|
29
29
|
private colorize;
|
|
30
30
|
writeReport(report: string): Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -47,13 +47,11 @@ function shouldUseColor(option) {
|
|
|
47
47
|
}
|
|
48
48
|
var ToonReporter = class {
|
|
49
49
|
constructor(options = {}) {
|
|
50
|
-
this.start = 0;
|
|
51
50
|
this.options = options;
|
|
52
51
|
this.useColor = shouldUseColor(options.color);
|
|
53
52
|
}
|
|
54
53
|
onInit(ctx) {
|
|
55
54
|
this.ctx = ctx;
|
|
56
|
-
this.start = Date.now();
|
|
57
55
|
this.coverageMap = void 0;
|
|
58
56
|
const coverage = ctx.config.coverage;
|
|
59
57
|
if (coverage?.reporter) coverage.reporter = [];
|
|
@@ -78,19 +76,27 @@ var ToonReporter = class {
|
|
|
78
76
|
const verbose = this.options.verbose;
|
|
79
77
|
for (const file of map.files()) {
|
|
80
78
|
const fc = map.fileCoverageFor(file);
|
|
79
|
+
const fileSummary = fc.toSummary().toJSON();
|
|
81
80
|
const uncoveredLines = fc.getUncoveredLines();
|
|
82
|
-
const
|
|
83
|
-
|
|
81
|
+
const lines = fileSummary.lines?.pct ?? 100;
|
|
82
|
+
const stmts = fileSummary.statements?.pct ?? 100;
|
|
83
|
+
const branch = fileSummary.branches?.pct ?? 100;
|
|
84
|
+
const funcs = fileSummary.functions?.pct ?? 100;
|
|
85
|
+
if (!verbose && lines === 100 && stmts === 100 && branch === 100 && funcs === 100) continue;
|
|
84
86
|
const entry = {
|
|
85
87
|
file: relative(rootDir, file),
|
|
86
88
|
uncoveredLines: this.formatLineRanges(uncoveredLines)
|
|
87
89
|
};
|
|
88
90
|
if (verbose) {
|
|
89
|
-
|
|
90
|
-
entry["
|
|
91
|
-
entry["
|
|
92
|
-
entry["
|
|
93
|
-
|
|
91
|
+
entry["lines%"] = lines;
|
|
92
|
+
entry["stmts%"] = stmts;
|
|
93
|
+
entry["branch%"] = branch;
|
|
94
|
+
entry["funcs%"] = funcs;
|
|
95
|
+
} else {
|
|
96
|
+
if (lines < 100) entry["lines%"] = lines;
|
|
97
|
+
if (stmts < 100) entry["stmts%"] = stmts;
|
|
98
|
+
if (branch < 100) entry["branch%"] = branch;
|
|
99
|
+
if (funcs < 100) entry["funcs%"] = funcs;
|
|
94
100
|
}
|
|
95
101
|
entries.push(entry);
|
|
96
102
|
}
|
|
@@ -150,8 +156,8 @@ var ToonReporter = class {
|
|
|
150
156
|
if (name && name !== "Error" && !message.startsWith(name)) message = `${name}: ${message}`;
|
|
151
157
|
return message;
|
|
152
158
|
}
|
|
153
|
-
|
|
154
|
-
const tests = getTests(
|
|
159
|
+
buildReportForModules(modules) {
|
|
160
|
+
const tests = getTests(modules.map((m) => m.task));
|
|
155
161
|
const rootDir = this.ctx.config.root;
|
|
156
162
|
const failedTests = tests.filter((t) => t.result?.state === "fail");
|
|
157
163
|
const passedCount = tests.filter((t) => t.result?.state === "pass").length;
|
|
@@ -165,20 +171,17 @@ var ToonReporter = class {
|
|
|
165
171
|
const { expected, got } = this.parseExpectedGot(error);
|
|
166
172
|
const relPath = loc?.relPath || relative(rootDir, t.file.filepath);
|
|
167
173
|
const at = this.formatLocation(relPath, loc?.line || t.location?.line, loc?.column || t.location?.column);
|
|
174
|
+
const failureDetails = expected !== void 0 && got !== void 0 ? {
|
|
175
|
+
expected,
|
|
176
|
+
got
|
|
177
|
+
} : { error: this.formatErrorMessage(error) };
|
|
168
178
|
if (t.each) {
|
|
169
179
|
if (!grouped.has(at)) grouped.set(at, []);
|
|
170
|
-
grouped.get(at).push(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
const failure = { at };
|
|
176
|
-
if (expected !== void 0 && got !== void 0) {
|
|
177
|
-
failure.expected = expected;
|
|
178
|
-
failure.got = got;
|
|
179
|
-
} else if (error) failure.error = this.formatErrorMessage(error);
|
|
180
|
-
failures.push(failure);
|
|
181
|
-
}
|
|
180
|
+
grouped.get(at).push(failureDetails);
|
|
181
|
+
} else failures.push({
|
|
182
|
+
at,
|
|
183
|
+
...failureDetails
|
|
184
|
+
});
|
|
182
185
|
}
|
|
183
186
|
for (const [at, params] of grouped) failures.push({
|
|
184
187
|
at,
|
|
@@ -192,6 +195,29 @@ var ToonReporter = class {
|
|
|
192
195
|
if (failures.length > 0) report.failing = failures;
|
|
193
196
|
if (todoTests.length > 0) report.todo = todoTests.map(mapToSkipped);
|
|
194
197
|
if (skippedTests.length > 0) report.skipped = skippedTests.map(mapToSkipped);
|
|
198
|
+
return report;
|
|
199
|
+
}
|
|
200
|
+
async onTestRunEnd(testModules, _unhandledErrors, _reason) {
|
|
201
|
+
const projectNames = /* @__PURE__ */ new Set();
|
|
202
|
+
const modulesByProject = /* @__PURE__ */ new Map();
|
|
203
|
+
for (const m of testModules) {
|
|
204
|
+
const projectName = m.project?.name || "";
|
|
205
|
+
projectNames.add(projectName);
|
|
206
|
+
if (!modulesByProject.has(projectName)) modulesByProject.set(projectName, []);
|
|
207
|
+
modulesByProject.get(projectName).push(m);
|
|
208
|
+
}
|
|
209
|
+
if (projectNames.size > 1) {
|
|
210
|
+
const projectReports = {};
|
|
211
|
+
for (const [projectName, modules] of modulesByProject) projectReports[projectName || "default"] = this.buildReportForModules(modules);
|
|
212
|
+
const coverage$1 = this.getCoverageSummary();
|
|
213
|
+
if (coverage$1) await this.writeReport(encode({
|
|
214
|
+
...projectReports,
|
|
215
|
+
coverage: coverage$1
|
|
216
|
+
}));
|
|
217
|
+
else await this.writeReport(encode(projectReports));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const report = this.buildReportForModules([...testModules]);
|
|
195
221
|
const coverage = this.getCoverageSummary();
|
|
196
222
|
if (coverage) report.coverage = coverage;
|
|
197
223
|
await this.writeReport(encode(report));
|
package/dist/playwright.d.mts
CHANGED
|
@@ -12,7 +12,6 @@ declare class ToonPlaywrightReporter implements Reporter {
|
|
|
12
12
|
private options;
|
|
13
13
|
constructor(options?: ToonPlaywrightReporterOptions);
|
|
14
14
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
15
|
-
private get rootDir();
|
|
16
15
|
private formatLocation;
|
|
17
16
|
private stripAnsi;
|
|
18
17
|
private stripOuterQuotes;
|
package/dist/playwright.mjs
CHANGED
|
@@ -11,11 +11,8 @@ var ToonPlaywrightReporter = class {
|
|
|
11
11
|
this.config = config;
|
|
12
12
|
this.suite = suite;
|
|
13
13
|
}
|
|
14
|
-
get rootDir() {
|
|
15
|
-
return this.config.rootDir;
|
|
16
|
-
}
|
|
17
14
|
formatLocation(filePath, line, column) {
|
|
18
|
-
const relPath = relative(
|
|
15
|
+
const relPath = relative(process.cwd(), filePath);
|
|
19
16
|
return line ? `${relPath}:${line}:${column || 0}` : relPath;
|
|
20
17
|
}
|
|
21
18
|
stripAnsi(str) {
|