You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
8.2 KiB
299 lines
8.2 KiB
'use strict'; |
|
|
|
Object.defineProperty(exports, '__esModule', { |
|
value: true |
|
}); |
|
exports.runAndTransformResultsToJestFormat = exports.initialize = void 0; |
|
|
|
var _throat = _interopRequireDefault(require('throat')); |
|
|
|
var _testResult = require('@jest/test-result'); |
|
|
|
var _expect = require('expect'); |
|
|
|
var _jestEach = require('jest-each'); |
|
|
|
var _jestMessageUtil = require('jest-message-util'); |
|
|
|
var _jestSnapshot = require('jest-snapshot'); |
|
|
|
var _ = _interopRequireDefault(require('..')); |
|
|
|
var _run = _interopRequireDefault(require('../run')); |
|
|
|
var _state = require('../state'); |
|
|
|
var _testCaseReportHandler = _interopRequireDefault( |
|
require('../testCaseReportHandler') |
|
); |
|
|
|
var _utils = require('../utils'); |
|
|
|
var _jestExpect = _interopRequireDefault(require('./jestExpect')); |
|
|
|
function _interopRequireDefault(obj) { |
|
return obj && obj.__esModule ? obj : {default: obj}; |
|
} |
|
|
|
/** |
|
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
*/ |
|
const initialize = async ({ |
|
config, |
|
environment, |
|
globalConfig, |
|
localRequire, |
|
parentProcess, |
|
sendMessageToJest, |
|
setGlobalsForRuntime, |
|
testPath |
|
}) => { |
|
if (globalConfig.testTimeout) { |
|
(0, _state.getState)().testTimeout = globalConfig.testTimeout; |
|
} |
|
|
|
const mutex = (0, _throat.default)(globalConfig.maxConcurrency); // @ts-expect-error |
|
|
|
const globalsObject = { |
|
..._.default, |
|
fdescribe: _.default.describe.only, |
|
fit: _.default.it.only, |
|
xdescribe: _.default.describe.skip, |
|
xit: _.default.it.skip, |
|
xtest: _.default.it.skip |
|
}; |
|
|
|
globalsObject.test.concurrent = (test => { |
|
const concurrent = (testName, testFn, timeout) => { |
|
// For concurrent tests we first run the function that returns promise, and then register a |
|
// normal test that will be waiting on the returned promise (when we start the test, the promise |
|
// will already be in the process of execution). |
|
// Unfortunately at this stage there's no way to know if there are any `.only` tests in the suite |
|
// that will result in this test to be skipped, so we'll be executing the promise function anyway, |
|
// even if it ends up being skipped. |
|
const promise = mutex(() => testFn()); // Avoid triggering the uncaught promise rejection handler in case the test errors before |
|
// being awaited on. |
|
|
|
promise.catch(() => {}); |
|
globalsObject.test(testName, () => promise, timeout); |
|
}; |
|
|
|
const only = (testName, testFn, timeout) => { |
|
const promise = mutex(() => testFn()); // eslint-disable-next-line jest/no-focused-tests |
|
|
|
test.only(testName, () => promise, timeout); |
|
}; |
|
|
|
concurrent.only = only; |
|
concurrent.skip = test.skip; |
|
concurrent.each = (0, _jestEach.bind)(test, false); |
|
concurrent.skip.each = (0, _jestEach.bind)(test.skip, false); |
|
only.each = (0, _jestEach.bind)(test.only, false); |
|
return concurrent; |
|
})(globalsObject.test); |
|
|
|
(0, _state.addEventHandler)(eventHandler); |
|
|
|
if (environment.handleTestEvent) { |
|
(0, _state.addEventHandler)(environment.handleTestEvent.bind(environment)); |
|
} |
|
|
|
const runtimeGlobals = { |
|
...globalsObject, |
|
expect: (0, _jestExpect.default)(globalConfig) |
|
}; |
|
setGlobalsForRuntime(runtimeGlobals); |
|
|
|
if (config.injectGlobals) { |
|
Object.assign(environment.global, runtimeGlobals); |
|
} |
|
|
|
await (0, _state.dispatch)({ |
|
name: 'setup', |
|
parentProcess, |
|
runtimeGlobals, |
|
testNamePattern: globalConfig.testNamePattern |
|
}); |
|
|
|
if (config.testLocationInResults) { |
|
await (0, _state.dispatch)({ |
|
name: 'include_test_location_in_result' |
|
}); |
|
} // Jest tests snapshotSerializers in order preceding built-in serializers. |
|
// Therefore, add in reverse because the last added is the first tested. |
|
|
|
config.snapshotSerializers |
|
.concat() |
|
.reverse() |
|
.forEach(path => (0, _jestSnapshot.addSerializer)(localRequire(path))); |
|
const {expand, updateSnapshot} = globalConfig; |
|
const snapshotResolver = await (0, _jestSnapshot.buildSnapshotResolver)( |
|
config, |
|
localRequire |
|
); |
|
const snapshotPath = snapshotResolver.resolveSnapshotPath(testPath); |
|
const snapshotState = new _jestSnapshot.SnapshotState(snapshotPath, { |
|
expand, |
|
prettierPath: config.prettierPath, |
|
snapshotFormat: config.snapshotFormat, |
|
updateSnapshot |
|
}); // @ts-expect-error: snapshotState is a jest extension of `expect` |
|
|
|
(0, _expect.setState)({ |
|
snapshotState, |
|
testPath |
|
}); |
|
(0, _state.addEventHandler)(handleSnapshotStateAfterRetry(snapshotState)); |
|
|
|
if (sendMessageToJest) { |
|
(0, _state.addEventHandler)( |
|
(0, _testCaseReportHandler.default)(testPath, sendMessageToJest) |
|
); |
|
} // Return it back to the outer scope (test runner outside the VM). |
|
|
|
return { |
|
globals: globalsObject, |
|
snapshotState |
|
}; |
|
}; |
|
|
|
exports.initialize = initialize; |
|
|
|
const runAndTransformResultsToJestFormat = async ({ |
|
config, |
|
globalConfig, |
|
testPath |
|
}) => { |
|
const runResult = await (0, _run.default)(); |
|
let numFailingTests = 0; |
|
let numPassingTests = 0; |
|
let numPendingTests = 0; |
|
let numTodoTests = 0; |
|
const assertionResults = runResult.testResults.map(testResult => { |
|
let status; |
|
|
|
if (testResult.status === 'skip') { |
|
status = 'pending'; |
|
numPendingTests += 1; |
|
} else if (testResult.status === 'todo') { |
|
status = 'todo'; |
|
numTodoTests += 1; |
|
} else if (testResult.errors.length) { |
|
status = 'failed'; |
|
numFailingTests += 1; |
|
} else { |
|
status = 'passed'; |
|
numPassingTests += 1; |
|
} |
|
|
|
const ancestorTitles = testResult.testPath.filter( |
|
name => name !== _state.ROOT_DESCRIBE_BLOCK_NAME |
|
); |
|
const title = ancestorTitles.pop(); |
|
return { |
|
ancestorTitles, |
|
duration: testResult.duration, |
|
failureDetails: testResult.errorsDetailed, |
|
failureMessages: testResult.errors, |
|
fullName: title |
|
? ancestorTitles.concat(title).join(' ') |
|
: ancestorTitles.join(' '), |
|
invocations: testResult.invocations, |
|
location: testResult.location, |
|
numPassingAsserts: 0, |
|
status, |
|
title: testResult.testPath[testResult.testPath.length - 1] |
|
}; |
|
}); |
|
let failureMessage = (0, _jestMessageUtil.formatResultsErrors)( |
|
assertionResults, |
|
config, |
|
globalConfig, |
|
testPath |
|
); |
|
let testExecError; |
|
|
|
if (runResult.unhandledErrors.length) { |
|
testExecError = { |
|
message: '', |
|
stack: runResult.unhandledErrors.join('\n') |
|
}; |
|
failureMessage = |
|
(failureMessage || '') + |
|
'\n\n' + |
|
runResult.unhandledErrors |
|
.map(err => |
|
(0, _jestMessageUtil.formatExecError)(err, config, globalConfig) |
|
) |
|
.join('\n'); |
|
} |
|
|
|
await (0, _state.dispatch)({ |
|
name: 'teardown' |
|
}); |
|
return { |
|
...(0, _testResult.createEmptyTestResult)(), |
|
console: undefined, |
|
displayName: config.displayName, |
|
failureMessage, |
|
numFailingTests, |
|
numPassingTests, |
|
numPendingTests, |
|
numTodoTests, |
|
testExecError, |
|
testFilePath: testPath, |
|
testResults: assertionResults |
|
}; |
|
}; |
|
|
|
exports.runAndTransformResultsToJestFormat = runAndTransformResultsToJestFormat; |
|
|
|
const handleSnapshotStateAfterRetry = snapshotState => event => { |
|
switch (event.name) { |
|
case 'test_retry': { |
|
// Clear any snapshot data that occurred in previous test run |
|
snapshotState.clear(); |
|
} |
|
} |
|
}; |
|
|
|
const eventHandler = async event => { |
|
switch (event.name) { |
|
case 'test_start': { |
|
(0, _expect.setState)({ |
|
currentTestName: (0, _utils.getTestID)(event.test) |
|
}); |
|
break; |
|
} |
|
|
|
case 'test_done': { |
|
_addSuppressedErrors(event.test); |
|
|
|
_addExpectedAssertionErrors(event.test); |
|
|
|
break; |
|
} |
|
} |
|
}; |
|
|
|
const _addExpectedAssertionErrors = test => { |
|
const failures = (0, _expect.extractExpectedAssertionsErrors)(); |
|
const errors = failures.map(failure => failure.error); |
|
test.errors = test.errors.concat(errors); |
|
}; // Get suppressed errors from ``jest-matchers`` that weren't throw during |
|
// test execution and add them to the test result, potentially failing |
|
// a passing test. |
|
|
|
const _addSuppressedErrors = test => { |
|
const {suppressedErrors} = (0, _expect.getState)(); |
|
(0, _expect.setState)({ |
|
suppressedErrors: [] |
|
}); |
|
|
|
if (suppressedErrors.length) { |
|
test.errors = test.errors.concat(suppressedErrors); |
|
} |
|
};
|
|
|