feat(testrunner): migrate from events to a delegate (#1647)
This allows an async handler for each event that can be awaited. Drive-by: merge TestPass into TestRunner.
This commit is contained in:
parent
f216ab98e7
commit
823f961d8d
|
|
@ -33,13 +33,10 @@ class Reporter {
|
||||||
this._verbose = verbose;
|
this._verbose = verbose;
|
||||||
this._summary = summary;
|
this._summary = summary;
|
||||||
this._testCounter = 0;
|
this._testCounter = 0;
|
||||||
runner.on('started', this._onStarted.bind(this));
|
runner.setDelegate(this);
|
||||||
runner.on('finished', this._onFinished.bind(this));
|
|
||||||
runner.on('teststarted', this._onTestStarted.bind(this));
|
|
||||||
runner.on('testfinished', this._onTestFinished.bind(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onStarted(testRuns) {
|
onStarted(testRuns) {
|
||||||
this._testCounter = 0;
|
this._testCounter = 0;
|
||||||
this._timestamp = Date.now();
|
this._timestamp = Date.now();
|
||||||
const allTests = this._runner.tests();
|
const allTests = this._runner.tests();
|
||||||
|
|
@ -83,7 +80,7 @@ class Reporter {
|
||||||
console.log('');
|
console.log('');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onFinished(result) {
|
onFinished(result) {
|
||||||
this._printTestResults(result);
|
this._printTestResults(result);
|
||||||
if (!result.ok())
|
if (!result.ok())
|
||||||
this._printFailedResult(result);
|
this._printFailedResult(result);
|
||||||
|
|
@ -149,10 +146,10 @@ class Reporter {
|
||||||
console.log(`Finished in ${colors.yellow(seconds)} seconds`);
|
console.log(`Finished in ${colors.yellow(seconds)} seconds`);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onTestStarted(testRun) {
|
onTestRunStarted(testRun) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onTestFinished(testRun) {
|
onTestRunFinished(testRun) {
|
||||||
if (this._verbose) {
|
if (this._verbose) {
|
||||||
++this._testCounter;
|
++this._testCounter;
|
||||||
this._printVerboseTestRunResult(this._testCounter, testRun);
|
this._printVerboseTestRunResult(this._testCounter, testRun);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
|
||||||
const {SourceMapSupport} = require('./SourceMapSupport');
|
const {SourceMapSupport} = require('./SourceMapSupport');
|
||||||
const debug = require('debug');
|
const debug = require('debug');
|
||||||
const Location = require('./Location');
|
const Location = require('./Location');
|
||||||
|
|
@ -368,8 +367,8 @@ class Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestWorker {
|
class TestWorker {
|
||||||
constructor(testPass, workerId, parallelIndex) {
|
constructor(testRunner, workerId, parallelIndex) {
|
||||||
this._testPass = testPass;
|
this._testRunner = testRunner;
|
||||||
this._state = { parallelIndex };
|
this._state = { parallelIndex };
|
||||||
this._environmentStack = [];
|
this._environmentStack = [];
|
||||||
this._terminating = false;
|
this._terminating = false;
|
||||||
|
|
@ -474,7 +473,7 @@ class TestWorker {
|
||||||
testRun._error = await promise;
|
testRun._error = await promise;
|
||||||
this._runningTestTerminate = null;
|
this._runningTestTerminate = null;
|
||||||
if (testRun._error && testRun._error.stack)
|
if (testRun._error && testRun._error.stack)
|
||||||
await this._testPass._runner._sourceMapSupport.rewriteStackTraceWithSourceMaps(testRun._error);
|
await this._testRunner._sourceMapSupport.rewriteStackTraceWithSourceMaps(testRun._error);
|
||||||
if (!testRun._error)
|
if (!testRun._error)
|
||||||
testRun._result = TestResult.Ok;
|
testRun._result = TestResult.Ok;
|
||||||
else if (testRun._error === TimeoutError)
|
else if (testRun._error === TimeoutError)
|
||||||
|
|
@ -497,7 +496,7 @@ class TestWorker {
|
||||||
|
|
||||||
async _runHook(testRun, hook, fullName, passTest = false) {
|
async _runHook(testRun, hook, fullName, passTest = false) {
|
||||||
await this._willStartHook(hook, fullName);
|
await this._willStartHook(hook, fullName);
|
||||||
const timeout = this._testPass._runner._timeout;
|
const timeout = this._testRunner._timeout;
|
||||||
const { promise, terminate } = runUserCallback(hook.body, timeout, passTest ? [this._state, testRun.test()] : [this._state]);
|
const { promise, terminate } = runUserCallback(hook.body, timeout, passTest ? [this._state, testRun.test()] : [this._state]);
|
||||||
this._runningHookTerminate = terminate;
|
this._runningHookTerminate = terminate;
|
||||||
let error = await promise;
|
let error = await promise;
|
||||||
|
|
@ -518,7 +517,7 @@ class TestWorker {
|
||||||
error = null;
|
error = null;
|
||||||
} else {
|
} else {
|
||||||
if (error.stack)
|
if (error.stack)
|
||||||
await this._testPass._runner._sourceMapSupport.rewriteStackTraceWithSourceMaps(error);
|
await this._testRunner._sourceMapSupport.rewriteStackTraceWithSourceMaps(error);
|
||||||
message = `${hook.location.toDetailedString()} - FAILED while running "${hook.name}" in suite "${fullName}": `;
|
message = `${hook.location.toDetailedString()} - FAILED while running "${hook.name}" in suite "${fullName}": `;
|
||||||
}
|
}
|
||||||
await this._didFailHook(hook, fullName, message, error);
|
await this._didFailHook(hook, fullName, message, error);
|
||||||
|
|
@ -534,13 +533,13 @@ class TestWorker {
|
||||||
async _willStartTestRun(testRun) {
|
async _willStartTestRun(testRun) {
|
||||||
testRun._startTimestamp = Date.now();
|
testRun._startTimestamp = Date.now();
|
||||||
testRun._workerId = this._workerId;
|
testRun._workerId = this._workerId;
|
||||||
this._testPass._runner.emit(TestRunner.Events.TestStarted, testRun);
|
await this._testRunner._delegate.onTestRunStarted(testRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _didFinishTestRun(testRun) {
|
async _didFinishTestRun(testRun) {
|
||||||
testRun._endTimestamp = Date.now();
|
testRun._endTimestamp = Date.now();
|
||||||
testRun._workerId = this._workerId;
|
testRun._workerId = this._workerId;
|
||||||
this._testPass._runner.emit(TestRunner.Events.TestFinished, testRun);
|
await this._testRunner._delegate.onTestRunFinished(testRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _willStartTestBody(testRun) {
|
async _willStartTestBody(testRun) {
|
||||||
|
|
@ -558,8 +557,8 @@ class TestWorker {
|
||||||
async _didFailHook(hook, fullName, message, error) {
|
async _didFailHook(hook, fullName, message, error) {
|
||||||
debug('testrunner:hook')(`[${this._workerId}] "${hook.name}" FAILED for "${fullName}" (${hook.location})`);
|
debug('testrunner:hook')(`[${this._workerId}] "${hook.name}" FAILED for "${fullName}" (${hook.location})`);
|
||||||
if (message)
|
if (message)
|
||||||
this._testPass._result.addError(message, error, this);
|
this._testRunner._result.addError(message, error, this);
|
||||||
this._testPass._result.setResult(TestResult.Crashed, message);
|
this._testRunner._result.setResult(TestResult.Crashed, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _didCompleteHook(hook, fullName) {
|
async _didCompleteHook(hook, fullName) {
|
||||||
|
|
@ -575,108 +574,8 @@ class TestWorker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestPass {
|
class TestRunner {
|
||||||
constructor(runner, parallel, breakOnFailure) {
|
|
||||||
this._runner = runner;
|
|
||||||
this._workers = [];
|
|
||||||
this._nextWorkerId = 1;
|
|
||||||
this._parallel = parallel;
|
|
||||||
this._breakOnFailure = breakOnFailure;
|
|
||||||
this._errors = [];
|
|
||||||
this._result = new Result();
|
|
||||||
this._terminating = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(testRuns) {
|
|
||||||
const terminations = [
|
|
||||||
createTermination.call(this, 'SIGINT', TestResult.Terminated, 'SIGINT received'),
|
|
||||||
createTermination.call(this, 'SIGHUP', TestResult.Terminated, 'SIGHUP received'),
|
|
||||||
createTermination.call(this, 'SIGTERM', TestResult.Terminated, 'SIGTERM received'),
|
|
||||||
createTermination.call(this, 'unhandledRejection', TestResult.Crashed, 'UNHANDLED PROMISE REJECTION'),
|
|
||||||
createTermination.call(this, 'uncaughtException', TestResult.Crashed, 'UNHANDLED ERROR'),
|
|
||||||
];
|
|
||||||
for (const termination of terminations)
|
|
||||||
process.on(termination.event, termination.handler);
|
|
||||||
|
|
||||||
this._result = new Result();
|
|
||||||
this._result.runs = testRuns;
|
|
||||||
|
|
||||||
const parallel = Math.min(this._parallel, testRuns.length);
|
|
||||||
const workerPromises = [];
|
|
||||||
for (let i = 0; i < parallel; ++i) {
|
|
||||||
const initialTestRunIndex = i * Math.floor(testRuns.length / parallel);
|
|
||||||
workerPromises.push(this._runWorker(initialTestRunIndex, testRuns, i));
|
|
||||||
}
|
|
||||||
await Promise.all(workerPromises);
|
|
||||||
|
|
||||||
for (const termination of terminations)
|
|
||||||
process.removeListener(termination.event, termination.handler);
|
|
||||||
|
|
||||||
if (testRuns.some(run => run.isFailure()))
|
|
||||||
this._result.setResult(TestResult.Failed, '');
|
|
||||||
return this._result;
|
|
||||||
|
|
||||||
function createTermination(event, result, message) {
|
|
||||||
return {
|
|
||||||
event,
|
|
||||||
message,
|
|
||||||
handler: error => this._terminate(result, message, event === 'SIGTERM', event.startsWith('SIG') ? null : error)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async _runWorker(testRunIndex, testRuns, parallelIndex) {
|
|
||||||
let worker = new TestWorker(this, this._nextWorkerId++, parallelIndex);
|
|
||||||
this._workers[parallelIndex] = worker;
|
|
||||||
while (!this._terminating) {
|
|
||||||
let skipped = 0;
|
|
||||||
while (skipped < testRuns.length && testRuns[testRunIndex]._result !== null) {
|
|
||||||
testRunIndex = (testRunIndex + 1) % testRuns.length;
|
|
||||||
skipped++;
|
|
||||||
}
|
|
||||||
const testRun = testRuns[testRunIndex];
|
|
||||||
if (testRun._result !== null) {
|
|
||||||
// All tests have been run.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark as running so that other workers do not run it again.
|
|
||||||
testRun._result = 'running';
|
|
||||||
await worker.run(testRun);
|
|
||||||
if (testRun.isFailure()) {
|
|
||||||
// Something went wrong during test run, let's use a fresh worker.
|
|
||||||
await worker.shutdown();
|
|
||||||
if (this._breakOnFailure) {
|
|
||||||
const message = `Terminating because a test has failed and |testRunner.breakOnFailure| is enabled`;
|
|
||||||
await this._terminate(TestResult.Terminated, message, false /* force */, null /* error */);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
worker = new TestWorker(this, this._nextWorkerId++, parallelIndex);
|
|
||||||
this._workers[parallelIndex] = worker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await worker.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
async _terminate(result, message, force, error) {
|
|
||||||
debug('testrunner')(`TERMINATED result = ${result}, message = ${message}`);
|
|
||||||
this._terminating = true;
|
|
||||||
for (const worker of this._workers)
|
|
||||||
worker.terminate(force /* terminateHooks */);
|
|
||||||
this._result.setResult(result, message);
|
|
||||||
if (this._result.message === 'SIGINT received' && message === 'SIGTERM received')
|
|
||||||
this._result.message = message;
|
|
||||||
if (error) {
|
|
||||||
if (error.stack)
|
|
||||||
await this._runner._sourceMapSupport.rewriteStackTraceWithSourceMaps(error);
|
|
||||||
this._result.addError(message, error, this._workers.length === 1 ? this._workers[0] : null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestRunner extends EventEmitter {
|
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super();
|
|
||||||
const {
|
const {
|
||||||
timeout = 10 * 1000, // Default timeout is 10 seconds.
|
timeout = 10 * 1000, // Default timeout is 10 seconds.
|
||||||
parallel = 1,
|
parallel = 1,
|
||||||
|
|
@ -697,6 +596,17 @@ class TestRunner extends EventEmitter {
|
||||||
this._suiteAttributes = new Map();
|
this._suiteAttributes = new Map();
|
||||||
this._testModifiers = new Map();
|
this._testModifiers = new Map();
|
||||||
this._testAttributes = new Map();
|
this._testAttributes = new Map();
|
||||||
|
this._nextWorkerId = 1;
|
||||||
|
this._workers = [];
|
||||||
|
this._terminating = false;
|
||||||
|
this._result = null;
|
||||||
|
|
||||||
|
this._delegate = {
|
||||||
|
async onStarted(testRuns) {},
|
||||||
|
async onFinished(result) {},
|
||||||
|
async onTestRunStarted(testRun) {},
|
||||||
|
async onTestRunFinished(testRun) {},
|
||||||
|
};
|
||||||
|
|
||||||
this.beforeAll = (callback) => this._currentEnvironment.beforeAll(callback);
|
this.beforeAll = (callback) => this._currentEnvironment.beforeAll(callback);
|
||||||
this.beforeEach = (callback) => this._currentEnvironment.beforeEach(callback);
|
this.beforeEach = (callback) => this._currentEnvironment.beforeEach(callback);
|
||||||
|
|
@ -785,6 +695,10 @@ class TestRunner extends EventEmitter {
|
||||||
this._suiteAttributes.set(name, callback);
|
this._suiteAttributes.set(name, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDelegate(delegate) {
|
||||||
|
this._delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
async run(options = {}) {
|
async run(options = {}) {
|
||||||
const { totalTimeout = 0 } = options;
|
const { totalTimeout = 0 } = options;
|
||||||
const testRuns = [];
|
const testRuns = [];
|
||||||
|
|
@ -795,31 +709,115 @@ class TestRunner extends EventEmitter {
|
||||||
for (let i = 0; i < repeat; i++)
|
for (let i = 0; i < repeat; i++)
|
||||||
testRuns.push(new TestRun(test));
|
testRuns.push(new TestRun(test));
|
||||||
}
|
}
|
||||||
this.emit(TestRunner.Events.Started, testRuns);
|
|
||||||
|
|
||||||
let result;
|
this._result = new Result();
|
||||||
|
|
||||||
if (this._crashIfTestsAreFocusedOnCI && process.env.CI && this.hasFocusedTestsOrSuites()) {
|
if (this._crashIfTestsAreFocusedOnCI && process.env.CI && this.hasFocusedTestsOrSuites()) {
|
||||||
result = new Result();
|
await this._delegate.onStarted([]);
|
||||||
result.setResult(TestResult.Crashed, '"focused" tests or suites are probitted on CI');
|
this._result.setResult(TestResult.Crashed, '"focused" tests or suites are probitted on CI');
|
||||||
|
await this._delegate.onFinished(this._result);
|
||||||
} else {
|
} else {
|
||||||
this._runningPass = new TestPass(this, this._parallel, this._breakOnFailure);
|
await this._delegate.onStarted(testRuns);
|
||||||
|
this._result.runs = testRuns;
|
||||||
|
|
||||||
let timeoutId;
|
let timeoutId;
|
||||||
if (totalTimeout) {
|
if (totalTimeout) {
|
||||||
timeoutId = setTimeout(() => {
|
timeoutId = setTimeout(() => {
|
||||||
this._runningPass._terminate(TestResult.Terminated, `Total timeout of ${totalTimeout}ms reached.`, true /* force */, null /* error */);
|
this._terminate(TestResult.Terminated, `Total timeout of ${totalTimeout}ms reached.`, true /* force */, null /* error */);
|
||||||
}, totalTimeout);
|
}, totalTimeout);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
result = await this._runningPass.run(testRuns).catch(e => { console.error(e); throw e; });
|
const terminations = [
|
||||||
} finally {
|
createTermination.call(this, 'SIGINT', TestResult.Terminated, 'SIGINT received'),
|
||||||
this._runningPass = null;
|
createTermination.call(this, 'SIGHUP', TestResult.Terminated, 'SIGHUP received'),
|
||||||
clearTimeout(timeoutId);
|
createTermination.call(this, 'SIGTERM', TestResult.Terminated, 'SIGTERM received'),
|
||||||
|
createTermination.call(this, 'unhandledRejection', TestResult.Crashed, 'UNHANDLED PROMISE REJECTION'),
|
||||||
|
createTermination.call(this, 'uncaughtException', TestResult.Crashed, 'UNHANDLED ERROR'),
|
||||||
|
];
|
||||||
|
for (const termination of terminations)
|
||||||
|
process.on(termination.event, termination.handler);
|
||||||
|
|
||||||
|
const parallel = Math.min(this._parallel, testRuns.length);
|
||||||
|
const workerPromises = [];
|
||||||
|
for (let i = 0; i < parallel; ++i) {
|
||||||
|
const initialTestRunIndex = i * Math.floor(testRuns.length / parallel);
|
||||||
|
workerPromises.push(this._runWorker(initialTestRunIndex, testRuns, i));
|
||||||
|
}
|
||||||
|
await Promise.all(workerPromises);
|
||||||
|
|
||||||
|
for (const termination of terminations)
|
||||||
|
process.removeListener(termination.event, termination.handler);
|
||||||
|
|
||||||
|
if (testRuns.some(run => run.isFailure()))
|
||||||
|
this._result.setResult(TestResult.Failed, '');
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
await this._delegate.onFinished(this._result);
|
||||||
|
|
||||||
|
function createTermination(event, result, message) {
|
||||||
|
return {
|
||||||
|
event,
|
||||||
|
message,
|
||||||
|
handler: error => this._terminate(result, message, event === 'SIGTERM', event.startsWith('SIG') ? null : error),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.emit(TestRunner.Events.Finished, result);
|
|
||||||
|
const result = this._result;
|
||||||
|
this._result = null;
|
||||||
|
this._workers = [];
|
||||||
|
this._terminating = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _runWorker(testRunIndex, testRuns, parallelIndex) {
|
||||||
|
let worker = new TestWorker(this, this._nextWorkerId++, parallelIndex);
|
||||||
|
this._workers[parallelIndex] = worker;
|
||||||
|
while (!this._terminating) {
|
||||||
|
let skipped = 0;
|
||||||
|
while (skipped < testRuns.length && testRuns[testRunIndex]._result !== null) {
|
||||||
|
testRunIndex = (testRunIndex + 1) % testRuns.length;
|
||||||
|
skipped++;
|
||||||
|
}
|
||||||
|
const testRun = testRuns[testRunIndex];
|
||||||
|
if (testRun._result !== null) {
|
||||||
|
// All tests have been run.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as running so that other workers do not run it again.
|
||||||
|
testRun._result = 'running';
|
||||||
|
await worker.run(testRun);
|
||||||
|
if (testRun.isFailure()) {
|
||||||
|
// Something went wrong during test run, let's use a fresh worker.
|
||||||
|
await worker.shutdown();
|
||||||
|
if (this._breakOnFailure) {
|
||||||
|
const message = `Terminating because a test has failed and |testRunner.breakOnFailure| is enabled`;
|
||||||
|
await this._terminate(TestResult.Terminated, message, false /* force */, null /* error */);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
worker = new TestWorker(this, this._nextWorkerId++, parallelIndex);
|
||||||
|
this._workers[parallelIndex] = worker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await worker.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _terminate(result, message, force, error) {
|
||||||
|
debug('testrunner')(`TERMINATED result = ${result}, message = ${message}`);
|
||||||
|
this._terminating = true;
|
||||||
|
for (const worker of this._workers)
|
||||||
|
worker.terminate(force /* terminateHooks */);
|
||||||
|
this._result.setResult(result, message);
|
||||||
|
if (this._result.message === 'SIGINT received' && message === 'SIGTERM received')
|
||||||
|
this._result.message = message;
|
||||||
|
if (error) {
|
||||||
|
if (error.stack)
|
||||||
|
await this._sourceMapSupport.rewriteStackTraceWithSourceMaps(error);
|
||||||
|
this._result.addError(message, error, this._workers.length === 1 ? this._workers[0] : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_testsToRun() {
|
_testsToRun() {
|
||||||
if (!this.hasFocusedTestsOrSuites())
|
if (!this.hasFocusedTestsOrSuites())
|
||||||
return this._tests;
|
return this._tests;
|
||||||
|
|
@ -844,9 +842,9 @@ class TestRunner extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async terminate() {
|
async terminate() {
|
||||||
if (!this._runningPass)
|
if (!this._result)
|
||||||
return;
|
return;
|
||||||
await this._runningPass._terminate(TestResult.Terminated, 'Terminated with |TestRunner.terminate()| call', true /* force */, null /* error */);
|
await this._terminate(TestResult.Terminated, 'Terminated with |TestRunner.terminate()| call', true /* force */, null /* error */);
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout() {
|
timeout() {
|
||||||
|
|
@ -877,11 +875,4 @@ class TestRunner extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRunner.Events = {
|
|
||||||
Started: 'started',
|
|
||||||
Finished: 'finished',
|
|
||||||
TestStarted: 'teststarted',
|
|
||||||
TestFinished: 'testfinished',
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = TestRunner;
|
module.exports = TestRunner;
|
||||||
|
|
|
||||||
|
|
@ -795,8 +795,8 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('TestRunner Events', () => {
|
describe('TestRunner delegate', () => {
|
||||||
it('should emit events in proper order', async() => {
|
it('should call delegate methpds in proper order', async() => {
|
||||||
const log = [];
|
const log = [];
|
||||||
const t = newTestRunner();
|
const t = newTestRunner();
|
||||||
t.beforeAll(() => log.push('beforeAll'));
|
t.beforeAll(() => log.push('beforeAll'));
|
||||||
|
|
@ -804,10 +804,12 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||||
t.it('test#1', () => log.push('test#1'));
|
t.it('test#1', () => log.push('test#1'));
|
||||||
t.afterEach(() => log.push('afterEach'));
|
t.afterEach(() => log.push('afterEach'));
|
||||||
t.afterAll(() => log.push('afterAll'));
|
t.afterAll(() => log.push('afterAll'));
|
||||||
t.on('started', () => log.push('E:started'));
|
t.setDelegate({
|
||||||
t.on('teststarted', () => log.push('E:teststarted'));
|
onStarted: () => log.push('E:started'),
|
||||||
t.on('testfinished', () => log.push('E:testfinished'));
|
onTestRunStarted: () => log.push('E:teststarted'),
|
||||||
t.on('finished', () => log.push('E:finished'));
|
onTestRunFinished: () => log.push('E:testfinished'),
|
||||||
|
onFinished: () => log.push('E:finished'),
|
||||||
|
});
|
||||||
await t.run();
|
await t.run();
|
||||||
expect(log).toEqual([
|
expect(log).toEqual([
|
||||||
'E:started',
|
'E:started',
|
||||||
|
|
@ -821,10 +823,15 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||||
'E:finished',
|
'E:finished',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
it('should emit finish event with result', async() => {
|
it('should call onFinished with result', async() => {
|
||||||
const t = newTestRunner();
|
const t = newTestRunner();
|
||||||
const [result] = await Promise.all([
|
const [result] = await Promise.all([
|
||||||
new Promise(x => t.once('finished', x)),
|
new Promise(x => t.setDelegate({
|
||||||
|
onStarted() {},
|
||||||
|
onFinished(result) { x(result); },
|
||||||
|
onTestRunStarted() {},
|
||||||
|
onTestRunFinished() {},
|
||||||
|
})),
|
||||||
t.run(),
|
t.run(),
|
||||||
]);
|
]);
|
||||||
expect(result.result).toBe('ok');
|
expect(result.result).toBe('ok');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue