mocha 8.1.0 → 8.2.0
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/CHANGELOG.md +83 -0
- package/README.md +2 -0
- package/browser-entry.js +2 -2
- package/lib/cli/cli.js +19 -8
- package/lib/cli/index.js +0 -6
- package/lib/cli/lookup-files.js +37 -31
- package/lib/cli/node-flags.js +6 -7
- package/lib/cli/options.js +5 -4
- package/lib/cli/run-helpers.js +21 -56
- package/lib/cli/run-option-metadata.js +25 -2
- package/lib/cli/run.js +5 -9
- package/lib/cli/watch-run.js +49 -30
- package/lib/errors.js +129 -20
- package/lib/hook.js +14 -9
- package/lib/mocha.js +266 -66
- package/lib/nodejs/buffered-worker-pool.js +1 -3
- package/lib/nodejs/file-unloader.js +15 -0
- package/lib/nodejs/parallel-buffered-runner.js +156 -18
- package/lib/nodejs/reporters/parallel-buffered.js +61 -29
- package/lib/nodejs/serializer.js +15 -7
- package/lib/nodejs/worker.js +9 -12
- package/lib/plugin-loader.js +286 -0
- package/lib/reporters/base.js +3 -3
- package/lib/reporters/json-stream.js +2 -1
- package/lib/reporters/json.js +1 -0
- package/lib/runnable.js +6 -0
- package/lib/runner.js +209 -104
- package/lib/suite.js +34 -15
- package/lib/test.js +6 -2
- package/lib/utils.js +151 -66
- package/mocha.js +10008 -6258
- package/mocha.js.map +1 -1
- package/package.json +68 -56
package/lib/runner.js
CHANGED
|
@@ -8,7 +8,6 @@ var util = require('util');
|
|
|
8
8
|
var EventEmitter = require('events').EventEmitter;
|
|
9
9
|
var Pending = require('./pending');
|
|
10
10
|
var utils = require('./utils');
|
|
11
|
-
var inherits = utils.inherits;
|
|
12
11
|
var debug = require('debug')('mocha:runner');
|
|
13
12
|
var Runnable = require('./runnable');
|
|
14
13
|
var Suite = require('./suite');
|
|
@@ -24,7 +23,7 @@ var dQuote = utils.dQuote;
|
|
|
24
23
|
var sQuote = utils.sQuote;
|
|
25
24
|
var stackFilter = utils.stackTraceFilter();
|
|
26
25
|
var stringify = utils.stringify;
|
|
27
|
-
|
|
26
|
+
|
|
28
27
|
var errors = require('./errors');
|
|
29
28
|
var createInvalidExceptionError = errors.createInvalidExceptionError;
|
|
30
29
|
var createUnsupportedError = errors.createUnsupportedError;
|
|
@@ -128,54 +127,59 @@ var constants = utils.defineConstants(
|
|
|
128
127
|
}
|
|
129
128
|
);
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
if (typeof opts === 'boolean') {
|
|
149
|
-
this._delay = opts;
|
|
150
|
-
opts = {};
|
|
151
|
-
} else {
|
|
152
|
-
this._delay = opts.delay;
|
|
153
|
-
}
|
|
154
|
-
var self = this;
|
|
155
|
-
this._globals = [];
|
|
156
|
-
this._abort = false;
|
|
157
|
-
this.suite = suite;
|
|
158
|
-
this._opts = opts;
|
|
159
|
-
this.state = constants.STATE_IDLE;
|
|
160
|
-
this.total = suite.total();
|
|
161
|
-
this.failures = 0;
|
|
162
|
-
this._eventListeners = [];
|
|
163
|
-
this.on(constants.EVENT_TEST_END, function(test) {
|
|
164
|
-
if (test.type === 'test' && test.retriedTest() && test.parent) {
|
|
165
|
-
var idx =
|
|
166
|
-
test.parent.tests && test.parent.tests.indexOf(test.retriedTest());
|
|
167
|
-
if (idx > -1) test.parent.tests[idx] = test;
|
|
130
|
+
class Runner extends EventEmitter {
|
|
131
|
+
/**
|
|
132
|
+
* Initialize a `Runner` at the Root {@link Suite}, which represents a hierarchy of {@link Suite|Suites} and {@link Test|Tests}.
|
|
133
|
+
*
|
|
134
|
+
* @extends external:EventEmitter
|
|
135
|
+
* @public
|
|
136
|
+
* @class
|
|
137
|
+
* @param {Suite} suite - Root suite
|
|
138
|
+
* @param {Object|boolean} [opts] - Options. If `boolean`, whether or not to delay execution of root suite until ready (for backwards compatibility).
|
|
139
|
+
* @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.
|
|
140
|
+
* @param {boolean} [opts.cleanReferencesAfterRun] - Whether to clean references to test fns and hooks when a suite is done.
|
|
141
|
+
*/
|
|
142
|
+
constructor(suite, opts) {
|
|
143
|
+
super();
|
|
144
|
+
if (opts === undefined) {
|
|
145
|
+
opts = {};
|
|
168
146
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
147
|
+
if (typeof opts === 'boolean') {
|
|
148
|
+
// TODO: deprecate this
|
|
149
|
+
this._delay = opts;
|
|
150
|
+
opts = {};
|
|
151
|
+
} else {
|
|
152
|
+
this._delay = opts.delay;
|
|
153
|
+
}
|
|
154
|
+
var self = this;
|
|
155
|
+
this._globals = [];
|
|
156
|
+
this._abort = false;
|
|
157
|
+
this.suite = suite;
|
|
158
|
+
this._opts = opts;
|
|
159
|
+
this.state = constants.STATE_IDLE;
|
|
160
|
+
this.total = suite.total();
|
|
161
|
+
this.failures = 0;
|
|
162
|
+
/**
|
|
163
|
+
* @type {Map<EventEmitter,Map<string,Set<EventListener>>>}
|
|
164
|
+
*/
|
|
165
|
+
this._eventListeners = new Map();
|
|
166
|
+
this.on(constants.EVENT_TEST_END, function(test) {
|
|
167
|
+
if (test.type === 'test' && test.retriedTest() && test.parent) {
|
|
168
|
+
var idx =
|
|
169
|
+
test.parent.tests && test.parent.tests.indexOf(test.retriedTest());
|
|
170
|
+
if (idx > -1) test.parent.tests[idx] = test;
|
|
171
|
+
}
|
|
172
|
+
self.checkGlobals(test);
|
|
173
|
+
});
|
|
174
|
+
this.on(constants.EVENT_HOOK_END, function(hook) {
|
|
175
|
+
self.checkGlobals(hook);
|
|
176
|
+
});
|
|
177
|
+
this._defaultGrep = /.*/;
|
|
178
|
+
this.grep(this._defaultGrep);
|
|
179
|
+
this.globals(this.globalProps());
|
|
177
180
|
|
|
178
|
-
|
|
181
|
+
this.uncaught = this._uncaught.bind(this);
|
|
182
|
+
}
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
/**
|
|
@@ -186,11 +190,6 @@ function Runner(suite, opts) {
|
|
|
186
190
|
*/
|
|
187
191
|
Runner.immediately = global.setImmediate || process.nextTick;
|
|
188
192
|
|
|
189
|
-
/**
|
|
190
|
-
* Inherit from `EventEmitter.prototype`.
|
|
191
|
-
*/
|
|
192
|
-
inherits(Runner, EventEmitter);
|
|
193
|
-
|
|
194
193
|
/**
|
|
195
194
|
* Replacement for `target.on(eventName, listener)` that does bookkeeping to remove them when this runner instance is disposed.
|
|
196
195
|
* @param {EventEmitter} target - The `EventEmitter`
|
|
@@ -199,33 +198,62 @@ inherits(Runner, EventEmitter);
|
|
|
199
198
|
* @private
|
|
200
199
|
*/
|
|
201
200
|
Runner.prototype._addEventListener = function(target, eventName, listener) {
|
|
201
|
+
debug(
|
|
202
|
+
'_addEventListener(): adding for event %s; %d current listeners',
|
|
203
|
+
eventName,
|
|
204
|
+
target.listenerCount(eventName)
|
|
205
|
+
);
|
|
206
|
+
/* istanbul ignore next */
|
|
207
|
+
if (
|
|
208
|
+
this._eventListeners.has(target) &&
|
|
209
|
+
this._eventListeners.get(target).has(eventName) &&
|
|
210
|
+
this._eventListeners
|
|
211
|
+
.get(target)
|
|
212
|
+
.get(eventName)
|
|
213
|
+
.has(listener)
|
|
214
|
+
) {
|
|
215
|
+
debug(
|
|
216
|
+
'warning: tried to attach duplicate event listener for %s',
|
|
217
|
+
eventName
|
|
218
|
+
);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
202
221
|
target.on(eventName, listener);
|
|
203
|
-
this._eventListeners.
|
|
222
|
+
const targetListeners = this._eventListeners.has(target)
|
|
223
|
+
? this._eventListeners.get(target)
|
|
224
|
+
: new Map();
|
|
225
|
+
const targetEventListeners = targetListeners.has(eventName)
|
|
226
|
+
? targetListeners.get(eventName)
|
|
227
|
+
: new Set();
|
|
228
|
+
targetEventListeners.add(listener);
|
|
229
|
+
targetListeners.set(eventName, targetEventListeners);
|
|
230
|
+
this._eventListeners.set(target, targetListeners);
|
|
204
231
|
};
|
|
205
232
|
|
|
206
233
|
/**
|
|
207
234
|
* Replacement for `target.removeListener(eventName, listener)` that also updates the bookkeeping.
|
|
208
235
|
* @param {EventEmitter} target - The `EventEmitter`
|
|
209
|
-
* @param {string} eventName - The event
|
|
236
|
+
* @param {string} eventName - The event name
|
|
210
237
|
* @param {function} listener - Listener function
|
|
211
238
|
* @private
|
|
212
239
|
*/
|
|
213
240
|
Runner.prototype._removeEventListener = function(target, eventName, listener) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
241
|
+
target.removeListener(eventName, listener);
|
|
242
|
+
|
|
243
|
+
if (this._eventListeners.has(target)) {
|
|
244
|
+
const targetListeners = this._eventListeners.get(target);
|
|
245
|
+
if (targetListeners.has(eventName)) {
|
|
246
|
+
const targetEventListeners = targetListeners.get(eventName);
|
|
247
|
+
targetEventListeners.delete(listener);
|
|
248
|
+
if (!targetEventListeners.size) {
|
|
249
|
+
targetListeners.delete(eventName);
|
|
250
|
+
}
|
|
224
251
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
252
|
+
if (!targetListeners.size) {
|
|
253
|
+
this._eventListeners.delete(target);
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
debug('trying to remove listener for untracked object %s', target);
|
|
229
257
|
}
|
|
230
258
|
};
|
|
231
259
|
|
|
@@ -235,12 +263,14 @@ Runner.prototype._removeEventListener = function(target, eventName, listener) {
|
|
|
235
263
|
*/
|
|
236
264
|
Runner.prototype.dispose = function() {
|
|
237
265
|
this.removeAllListeners();
|
|
238
|
-
this._eventListeners.forEach(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
266
|
+
this._eventListeners.forEach((targetListeners, target) => {
|
|
267
|
+
targetListeners.forEach((targetEventListeners, eventName) => {
|
|
268
|
+
targetEventListeners.forEach(listener => {
|
|
269
|
+
target.removeListener(eventName, listener);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
243
272
|
});
|
|
273
|
+
this._eventListeners.clear();
|
|
244
274
|
};
|
|
245
275
|
|
|
246
276
|
/**
|
|
@@ -976,73 +1006,119 @@ Runner.prototype._uncaught = function(err) {
|
|
|
976
1006
|
* @memberof Runner
|
|
977
1007
|
* @param {Function} fn - Callback when finished
|
|
978
1008
|
* @param {{files: string[], options: Options}} [opts] - For subclasses
|
|
979
|
-
* @
|
|
1009
|
+
* @returns {Runner} Runner instance.
|
|
980
1010
|
*/
|
|
981
|
-
Runner.prototype.run = function(fn, opts) {
|
|
982
|
-
var self = this;
|
|
1011
|
+
Runner.prototype.run = function(fn, opts = {}) {
|
|
983
1012
|
var rootSuite = this.suite;
|
|
1013
|
+
var options = opts.options || {};
|
|
984
1014
|
|
|
1015
|
+
debug('run(): got options: %O', options);
|
|
985
1016
|
fn = fn || function() {};
|
|
986
1017
|
|
|
987
|
-
|
|
1018
|
+
const end = () => {
|
|
1019
|
+
debug('run(): root suite completed; emitting %s', constants.EVENT_RUN_END);
|
|
1020
|
+
this.emit(constants.EVENT_RUN_END);
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
const begin = () => {
|
|
1024
|
+
debug('run(): emitting %s', constants.EVENT_RUN_BEGIN);
|
|
1025
|
+
this.emit(constants.EVENT_RUN_BEGIN);
|
|
1026
|
+
debug('run(): emitted %s', constants.EVENT_RUN_BEGIN);
|
|
1027
|
+
|
|
1028
|
+
this.runSuite(rootSuite, async () => {
|
|
1029
|
+
end();
|
|
1030
|
+
});
|
|
1031
|
+
};
|
|
1032
|
+
|
|
1033
|
+
const prepare = () => {
|
|
988
1034
|
debug('run(): starting');
|
|
989
1035
|
// If there is an `only` filter
|
|
990
1036
|
if (rootSuite.hasOnly()) {
|
|
991
1037
|
rootSuite.filterOnly();
|
|
992
1038
|
debug('run(): filtered exclusive Runnables');
|
|
993
1039
|
}
|
|
994
|
-
|
|
995
|
-
if (
|
|
996
|
-
|
|
1040
|
+
this.state = constants.STATE_RUNNING;
|
|
1041
|
+
if (this._delay) {
|
|
1042
|
+
this.emit(constants.EVENT_DELAY_END);
|
|
997
1043
|
debug('run(): "delay" ended');
|
|
998
1044
|
}
|
|
999
|
-
debug('run(): emitting %s', constants.EVENT_RUN_BEGIN);
|
|
1000
|
-
self.emit(constants.EVENT_RUN_BEGIN);
|
|
1001
|
-
debug('run(): emitted %s', constants.EVENT_RUN_BEGIN);
|
|
1002
1045
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
'run(): root suite completed; emitting %s',
|
|
1006
|
-
constants.EVENT_RUN_END
|
|
1007
|
-
);
|
|
1008
|
-
self.emit(constants.EVENT_RUN_END);
|
|
1009
|
-
debug('run(): emitted %s', constants.EVENT_RUN_END);
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1046
|
+
return begin();
|
|
1047
|
+
};
|
|
1012
1048
|
|
|
1013
1049
|
// references cleanup to avoid memory leaks
|
|
1014
1050
|
if (this._opts.cleanReferencesAfterRun) {
|
|
1015
|
-
this.on(constants.EVENT_SUITE_END,
|
|
1051
|
+
this.on(constants.EVENT_SUITE_END, suite => {
|
|
1016
1052
|
suite.cleanReferences();
|
|
1017
1053
|
});
|
|
1018
1054
|
}
|
|
1019
1055
|
|
|
1020
1056
|
// callback
|
|
1021
1057
|
this.on(constants.EVENT_RUN_END, function() {
|
|
1022
|
-
|
|
1023
|
-
debug(constants.EVENT_RUN_END);
|
|
1058
|
+
this.state = constants.STATE_STOPPED;
|
|
1024
1059
|
debug('run(): emitted %s', constants.EVENT_RUN_END);
|
|
1025
|
-
fn(
|
|
1060
|
+
fn(this.failures);
|
|
1026
1061
|
});
|
|
1027
1062
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1063
|
+
this._removeEventListener(process, 'uncaughtException', this.uncaught);
|
|
1064
|
+
this._removeEventListener(process, 'unhandledRejection', this.uncaught);
|
|
1065
|
+
this._addEventListener(process, 'uncaughtException', this.uncaught);
|
|
1066
|
+
this._addEventListener(process, 'unhandledRejection', this.uncaught);
|
|
1030
1067
|
|
|
1031
1068
|
if (this._delay) {
|
|
1032
1069
|
// for reporters, I guess.
|
|
1033
1070
|
// might be nice to debounce some dots while we wait.
|
|
1034
1071
|
this.emit(constants.EVENT_DELAY_BEGIN, rootSuite);
|
|
1035
|
-
rootSuite.once(EVENT_ROOT_SUITE_RUN,
|
|
1072
|
+
rootSuite.once(EVENT_ROOT_SUITE_RUN, prepare);
|
|
1036
1073
|
debug('run(): waiting for green light due to --delay');
|
|
1037
1074
|
} else {
|
|
1038
|
-
Runner.immediately(
|
|
1039
|
-
start();
|
|
1040
|
-
});
|
|
1075
|
+
Runner.immediately(prepare);
|
|
1041
1076
|
}
|
|
1042
1077
|
|
|
1043
1078
|
return this;
|
|
1044
1079
|
};
|
|
1045
1080
|
|
|
1081
|
+
/**
|
|
1082
|
+
* Toggle partial object linking behavior; used for building object references from
|
|
1083
|
+
* unique ID's. Does nothing in serial mode, because the object references already exist.
|
|
1084
|
+
* Subclasses can implement this (e.g., `ParallelBufferedRunner`)
|
|
1085
|
+
* @abstract
|
|
1086
|
+
* @param {boolean} [value] - If `true`, enable partial object linking, otherwise disable
|
|
1087
|
+
* @returns {Runner}
|
|
1088
|
+
* @chainable
|
|
1089
|
+
* @public
|
|
1090
|
+
* @example
|
|
1091
|
+
* // this reporter needs proper object references when run in parallel mode
|
|
1092
|
+
* class MyReporter() {
|
|
1093
|
+
* constructor(runner) {
|
|
1094
|
+
* this.runner.linkPartialObjects(true)
|
|
1095
|
+
* .on(EVENT_SUITE_BEGIN, suite => {
|
|
1096
|
+
// this Suite may be the same object...
|
|
1097
|
+
* })
|
|
1098
|
+
* .on(EVENT_TEST_BEGIN, test => {
|
|
1099
|
+
* // ...as the `test.parent` property
|
|
1100
|
+
* });
|
|
1101
|
+
* }
|
|
1102
|
+
* }
|
|
1103
|
+
*/
|
|
1104
|
+
Runner.prototype.linkPartialObjects = function(value) {
|
|
1105
|
+
return this;
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
/*
|
|
1109
|
+
* Like {@link Runner#run}, but does not accept a callback and returns a `Promise` instead of a `Runner`.
|
|
1110
|
+
* This function cannot reject; an `unhandledRejection` event will bubble up to the `process` object instead.
|
|
1111
|
+
* @public
|
|
1112
|
+
* @memberof Runner
|
|
1113
|
+
* @param {Object} [opts] - Options for {@link Runner#run}
|
|
1114
|
+
* @returns {Promise<number>} Failure count
|
|
1115
|
+
*/
|
|
1116
|
+
Runner.prototype.runAsync = async function runAsync(opts = {}) {
|
|
1117
|
+
return new Promise(resolve => {
|
|
1118
|
+
this.run(resolve, opts);
|
|
1119
|
+
});
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1046
1122
|
/**
|
|
1047
1123
|
* Cleanly abort execution.
|
|
1048
1124
|
*
|
|
@@ -1057,6 +1133,31 @@ Runner.prototype.abort = function() {
|
|
|
1057
1133
|
return this;
|
|
1058
1134
|
};
|
|
1059
1135
|
|
|
1136
|
+
/**
|
|
1137
|
+
* Returns `true` if Mocha is running in parallel mode. For reporters.
|
|
1138
|
+
*
|
|
1139
|
+
* Subclasses should return an appropriate value.
|
|
1140
|
+
* @public
|
|
1141
|
+
* @returns {false}
|
|
1142
|
+
*/
|
|
1143
|
+
Runner.prototype.isParallelMode = function isParallelMode() {
|
|
1144
|
+
return false;
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* Configures an alternate reporter for worker processes to use. Subclasses
|
|
1149
|
+
* using worker processes should implement this.
|
|
1150
|
+
* @public
|
|
1151
|
+
* @param {string} path - Absolute path to alternate reporter for worker processes to use
|
|
1152
|
+
* @returns {Runner}
|
|
1153
|
+
* @throws When in serial mode
|
|
1154
|
+
* @chainable
|
|
1155
|
+
* @abstract
|
|
1156
|
+
*/
|
|
1157
|
+
Runner.prototype.workerReporter = function() {
|
|
1158
|
+
throw createUnsupportedError('workerReporter() not supported in serial mode');
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1060
1161
|
/**
|
|
1061
1162
|
* Filter leaks with the given globals flagged as `ok`.
|
|
1062
1163
|
*
|
|
@@ -1122,7 +1223,9 @@ function isError(err) {
|
|
|
1122
1223
|
*/
|
|
1123
1224
|
function thrown2Error(err) {
|
|
1124
1225
|
return new Error(
|
|
1125
|
-
|
|
1226
|
+
`the ${utils.canonicalType(err)} ${stringify(
|
|
1227
|
+
err
|
|
1228
|
+
)} was thrown, throw an Error :)`
|
|
1126
1229
|
);
|
|
1127
1230
|
}
|
|
1128
1231
|
|
|
@@ -1133,3 +1236,5 @@ Runner.constants = constants;
|
|
|
1133
1236
|
* @external EventEmitter
|
|
1134
1237
|
* @see {@link https://nodejs.org/api/events.html#events_class_eventemitter}
|
|
1135
1238
|
*/
|
|
1239
|
+
|
|
1240
|
+
module.exports = Runner;
|
package/lib/suite.js
CHANGED
|
@@ -4,14 +4,23 @@
|
|
|
4
4
|
* Module dependencies.
|
|
5
5
|
* @private
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
const {EventEmitter} = require('events');
|
|
8
|
+
const Hook = require('./hook');
|
|
9
|
+
var {
|
|
10
|
+
assignNewMochaID,
|
|
11
|
+
clamp,
|
|
12
|
+
constants: utilsConstants,
|
|
13
|
+
createMap,
|
|
14
|
+
defineConstants,
|
|
15
|
+
getMochaID,
|
|
16
|
+
inherits,
|
|
17
|
+
isString
|
|
18
|
+
} = require('./utils');
|
|
19
|
+
const debug = require('debug')('mocha:suite');
|
|
20
|
+
const milliseconds = require('ms');
|
|
21
|
+
const errors = require('./errors');
|
|
22
|
+
|
|
23
|
+
const {MOCHA_ID_PROP_NAME} = utilsConstants;
|
|
15
24
|
|
|
16
25
|
/**
|
|
17
26
|
* Expose `Suite`.
|
|
@@ -47,8 +56,8 @@ Suite.create = function(parent, title) {
|
|
|
47
56
|
* @param {boolean} [isRoot=false] - Whether this is the root suite.
|
|
48
57
|
*/
|
|
49
58
|
function Suite(title, parentContext, isRoot) {
|
|
50
|
-
if (!
|
|
51
|
-
throw createInvalidArgumentTypeError(
|
|
59
|
+
if (!isString(title)) {
|
|
60
|
+
throw errors.createInvalidArgumentTypeError(
|
|
52
61
|
'Suite argument "title" must be a string. Received type "' +
|
|
53
62
|
typeof title +
|
|
54
63
|
'"',
|
|
@@ -74,11 +83,19 @@ function Suite(title, parentContext, isRoot) {
|
|
|
74
83
|
this._bail = false;
|
|
75
84
|
this._onlyTests = [];
|
|
76
85
|
this._onlySuites = [];
|
|
86
|
+
assignNewMochaID(this);
|
|
87
|
+
|
|
88
|
+
Object.defineProperty(this, 'id', {
|
|
89
|
+
get() {
|
|
90
|
+
return getMochaID(this);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
77
94
|
this.reset();
|
|
78
95
|
|
|
79
96
|
this.on('newListener', function(event) {
|
|
80
97
|
if (deprecatedEvents[event]) {
|
|
81
|
-
|
|
98
|
+
errors.deprecate(
|
|
82
99
|
'Event "' +
|
|
83
100
|
event +
|
|
84
101
|
'" is deprecated. Please let the Mocha team know about your use case: https://git.io/v6Lwm'
|
|
@@ -145,7 +162,7 @@ Suite.prototype.timeout = function(ms) {
|
|
|
145
162
|
// Clamp to range
|
|
146
163
|
var INT_MAX = Math.pow(2, 31) - 1;
|
|
147
164
|
var range = [0, INT_MAX];
|
|
148
|
-
ms =
|
|
165
|
+
ms = clamp(ms, range);
|
|
149
166
|
|
|
150
167
|
debug('timeout %d', ms);
|
|
151
168
|
this._timeout = parseInt(ms, 10);
|
|
@@ -579,11 +596,13 @@ Suite.prototype.serialize = function serialize() {
|
|
|
579
596
|
$$fullTitle: this.fullTitle(),
|
|
580
597
|
$$isPending: this.isPending(),
|
|
581
598
|
root: this.root,
|
|
582
|
-
title: this.title
|
|
599
|
+
title: this.title,
|
|
600
|
+
id: this.id,
|
|
601
|
+
parent: this.parent ? {[MOCHA_ID_PROP_NAME]: this.parent.id} : null
|
|
583
602
|
};
|
|
584
603
|
};
|
|
585
604
|
|
|
586
|
-
var constants =
|
|
605
|
+
var constants = defineConstants(
|
|
587
606
|
/**
|
|
588
607
|
* {@link Suite}-related constants.
|
|
589
608
|
* @public
|
|
@@ -671,6 +690,6 @@ var deprecatedEvents = Object.keys(constants)
|
|
|
671
690
|
.reduce(function(acc, constant) {
|
|
672
691
|
acc[constants[constant]] = true;
|
|
673
692
|
return acc;
|
|
674
|
-
},
|
|
693
|
+
}, createMap());
|
|
675
694
|
|
|
676
695
|
Suite.constants = constants;
|
package/lib/test.js
CHANGED
|
@@ -5,6 +5,8 @@ var errors = require('./errors');
|
|
|
5
5
|
var createInvalidArgumentTypeError = errors.createInvalidArgumentTypeError;
|
|
6
6
|
var isString = utils.isString;
|
|
7
7
|
|
|
8
|
+
const {MOCHA_ID_PROP_NAME} = utils.constants;
|
|
9
|
+
|
|
8
10
|
module.exports = Test;
|
|
9
11
|
|
|
10
12
|
/**
|
|
@@ -98,12 +100,14 @@ Test.prototype.serialize = function serialize() {
|
|
|
98
100
|
duration: this.duration,
|
|
99
101
|
err: this.err,
|
|
100
102
|
parent: {
|
|
101
|
-
$$fullTitle: this.parent.fullTitle()
|
|
103
|
+
$$fullTitle: this.parent.fullTitle(),
|
|
104
|
+
[MOCHA_ID_PROP_NAME]: this.parent.id
|
|
102
105
|
},
|
|
103
106
|
speed: this.speed,
|
|
104
107
|
state: this.state,
|
|
105
108
|
title: this.title,
|
|
106
109
|
type: this.type,
|
|
107
|
-
file: this.file
|
|
110
|
+
file: this.file,
|
|
111
|
+
[MOCHA_ID_PROP_NAME]: this.id
|
|
108
112
|
};
|
|
109
113
|
};
|