@modern-js/plugin-testing 1.5.6 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/dist/js/modern/base/config/index.js +18 -0
- package/dist/js/modern/base/config/patches/assetsModule.js +11 -0
- package/dist/js/modern/base/config/patches/filemock.js +1 -0
- package/dist/js/modern/base/config/patches/index.js +13 -0
- package/dist/js/modern/base/config/patches/transformer.js +49 -0
- package/dist/js/modern/base/config/resolver.js +15 -0
- package/dist/js/modern/base/config/testConfigOperator.js +86 -0
- package/dist/js/modern/base/config/transformer/babelTransformer.js +12 -0
- package/dist/js/modern/base/hook.js +7 -0
- package/dist/js/modern/base/index.js +6 -0
- package/dist/js/modern/base/runJest.js +94 -0
- package/dist/js/modern/base/types/index.js +0 -0
- package/dist/js/modern/base/utils.js +59 -0
- package/dist/js/modern/cli/bff/app.js +22 -0
- package/dist/js/modern/cli/bff/constant.js +1 -0
- package/dist/js/modern/cli/bff/env.js +28 -0
- package/dist/js/modern/cli/bff/index.js +110 -0
- package/dist/js/modern/cli/bff/mockAPI.js +109 -0
- package/dist/js/modern/cli/bff/setup.js +33 -0
- package/dist/js/modern/cli/bff/utils/index.js +25 -0
- package/dist/js/modern/cli/index.js +2 -2
- package/dist/js/modern/cli/test.js +1 -1
- package/dist/js/modern/runtime-testing/base.js +1 -1
- package/dist/js/modern/runtime-testing/request.js +17 -0
- package/dist/js/node/base/config/index.js +31 -0
- package/dist/js/node/base/config/patches/assetsModule.js +20 -0
- package/dist/js/node/base/config/patches/filemock.js +8 -0
- package/dist/js/node/base/config/patches/index.js +24 -0
- package/dist/js/node/base/config/patches/transformer.js +58 -0
- package/dist/js/node/base/config/resolver.js +20 -0
- package/dist/js/node/base/config/testConfigOperator.js +93 -0
- package/dist/js/node/base/config/transformer/babelTransformer.js +23 -0
- package/dist/js/node/base/hook.js +18 -0
- package/dist/js/node/base/index.js +73 -0
- package/dist/js/node/base/runJest.js +109 -0
- package/dist/js/node/base/types/index.js +0 -0
- package/dist/js/node/base/utils.js +79 -0
- package/dist/js/node/cli/bff/app.js +34 -0
- package/dist/js/node/cli/bff/constant.js +8 -0
- package/dist/js/node/cli/bff/env.js +42 -0
- package/dist/js/node/cli/bff/index.js +129 -0
- package/dist/js/node/cli/bff/mockAPI.js +124 -0
- package/dist/js/node/cli/bff/setup.js +41 -0
- package/dist/js/node/cli/bff/utils/index.js +38 -0
- package/dist/js/node/cli/index.js +7 -7
- package/dist/js/node/cli/test.js +2 -2
- package/dist/js/node/runtime-testing/base.js +2 -2
- package/dist/js/node/runtime-testing/request.js +24 -0
- package/dist/js/treeshaking/base/config/index.js +40 -0
- package/dist/js/treeshaking/base/config/patches/assetsModule.js +11 -0
- package/dist/js/treeshaking/base/config/patches/filemock.js +1 -0
- package/dist/js/treeshaking/base/config/patches/index.js +85 -0
- package/dist/js/treeshaking/base/config/patches/transformer.js +45 -0
- package/dist/js/treeshaking/base/config/resolver.js +17 -0
- package/dist/js/treeshaking/base/config/testConfigOperator.js +91 -0
- package/dist/js/treeshaking/base/config/transformer/babelTransformer.js +12 -0
- package/dist/js/treeshaking/base/hook.js +7 -0
- package/dist/js/treeshaking/base/index.js +6 -0
- package/dist/js/treeshaking/base/runJest.js +194 -0
- package/dist/js/treeshaking/base/types/index.js +0 -0
- package/dist/js/treeshaking/base/utils.js +60 -0
- package/dist/js/treeshaking/cli/bff/app.js +47 -0
- package/dist/js/treeshaking/cli/bff/constant.js +1 -0
- package/dist/js/treeshaking/cli/bff/env.js +98 -0
- package/dist/js/treeshaking/cli/bff/index.js +145 -0
- package/dist/js/treeshaking/cli/bff/mockAPI.js +113 -0
- package/dist/js/treeshaking/cli/bff/setup.js +33 -0
- package/dist/js/treeshaking/cli/bff/utils/index.js +22 -0
- package/dist/js/treeshaking/cli/index.js +2 -2
- package/dist/js/treeshaking/cli/test.js +1 -1
- package/dist/js/treeshaking/runtime-testing/base.js +1 -1
- package/dist/js/treeshaking/runtime-testing/request.js +24 -0
- package/dist/types/base/config/index.d.ts +124 -0
- package/dist/types/base/config/patches/assetsModule.d.ts +6 -0
- package/dist/types/base/config/patches/filemock.d.ts +3 -0
- package/dist/types/base/config/patches/index.d.ts +2 -0
- package/dist/types/base/config/patches/transformer.d.ts +6 -0
- package/dist/types/base/config/resolver.d.ts +1 -0
- package/dist/types/base/config/testConfigOperator.d.ts +248 -0
- package/dist/types/base/config/transformer/babelTransformer.d.ts +2 -0
- package/dist/types/base/hook.d.ts +13 -0
- package/dist/types/base/index.d.ts +6 -0
- package/dist/types/base/runJest.d.ts +22 -0
- package/dist/types/base/types/index.d.ts +1 -0
- package/dist/types/base/utils.d.ts +12 -0
- package/dist/types/cli/bff/app.d.ts +6 -0
- package/dist/types/cli/bff/constant.d.ts +1 -0
- package/dist/types/cli/bff/env.d.ts +6 -0
- package/dist/types/cli/bff/index.d.ts +19 -0
- package/dist/types/cli/bff/mockAPI.d.ts +3 -0
- package/dist/types/cli/bff/setup.d.ts +1 -0
- package/dist/types/cli/bff/utils/index.d.ts +1 -0
- package/dist/types/cli/index.d.ts +1 -1
- package/dist/types/runtime-testing/base.d.ts +1 -1
- package/dist/types/runtime-testing/request.d.ts +4 -0
- package/package.json +23 -10
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,43 @@
|
|
1
1
|
# @modern-js/plugin-testing
|
2
2
|
|
3
|
+
## 1.6.0
|
4
|
+
|
5
|
+
### Minor Changes
|
6
|
+
|
7
|
+
- 10f4283: chore(testing): merge `@modern-js/testing-plugin-bff` to `@modern-js/plugin-testing`
|
8
|
+
|
9
|
+
chore(testing): 合并 `@modern-js/testing-plugin-bff` 到 `@modern-js/plugin-testing`
|
10
|
+
|
11
|
+
- 10f4283: chore(testing): delete `@modern-js/bff-utils`
|
12
|
+
|
13
|
+
chore(testing): 删除 `@modern-js/bff-utils`
|
14
|
+
|
15
|
+
- 10f4283: chore(testing): merge `@modern-js/testing` to `@modern-js/plugin-testing`
|
16
|
+
|
17
|
+
chore(testing): 合并 `@modern-js/testing` 到 `@modern-js/plugin-testing`
|
18
|
+
|
19
|
+
## 1.5.7
|
20
|
+
|
21
|
+
### Patch Changes
|
22
|
+
|
23
|
+
- 77a8e9e: fix: remove bff-utils
|
24
|
+
- Updated dependencies [77a8e9e]
|
25
|
+
- Updated dependencies [550e2bd]
|
26
|
+
- Updated dependencies [87eb9f8]
|
27
|
+
- Updated dependencies [43b2224]
|
28
|
+
- Updated dependencies [2b06fe3]
|
29
|
+
- Updated dependencies [3050acc]
|
30
|
+
- Updated dependencies [f29e9ba]
|
31
|
+
- Updated dependencies [2dacc89]
|
32
|
+
- Updated dependencies [338496c]
|
33
|
+
- Updated dependencies [a90bc96]
|
34
|
+
- @modern-js/testing-plugin-bff@1.5.0
|
35
|
+
- @modern-js/bff-utils@1.3.0
|
36
|
+
- @modern-js/webpack@1.11.3
|
37
|
+
- @modern-js/runtime-core@1.5.2
|
38
|
+
- @modern-js/utils@1.7.9
|
39
|
+
- @modern-js/testing@1.5.4
|
40
|
+
|
3
41
|
## 1.5.6
|
4
42
|
|
5
43
|
### Patch Changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { applyPatches } from "./patches";
|
2
|
+
import { TestConfigOperator } from "./testConfigOperator";
|
3
|
+
/**
|
4
|
+
* Parse jest config
|
5
|
+
*/
|
6
|
+
|
7
|
+
const getJestUtils = testConfig => {
|
8
|
+
const testOperator = new TestConfigOperator(testConfig);
|
9
|
+
return testOperator;
|
10
|
+
};
|
11
|
+
|
12
|
+
const patchConfig = async testOperator => {
|
13
|
+
await applyPatches(testOperator);
|
14
|
+
return testOperator.jestConfig;
|
15
|
+
};
|
16
|
+
|
17
|
+
export const DEFAULT_RESOLVER_PATH = require.resolve("./resolver");
|
18
|
+
export { getJestUtils, patchConfig };
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/**
|
2
|
+
* Merge config from testConfig.jest
|
3
|
+
*/
|
4
|
+
export const patchAssetsModule = testOperator => {
|
5
|
+
testOperator.mergeJestConfig({
|
6
|
+
moduleNameMapper: {
|
7
|
+
'\\.(css|less|scss|sass)$': require.resolve('identity-obj-proxy'),
|
8
|
+
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': require.resolve("./filemock.js")
|
9
|
+
}
|
10
|
+
});
|
11
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export default 'test-file-stub';
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { patchTransformer } from "./transformer";
|
2
|
+
import { patchAssetsModule } from "./assetsModule";
|
3
|
+
|
4
|
+
const _applyPatches = async (patches, testOperator) => {
|
5
|
+
for (const patch of patches) {
|
6
|
+
await patch(testOperator);
|
7
|
+
}
|
8
|
+
};
|
9
|
+
|
10
|
+
const patches = [patchTransformer, patchAssetsModule];
|
11
|
+
export const applyPatches = async testConfig => {
|
12
|
+
await _applyPatches(patches, testConfig);
|
13
|
+
};
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { readCompilerOptions } from "../../utils";
|
2
|
+
|
3
|
+
const resolveTsCompilerOptions = () => {
|
4
|
+
const tsCompilerOptions = readCompilerOptions() || {};
|
5
|
+
const {
|
6
|
+
jsx
|
7
|
+
} = tsCompilerOptions;
|
8
|
+
|
9
|
+
if (!jsx) {
|
10
|
+
return null;
|
11
|
+
}
|
12
|
+
|
13
|
+
tsCompilerOptions.jsx = 'react-jsx';
|
14
|
+
return tsCompilerOptions;
|
15
|
+
};
|
16
|
+
/**
|
17
|
+
* Map `TestConfig.transformer` to jest config
|
18
|
+
*/
|
19
|
+
|
20
|
+
|
21
|
+
export const patchTransformer = testOperator => {
|
22
|
+
const {
|
23
|
+
transformer
|
24
|
+
} = testOperator.testConfig;
|
25
|
+
|
26
|
+
if (transformer === 'babel-jest') {
|
27
|
+
testOperator.mergeJestConfig({
|
28
|
+
transform: {
|
29
|
+
'\\.[jt]sx?$': require.resolve("../transformer/babelTransformer")
|
30
|
+
}
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
if (transformer === 'ts-jest') {
|
35
|
+
testOperator.mergeJestConfig({
|
36
|
+
transform: {
|
37
|
+
'\\.[jt]sx?$': require.resolve('ts-jest')
|
38
|
+
}
|
39
|
+
});
|
40
|
+
const compilerOptions = resolveTsCompilerOptions();
|
41
|
+
compilerOptions && testOperator.mergeJestConfig({
|
42
|
+
globals: {
|
43
|
+
'ts-jest': {
|
44
|
+
tsconfig: compilerOptions
|
45
|
+
}
|
46
|
+
}
|
47
|
+
});
|
48
|
+
}
|
49
|
+
};
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import enhanceResolve from 'enhanced-resolve';
|
2
|
+
const resolver = enhanceResolve.create.sync({
|
3
|
+
conditionNames: ['require', 'node', 'default'],
|
4
|
+
extensions: ['.js', '.json', '.node', '.ts', '.tsx']
|
5
|
+
});
|
6
|
+
|
7
|
+
const shouldResolveByEnhance = url => /^@[^/]+\/[^/]+\/.*/.test(url);
|
8
|
+
|
9
|
+
module.exports = function (request, options) {
|
10
|
+
if (shouldResolveByEnhance(request)) {
|
11
|
+
return resolver(options.basedir, request);
|
12
|
+
}
|
13
|
+
|
14
|
+
return options.defaultResolver(request, options);
|
15
|
+
};
|
@@ -0,0 +1,86 @@
|
|
1
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
2
|
+
|
3
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
4
|
+
|
5
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
6
|
+
|
7
|
+
import { merge } from '@modern-js/utils/lodash';
|
8
|
+
|
9
|
+
class TestConfigOperator {
|
10
|
+
constructor(testConfig) {
|
11
|
+
_defineProperty(this, "_testConfig", void 0);
|
12
|
+
|
13
|
+
_defineProperty(this, "_jestConfig", void 0);
|
14
|
+
|
15
|
+
_defineProperty(this, "userJestConfig", void 0);
|
16
|
+
|
17
|
+
_defineProperty(this, "defaultTestConfig", {
|
18
|
+
transformer: 'babel-jest'
|
19
|
+
});
|
20
|
+
|
21
|
+
this._testConfig = testConfig;
|
22
|
+
this._jestConfig = {};
|
23
|
+
this.userJestConfig = testConfig.jest;
|
24
|
+
this.initial();
|
25
|
+
}
|
26
|
+
|
27
|
+
initial() {
|
28
|
+
this._testConfig = merge({}, this.defaultTestConfig, this.testConfig);
|
29
|
+
}
|
30
|
+
|
31
|
+
get jestConfig() {
|
32
|
+
return this._jestConfig;
|
33
|
+
}
|
34
|
+
|
35
|
+
get testConfig() {
|
36
|
+
return this._testConfig;
|
37
|
+
}
|
38
|
+
|
39
|
+
mergeJestConfig(sourceConfig) {
|
40
|
+
this._jestConfig = merge({}, this._jestConfig, sourceConfig);
|
41
|
+
}
|
42
|
+
|
43
|
+
setJestUserConfig() {
|
44
|
+
const {
|
45
|
+
userJestConfig
|
46
|
+
} = this;
|
47
|
+
|
48
|
+
if (typeof userJestConfig === 'object') {
|
49
|
+
this.setJestConfig(userJestConfig);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
setJestConfig(sourceConfig, options) {
|
54
|
+
if (options) {
|
55
|
+
const {
|
56
|
+
force
|
57
|
+
} = options;
|
58
|
+
|
59
|
+
if (force) {
|
60
|
+
this._jestConfig = sourceConfig;
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
this._jestConfig = _objectSpread(_objectSpread({}, this._jestConfig), sourceConfig);
|
66
|
+
}
|
67
|
+
|
68
|
+
getFinalConfig() {
|
69
|
+
const {
|
70
|
+
userJestConfig
|
71
|
+
} = this;
|
72
|
+
|
73
|
+
if (!userJestConfig) {
|
74
|
+
return this._jestConfig;
|
75
|
+
}
|
76
|
+
|
77
|
+
if (typeof userJestConfig === 'function') {
|
78
|
+
return userJestConfig(this._jestConfig);
|
79
|
+
}
|
80
|
+
|
81
|
+
return this.jestConfig;
|
82
|
+
}
|
83
|
+
|
84
|
+
}
|
85
|
+
|
86
|
+
export { TestConfigOperator };
|
@@ -0,0 +1,12 @@
|
|
1
|
+
var _babelJest$createTran;
|
2
|
+
|
3
|
+
import babelJest from 'babel-jest';
|
4
|
+
const babelTransformer = (_babelJest$createTran = babelJest.createTransformer) === null || _babelJest$createTran === void 0 ? void 0 : _babelJest$createTran.call(babelJest, {
|
5
|
+
presets: [[require.resolve('@modern-js/babel-preset-app'), {
|
6
|
+
appDirectory: process.cwd(),
|
7
|
+
modules: 'cjs'
|
8
|
+
}]],
|
9
|
+
configFile: false,
|
10
|
+
babelrc: false
|
11
|
+
});
|
12
|
+
export default babelTransformer;
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { createAsyncPipeline, createParallelWorkflow } from '@modern-js/plugin';
|
2
|
+
export const jestConfigHook = createAsyncPipeline();
|
3
|
+
export const afterTestHook = createParallelWorkflow();
|
4
|
+
export const testingHooks = {
|
5
|
+
jestConfig: createAsyncPipeline(),
|
6
|
+
afterTest: createParallelWorkflow()
|
7
|
+
};
|
@@ -0,0 +1,6 @@
|
|
1
|
+
export { runTest, runJest } from "./runJest";
|
2
|
+
export { getModuleNameMapper } from "./utils";
|
3
|
+
export { DEFAULT_RESOLVER_PATH } from "./config";
|
4
|
+
export { TestConfigOperator } from "./config/testConfigOperator";
|
5
|
+
export { testingHooks } from "./hook";
|
6
|
+
export * from "./types";
|
@@ -0,0 +1,94 @@
|
|
1
|
+
/**
|
2
|
+
* @file run jest by nodejs API
|
3
|
+
* @description
|
4
|
+
* Jest does not provide node API to run jest.
|
5
|
+
* The followed code is inspired by
|
6
|
+
* https://github.com/facebook/jest/blob/fdc74af37235354e077edeeee8aa2d1a4a863032/packages/jest-cli/src/cli/index.ts#L21
|
7
|
+
*/
|
8
|
+
import yargs from 'yargs/yargs';
|
9
|
+
import { runCLI } from 'jest';
|
10
|
+
import { chalk } from '@modern-js/utils';
|
11
|
+
import { getJestUtils, patchConfig } from "./config";
|
12
|
+
import { debug } from "./utils";
|
13
|
+
|
14
|
+
const buildArgv = async (rawArgv, config) => {
|
15
|
+
const argv = await yargs(rawArgv).argv;
|
16
|
+
const result = {
|
17
|
+
$0: argv.$0,
|
18
|
+
_: argv._.slice(1)
|
19
|
+
};
|
20
|
+
Object.keys(argv).forEach(key => {
|
21
|
+
if (key.includes('-') || key === '_') {
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
result[key] = argv[key];
|
26
|
+
});
|
27
|
+
|
28
|
+
if (config) {
|
29
|
+
result.config = JSON.stringify(config);
|
30
|
+
}
|
31
|
+
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
|
35
|
+
const readResultsAndExit = (result, globalConfig) => {
|
36
|
+
const code = !result || result.success ? 0 : globalConfig.testFailureExitCode; // Only exit if needed
|
37
|
+
|
38
|
+
process.on('exit', () => {
|
39
|
+
if (typeof code === 'number' && code !== 0) {
|
40
|
+
process.exitCode = code;
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
if (globalConfig.forceExit) {
|
45
|
+
if (!globalConfig.detectOpenHandles) {
|
46
|
+
console.warn(`${chalk.bold('Force exiting Jest: ')}Have you considered using \`--detectOpenHandles\` to detect ` + `async operations that kept running after all tests finished?`);
|
47
|
+
} // eslint-disable-next-line no-process-exit
|
48
|
+
|
49
|
+
|
50
|
+
process.exit(code);
|
51
|
+
} else if (!globalConfig.detectOpenHandles) {
|
52
|
+
setTimeout(() => {
|
53
|
+
console.warn(chalk.yellow.bold('Jest did not exit one second after the test run has completed.\n\n') + chalk.yellow('This usually means that there are asynchronous operations that ' + "weren't stopped in your tests. Consider running Jest with " + '`--detectOpenHandles` to troubleshoot this issue.'));
|
54
|
+
}, 1000).unref();
|
55
|
+
}
|
56
|
+
};
|
57
|
+
/**
|
58
|
+
* Node API: execute jest
|
59
|
+
*/
|
60
|
+
|
61
|
+
|
62
|
+
export async function runJest(config, pwd = process.cwd()) {
|
63
|
+
try {
|
64
|
+
const argvConfig = await buildArgv(process.argv.slice(2), config);
|
65
|
+
const {
|
66
|
+
results,
|
67
|
+
globalConfig
|
68
|
+
} = await runCLI(argvConfig, [pwd]);
|
69
|
+
readResultsAndExit(results, globalConfig);
|
70
|
+
} catch (e) {
|
71
|
+
console.error(chalk.red((e === null || e === void 0 ? void 0 : e.stack) || e)); // eslint-disable-next-line no-process-exit
|
72
|
+
|
73
|
+
process.exit(1);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
/**
|
77
|
+
* Node API: run test
|
78
|
+
*/
|
79
|
+
|
80
|
+
export async function runTest(api, config, pwd = process.cwd()) {
|
81
|
+
process.env.NODE_ENV = 'test';
|
82
|
+
const jestUtils = getJestUtils(config);
|
83
|
+
await patchConfig(jestUtils); // 确保用户设置的配置可以被插件处理,比如设置在 projects 中
|
84
|
+
|
85
|
+
jestUtils.setJestUserConfig();
|
86
|
+
const hookRunners = api.useHookRunners();
|
87
|
+
const testConfigOperator = await hookRunners.jestConfig(jestUtils, {
|
88
|
+
onLast: input => input
|
89
|
+
});
|
90
|
+
const finalConfig = testConfigOperator.getFinalConfig();
|
91
|
+
debug('Jest config:', finalConfig);
|
92
|
+
await runJest(finalConfig, pwd);
|
93
|
+
await hookRunners.afterTest();
|
94
|
+
}
|
File without changes
|
@@ -0,0 +1,59 @@
|
|
1
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
2
|
+
|
3
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
4
|
+
|
5
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
6
|
+
|
7
|
+
import fs from 'fs';
|
8
|
+
import path from 'path';
|
9
|
+
import { createDebugger } from '@modern-js/utils';
|
10
|
+
export const debug = createDebugger('test');
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Read `compilerOptions` in the current pwd's tsconfig.json file
|
14
|
+
*/
|
15
|
+
export const readCompilerOptions = (pwd = process.cwd(), filename = 'tsconfig.json') => {
|
16
|
+
let tsConfig = {};
|
17
|
+
let extendedCompilerOptions = {};
|
18
|
+
let tsconfigFile = '';
|
19
|
+
|
20
|
+
try {
|
21
|
+
const maybeTsconfigFile = path.join(pwd, filename);
|
22
|
+
|
23
|
+
if (fs.existsSync(maybeTsconfigFile)) {
|
24
|
+
tsconfigFile = maybeTsconfigFile;
|
25
|
+
} else {
|
26
|
+
tsconfigFile = require.resolve(filename);
|
27
|
+
}
|
28
|
+
|
29
|
+
({
|
30
|
+
config: tsConfig
|
31
|
+
} = require('typescript').parseConfigFileTextToJson(tsconfigFile, fs.readFileSync(tsconfigFile, 'utf8')));
|
32
|
+
} catch (e) {
|
33
|
+
return {};
|
34
|
+
}
|
35
|
+
|
36
|
+
if (tsConfig.extends) {
|
37
|
+
extendedCompilerOptions = readCompilerOptions(path.dirname(tsconfigFile), tsConfig.extends);
|
38
|
+
}
|
39
|
+
|
40
|
+
return _objectSpread(_objectSpread({}, extendedCompilerOptions), tsConfig.compilerOptions);
|
41
|
+
};
|
42
|
+
export const getModuleNameMapper = alias => Object.keys(alias).reduce((memo, cur) => {
|
43
|
+
const aliasValue = Array.isArray(alias[cur]) ? alias[cur] : [alias[cur]];
|
44
|
+
const isFile = aliasValue.some(s => s.endsWith('.js')); // It's special for if using @modern-js/runtime alias other module @modern-js/runtime/model would not work.
|
45
|
+
|
46
|
+
if (cur === '@modern-js/runtime$') {
|
47
|
+
memo[`.+${cur}`] = aliasValue[0];
|
48
|
+
return memo;
|
49
|
+
}
|
50
|
+
|
51
|
+
if (isFile) {
|
52
|
+
memo[cur] = aliasValue[0];
|
53
|
+
}
|
54
|
+
|
55
|
+
const key = `^${cur}/(.*)$`;
|
56
|
+
const value = path.normalize(`${aliasValue}/$1`);
|
57
|
+
memo[key] = value;
|
58
|
+
return memo;
|
59
|
+
}, {});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
2
|
+
import { Server } from '@modern-js/server';
|
3
|
+
const store = new AsyncLocalStorage();
|
4
|
+
export const isInHandler = () => Boolean(store.getStore());
|
5
|
+
|
6
|
+
const createApp = async (pwd, config, plugins, routes) => {
|
7
|
+
config.output.path = './';
|
8
|
+
const server = new Server({
|
9
|
+
apiOnly: true,
|
10
|
+
dev: {
|
11
|
+
watch: false
|
12
|
+
},
|
13
|
+
pwd,
|
14
|
+
config,
|
15
|
+
plugins,
|
16
|
+
routes
|
17
|
+
});
|
18
|
+
await server.init();
|
19
|
+
return server.getRequestHandler();
|
20
|
+
};
|
21
|
+
|
22
|
+
export { createApp };
|
@@ -0,0 +1 @@
|
|
1
|
+
export const bff_info_key = 'modern_bff_info';
|
@@ -0,0 +1,28 @@
|
|
1
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
2
|
+
|
3
|
+
import NodeEnvironment from 'jest-environment-node';
|
4
|
+
import { createApp } from "./app";
|
5
|
+
import { bff_info_key } from "./constant";
|
6
|
+
export default class extends NodeEnvironment {
|
7
|
+
constructor(...args) {
|
8
|
+
super(...args);
|
9
|
+
|
10
|
+
_defineProperty(this, "app", void 0);
|
11
|
+
}
|
12
|
+
|
13
|
+
async setup() {
|
14
|
+
const bff_info = this.global[bff_info_key];
|
15
|
+
const {
|
16
|
+
plugins
|
17
|
+
} = bff_info; // eslint-disable-next-line no-multi-assign
|
18
|
+
|
19
|
+
this.global.app = this.app = await createApp(bff_info.appDir, bff_info.modernUserConfig, plugins, bff_info.routes);
|
20
|
+
}
|
21
|
+
|
22
|
+
async teardown() {
|
23
|
+
var _this$app, _this$app$server;
|
24
|
+
|
25
|
+
await ((_this$app = this.app) === null || _this$app === void 0 ? void 0 : (_this$app$server = _this$app.server) === null || _this$app$server === void 0 ? void 0 : _this$app$server.close());
|
26
|
+
}
|
27
|
+
|
28
|
+
}
|
@@ -0,0 +1,110 @@
|
|
1
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
2
|
+
|
3
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
4
|
+
|
5
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
6
|
+
|
7
|
+
import path from 'path';
|
8
|
+
import { isApiOnly } from '@modern-js/utils';
|
9
|
+
import { getModuleNameMapper, DEFAULT_RESOLVER_PATH } from "../../base";
|
10
|
+
import { bff_info_key } from "./constant";
|
11
|
+
import { isBFFProject } from "./utils";
|
12
|
+
export const setJestConfigForBFF = async ({
|
13
|
+
pwd,
|
14
|
+
userConfig,
|
15
|
+
plugins,
|
16
|
+
routes,
|
17
|
+
utils
|
18
|
+
}) => {
|
19
|
+
var _userConfig$source;
|
20
|
+
|
21
|
+
const bffConfig = {
|
22
|
+
rootDir: path.join(pwd, './api'),
|
23
|
+
setupFilesAfterEnv: [require.resolve("./setup")],
|
24
|
+
testEnvironment: require.resolve("./env"),
|
25
|
+
testMatch: [`**/api/**/*.test.[jt]s`],
|
26
|
+
globals: {
|
27
|
+
[bff_info_key]: {
|
28
|
+
appDir: pwd,
|
29
|
+
modernUserConfig: userConfig,
|
30
|
+
plugins,
|
31
|
+
routes
|
32
|
+
}
|
33
|
+
}
|
34
|
+
};
|
35
|
+
const {
|
36
|
+
jestConfig
|
37
|
+
} = utils;
|
38
|
+
const alias = (userConfig === null || userConfig === void 0 ? void 0 : (_userConfig$source = userConfig.source) === null || _userConfig$source === void 0 ? void 0 : _userConfig$source.alias) || {};
|
39
|
+
const aliasMapper = getModuleNameMapper(alias);
|
40
|
+
const {
|
41
|
+
transform,
|
42
|
+
moduleNameMapper
|
43
|
+
} = jestConfig;
|
44
|
+
const apiOnly = await isApiOnly(pwd);
|
45
|
+
|
46
|
+
const mergedModuleNameMapper = _objectSpread(_objectSpread({}, moduleNameMapper), aliasMapper);
|
47
|
+
|
48
|
+
const resolver = jestConfig.resolver || DEFAULT_RESOLVER_PATH; // 这三个配置不能设置在 projects 中,需要设置在外层(https://github.com/facebook/jest/issues/9696)
|
49
|
+
|
50
|
+
const configFields = ['coverage', 'collectCoverage', 'testTimeout'];
|
51
|
+
const commonConfig = configFields.reduce((obj, field) => {
|
52
|
+
if (jestConfig.hasOwnProperty(field)) {
|
53
|
+
obj[field] = jestConfig[field];
|
54
|
+
}
|
55
|
+
|
56
|
+
return obj;
|
57
|
+
}, {});
|
58
|
+
|
59
|
+
if (!apiOnly) {
|
60
|
+
utils.setJestConfig({
|
61
|
+
projects: [_objectSpread({}, jestConfig), _objectSpread({
|
62
|
+
transform,
|
63
|
+
moduleNameMapper: mergedModuleNameMapper,
|
64
|
+
resolver
|
65
|
+
}, bffConfig)]
|
66
|
+
}, {
|
67
|
+
force: true
|
68
|
+
});
|
69
|
+
} else {
|
70
|
+
utils.setJestConfig({
|
71
|
+
projects: [_objectSpread({
|
72
|
+
transform,
|
73
|
+
moduleNameMapper: mergedModuleNameMapper,
|
74
|
+
resolver
|
75
|
+
}, bffConfig)]
|
76
|
+
}, {
|
77
|
+
force: true
|
78
|
+
});
|
79
|
+
}
|
80
|
+
|
81
|
+
utils.setJestConfig(commonConfig);
|
82
|
+
};
|
83
|
+
export default (() => ({
|
84
|
+
name: '@modern-js/testing-plugin-bff',
|
85
|
+
|
86
|
+
setup(api) {
|
87
|
+
return {
|
88
|
+
jestConfig: async (utils, next) => {
|
89
|
+
const appContext = api.useAppContext();
|
90
|
+
const pwd = appContext.appDirectory;
|
91
|
+
|
92
|
+
if (!isBFFProject(pwd)) {
|
93
|
+
return next(utils);
|
94
|
+
}
|
95
|
+
|
96
|
+
const userConfig = api.useResolvedConfigContext();
|
97
|
+
const plugins = appContext.plugins.map(p => p.server).filter(Boolean);
|
98
|
+
await setJestConfigForBFF({
|
99
|
+
pwd,
|
100
|
+
userConfig,
|
101
|
+
plugins,
|
102
|
+
routes: appContext.serverRoutes,
|
103
|
+
utils
|
104
|
+
});
|
105
|
+
return next(utils);
|
106
|
+
}
|
107
|
+
};
|
108
|
+
}
|
109
|
+
|
110
|
+
}));
|