107 lines
3.5 KiB
TypeScript
107 lines
3.5 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, effectScope } from 'vue'
|
|
import { useMobilePlanListDetails } from '../src/views/m/pl/plan/mobileListDetails'
|
|
import { formatBrandConstraintLabel } from '../src/utils/crm-product-brand'
|
|
import { getPlanProductActualQuantity } from '../src/utils/pl-display'
|
|
|
|
function card(plan: any) {
|
|
const ast = ts.createSourceFile(
|
|
'card.ts',
|
|
parse(
|
|
readFileSync(new URL('../src/views/m/pl/plan-cert/PlanCard.vue', import.meta.url), 'utf8')
|
|
).descriptor.scriptSetup!.content,
|
|
ts.ScriptTarget.Latest,
|
|
true
|
|
)
|
|
const code = ast.statements
|
|
.filter(
|
|
(n) =>
|
|
ts.isVariableStatement(n) &&
|
|
n.declarationList.declarations.some((d) => d.name.getText(ast) === 'productNameLabel')
|
|
)
|
|
.map((n) => n.getText(ast))
|
|
.join('\n')
|
|
const shared = ts.createSourceFile(
|
|
'shared.ts',
|
|
readFileSync(new URL('../src/utils/mp-pl-plan-card.ts', import.meta.url), 'utf8'),
|
|
ts.ScriptTarget.Latest,
|
|
true
|
|
)
|
|
const productCode = shared.statements
|
|
.filter(
|
|
(node) =>
|
|
ts.isFunctionDeclaration(node) &&
|
|
[
|
|
'formatStopProductLine',
|
|
'resolveLinkedPlanProduct',
|
|
'formatQty',
|
|
'resolveUnitLabel'
|
|
].includes(node.name!.text)
|
|
)
|
|
.map((node) => node.getText(shared))
|
|
.join('\n')
|
|
const env = {
|
|
props: { plan },
|
|
computed,
|
|
formatBrandConstraintLabel,
|
|
getPlanProductActualQuantity,
|
|
resolveProductHazardFlags: () => ({ isToxic: false, isExplosive: false }),
|
|
resolveMpPackageSpecLabel: (value: string) => value || '—',
|
|
resolveMpProductUnitLabel: (value: string) => value || '—'
|
|
}
|
|
return new Function(
|
|
...Object.keys(env),
|
|
`${ts.transpile(code + '\n' + productCode, { target: ts.ScriptTarget.ESNext })}; return {productNameLabel,productLine: (product, kind) => formatStopProductLine(props.plan, { kind }, product)}`
|
|
)(...Object.values(env))
|
|
}
|
|
test('certificate expanded card joins list standard names, preserves segment empty brands and actual quantities', async () => {
|
|
const scope = effectScope()
|
|
const detail = {
|
|
id: 'A',
|
|
products: [
|
|
{
|
|
id: 'p',
|
|
productName: '根别名',
|
|
brandMode: 'required',
|
|
brandName: '根品牌',
|
|
aliasName: '根别名'
|
|
}
|
|
]
|
|
}
|
|
const api = scope.run(() =>
|
|
useMobilePlanListDetails({ scope: () => 'query/account', load: async () => detail })
|
|
)!
|
|
await api.ensure('A')
|
|
const displayed = api.cardPlan({
|
|
id: 'A',
|
|
products: [{ id: 'p', productName: '标准产品' }]
|
|
} as any)
|
|
const h = card(displayed)
|
|
const row = {
|
|
planProductId: 'p',
|
|
productName: '根别名',
|
|
model: '99%',
|
|
unit: '吨',
|
|
planQty: 3,
|
|
inboundQty: 8,
|
|
outboundQty: 0,
|
|
mobileProductMeta: { brandMode: 'any', brandName: '', aliasName: '送货别名' }
|
|
}
|
|
assert.equal(h.productNameLabel.value, '标准产品')
|
|
const renderProduct = h.productLine
|
|
const delivery = renderProduct(row, 'delivery')
|
|
assert.equal(delivery.name, '标准产品')
|
|
assert.equal(delivery.brand, '—')
|
|
assert.equal(delivery.alias, '送货别名')
|
|
assert.equal(delivery.actualQty, '0')
|
|
assert.equal(renderProduct({ ...row, outboundQty: undefined }, 'delivery').actualQty, '—')
|
|
assert.equal(renderProduct(row, 'load').actualQty, '8')
|
|
scope.stop()
|
|
})
|
|
|
|
// Retired attachment/ready list expansion is replaced by real quota list coverage in quota-mobile-state.test.ts.
|