mocha-sprint-file-reporter 1.0.127

Sign up to get free protection for your applications and to get access to all the features.
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
+ }