@modern-js/plugin-testing 1.5.7 → 1.7.1-beta.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 +40 -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 +43 -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 +113 -0
- package/dist/js/modern/cli/bff/mockAPI.js +111 -0
- package/dist/js/modern/cli/bff/setup.js +44 -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/app.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 +59 -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 +132 -0
- package/dist/js/node/cli/bff/mockAPI.js +126 -0
- package/dist/js/node/cli/bff/setup.js +53 -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/app.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 +92 -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 +149 -0
- package/dist/js/treeshaking/cli/bff/mockAPI.js +115 -0
- package/dist/js/treeshaking/cli/bff/setup.js +76 -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/app.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 +8 -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 +47 -11
@@ -0,0 +1,109 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.runJest = runJest;
|
7
|
+
exports.runTest = runTest;
|
8
|
+
|
9
|
+
var _yargs = _interopRequireDefault(require("yargs/yargs"));
|
10
|
+
|
11
|
+
var _jest = require("jest");
|
12
|
+
|
13
|
+
var _utils = require("@modern-js/utils");
|
14
|
+
|
15
|
+
var _config = require("./config");
|
16
|
+
|
17
|
+
var _utils2 = require("./utils");
|
18
|
+
|
19
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
20
|
+
|
21
|
+
/**
|
22
|
+
* @file run jest by nodejs API
|
23
|
+
* @description
|
24
|
+
* Jest does not provide node API to run jest.
|
25
|
+
* The followed code is inspired by
|
26
|
+
* https://github.com/facebook/jest/blob/fdc74af37235354e077edeeee8aa2d1a4a863032/packages/jest-cli/src/cli/index.ts#L21
|
27
|
+
*/
|
28
|
+
const buildArgv = async (rawArgv, config) => {
|
29
|
+
const argv = await (0, _yargs.default)(rawArgv).argv;
|
30
|
+
const result = {
|
31
|
+
$0: argv.$0,
|
32
|
+
_: argv._.slice(1)
|
33
|
+
};
|
34
|
+
Object.keys(argv).forEach(key => {
|
35
|
+
if (key.includes('-') || key === '_') {
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
|
39
|
+
result[key] = argv[key];
|
40
|
+
});
|
41
|
+
|
42
|
+
if (config) {
|
43
|
+
result.config = JSON.stringify(config);
|
44
|
+
}
|
45
|
+
|
46
|
+
return result;
|
47
|
+
};
|
48
|
+
|
49
|
+
const readResultsAndExit = (result, globalConfig) => {
|
50
|
+
const code = !result || result.success ? 0 : globalConfig.testFailureExitCode; // Only exit if needed
|
51
|
+
|
52
|
+
process.on('exit', () => {
|
53
|
+
if (typeof code === 'number' && code !== 0) {
|
54
|
+
process.exitCode = code;
|
55
|
+
}
|
56
|
+
});
|
57
|
+
|
58
|
+
if (globalConfig.forceExit) {
|
59
|
+
if (!globalConfig.detectOpenHandles) {
|
60
|
+
console.warn(`${_utils.chalk.bold('Force exiting Jest: ')}Have you considered using \`--detectOpenHandles\` to detect ` + `async operations that kept running after all tests finished?`);
|
61
|
+
} // eslint-disable-next-line no-process-exit
|
62
|
+
|
63
|
+
|
64
|
+
process.exit(code);
|
65
|
+
} else if (!globalConfig.detectOpenHandles) {
|
66
|
+
setTimeout(() => {
|
67
|
+
console.warn(_utils.chalk.yellow.bold('Jest did not exit one second after the test run has completed.\n\n') + _utils.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.'));
|
68
|
+
}, 1000).unref();
|
69
|
+
}
|
70
|
+
};
|
71
|
+
/**
|
72
|
+
* Node API: execute jest
|
73
|
+
*/
|
74
|
+
|
75
|
+
|
76
|
+
async function runJest(config, pwd = process.cwd()) {
|
77
|
+
try {
|
78
|
+
const argvConfig = await buildArgv(process.argv.slice(2), config);
|
79
|
+
const {
|
80
|
+
results,
|
81
|
+
globalConfig
|
82
|
+
} = await (0, _jest.runCLI)(argvConfig, [pwd]);
|
83
|
+
readResultsAndExit(results, globalConfig);
|
84
|
+
} catch (e) {
|
85
|
+
console.error(_utils.chalk.red((e === null || e === void 0 ? void 0 : e.stack) || e)); // eslint-disable-next-line no-process-exit
|
86
|
+
|
87
|
+
process.exit(1);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
/**
|
91
|
+
* Node API: run test
|
92
|
+
*/
|
93
|
+
|
94
|
+
|
95
|
+
async function runTest(api, config, pwd = process.cwd()) {
|
96
|
+
process.env.NODE_ENV = 'test';
|
97
|
+
const jestUtils = (0, _config.getJestUtils)(config);
|
98
|
+
await (0, _config.patchConfig)(jestUtils); // 确保用户设置的配置可以被插件处理,比如设置在 projects 中
|
99
|
+
|
100
|
+
jestUtils.setJestUserConfig();
|
101
|
+
const hookRunners = api.useHookRunners();
|
102
|
+
const testConfigOperator = await hookRunners.jestConfig(jestUtils, {
|
103
|
+
onLast: input => input
|
104
|
+
});
|
105
|
+
const finalConfig = testConfigOperator.getFinalConfig();
|
106
|
+
(0, _utils2.debug)('Jest config:', finalConfig);
|
107
|
+
await runJest(finalConfig, pwd);
|
108
|
+
await hookRunners.afterTest();
|
109
|
+
}
|
File without changes
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.readCompilerOptions = exports.getModuleNameMapper = exports.debug = void 0;
|
7
|
+
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
9
|
+
|
10
|
+
var _path = _interopRequireDefault(require("path"));
|
11
|
+
|
12
|
+
var _utils = require("@modern-js/utils");
|
13
|
+
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
15
|
+
|
16
|
+
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; }
|
17
|
+
|
18
|
+
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; }
|
19
|
+
|
20
|
+
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; }
|
21
|
+
|
22
|
+
const debug = (0, _utils.createDebugger)('test');
|
23
|
+
exports.debug = debug;
|
24
|
+
|
25
|
+
/**
|
26
|
+
* Read `compilerOptions` in the current pwd's tsconfig.json file
|
27
|
+
*/
|
28
|
+
const readCompilerOptions = (pwd = process.cwd(), filename = 'tsconfig.json') => {
|
29
|
+
let tsConfig = {};
|
30
|
+
let extendedCompilerOptions = {};
|
31
|
+
let tsconfigFile = '';
|
32
|
+
|
33
|
+
try {
|
34
|
+
const maybeTsconfigFile = _path.default.join(pwd, filename);
|
35
|
+
|
36
|
+
if (_fs.default.existsSync(maybeTsconfigFile)) {
|
37
|
+
tsconfigFile = maybeTsconfigFile;
|
38
|
+
} else {
|
39
|
+
tsconfigFile = require.resolve(filename);
|
40
|
+
}
|
41
|
+
|
42
|
+
({
|
43
|
+
config: tsConfig
|
44
|
+
} = require('typescript').parseConfigFileTextToJson(tsconfigFile, _fs.default.readFileSync(tsconfigFile, 'utf8')));
|
45
|
+
} catch (e) {
|
46
|
+
return {};
|
47
|
+
}
|
48
|
+
|
49
|
+
if (tsConfig.extends) {
|
50
|
+
extendedCompilerOptions = readCompilerOptions(_path.default.dirname(tsconfigFile), tsConfig.extends);
|
51
|
+
}
|
52
|
+
|
53
|
+
return _objectSpread(_objectSpread({}, extendedCompilerOptions), tsConfig.compilerOptions);
|
54
|
+
};
|
55
|
+
|
56
|
+
exports.readCompilerOptions = readCompilerOptions;
|
57
|
+
|
58
|
+
const getModuleNameMapper = alias => Object.keys(alias).reduce((memo, cur) => {
|
59
|
+
const aliasValue = Array.isArray(alias[cur]) ? alias[cur] : [alias[cur]];
|
60
|
+
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.
|
61
|
+
|
62
|
+
if (cur === '@modern-js/runtime$') {
|
63
|
+
memo[`.+${cur}`] = aliasValue[0];
|
64
|
+
return memo;
|
65
|
+
}
|
66
|
+
|
67
|
+
if (isFile) {
|
68
|
+
memo[cur] = aliasValue[0];
|
69
|
+
}
|
70
|
+
|
71
|
+
const key = `^${cur}/(.*)$`;
|
72
|
+
|
73
|
+
const value = _path.default.normalize(`${aliasValue}/$1`);
|
74
|
+
|
75
|
+
memo[key] = value;
|
76
|
+
return memo;
|
77
|
+
}, {});
|
78
|
+
|
79
|
+
exports.getModuleNameMapper = getModuleNameMapper;
|
@@ -0,0 +1,59 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.isInHandler = exports.getApp = exports.createApp = exports.closeServer = void 0;
|
7
|
+
|
8
|
+
var _async_hooks = require("async_hooks");
|
9
|
+
|
10
|
+
var _server = require("@modern-js/server");
|
11
|
+
|
12
|
+
const store = new _async_hooks.AsyncLocalStorage();
|
13
|
+
|
14
|
+
const isInHandler = () => Boolean(store.getStore());
|
15
|
+
|
16
|
+
exports.isInHandler = isInHandler;
|
17
|
+
let server = null;
|
18
|
+
|
19
|
+
const createApp = async (pwd, config, plugins, routes) => {
|
20
|
+
if (!server) {
|
21
|
+
config.output.path = './';
|
22
|
+
server = new _server.Server({
|
23
|
+
apiOnly: true,
|
24
|
+
dev: {
|
25
|
+
watch: false
|
26
|
+
},
|
27
|
+
pwd,
|
28
|
+
config,
|
29
|
+
plugins,
|
30
|
+
routes
|
31
|
+
});
|
32
|
+
await server.init();
|
33
|
+
}
|
34
|
+
|
35
|
+
const app = server.getRequestHandler();
|
36
|
+
return app;
|
37
|
+
};
|
38
|
+
|
39
|
+
exports.createApp = createApp;
|
40
|
+
|
41
|
+
const getApp = () => {
|
42
|
+
if (!server) {
|
43
|
+
throw new Error('please createApp first');
|
44
|
+
}
|
45
|
+
|
46
|
+
return server.getRequestHandler();
|
47
|
+
};
|
48
|
+
|
49
|
+
exports.getApp = getApp;
|
50
|
+
|
51
|
+
const closeServer = async () => {
|
52
|
+
if (!server) {
|
53
|
+
throw new Error('please createApp first');
|
54
|
+
}
|
55
|
+
|
56
|
+
await server.close();
|
57
|
+
};
|
58
|
+
|
59
|
+
exports.closeServer = closeServer;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
var _jestEnvironmentNode = _interopRequireDefault(require("jest-environment-node"));
|
9
|
+
|
10
|
+
var _app = require("./app");
|
11
|
+
|
12
|
+
var _constant = require("./constant");
|
13
|
+
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
15
|
+
|
16
|
+
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; }
|
17
|
+
|
18
|
+
class _default extends _jestEnvironmentNode.default {
|
19
|
+
constructor(...args) {
|
20
|
+
super(...args);
|
21
|
+
|
22
|
+
_defineProperty(this, "app", void 0);
|
23
|
+
}
|
24
|
+
|
25
|
+
async setup() {
|
26
|
+
const bff_info = this.global[_constant.bff_info_key];
|
27
|
+
const {
|
28
|
+
plugins
|
29
|
+
} = bff_info; // eslint-disable-next-line no-multi-assign
|
30
|
+
|
31
|
+
this.global.app = this.app = await (0, _app.createApp)(bff_info.appDir, bff_info.modernUserConfig, plugins, bff_info.routes);
|
32
|
+
}
|
33
|
+
|
34
|
+
async teardown() {
|
35
|
+
var _this$app, _this$app$server;
|
36
|
+
|
37
|
+
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());
|
38
|
+
}
|
39
|
+
|
40
|
+
}
|
41
|
+
|
42
|
+
exports.default = _default;
|
@@ -0,0 +1,132 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.setJestConfigForBFF = exports.default = void 0;
|
7
|
+
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
9
|
+
|
10
|
+
var _utils = require("@modern-js/utils");
|
11
|
+
|
12
|
+
var _base = require("../../base");
|
13
|
+
|
14
|
+
var _constant = require("./constant");
|
15
|
+
|
16
|
+
var _utils2 = require("./utils");
|
17
|
+
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
19
|
+
|
20
|
+
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; }
|
21
|
+
|
22
|
+
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; }
|
23
|
+
|
24
|
+
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; }
|
25
|
+
|
26
|
+
const setJestConfigForBFF = async ({
|
27
|
+
pwd,
|
28
|
+
userConfig,
|
29
|
+
plugins,
|
30
|
+
routes,
|
31
|
+
utils
|
32
|
+
}) => {
|
33
|
+
var _userConfig$source;
|
34
|
+
|
35
|
+
const bffConfig = {
|
36
|
+
rootDir: _path.default.join(pwd, './api'),
|
37
|
+
setupFilesAfterEnv: [require.resolve("./setup")],
|
38
|
+
testEnvironment: 'node',
|
39
|
+
testMatch: [`**/api/**/*.test.[jt]s`],
|
40
|
+
globals: {
|
41
|
+
[_constant.bff_info_key]: {
|
42
|
+
appDir: pwd,
|
43
|
+
modernUserConfig: userConfig,
|
44
|
+
plugins,
|
45
|
+
routes
|
46
|
+
}
|
47
|
+
}
|
48
|
+
};
|
49
|
+
const {
|
50
|
+
jestConfig
|
51
|
+
} = utils;
|
52
|
+
const alias = (userConfig === null || userConfig === void 0 ? void 0 : (_userConfig$source = userConfig.source) === null || _userConfig$source === void 0 ? void 0 : _userConfig$source.alias) || {};
|
53
|
+
const aliasMapper = (0, _base.getModuleNameMapper)(alias);
|
54
|
+
const {
|
55
|
+
moduleNameMapper
|
56
|
+
} = jestConfig; // 服务端统一使用 ts-jest
|
57
|
+
|
58
|
+
const transform = {
|
59
|
+
'\\.[jt]sx?$': require.resolve('ts-jest')
|
60
|
+
};
|
61
|
+
const apiOnly = await (0, _utils.isApiOnly)(pwd);
|
62
|
+
|
63
|
+
const mergedModuleNameMapper = _objectSpread(_objectSpread({}, moduleNameMapper), aliasMapper);
|
64
|
+
|
65
|
+
const resolver = jestConfig.resolver || _base.DEFAULT_RESOLVER_PATH; // 这三个配置不能设置在 projects 中,需要设置在外层(https://github.com/facebook/jest/issues/9696)
|
66
|
+
|
67
|
+
const configFields = ['coverage', 'collectCoverage', 'testTimeout'];
|
68
|
+
const commonConfig = configFields.reduce((obj, field) => {
|
69
|
+
if (jestConfig.hasOwnProperty(field)) {
|
70
|
+
obj[field] = jestConfig[field];
|
71
|
+
}
|
72
|
+
|
73
|
+
return obj;
|
74
|
+
}, {});
|
75
|
+
|
76
|
+
if (!apiOnly) {
|
77
|
+
utils.setJestConfig({
|
78
|
+
projects: [_objectSpread({}, jestConfig), _objectSpread({
|
79
|
+
transform,
|
80
|
+
moduleNameMapper: mergedModuleNameMapper,
|
81
|
+
resolver
|
82
|
+
}, bffConfig)]
|
83
|
+
}, {
|
84
|
+
force: true
|
85
|
+
});
|
86
|
+
} else {
|
87
|
+
utils.setJestConfig({
|
88
|
+
projects: [_objectSpread({
|
89
|
+
transform,
|
90
|
+
moduleNameMapper: mergedModuleNameMapper,
|
91
|
+
resolver
|
92
|
+
}, bffConfig)]
|
93
|
+
}, {
|
94
|
+
force: true
|
95
|
+
});
|
96
|
+
}
|
97
|
+
|
98
|
+
utils.setJestConfig(commonConfig);
|
99
|
+
};
|
100
|
+
|
101
|
+
exports.setJestConfigForBFF = setJestConfigForBFF;
|
102
|
+
|
103
|
+
var _default = () => ({
|
104
|
+
name: '@modern-js/testing-plugin-bff',
|
105
|
+
|
106
|
+
setup(api) {
|
107
|
+
return {
|
108
|
+
jestConfig: async (utils, next) => {
|
109
|
+
const appContext = api.useAppContext();
|
110
|
+
const pwd = appContext.appDirectory;
|
111
|
+
|
112
|
+
if (!(0, _utils2.isBFFProject)(pwd)) {
|
113
|
+
return next(utils);
|
114
|
+
}
|
115
|
+
|
116
|
+
const userConfig = api.useResolvedConfigContext();
|
117
|
+
const plugins = appContext.plugins.map(p => p.server).filter(Boolean);
|
118
|
+
await setJestConfigForBFF({
|
119
|
+
pwd,
|
120
|
+
userConfig,
|
121
|
+
plugins,
|
122
|
+
routes: appContext.serverRoutes,
|
123
|
+
utils
|
124
|
+
});
|
125
|
+
return next(utils);
|
126
|
+
}
|
127
|
+
};
|
128
|
+
}
|
129
|
+
|
130
|
+
});
|
131
|
+
|
132
|
+
exports.default = _default;
|
@@ -0,0 +1,126 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
var ptr = _interopRequireWildcard(require("path-to-regexp"));
|
9
|
+
|
10
|
+
var mockAppModule = _interopRequireWildcard(require("./app"));
|
11
|
+
|
12
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
13
|
+
|
14
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
15
|
+
|
16
|
+
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; }
|
17
|
+
|
18
|
+
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; }
|
19
|
+
|
20
|
+
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; }
|
21
|
+
|
22
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
23
|
+
const mock_replaceUrlWithParams = (url, paramValues, payload) => {
|
24
|
+
const keys = [];
|
25
|
+
ptr.pathToRegexp(url, keys);
|
26
|
+
const params = keys.reduce((cur, key, index) => {
|
27
|
+
if (paramValues[index]) {
|
28
|
+
cur[key.name] = paramValues[index];
|
29
|
+
}
|
30
|
+
|
31
|
+
return cur;
|
32
|
+
}, {});
|
33
|
+
const getFinalPath = ptr.compile(url, {
|
34
|
+
encode: encodeURIComponent
|
35
|
+
});
|
36
|
+
return getFinalPath(_objectSpread(_objectSpread({}, params), payload));
|
37
|
+
}; // eslint-disable-next-line @typescript-eslint/naming-convention
|
38
|
+
|
39
|
+
|
40
|
+
const mock_getParamsAndPayload = args => {
|
41
|
+
if (args.length === 0) {
|
42
|
+
return [[], {}];
|
43
|
+
}
|
44
|
+
|
45
|
+
const head = args[0];
|
46
|
+
|
47
|
+
if (typeof head === 'object') {
|
48
|
+
return [[], head];
|
49
|
+
} else {
|
50
|
+
const latest = args[args.length - 1];
|
51
|
+
|
52
|
+
if (typeof latest === 'object') {
|
53
|
+
return [args.slice(0, args.length - 1), latest];
|
54
|
+
} else {
|
55
|
+
return [args, {}];
|
56
|
+
}
|
57
|
+
}
|
58
|
+
};
|
59
|
+
|
60
|
+
var _default = mockApiInfosByFile => {
|
61
|
+
const files = Object.keys(mockApiInfosByFile);
|
62
|
+
files.forEach(mockedFile => {
|
63
|
+
jest.mock(mockedFile, () => {
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
65
|
+
const supertest = require('supertest');
|
66
|
+
|
67
|
+
return mockApiInfosByFile[mockedFile].reduce((res, info) => {
|
68
|
+
const module = {
|
69
|
+
[info.name]: (...args) => {
|
70
|
+
if (mockAppModule.isInHandler()) {
|
71
|
+
return info.handler(...args);
|
72
|
+
}
|
73
|
+
|
74
|
+
const [params, payload] = mock_getParamsAndPayload(args);
|
75
|
+
const {
|
76
|
+
returnHttp
|
77
|
+
} = module[info.name];
|
78
|
+
const url = mock_replaceUrlWithParams(info.routePath, params, payload.params);
|
79
|
+
const app = mockAppModule.getApp();
|
80
|
+
let test = supertest(app)[info.httpMethod.toLowerCase()](url);
|
81
|
+
|
82
|
+
if (payload.query) {
|
83
|
+
test = test.query(payload.query);
|
84
|
+
}
|
85
|
+
|
86
|
+
if (payload.body) {
|
87
|
+
test = test.send(payload.body);
|
88
|
+
}
|
89
|
+
|
90
|
+
if (payload.data) {
|
91
|
+
test = test.send(payload.data);
|
92
|
+
}
|
93
|
+
|
94
|
+
if (payload.headers) {
|
95
|
+
for (const name in payload.headers) {
|
96
|
+
test = test.set(name, payload.headers[name]);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
if (payload.cookies) {
|
101
|
+
test = test.set('Cookie', [payload.cookies]);
|
102
|
+
}
|
103
|
+
|
104
|
+
if (returnHttp) {
|
105
|
+
return test;
|
106
|
+
}
|
107
|
+
|
108
|
+
return test.then(value => {
|
109
|
+
try {
|
110
|
+
return JSON.parse(value.text);
|
111
|
+
} catch (_unused) {
|
112
|
+
return value.text;
|
113
|
+
}
|
114
|
+
});
|
115
|
+
}
|
116
|
+
};
|
117
|
+
res[info.name] = module[info.name];
|
118
|
+
Object.assign(res[info.name], info.handler);
|
119
|
+
res.__esModule = true;
|
120
|
+
return res;
|
121
|
+
}, {});
|
122
|
+
});
|
123
|
+
});
|
124
|
+
};
|
125
|
+
|
126
|
+
exports.default = _default;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _path = _interopRequireDefault(require("path"));
|
4
|
+
|
5
|
+
var _bffCore = require("@modern-js/bff-core");
|
6
|
+
|
7
|
+
var _constant = require("./constant");
|
8
|
+
|
9
|
+
var _mockAPI = _interopRequireDefault(require("./mockAPI"));
|
10
|
+
|
11
|
+
var _app = require("./app");
|
12
|
+
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
14
|
+
|
15
|
+
let uped = false;
|
16
|
+
const BEFORE_ALL_TIMEOUT = 30000;
|
17
|
+
|
18
|
+
const setup = () => {
|
19
|
+
var _bff_info$modernUserC, _bff_info$modernUserC2;
|
20
|
+
|
21
|
+
if (uped) {
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
uped = true;
|
26
|
+
const bff_info = global[_constant.bff_info_key];
|
27
|
+
const prefix = bff_info === null || bff_info === void 0 ? void 0 : (_bff_info$modernUserC = bff_info.modernUserConfig) === null || _bff_info$modernUserC === void 0 ? void 0 : (_bff_info$modernUserC2 = _bff_info$modernUserC.bff) === null || _bff_info$modernUserC2 === void 0 ? void 0 : _bff_info$modernUserC2.prefix;
|
28
|
+
const apiRouter = new _bffCore.ApiRouter({
|
29
|
+
apiDir: _path.default.join(bff_info.appDir, './api'),
|
30
|
+
prefix
|
31
|
+
});
|
32
|
+
const apiInfos = apiRouter.getApiHandlers();
|
33
|
+
const apiInfosByFile = apiInfos.reduce((res, apiInfo) => {
|
34
|
+
if (!res[apiInfo.filename]) {
|
35
|
+
res[apiInfo.filename] = [];
|
36
|
+
}
|
37
|
+
|
38
|
+
res[apiInfo.filename].push(apiInfo);
|
39
|
+
return res;
|
40
|
+
}, {});
|
41
|
+
let app = null;
|
42
|
+
beforeAll(async () => {
|
43
|
+
if (!app) {
|
44
|
+
app = await (0, _app.createApp)(bff_info.appDir, bff_info.modernUserConfig, bff_info.plugins, bff_info.routes);
|
45
|
+
}
|
46
|
+
}, BEFORE_ALL_TIMEOUT);
|
47
|
+
afterAll(async () => {
|
48
|
+
await (0, _app.closeServer)();
|
49
|
+
});
|
50
|
+
(0, _mockAPI.default)(apiInfosByFile);
|
51
|
+
};
|
52
|
+
|
53
|
+
setup();
|
@@ -0,0 +1,38 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.isBFFProject = void 0;
|
7
|
+
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
9
|
+
|
10
|
+
var _utils = require("@modern-js/utils");
|
11
|
+
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
13
|
+
|
14
|
+
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; }
|
15
|
+
|
16
|
+
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; }
|
17
|
+
|
18
|
+
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; }
|
19
|
+
|
20
|
+
const isBFFProject = pwd => {
|
21
|
+
try {
|
22
|
+
const packageJson = require(_path.default.join(pwd, './package.json'));
|
23
|
+
|
24
|
+
const {
|
25
|
+
dependencies,
|
26
|
+
devDependencies
|
27
|
+
} = packageJson;
|
28
|
+
const isBFF = Object.keys(_objectSpread(_objectSpread({}, dependencies), devDependencies)).some(dependency => dependency.includes('plugin-bff'));
|
29
|
+
const isMWA = Object.keys(devDependencies).some(devDependency => devDependency.includes('app-tools'));
|
30
|
+
return isMWA && isBFF;
|
31
|
+
} catch (error) {
|
32
|
+
// eslint-disable-next-line no-console
|
33
|
+
console.log(_utils.chalk.red(error));
|
34
|
+
return false;
|
35
|
+
}
|
36
|
+
};
|
37
|
+
|
38
|
+
exports.isBFFProject = isBFFProject;
|