69 lines
3.7 KiB
JavaScript
69 lines
3.7 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
|
|
const html = fs.readFileSync('workbench.html', 'utf8');
|
|
|
|
function extractFunction(name) {
|
|
const start = html.indexOf(`function ${name}(`);
|
|
assert.notEqual(start, -1, `${name} should exist`);
|
|
const bodyStart = html.indexOf('{', start);
|
|
let depth = 0;
|
|
for (let index = bodyStart; index < html.length; index += 1) {
|
|
if (html[index] === '{') depth += 1;
|
|
if (html[index] === '}') depth -= 1;
|
|
if (depth === 0) return html.slice(start, index + 1);
|
|
}
|
|
throw new Error(`Unable to extract ${name}`);
|
|
}
|
|
|
|
const createPage = html.match(/<div class="page-content" id="page-labeling">([\s\S]*?)<!-- ========== MODAL: 编辑贴标申请/)?.[1] || '';
|
|
const editModal = html.match(/<div class="modal-overlay" id="labeling-edit-modal"([\s\S]*?)<!-- ========== PAGE: 仓储转运单列表/)?.[1] || '';
|
|
assert.ok(editModal, 'labeling edit modal should exist');
|
|
|
|
const fieldNames = source => Array.from(source.matchAll(/\bname="([^"]+)"/g), match => match[1]).sort();
|
|
assert.deepEqual(fieldNames(editModal), fieldNames(createPage), 'edit modal should expose the same fields as create order');
|
|
assert.match(editModal, /onsubmit="submitLabelingEdit\(event\)"/);
|
|
|
|
const tbody = { innerHTML: '' };
|
|
const controls = {
|
|
'labeling-list-body': tbody,
|
|
'labeling-total': { textContent: '' }
|
|
};
|
|
const renderLabelingList = vm.runInNewContext(
|
|
`(${extractFunction('renderLabelingList')})`,
|
|
{
|
|
document: { getElementById: id => controls[id] || null },
|
|
labelingFilteredOrders: null,
|
|
loadLabelingOrders: () => [{
|
|
id: 'order-1', orderNo: 'TB001', inboundNo: 'RK001', warehouse: '美西洛杉矶仓',
|
|
labelRequirement: '换箱唛', skuCount: 1, totalBoxes: 2, status: '待处理', createdAt: '2026-09-04 09:00'
|
|
}],
|
|
escapeLabelingHtml: value => String(value == null ? '' : value),
|
|
labelingStatusClass: () => 'status-pending'
|
|
}
|
|
);
|
|
renderLabelingList();
|
|
assert.match(tbody.innerHTML, />查看<\/button>[\s\S]*?>编辑<\/button>/, 'each row should show edit after view');
|
|
assert.match(tbody.innerHTML, /openLabelingEdit\(this\.dataset\.labelingId\)/);
|
|
|
|
const mergeLabelingOrder = vm.runInNewContext(`(${extractFunction('mergeLabelingOrder')})`);
|
|
const original = {
|
|
id: 'order-1', orderNo: 'TB001', status: '处理中', createdAt: '2026-09-01 08:00', updatedAt: '2026-09-01 08:00',
|
|
inboundNo: 'OLD', warehouse: '旧仓', deadline: '2026-09-05T10:00', contact: '旧联系人', phone: '100', remark: '旧备注',
|
|
labelRequirement: '换箱唛', skuCount: 1, totalBoxes: 2, items: [{ sku: 'OLD-SKU', name: '旧商品', boxes: 2, requirement: '换箱唛', fileName: 'old.pdf', relationFileName: 'old.xlsx' }],
|
|
fees: { opening: '-', picking: '-', relabel: '-', carton: '-', total: '-' }
|
|
};
|
|
const updated = mergeLabelingOrder(original, {
|
|
inboundNo: 'RK009', warehouse: '美东新泽西仓', deadline: '2026-09-10T10:30', contact: '新联系人', phone: '200', remark: '新备注',
|
|
items: [{ sku: 'SKU-1', name: '商品一', boxes: 3, requirement: '换SKU标', fileName: '', relationFileName: '' }]
|
|
});
|
|
assert.deepEqual(JSON.parse(JSON.stringify(updated)), {
|
|
id: 'order-1', orderNo: 'TB001', status: '处理中', createdAt: '2026-09-01 08:00', updatedAt: updated.updatedAt,
|
|
inboundNo: 'RK009', warehouse: '美东新泽西仓', deadline: '2026-09-10T10:30', contact: '新联系人', phone: '200', remark: '新备注',
|
|
labelRequirement: '换SKU标', skuCount: 1, totalBoxes: 3, items: [{ sku: 'SKU-1', name: '商品一', boxes: 3, requirement: '换SKU标', fileName: 'old.pdf', relationFileName: 'old.xlsx' }],
|
|
fees: { opening: '-', picking: '-', relabel: '-', carton: '-', total: '-' }
|
|
});
|
|
|
|
console.log('labeling edit: ok');
|