115 lines
5.7 KiB
JavaScript
115 lines
5.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
|
|
const root = path.resolve(__dirname, '..');
|
|
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'prototype-src', 'manifest.json'), 'utf8'));
|
|
const html = fs.readFileSync(path.join(root, manifest.source), 'utf8');
|
|
const failures = [];
|
|
function expect(condition, message) { if (!condition) failures.push(message); }
|
|
function section(startMarker, endMarker) {
|
|
const start = html.indexOf(startMarker);
|
|
const end = html.indexOf(endMarker, start + startMarker.length);
|
|
return start >= 0 && end > start ? html.slice(start, end) : '';
|
|
}
|
|
function functionSource(name) {
|
|
const start = html.indexOf(`function ${name}(`);
|
|
if (start < 0) return '';
|
|
const braceStart = html.indexOf('{', start);
|
|
let depth = 0; let quote = ''; let escaped = false;
|
|
for (let index = braceStart; index < html.length; index += 1) {
|
|
const char = html[index];
|
|
if (quote) {
|
|
if (escaped) escaped = false;
|
|
else if (char === '\\') escaped = true;
|
|
else if (char === quote) quote = '';
|
|
continue;
|
|
}
|
|
if (char === "'" || char === '"' || char === '`') { quote = char; continue; }
|
|
if (char === '{') depth += 1;
|
|
if (char === '}' && --depth === 0) return html.slice(start, index + 1);
|
|
}
|
|
return '';
|
|
}
|
|
|
|
const lastMilePage = section('<div class="page" id="page-last-mile-orders">', '<!-- ==================== OVERSEAS WAREHOUSE - 尾程订单详情');
|
|
const renderList = functionSource('renderLastMileOrders');
|
|
const renderOperations = functionSource('renderLastMileOperationItems');
|
|
const renderDetail = functionSource('renderLastMileOrderDetail');
|
|
const getFirstLeg = functionSource('getLastMileFirstLegOrder');
|
|
const isDetained = functionSource('isLastMileOrderDetained');
|
|
const openOutbound = functionSource('openLastMileOutboundPlan');
|
|
const saveOutbound = functionSource('saveLastMileOutboundPlan');
|
|
|
|
expect(/>是否暂扣<\/th>/.test(lastMilePage), '尾程订单列表应显示是否暂扣列');
|
|
expect(/isLastMileOrderDetained/.test(renderList), '尾程订单列表应实时渲染暂扣状态');
|
|
expect(/是否暂扣/.test(renderDetail), '尾程订单详情应显示是否暂扣');
|
|
expect(Boolean(getFirstLeg), '缺少 getLastMileFirstLegOrder 函数');
|
|
expect(Boolean(isDetained), '缺少 isLastMileOrderDetained 函数');
|
|
expect(/isLastMileOrderDetained/.test(renderOperations) && /不能创建出库单/.test(renderOperations), '列表出库计划操作应在暂扣时禁用');
|
|
expect(/isLastMileOrderDetained/.test(openOutbound) && /不能创建出库单/.test(openOutbound), '打开出库计划应拦截暂扣订单');
|
|
expect(/isLastMileOrderDetained/.test(saveOutbound) && /不能创建出库单/.test(saveOutbound), '保存出库计划应二次拦截暂扣订单');
|
|
expect(/isDetained\s*:\s*true/.test(html), '应提供一条暂扣头程订单样例');
|
|
|
|
if (getFirstLeg && isDetained) {
|
|
try {
|
|
const context = {lastMileFirstLegSamples: [
|
|
{firstLegNo: 'H-BOOL', isDetained: true},
|
|
{firstLegNo: 'H-TEXT', detainFlag: '是'},
|
|
{firstLegNo: 'H-NUM', holdStatus: 1},
|
|
{firstLegNo: 'H-NO', isDetained: false}
|
|
]};
|
|
vm.createContext(context);
|
|
vm.runInContext(`${getFirstLeg}\n${isDetained}`, context, {timeout: 1000});
|
|
expect(context.isLastMileOrderDetained({firstLegNo: 'H-BOOL'}) === true, '应识别布尔暂扣状态');
|
|
expect(context.isLastMileOrderDetained({firstLegNo: 'H-TEXT'}) === true, '应识别“是”暂扣状态');
|
|
expect(context.isLastMileOrderDetained({firstLegNo: 'H-NUM'}) === true, '应识别数值暂扣状态');
|
|
expect(context.isLastMileOrderDetained({firstLegNo: 'H-NO'}) === false, '解除暂扣后应立即恢复');
|
|
expect(context.isLastMileOrderDetained({firstLegNo: 'UNKNOWN'}) === false, '未知头程订单应按未暂扣处理');
|
|
} catch (error) {
|
|
failures.push(`暂扣判断行为执行失败:${error.message}`);
|
|
}
|
|
}
|
|
|
|
if (openOutbound && saveOutbound && getFirstLeg && isDetained) {
|
|
try {
|
|
const order = {no:'LMO-HOLD',firstLegNo:'H-HOLD',fbaWarehouse:'FBA ONT8',cargo:[],logs:[]};
|
|
const elements = {
|
|
'lmo-outbound-date': {value:'2026-08-20'},
|
|
'lmo-outbound-fba': {value:'FBA ONT8'},
|
|
'lmo-outbound-mode': {value:'卡车派送'},
|
|
'lmo-outbound-remark': {value:'',trim(){return '';}}
|
|
};
|
|
const calls = {modal:0,toast:[],hidden:0,refresh:0};
|
|
const context = {
|
|
lastMileFirstLegSamples:[{firstLegNo:'H-HOLD',isDetained:true}],
|
|
lastMileOrderData:[order],currentLastMileActionNo:'',fbaOutboundOrderData:[],
|
|
lmoActionOrder(){this.currentLastMileActionNo=order.no;return order;},
|
|
document:{getElementById:id=>elements[id]},
|
|
showModal(){calls.modal++;},hideModal(){calls.hidden++;},
|
|
showToast(message,type){calls.toast.push({message,type});},
|
|
lmoNow:()=> '2026-08-12 10:00',refreshLastMileViews(){calls.refresh++;}
|
|
};
|
|
vm.createContext(context);
|
|
vm.runInContext(`${getFirstLeg}\n${isDetained}\n${openOutbound}\n${saveOutbound}`, context, {timeout:1000});
|
|
context.openLastMileOutboundPlan(order.no);
|
|
expect(calls.modal===0, '暂扣订单不应打开出库计划弹窗');
|
|
context.currentLastMileActionNo=order.no;
|
|
context.saveLastMileOutboundPlan();
|
|
expect(!order.outboundPlan && !order.outboundNo && context.fbaOutboundOrderData.length===0, '暂扣订单不应生成出库计划或出库单');
|
|
expect(calls.toast.some(item=>/暂扣/.test(item.message)), '暂扣拦截应显示明确提示');
|
|
} catch (error) {
|
|
failures.push(`暂扣出库拦截行为执行失败:${error.message}`);
|
|
}
|
|
}
|
|
|
|
if (failures.length) {
|
|
console.error('LAST_MILE_HOLD_OUTBOUND_CHECK_FAIL');
|
|
failures.forEach(failure => console.error(`- ${failure}`));
|
|
process.exitCode = 1;
|
|
} else {
|
|
console.log('LAST_MILE_HOLD_OUTBOUND_CHECK_PASS');
|
|
}
|