93 行
3.2 KiB
JavaScript
93 行
3.2 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const vm = require('vm');
|
|
|
|
let passed = 0;
|
|
let failed = 0;
|
|
|
|
function assert(condition, testName, detail = '') {
|
|
if (condition) {
|
|
console.log(` [PASS] ${testName}`);
|
|
passed++;
|
|
} else {
|
|
console.error(` [FAIL] ${testName} - ${detail}`);
|
|
failed++;
|
|
}
|
|
}
|
|
|
|
console.log("========================================================");
|
|
console.log(" 订单页面 JS 语法与模板渲染健壮性 TDD 自动化测试");
|
|
console.log("========================================================\n");
|
|
|
|
// 1. 验证 order.js 文件存在与语法解析
|
|
const orderJsPath = path.resolve(__dirname, '../public/assets/js/backend/shopro/order/order.js');
|
|
assert(fs.existsSync(orderJsPath), 'order.js 文件存在');
|
|
|
|
const orderJsContent = fs.readFileSync(orderJsPath, 'utf-8');
|
|
|
|
// 语法检查
|
|
let syntaxOk = false;
|
|
let syntaxErrorMsg = '';
|
|
try {
|
|
new vm.Script(orderJsContent, { filename: 'order.js' });
|
|
syntaxOk = true;
|
|
} catch (e) {
|
|
syntaxErrorMsg = e.message;
|
|
}
|
|
assert(syntaxOk, 'order.js 语法解析无 SyntaxError', syntaxErrorMsg);
|
|
|
|
// 2. 验证 order.js 结构与闭合完整性
|
|
const dummyDefine = function (deps, factory) {
|
|
const $ = () => ({});
|
|
const Backend = { api: {} };
|
|
const Table = {};
|
|
const Form = {};
|
|
return factory($, undefined, Backend, Table, Form);
|
|
};
|
|
|
|
let moduleLoaded = false;
|
|
let controllerObj = null;
|
|
try {
|
|
const sandbox = {
|
|
define: dummyDefine,
|
|
console: console,
|
|
location: { search: '?ref=addtabs' },
|
|
window: {},
|
|
Fast: { api: { ajax: () => {}, open: () => {}, fixurl: (u) => u } },
|
|
Vue: {
|
|
ref: (v) => ({ value: v }),
|
|
reactive: (o) => o,
|
|
onMounted: () => {},
|
|
getCurrentInstance: () => ({ proxy: { $refs: {} } })
|
|
},
|
|
createApp: () => {}
|
|
};
|
|
vm.createContext(sandbox);
|
|
controllerObj = vm.runInContext(orderJsContent, sandbox);
|
|
if (controllerObj && typeof controllerObj.index === 'function' && typeof controllerObj.detail === 'function') {
|
|
moduleLoaded = true;
|
|
}
|
|
} catch (e) {
|
|
syntaxErrorMsg = e.message;
|
|
}
|
|
assert(moduleLoaded, 'order.js 成功执行并导出包含 index 和 detail 的 Controller 对象', syntaxErrorMsg);
|
|
|
|
// 3. 验证 detail 中的 onConfirm 闭合与 onBack 独立存在
|
|
const onConfirmPattern = /function onConfirm\(\)\s*\{[\s\S]*?proxy\.\$refs\['formRef'\]\.validate[\s\S]*?\}\);\s*\}\s*function onBack\(\)/;
|
|
assert(onConfirmPattern.test(orderJsContent), 'detail 中的 onConfirm 函数具有独立完整的闭合大括号,不侵入包裹后续方法');
|
|
|
|
// 4. 验证 index.html 模板中的按钮健壮性
|
|
const orderIndexPath = path.resolve(__dirname, '../application/admin/view/shopro/order/order/index.html');
|
|
assert(fs.existsSync(orderIndexPath), 'order/index.html 视图文件存在');
|
|
const orderIndexContent = fs.readFileSync(orderIndexPath, 'utf-8');
|
|
|
|
const unsafeBtnMatch = orderIndexContent.includes('scope.row?.btns.includes');
|
|
assert(!unsafeBtnMatch, 'order/index.html 中避免 scope.row?.btns.includes 引起的潜在 TypeError 崩溃');
|
|
|
|
console.log(`\n测试统计: 通过 ${passed}, 失败 ${failed}`);
|
|
if (failed > 0) {
|
|
process.exit(1);
|
|
} else {
|
|
process.exit(0);
|
|
}
|