@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.
Files changed (97) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/js/modern/base/config/index.js +18 -0
  3. package/dist/js/modern/base/config/patches/assetsModule.js +11 -0
  4. package/dist/js/modern/base/config/patches/filemock.js +1 -0
  5. package/dist/js/modern/base/config/patches/index.js +13 -0
  6. package/dist/js/modern/base/config/patches/transformer.js +49 -0
  7. package/dist/js/modern/base/config/resolver.js +15 -0
  8. package/dist/js/modern/base/config/testConfigOperator.js +86 -0
  9. package/dist/js/modern/base/config/transformer/babelTransformer.js +12 -0
  10. package/dist/js/modern/base/hook.js +7 -0
  11. package/dist/js/modern/base/index.js +6 -0
  12. package/dist/js/modern/base/runJest.js +94 -0
  13. package/dist/js/modern/base/types/index.js +0 -0
  14. package/dist/js/modern/base/utils.js +59 -0
  15. package/dist/js/modern/cli/bff/app.js +22 -0
  16. package/dist/js/modern/cli/bff/constant.js +1 -0
  17. package/dist/js/modern/cli/bff/env.js +28 -0
  18. package/dist/js/modern/cli/bff/index.js +110 -0
  19. package/dist/js/modern/cli/bff/mockAPI.js +109 -0
  20. package/dist/js/modern/cli/bff/setup.js +33 -0
  21. package/dist/js/modern/cli/bff/utils/index.js +25 -0
  22. package/dist/js/modern/cli/index.js +2 -2
  23. package/dist/js/modern/cli/test.js +1 -1
  24. package/dist/js/modern/runtime-testing/base.js +1 -1
  25. package/dist/js/modern/runtime-testing/request.js +17 -0
  26. package/dist/js/node/base/config/index.js +31 -0
  27. package/dist/js/node/base/config/patches/assetsModule.js +20 -0
  28. package/dist/js/node/base/config/patches/filemock.js +8 -0
  29. package/dist/js/node/base/config/patches/index.js +24 -0
  30. package/dist/js/node/base/config/patches/transformer.js +58 -0
  31. package/dist/js/node/base/config/resolver.js +20 -0
  32. package/dist/js/node/base/config/testConfigOperator.js +93 -0
  33. package/dist/js/node/base/config/transformer/babelTransformer.js +23 -0
  34. package/dist/js/node/base/hook.js +18 -0
  35. package/dist/js/node/base/index.js +73 -0
  36. package/dist/js/node/base/runJest.js +109 -0
  37. package/dist/js/node/base/types/index.js +0 -0
  38. package/dist/js/node/base/utils.js +79 -0
  39. package/dist/js/node/cli/bff/app.js +34 -0
  40. package/dist/js/node/cli/bff/constant.js +8 -0
  41. package/dist/js/node/cli/bff/env.js +42 -0
  42. package/dist/js/node/cli/bff/index.js +129 -0
  43. package/dist/js/node/cli/bff/mockAPI.js +124 -0
  44. package/dist/js/node/cli/bff/setup.js +41 -0
  45. package/dist/js/node/cli/bff/utils/index.js +38 -0
  46. package/dist/js/node/cli/index.js +7 -7
  47. package/dist/js/node/cli/test.js +2 -2
  48. package/dist/js/node/runtime-testing/base.js +2 -2
  49. package/dist/js/node/runtime-testing/request.js +24 -0
  50. package/dist/js/treeshaking/base/config/index.js +40 -0
  51. package/dist/js/treeshaking/base/config/patches/assetsModule.js +11 -0
  52. package/dist/js/treeshaking/base/config/patches/filemock.js +1 -0
  53. package/dist/js/treeshaking/base/config/patches/index.js +85 -0
  54. package/dist/js/treeshaking/base/config/patches/transformer.js +45 -0
  55. package/dist/js/treeshaking/base/config/resolver.js +17 -0
  56. package/dist/js/treeshaking/base/config/testConfigOperator.js +91 -0
  57. package/dist/js/treeshaking/base/config/transformer/babelTransformer.js +12 -0
  58. package/dist/js/treeshaking/base/hook.js +7 -0
  59. package/dist/js/treeshaking/base/index.js +6 -0
  60. package/dist/js/treeshaking/base/runJest.js +194 -0
  61. package/dist/js/treeshaking/base/types/index.js +0 -0
  62. package/dist/js/treeshaking/base/utils.js +60 -0
  63. package/dist/js/treeshaking/cli/bff/app.js +47 -0
  64. package/dist/js/treeshaking/cli/bff/constant.js +1 -0
  65. package/dist/js/treeshaking/cli/bff/env.js +98 -0
  66. package/dist/js/treeshaking/cli/bff/index.js +145 -0
  67. package/dist/js/treeshaking/cli/bff/mockAPI.js +113 -0
  68. package/dist/js/treeshaking/cli/bff/setup.js +33 -0
  69. package/dist/js/treeshaking/cli/bff/utils/index.js +22 -0
  70. package/dist/js/treeshaking/cli/index.js +2 -2
  71. package/dist/js/treeshaking/cli/test.js +1 -1
  72. package/dist/js/treeshaking/runtime-testing/base.js +1 -1
  73. package/dist/js/treeshaking/runtime-testing/request.js +24 -0
  74. package/dist/types/base/config/index.d.ts +124 -0
  75. package/dist/types/base/config/patches/assetsModule.d.ts +6 -0
  76. package/dist/types/base/config/patches/filemock.d.ts +3 -0
  77. package/dist/types/base/config/patches/index.d.ts +2 -0
  78. package/dist/types/base/config/patches/transformer.d.ts +6 -0
  79. package/dist/types/base/config/resolver.d.ts +1 -0
  80. package/dist/types/base/config/testConfigOperator.d.ts +248 -0
  81. package/dist/types/base/config/transformer/babelTransformer.d.ts +2 -0
  82. package/dist/types/base/hook.d.ts +13 -0
  83. package/dist/types/base/index.d.ts +6 -0
  84. package/dist/types/base/runJest.d.ts +22 -0
  85. package/dist/types/base/types/index.d.ts +1 -0
  86. package/dist/types/base/utils.d.ts +12 -0
  87. package/dist/types/cli/bff/app.d.ts +6 -0
  88. package/dist/types/cli/bff/constant.d.ts +1 -0
  89. package/dist/types/cli/bff/env.d.ts +6 -0
  90. package/dist/types/cli/bff/index.d.ts +19 -0
  91. package/dist/types/cli/bff/mockAPI.d.ts +3 -0
  92. package/dist/types/cli/bff/setup.d.ts +1 -0
  93. package/dist/types/cli/bff/utils/index.d.ts +1 -0
  94. package/dist/types/cli/index.d.ts +1 -1
  95. package/dist/types/runtime-testing/base.d.ts +1 -1
  96. package/dist/types/runtime-testing/request.d.ts +4 -0
  97. 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
+ }));