109 lines
3.6 KiB
TypeScript
109 lines
3.6 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { readFileSync } from 'node:fs'
|
|
import { parse } from '@vue/compiler-sfc'
|
|
import ts from 'typescript'
|
|
import { computed, ref } from 'vue'
|
|
import {
|
|
mapLoadFromApi,
|
|
mapDeliveriesFromApi,
|
|
resolveLoadViewAddress,
|
|
resolveDeliveryViewAddress,
|
|
resolveStopProductsForView
|
|
} from '../src/utils/pl-plan-stop-form'
|
|
import { resolvePlanStopsForList } from '../src/utils/pl-plan-list-display-rows'
|
|
import { stopProductMeta } from '../src/views/m/pl/plan-cert/model'
|
|
|
|
function declaration(source: string, name: string) {
|
|
const ast = ts.createSourceFile('test.ts', source, ts.ScriptTarget.Latest, true)
|
|
return ast.statements
|
|
.find((node) =>
|
|
ts.isFunctionDeclaration(node)
|
|
? node.name?.text === name
|
|
: ts.isVariableStatement(node) &&
|
|
node.declarationList.declarations.some((d) => d.name.getText(ast) === name)
|
|
)!
|
|
.getText(ast)
|
|
.replace(/^export /, '')
|
|
}
|
|
|
|
test('actual detail stop mapping retains per-line mobile metadata and explicit empty values', () => {
|
|
const loadMeta = {
|
|
aliasName: '装货别名',
|
|
brandMode: 'required',
|
|
brandName: '装货品牌',
|
|
brandId: 'b'
|
|
}
|
|
const deliveryMeta = { aliasName: null, brandMode: 'any', brandName: '', brandId: '' }
|
|
const line = {
|
|
id: 's',
|
|
planProductId: 'p',
|
|
productId: 'crm',
|
|
productName: '产品',
|
|
planQty: 0,
|
|
inboundQty: 0,
|
|
outboundQty: 0
|
|
}
|
|
const plan = ref<any>({
|
|
id: 'A',
|
|
load: { products: [{ ...line, mobileProductMeta: loadMeta }] },
|
|
deliveries: [{ products: [{ ...line, mobileProductMeta: deliveryMeta }] }]
|
|
})
|
|
const products = ref<any[]>([
|
|
{
|
|
id: 'p',
|
|
productId: 'crm',
|
|
productName: '根别名',
|
|
standardProductName: '标准产品',
|
|
aliasName: '根别名',
|
|
brandName: '根品牌',
|
|
brandMode: 'required',
|
|
quantity: 5
|
|
}
|
|
])
|
|
const source = parse(
|
|
readFileSync(new URL('../src/views/m/pl/plan-cert/CertDetail.vue', import.meta.url), 'utf8')
|
|
).descriptor.scriptSetup!.content
|
|
const shared = readFileSync(
|
|
new URL('../src/composables/usePlPlanViewDetail.ts', import.meta.url),
|
|
'utf8'
|
|
)
|
|
const code = declaration(shared, 'mapPlanProductToFormRow') + '\n' + declaration(source, 'stops')
|
|
const bindings = {
|
|
computed,
|
|
plan,
|
|
products,
|
|
resolvePlanStopsForList,
|
|
mapLoadFromApi,
|
|
mapDeliveriesFromApi,
|
|
resolveLoadViewAddress,
|
|
resolveDeliveryViewAddress,
|
|
resolveStopProductsForView
|
|
}
|
|
const stops = new Function(
|
|
...Object.keys(bindings),
|
|
`${ts.transpile(code, { target: ts.ScriptTarget.ESNext })}; return stops`
|
|
)(...Object.values(bindings)).value
|
|
assert.deepEqual(stops.load.products[0].mobileProductMeta, loadMeta)
|
|
assert.deepEqual(stops.deliveries[0].products[0].mobileProductMeta, deliveryMeta)
|
|
assert.equal(stopProductMeta(stops.deliveries[0].products[0], products.value).aliasName, null)
|
|
assert.equal(stops.load.products[0].standardProductName, '标准产品')
|
|
assert.equal(stops.load.products[0].planQty, 0)
|
|
assert.equal(stops.deliveries[0].products[0].outboundQty, 0)
|
|
})
|
|
|
|
test('certificate detail action and teleported preview controls retain 44px targets', () => {
|
|
const style = readFileSync(
|
|
new URL('../src/views/m/pl/plan-cert/cert.scss', import.meta.url),
|
|
'utf8'
|
|
)
|
|
const actions = style.slice(
|
|
style.indexOf('.cert-detail-actions {'),
|
|
style.indexOf('.cert-sheet-content {')
|
|
)
|
|
assert.match(actions, /min-height:\s*44px/)
|
|
const preview = style.slice(style.indexOf('.el-dialog .preview-toolbar .el-button {'))
|
|
assert.match(preview, /min-height:\s*44px !important/)
|
|
assert.match(preview, /min-width:\s*44px !important/)
|
|
})
|