mocha-sprint-file-reporter 1.0.127

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/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # Mocha Sprint File Reporter
2
+
3
+ A sprint file reporter for Mocha tests that give more accurate informations about test latency.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install --save-dev mocha-sprint-file-reporter
9
+ ```
10
+
11
+ # Preview
12
+
13
+ ![screenshot](./screen.png)
@@ -0,0 +1,7 @@
1
+ import * as Mocha from "mocha";
2
+ export default SprintFile;
3
+ declare function SprintFile(this: any, runner: Mocha.Runner, options: Mocha.MochaOptions): void;
4
+ declare namespace SprintFile {
5
+ var description: string;
6
+ }
7
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA+B/B,eAAe,UAAU,CAAC;AAE1B,iBAAS,UAAU,CACjB,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,OAAO,EAAE,KAAK,CAAC,YAAY,QAsJ5B;kBAzJQ,UAAU"}
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const write_format_1 = require("write-format");
37
+ const Mocha = __importStar(require("mocha"));
38
+ const util_1 = require("util");
39
+ const { Base } = Mocha.reporters;
40
+ const path = require("path");
41
+ const milliseconds = require("ms");
42
+ const constants = Mocha.Runner.constants;
43
+ const cyanLimit = 10; // percentage of timeout
44
+ const yellowLimit = 33; // percentage of timeout
45
+ const orangeLimit = 66; // percentage of timeout
46
+ const EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;
47
+ const EVENT_RUN_END = constants.EVENT_RUN_END;
48
+ const EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;
49
+ const EVENT_SUITE_END = constants.EVENT_SUITE_END;
50
+ const EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;
51
+ const EVENT_TEST_PASS = constants.EVENT_TEST_PASS;
52
+ const EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;
53
+ const EVENT_TEST_END = constants.EVENT_TEST_END;
54
+ const space = " ";
55
+ const tab = space.repeat(2);
56
+ const bold = (s) => (0, write_format_1.Cformat)(s, { effects: ["bold"] });
57
+ const arrow = bold("↪");
58
+ const cusPalette = {
59
+ smallFaint: { fg: "white", effects: ["italic", "faint"] },
60
+ };
61
+ const getExponent = (num) => [...String(num)].map((d) => "⁰¹²³⁴⁵⁶⁷⁸⁹"[+d]).join("") + "⁾";
62
+ exports = module.exports = SprintFile;
63
+ exports.default = SprintFile;
64
+ function SprintFile(runner, options) {
65
+ Base.call(this, runner, options);
66
+ const self = this;
67
+ const width = (Base.window.width * 0.75) | 0;
68
+ let indents = 0;
69
+ let N = 0;
70
+ self.TSlowCyan = [0, [0, 0]];
71
+ self.TSlowYellow = [0, [0, 0]];
72
+ self.TSlowOrange = [0, [0, 0]];
73
+ let SlowCyan = 0;
74
+ let SlowYellow = 0;
75
+ let SlowOrange = 0;
76
+ self.TErr = 0;
77
+ let Err = 0;
78
+ self.SucceedRange = [0, 0];
79
+ self.TestsTimeRange = [0, [0, 0]];
80
+ self.CurrTestsTimeRange = [0, [0, 0]];
81
+ runner.on(EVENT_RUN_BEGIN, function () {
82
+ (0, write_format_1.write)("\n");
83
+ });
84
+ runner.on(EVENT_SUITE_BEGIN, function (suite) {
85
+ ++indents;
86
+ if (indents === 2) {
87
+ (0, write_format_1.write)((0, util_1.format)(arrow + space + "%s", suite.title), {
88
+ fg: "white",
89
+ effects: ["bold"],
90
+ });
91
+ (0, write_format_1.write)((0, util_1.format)(" (%s)", path.basename(suite.file)), cusPalette.smallFaint);
92
+ (0, write_format_1.write)("\n" + tab);
93
+ }
94
+ });
95
+ runner.on(EVENT_SUITE_END, function () {
96
+ --indents;
97
+ if (indents === 1) {
98
+ N += 6;
99
+ (0, write_format_1.write)(tab);
100
+ if (Err !== self.TErr) {
101
+ (0, write_format_1.write)("FAILED", { fg: "red", effects: ["bold"] });
102
+ }
103
+ else if (SlowOrange !== self.TSlowOrange[0]) {
104
+ (0, write_format_1.write)("VRSLOW", { fg: { rgb: [255, 150, 50] } });
105
+ }
106
+ else if (SlowYellow !== self.TSlowYellow[0]) {
107
+ (0, write_format_1.write)("SLOWED", { fg: "yellow", effects: ["bold"] });
108
+ }
109
+ else if (SlowCyan !== self.TSlowCyan[0]) {
110
+ (0, write_format_1.write)("ABSLOW", { fg: "cyan", effects: ["bold"] });
111
+ }
112
+ else {
113
+ (0, write_format_1.write)("PASSED", { fg: "green", effects: ["bold"] });
114
+ }
115
+ (0, write_format_1.write)(space);
116
+ (0, write_format_1.write)((0, util_1.format)("%s" + space, milliseconds(self.CurrTestsTimeRange[0])), {
117
+ fg: "brightWhite",
118
+ });
119
+ self.writeRangeEpilogue(self.CurrTestsTimeRange[1], cusPalette.smallFaint);
120
+ (0, write_format_1.write)("\n");
121
+ self.TestsTimeRange = self.updateRange(self.CurrTestsTimeRange[1][0], self.CurrTestsTimeRange, self.CurrTestsTimeRange[0]);
122
+ self.TestsTimeRange = self.updateRange(self.CurrTestsTimeRange[1][1], self.CurrTestsTimeRange, 0);
123
+ self.CurrTestsTimeRange = [0, [0, 0]];
124
+ SlowCyan = self.TSlowCyan[0];
125
+ SlowYellow = self.TSlowYellow[0];
126
+ SlowOrange = self.TSlowOrange[0];
127
+ Err = self.TErr;
128
+ N = 0;
129
+ }
130
+ });
131
+ runner.on(EVENT_TEST_PENDING, function (test) {
132
+ if (++N % width === 0) {
133
+ (0, write_format_1.write)("\n" + tab);
134
+ }
135
+ (0, write_format_1.write)(Base.symbols.comma, {
136
+ fg: { rgb: [128, 0, 128] },
137
+ bg: { rgb: [147, 112, 219] },
138
+ effects: ["bold"],
139
+ });
140
+ });
141
+ runner.on(EVENT_TEST_PASS, function (test) {
142
+ if (++N % width === 0) {
143
+ (0, write_format_1.write)("\n" + tab);
144
+ }
145
+ if (test.duration > (test._timeout * orangeLimit) / 100) {
146
+ self.TSlowOrange = self.updateRange(test.duration, self.TSlowOrange);
147
+ (0, write_format_1.write)("*", {
148
+ fg: { rgb: [255, 120, 0] },
149
+ bg: { rgb: [255, 150, 50] },
150
+ effects: ["bold"],
151
+ });
152
+ }
153
+ else if (test.duration > (test._timeout * yellowLimit) / 100) {
154
+ self.TSlowYellow = self.updateRange(test.duration, self.TSlowYellow);
155
+ (0, write_format_1.write)(Base.symbols.dot, {
156
+ fg: "yellow",
157
+ bg: "brightYellow",
158
+ effects: ["bold"],
159
+ });
160
+ }
161
+ else if (test.duration > (test._timeout * cyanLimit) / 100) {
162
+ self.TSlowCyan = self.updateRange(test.duration, self.TSlowCyan);
163
+ (0, write_format_1.write)("~", { fg: "cyan", bg: "brightCyan", effects: ["bold"] });
164
+ }
165
+ else {
166
+ const [ignore, range] = self.updateRange(test.duration, [
167
+ 0,
168
+ self.SucceedRange,
169
+ ]);
170
+ self.SucceedRange = range;
171
+ (0, write_format_1.write)(Base.symbols.ok, {
172
+ fg: "green",
173
+ bg: "brightGreen",
174
+ effects: ["bold"],
175
+ });
176
+ }
177
+ });
178
+ runner.on(EVENT_TEST_END, function (test) {
179
+ if (test.duration === undefined)
180
+ return;
181
+ self.CurrTestsTimeRange = self.updateRange(test.duration, self.CurrTestsTimeRange, test.duration);
182
+ });
183
+ runner.on(EVENT_TEST_FAIL, function (test) {
184
+ const T = bold(Base.symbols.bang) + getExponent(++self.TErr);
185
+ N += T.length;
186
+ if (N % width === 0) {
187
+ (0, write_format_1.write)("\n" + tab);
188
+ }
189
+ (0, write_format_1.write)(T, { fg: "red", bg: "brightRed" });
190
+ });
191
+ runner.once(EVENT_RUN_END, function () {
192
+ self.sprintEpilogue();
193
+ });
194
+ }
195
+ (0, util_1.inherits)(SprintFile, Base);
196
+ SprintFile.description = "hierarchical & check matrix representation";
197
+ SprintFile.prototype.sprintEpilogue = function () {
198
+ var stats = this.stats;
199
+ const plural = stats.tests > 1 ? "s" : "";
200
+ (0, write_format_1.write)("\n " + arrow + space);
201
+ (0, write_format_1.write)(bold(stats.tests) + space + "Test" + plural + " runs in" + space, {
202
+ fg: "brightWhite",
203
+ });
204
+ (0, write_format_1.write)((0, util_1.format)("%s", milliseconds(stats.duration)), {
205
+ fg: "brightWhite",
206
+ effects: ["bold"],
207
+ });
208
+ (0, write_format_1.write)(space);
209
+ this.writeRangeEpilogue(this.TestsTimeRange[1], cusPalette.smallFaint);
210
+ (0, write_format_1.write)("\n " + arrow + space, { effects: ["bold"] });
211
+ (0, write_format_1.write)((0, util_1.format)("%s %s" + space, (0, write_format_1.Cformat)(stats.passes || 0, { effects: ["bold"] }), "succeeded"), { fg: "green" });
212
+ this.writeRangeEpilogue(this.SucceedRange, cusPalette.smallFaint);
213
+ if (this.TSlowCyan[0] > 0) {
214
+ (0, write_format_1.write)("\n " + arrow + space, { effects: ["bold"] });
215
+ const plural = this.TSlowCyan[0] > 1 ? "were" : "was";
216
+ const numFormated = (0, write_format_1.Cformat)(this.TSlowCyan[0], { effects: ["bold"] });
217
+ (0, write_format_1.write)(`${numFormated} ${plural} a bit slow`, {
218
+ fg: "cyan",
219
+ });
220
+ (0, write_format_1.write)(space);
221
+ this.writeRangeEpilogue(this.TSlowCyan[1]);
222
+ }
223
+ if (this.TSlowYellow[0] > 0) {
224
+ (0, write_format_1.write)("\n " + arrow + space);
225
+ const plural = this.TSlowYellow[0] > 1 ? "were" : "was";
226
+ const numFormated = (0, write_format_1.Cformat)(this.TSlowYellow[0], { effects: ["bold"] });
227
+ (0, write_format_1.write)(`${numFormated} ${plural} slow`, {
228
+ fg: "yellow",
229
+ });
230
+ (0, write_format_1.write)(space);
231
+ this.writeRangeEpilogue(this.TSlowYellow[1]);
232
+ }
233
+ if (this.TSlowOrange[0] > 0) {
234
+ (0, write_format_1.write)("\n " + arrow + space);
235
+ const plural = this.TSlowOrange[0] > 1 ? "were" : "was";
236
+ const numFormated = (0, write_format_1.Cformat)(this.TSlowOrange[0], { effects: ["bold"] });
237
+ (0, write_format_1.write)(`${numFormated} ${plural} very slow`, {
238
+ fg: { rgb: [255, 150, 50] },
239
+ });
240
+ (0, write_format_1.write)(space);
241
+ this.writeRangeEpilogue(this.TSlowOrange[1]);
242
+ }
243
+ if (stats.pending) {
244
+ (0, write_format_1.write)("\n " + arrow + space);
245
+ const plural = stats.pending > 1 ? "s" : "";
246
+ (0, write_format_1.write)(`${(0, write_format_1.Cformat)(stats.pending, { effects: ["bold"] })} pending${plural}`, {
247
+ fg: { rgb: [128, 0, 128] },
248
+ });
249
+ }
250
+ if (stats.failures) {
251
+ (0, write_format_1.write)("\n " + arrow + space);
252
+ const plural = stats.failures > 1 ? "s" : "";
253
+ (0, write_format_1.write)(`${(0, write_format_1.Cformat)(stats.failures, { effects: ["bold"] })} failing${plural}`, { fg: "red" });
254
+ (0, write_format_1.write)("\n");
255
+ Base.list(this.failures);
256
+ (0, write_format_1.write)("\n");
257
+ }
258
+ (0, write_format_1.write)("\n");
259
+ (0, write_format_1.write)("\n");
260
+ };
261
+ SprintFile.prototype.updateRange = function (duration, range, step = 1) {
262
+ range[0] += step;
263
+ if (range[1][0] === 0 || duration < range[1][0]) {
264
+ range[1][0] = duration;
265
+ }
266
+ if (range[1][1] === 0 || duration > range[1][1]) {
267
+ range[1][1] = duration;
268
+ }
269
+ return range;
270
+ };
271
+ SprintFile.prototype.writeRangeEpilogue = function (range, options = cusPalette.smallFaint) {
272
+ if (range[0] == 1 || range[0] == range[1]) {
273
+ (0, write_format_1.write)((0, util_1.format)("(%s)", milliseconds(range[0])), options);
274
+ }
275
+ else {
276
+ (0, write_format_1.write)((0, util_1.format)("(%s~%s)", milliseconds(range[0]), milliseconds(range[1])), options);
277
+ }
278
+ };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "mocha-sprint-file-reporter",
3
+ "version": "1.0.127",
4
+ "description": "A sprint file reporter for Mocha tests.",
5
+ "main": "dist/reporter.js",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "test": "mocha test/*.spec.ts",
9
+ "test:cov": "nyc mocha test/*.spec.ts",
10
+ "prepublishOnly": "npm run build"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/pantharius/mocha-sprint-file-reporter.git"
15
+ },
16
+ "author": "Alexis Breuvart",
17
+ "license": "MIT",
18
+ "dependencies": {
19
+ "@istanbuljs/nyc-config-typescript": "^1.0.2",
20
+ "@types/chai": "^4.3.0",
21
+ "@types/mocha": "^9.0.0",
22
+ "@types/node": "^22.9.1",
23
+ "@types/sinon": "^17.0.3",
24
+ "chai": "4.0.2",
25
+ "child_process": "^1.0.2",
26
+ "mocha": "^10.8.2",
27
+ "nyc": "^17.1.0",
28
+ "path": "^0.12.7",
29
+ "sinon": "^19.0.2",
30
+ "ts-loader": "^9.5.1",
31
+ "ts-node": "^10.9.2",
32
+ "tsconfig-paths": "^4.2.0",
33
+ "typescript": "^5.6.2",
34
+ "write-format": "^1.0.122"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md",
39
+ "LICENSE"
40
+ ]
41
+ }