forked from jestjs/jest
/
testWorker.ts
110 lines (100 loc) 路 2.83 KB
/
testWorker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* 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.
*
*/
import exit = require('exit');
import type {SerializableError, TestResult} from '@jest/test-result';
import type {Config} from '@jest/types';
import {ModuleMap, SerializableModuleMap} from 'jest-haste-map';
import {separateMessageFromStack} from 'jest-message-util';
import type Resolver from 'jest-resolve';
import Runtime from 'jest-runtime';
import {messageParent} from 'jest-worker';
import runTest from './runTest';
import type {
ErrorWithCode,
TestFileEvent,
TestRunnerSerializedContext,
} from './types';
export type SerializableResolver = {
config: Config.ProjectConfig;
serializableModuleMap: SerializableModuleMap;
};
type WorkerData = {
config: Config.ProjectConfig;
globalConfig: Config.GlobalConfig;
path: Config.Path;
context?: TestRunnerSerializedContext;
};
// Make sure uncaught errors are logged before we exit.
process.on('uncaughtException', err => {
console.error(err.stack);
exit(1);
});
const formatError = (error: string | ErrorWithCode): SerializableError => {
if (typeof error === 'string') {
const {message, stack} = separateMessageFromStack(error);
return {
message,
stack,
type: 'Error',
};
}
return {
code: error.code || undefined,
message: error.message,
stack: error.stack,
type: 'Error',
};
};
const resolvers = new Map<string, Resolver>();
const getResolver = (config: Config.ProjectConfig) => {
const resolver = resolvers.get(config.name);
if (!resolver) {
throw new Error('Cannot find resolver for: ' + config.name);
}
return resolver;
};
export function setup(setupData: {
serializableResolvers: Array<SerializableResolver>;
}): void {
// Module maps that will be needed for the test runs are passed.
for (const {
config,
serializableModuleMap,
} of setupData.serializableResolvers) {
const moduleMap = ModuleMap.fromJSON(serializableModuleMap);
resolvers.set(config.name, Runtime.createResolver(config, moduleMap));
}
}
const sendMessageToJest: TestFileEvent = (eventName, args) => {
messageParent([eventName, args]);
};
export async function worker({
config,
globalConfig,
path,
context,
}: WorkerData): Promise<TestResult> {
try {
return await runTest(
path,
globalConfig,
config,
getResolver(config),
context && {
...context,
changedFiles: context.changedFiles && new Set(context.changedFiles),
sourcesRelatedToTestsInChangedFiles:
context.sourcesRelatedToTestsInChangedFiles &&
new Set(context.sourcesRelatedToTestsInChangedFiles),
},
sendMessageToJest,
);
} catch (error) {
throw formatError(error);
}
}