301 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			301 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | Object.defineProperty(exports, '__esModule', { | ||
|  |   value: true | ||
|  | }); | ||
|  | exports.runAndTransformResultsToJestFormat = exports.initialize = void 0; | ||
|  | 
 | ||
|  | var _expect = require('expect'); | ||
|  | 
 | ||
|  | var _jestMessageUtil = require('jest-message-util'); | ||
|  | 
 | ||
|  | var _jestSnapshot = require('jest-snapshot'); | ||
|  | 
 | ||
|  | var _throat = _interopRequireDefault(require('throat')); | ||
|  | 
 | ||
|  | var _state = require('../state'); | ||
|  | 
 | ||
|  | var _utils = require('../utils'); | ||
|  | 
 | ||
|  | var _run = _interopRequireDefault(require('../run')); | ||
|  | 
 | ||
|  | var _ = _interopRequireDefault(require('..')); | ||
|  | 
 | ||
|  | function _interopRequireDefault(obj) { | ||
|  |   return obj && obj.__esModule ? obj : {default: obj}; | ||
|  | } | ||
|  | 
 | ||
|  | var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; | ||
|  | var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; | ||
|  | var Promise = global[Symbol.for('jest-native-promise')] || global.Promise; | ||
|  | 
 | ||
|  | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
|  |   try { | ||
|  |     var info = gen[key](arg); | ||
|  |     var value = info.value; | ||
|  |   } catch (error) { | ||
|  |     reject(error); | ||
|  |     return; | ||
|  |   } | ||
|  |   if (info.done) { | ||
|  |     resolve(value); | ||
|  |   } else { | ||
|  |     Promise.resolve(value).then(_next, _throw); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function _asyncToGenerator(fn) { | ||
|  |   return function() { | ||
|  |     var self = this, | ||
|  |       args = arguments; | ||
|  |     return new Promise(function(resolve, reject) { | ||
|  |       var gen = fn.apply(self, args); | ||
|  |       function _next(value) { | ||
|  |         asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); | ||
|  |       } | ||
|  |       function _throw(err) { | ||
|  |         asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); | ||
|  |       } | ||
|  |       _next(undefined); | ||
|  |     }); | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | const initialize = ({ | ||
|  |   config, | ||
|  |   environment, | ||
|  |   getPrettier, | ||
|  |   getBabelTraverse, | ||
|  |   globalConfig, | ||
|  |   localRequire, | ||
|  |   parentProcess, | ||
|  |   testPath | ||
|  | }) => { | ||
|  |   const mutex = (0, _throat.default)(globalConfig.maxConcurrency); | ||
|  |   Object.assign(global, _.default); | ||
|  |   global.xit = global.it.skip; | ||
|  |   global.xtest = global.it.skip; | ||
|  |   global.xdescribe = global.describe.skip; | ||
|  |   global.fit = global.it.only; | ||
|  |   global.fdescribe = global.describe.only; | ||
|  | 
 | ||
|  |   global.test.concurrent = (test => { | ||
|  |     const concurrent = (testName, testFn, timeout) => { | ||
|  |       // For concurrent tests we first run the function that returns promise, and then register a
 | ||
|  |       // nomral 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()); | ||
|  |       global.test(testName, () => promise, timeout); | ||
|  |     }; | ||
|  | 
 | ||
|  |     concurrent.only = (testName, testFn, timeout) => { | ||
|  |       const promise = mutex(() => testFn()); // eslint-disable-next-line jest/no-focused-tests
 | ||
|  | 
 | ||
|  |       test.only(testName, () => promise, timeout); | ||
|  |     }; | ||
|  | 
 | ||
|  |     concurrent.skip = test.skip; | ||
|  |     return concurrent; | ||
|  |   })(global.test); | ||
|  | 
 | ||
|  |   (0, _state.addEventHandler)(eventHandler); | ||
|  | 
 | ||
|  |   if (environment.handleTestEvent) { | ||
|  |     (0, _state.addEventHandler)(environment.handleTestEvent.bind(environment)); | ||
|  |   } | ||
|  | 
 | ||
|  |   (0, _state.dispatch)({ | ||
|  |     name: 'setup', | ||
|  |     parentProcess, | ||
|  |     testNamePattern: globalConfig.testNamePattern | ||
|  |   }); | ||
|  | 
 | ||
|  |   if (config.testLocationInResults) { | ||
|  |     (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 = globalConfig.expand, | ||
|  |     updateSnapshot = globalConfig.updateSnapshot; | ||
|  |   const snapshotResolver = (0, _jestSnapshot.buildSnapshotResolver)(config); | ||
|  |   const snapshotPath = snapshotResolver.resolveSnapshotPath(testPath); | ||
|  |   const snapshotState = new _jestSnapshot.SnapshotState(snapshotPath, { | ||
|  |     expand, | ||
|  |     getBabelTraverse, | ||
|  |     getPrettier, | ||
|  |     updateSnapshot | ||
|  |   }); | ||
|  |   (0, _expect.setState)({ | ||
|  |     snapshotState, | ||
|  |     testPath | ||
|  |   }); // Return it back to the outer scope (test runner outside the VM).
 | ||
|  | 
 | ||
|  |   return { | ||
|  |     globals: _.default, | ||
|  |     snapshotState | ||
|  |   }; | ||
|  | }; | ||
|  | 
 | ||
|  | exports.initialize = initialize; | ||
|  | 
 | ||
|  | const runAndTransformResultsToJestFormat = | ||
|  |   /*#__PURE__*/ | ||
|  |   (function() { | ||
|  |     var _ref = _asyncToGenerator(function*({config, globalConfig, testPath}) { | ||
|  |       const runResult = yield (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, | ||
|  |           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'); | ||
|  |       } | ||
|  | 
 | ||
|  |       (0, _state.dispatch)({ | ||
|  |         name: 'teardown' | ||
|  |       }); | ||
|  |       return { | ||
|  |         console: undefined, | ||
|  |         displayName: config.displayName, | ||
|  |         failureMessage, | ||
|  |         leaks: false, | ||
|  |         // That's legacy code, just adding it so Flow is happy.
 | ||
|  |         numFailingTests, | ||
|  |         numPassingTests, | ||
|  |         numPendingTests, | ||
|  |         numTodoTests, | ||
|  |         openHandles: [], | ||
|  |         perfStats: { | ||
|  |           // populated outside
 | ||
|  |           end: 0, | ||
|  |           start: 0 | ||
|  |         }, | ||
|  |         skipped: false, | ||
|  |         snapshot: { | ||
|  |           added: 0, | ||
|  |           fileDeleted: false, | ||
|  |           matched: 0, | ||
|  |           unchecked: 0, | ||
|  |           uncheckedKeys: [], | ||
|  |           unmatched: 0, | ||
|  |           updated: 0 | ||
|  |         }, | ||
|  |         sourceMaps: {}, | ||
|  |         testExecError, | ||
|  |         testFilePath: testPath, | ||
|  |         testResults: assertionResults | ||
|  |       }; | ||
|  |     }); | ||
|  | 
 | ||
|  |     return function runAndTransformResultsToJestFormat(_x) { | ||
|  |       return _ref.apply(this, arguments); | ||
|  |     }; | ||
|  |   })(); | ||
|  | 
 | ||
|  | exports.runAndTransformResultsToJestFormat = runAndTransformResultsToJestFormat; | ||
|  | 
 | ||
|  | const eventHandler = 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 _getState = (0, _expect.getState)(), | ||
|  |     suppressedErrors = _getState.suppressedErrors; | ||
|  | 
 | ||
|  |   (0, _expect.setState)({ | ||
|  |     suppressedErrors: [] | ||
|  |   }); | ||
|  | 
 | ||
|  |   if (suppressedErrors.length) { | ||
|  |     test.errors = test.errors.concat(suppressedErrors); | ||
|  |   } | ||
|  | }; |