134 lines
3.7 KiB
JavaScript
134 lines
3.7 KiB
JavaScript
/**
|
|
* "Buffered" reporter used internally by a worker process when running in parallel mode.
|
|
* @module reporters/parallel-buffered
|
|
* @private
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
const {
|
|
EVENT_SUITE_BEGIN,
|
|
EVENT_SUITE_END,
|
|
EVENT_TEST_FAIL,
|
|
EVENT_TEST_PASS,
|
|
EVENT_TEST_PENDING,
|
|
EVENT_TEST_BEGIN,
|
|
EVENT_TEST_END,
|
|
EVENT_TEST_RETRY,
|
|
EVENT_DELAY_BEGIN,
|
|
EVENT_DELAY_END,
|
|
EVENT_HOOK_BEGIN,
|
|
EVENT_HOOK_END,
|
|
EVENT_RUN_END
|
|
} = require('../../runner').constants;
|
|
const {SerializableEvent, SerializableWorkerResult} = require('../serializer');
|
|
const debug = require('debug')('mocha:reporters:buffered');
|
|
const Base = require('../../reporters/base');
|
|
|
|
/**
|
|
* List of events to listen to; these will be buffered and sent
|
|
* when `Mocha#run` is complete (via {@link ParallelBuffered#done}).
|
|
*/
|
|
const EVENT_NAMES = [
|
|
EVENT_SUITE_BEGIN,
|
|
EVENT_SUITE_END,
|
|
EVENT_TEST_BEGIN,
|
|
EVENT_TEST_PENDING,
|
|
EVENT_TEST_FAIL,
|
|
EVENT_TEST_PASS,
|
|
EVENT_TEST_RETRY,
|
|
EVENT_TEST_END,
|
|
EVENT_HOOK_BEGIN,
|
|
EVENT_HOOK_END
|
|
];
|
|
|
|
/**
|
|
* Like {@link EVENT_NAMES}, except we expect these events to only be emitted
|
|
* by the `Runner` once.
|
|
*/
|
|
const ONCE_EVENT_NAMES = [EVENT_DELAY_BEGIN, EVENT_DELAY_END];
|
|
|
|
/**
|
|
* The `ParallelBuffered` reporter is for use by concurrent runs. Instead of outputting
|
|
* to `STDOUT`, etc., it retains a list of events it receives and hands these
|
|
* off to the callback passed into {@link Mocha#run}. That callback will then
|
|
* return the data to the main process.
|
|
* @private
|
|
*/
|
|
class ParallelBuffered extends Base {
|
|
/**
|
|
* Listens for {@link Runner} events and retains them in an `events` instance prop.
|
|
* @param {Runner} runner
|
|
*/
|
|
constructor(runner, opts) {
|
|
super(runner, opts);
|
|
|
|
/**
|
|
* Retained list of events emitted from the {@link Runner} instance.
|
|
* @type {BufferedEvent[]}
|
|
* @memberOf Buffered
|
|
*/
|
|
const events = (this.events = []);
|
|
|
|
/**
|
|
* mapping of event names to listener functions we've created,
|
|
* so we can cleanly _remove_ them from the runner once it's completed.
|
|
*/
|
|
const listeners = new Map();
|
|
|
|
/**
|
|
* Creates a listener for event `eventName` and adds it to the `listeners`
|
|
* map. This is a defensive measure, so that we don't a) leak memory or b)
|
|
* remove _other_ listeners that may not be associated with this reporter.
|
|
* @param {string} eventName - Event name
|
|
*/
|
|
const createListener = eventName =>
|
|
listeners
|
|
.set(eventName, (runnable, err) => {
|
|
events.push(SerializableEvent.create(eventName, runnable, err));
|
|
})
|
|
.get(eventName);
|
|
|
|
EVENT_NAMES.forEach(evt => {
|
|
runner.on(evt, createListener(evt));
|
|
});
|
|
ONCE_EVENT_NAMES.forEach(evt => {
|
|
runner.once(evt, createListener(evt));
|
|
});
|
|
|
|
runner.once(EVENT_RUN_END, () => {
|
|
debug('received EVENT_RUN_END');
|
|
listeners.forEach((listener, evt) => {
|
|
runner.removeListener(evt, listener);
|
|
listeners.delete(evt);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Calls the {@link Mocha#run} callback (`callback`) with the test failure
|
|
* count and the array of {@link BufferedEvent} objects. Resets the array.
|
|
* @param {number} failures - Number of failed tests
|
|
* @param {Function} callback - The callback passed to {@link Mocha#run}.
|
|
*/
|
|
done(failures, callback) {
|
|
callback(SerializableWorkerResult.create(this.events, failures));
|
|
this.events = []; // defensive
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Serializable event data from a `Runner`. Keys of the `data` property
|
|
* beginning with `__` will be converted into a function which returns the value
|
|
* upon deserialization.
|
|
* @typedef {Object} BufferedEvent
|
|
* @property {string} name - Event name
|
|
* @property {object} data - Event parameters
|
|
*/
|
|
|
|
module.exports = ParallelBuffered;
|