Skip to content

Commit 41f9d56

Browse files
authored
Refactor statistics (#3458)
* collect stats
1 parent 4bef574 commit 41f9d56

File tree

6 files changed

+92
-52
lines changed

6 files changed

+92
-52
lines changed

lib/reporters/base.js

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,7 @@ exports.list = function(failures) {
270270
* Initialize a new `Base` reporter.
271271
*
272272
* All other reporters generally
273-
* inherit from this reporter, providing
274-
* stats such as test duration, number
275-
* of tests passed / failed etc.
273+
* inherit from this reporter.
276274
*
277275
* @memberof Mocha.reporters
278276
* @public
@@ -281,68 +279,31 @@ exports.list = function(failures) {
281279
*/
282280

283281
function Base(runner) {
284-
var stats = (this.stats = {
285-
suites: 0,
286-
tests: 0,
287-
passes: 0,
288-
pending: 0,
289-
failures: 0
290-
});
291282
var failures = (this.failures = []);
292283

293284
if (!runner) {
294-
return;
285+
throw new TypeError('Missing runner argument');
295286
}
287+
this.stats = runner.stats; // assigned so Reporters keep a closer reference
296288
this.runner = runner;
297289

298-
runner.stats = stats;
299-
300-
runner.on('start', function() {
301-
stats.start = new Date();
302-
});
303-
304-
runner.on('suite', function(suite) {
305-
stats.suites = stats.suites || 0;
306-
suite.root || stats.suites++;
307-
});
308-
309-
runner.on('test end', function() {
310-
stats.tests = stats.tests || 0;
311-
stats.tests++;
312-
});
313-
314290
runner.on('pass', function(test) {
315-
stats.passes = stats.passes || 0;
316-
317291
if (test.duration > test.slow()) {
318292
test.speed = 'slow';
319293
} else if (test.duration > test.slow() / 2) {
320294
test.speed = 'medium';
321295
} else {
322296
test.speed = 'fast';
323297
}
324-
325-
stats.passes++;
326298
});
327299

328300
runner.on('fail', function(test, err) {
329-
stats.failures = stats.failures || 0;
330-
stats.failures++;
331301
if (showDiff(err)) {
332302
stringifyDiffObjs(err);
333303
}
334304
test.err = err;
335305
failures.push(test);
336306
});
337-
338-
runner.once('end', function() {
339-
stats.end = new Date();
340-
stats.duration = stats.end - stats.start;
341-
});
342-
343-
runner.on('pending', function() {
344-
stats.pending++;
345-
});
346307
}
347308

348309
/**

lib/runner.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var utils = require('./utils');
1212
var inherits = utils.inherits;
1313
var debug = require('debug')('mocha:runner');
1414
var Runnable = require('./runnable');
15+
var createStatsCollector = require('./stats-collector');
1516
var stackFilter = utils.stackTraceFilter();
1617
var stringify = utils.stringify;
1718
var type = utils.type;
@@ -80,6 +81,7 @@ function Runner(suite, delay) {
8081
this._defaultGrep = /.*/;
8182
this.grep(this._defaultGrep);
8283
this.globals(this.globalProps().concat(extraGlobals()));
84+
createStatsCollector(this);
8385
}
8486

8587
/**

lib/stats-collector.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
/**
4+
* Test statistics collector.
5+
*
6+
* @typedef {Object} StatsCollector
7+
* @property {number} suites - integer count of suites run.
8+
* @property {number} tests - integer count of tests run.
9+
* @property {number} passes - integer count of passing tests.
10+
* @property {number} pending - integer count of pending tests.
11+
* @property {number} failures - integer count of failed tests.
12+
* @property {Date} start - time when testing began.
13+
* @property {Date} end - time when testing concluded.
14+
* @property {number} duration - number of msecs that testing took.
15+
*/
16+
17+
/**
18+
* Provides stats such as test duration,
19+
* number of tests passed / failed etc.
20+
*
21+
* @public
22+
* @memberof Mocha
23+
* @param {Runner} runner
24+
*/
25+
function createStatsCollector(runner) {
26+
var stats = {
27+
suites: 0,
28+
tests: 0,
29+
passes: 0,
30+
pending: 0,
31+
failures: 0
32+
};
33+
34+
if (!runner) {
35+
throw new TypeError('Missing runner argument');
36+
}
37+
38+
runner.stats = stats;
39+
40+
runner.once('start', function() {
41+
stats.start = new Date();
42+
});
43+
44+
runner.on('suite', function(suite) {
45+
suite.root || stats.suites++;
46+
});
47+
48+
runner.on('pass', function() {
49+
stats.passes++;
50+
});
51+
52+
runner.on('fail', function() {
53+
stats.failures++;
54+
});
55+
56+
runner.on('pending', function() {
57+
stats.pending++;
58+
});
59+
60+
runner.on('test end', function() {
61+
stats.tests++;
62+
});
63+
64+
runner.once('end', function() {
65+
stats.end = new Date();
66+
stats.duration = stats.end - stats.start;
67+
});
68+
}
69+
70+
module.exports = createStatsCollector;

test/reporters/helpers.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
scope of this function for the tests to run properly.
99
*/
1010

11+
var createStatsCollector = require('../../lib/stats-collector');
12+
1113
function createMockRunner(runStr, ifStr1, ifStr2, ifStr3, arg1, arg2) {
1214
var runnerFunction = createRunnerFunction(
1315
runStr,
@@ -17,10 +19,12 @@ function createMockRunner(runStr, ifStr1, ifStr2, ifStr3, arg1, arg2) {
1719
arg1,
1820
arg2
1921
);
20-
return {
22+
var mockRunner = {
2123
on: runnerFunction,
2224
once: runnerFunction
2325
};
26+
createStatsCollector(mockRunner);
27+
return mockRunner;
2428
}
2529

2630
function createRunnerFunction(runStr, ifStr1, ifStr2, ifStr3, arg1, arg2) {

test/reporters/list.spec.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ describe('List reporter', function() {
2121
duration: expectedDuration,
2222
slow: function() {}
2323
};
24+
2425
beforeEach(function() {
2526
useColors = Base.useColors;
2627
Base.useColors = false;
@@ -126,7 +127,11 @@ describe('List reporter', function() {
126127
test = {};
127128
runner = createMockRunner('fail', 'fail', null, null, test);
128129
runner.on = runner.once = function(event, callback) {
129-
if (!checked && event === 'fail') {
130+
if (
131+
!checked &&
132+
event === 'fail' &&
133+
callback.toString().includes('stringifyDiffObjs') // target correct fail event callback
134+
) {
130135
err = new Error('fake failure object with actual/expected');
131136
err.actual = actual;
132137
err.expected = expected;

test/reporters/xunit.spec.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ var fs = require('fs');
44
var mkdirp = require('mkdirp');
55
var path = require('path');
66
var assert = require('assert');
7+
var createStatsCollector = require('../../lib/stats-collector');
78
var reporters = require('../../').reporters;
89
var XUnit = reporters.XUnit;
910

1011
describe('XUnit reporter', function() {
1112
var stdout;
1213
var stdoutWrite;
14+
// the runner parameter of the reporter
1315
var runner;
1416

1517
var callbackArgument = null;
@@ -26,6 +28,7 @@ describe('XUnit reporter', function() {
2628
beforeEach(function() {
2729
stdout = [];
2830
runner = {on: function() {}, once: function() {}};
31+
createStatsCollector(runner);
2932
});
3033

3134
describe('if reporter options output is given', function() {
@@ -322,8 +325,6 @@ describe('XUnit reporter', function() {
322325
describe('custom suite name', function() {
323326
// capture the events that the reporter subscribes to
324327
var events;
325-
// the runner parameter of the reporter
326-
var runner;
327328
// capture output lines (will contain the resulting XML of the xunit reporter)
328329
var lines;
329330
// the file stream into which the xunit reporter will write into
@@ -332,13 +333,10 @@ describe('XUnit reporter', function() {
332333
beforeEach(function() {
333334
events = {};
334335

335-
runner = {
336-
on: function(eventName, eventHandler) {
337-
// capture the event handler
338-
events[eventName] = eventHandler;
339-
}
336+
runner.on = runner.once = function(eventName, eventHandler) {
337+
// capture the event handler
338+
events[eventName] = eventHandler;
340339
};
341-
runner.once = runner.on;
342340

343341
lines = [];
344342
fileStream = {

0 commit comments

Comments
 (0)