import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' import { parse, compileScript, compileTemplate } from '@vue/compiler-sfc' import ts from 'typescript' const filename = 'src/components/business/product-form-dialog/index.vue' const source = readFileSync(new URL('../' + filename, import.meta.url), 'utf8') const descriptor = parse(source).descriptor function nodes(node: any): any[] { return [node, ...(node.children || []).flatMap(nodes)] } const elements = nodes(descriptor.template!.ast) function prop(node: any, name: string, context: Record) { const attr = node.props.find( (p: any) => p.name === name || (p.name === 'bind' && p.arg?.content === name) ) if (!attr) return undefined return attr.type === 6 ? attr.value?.content : new Function(...Object.keys(context), `return (${attr.exp.content})`)( ...Object.values(context) ) } test('mobile numeric controls use left/right buttons while desktop keeps right controls', () => { const fields = elements.filter((n) => n.tag === 'el-input-number') assert.equal(fields.length, 3) for (const field of fields) { assert.equal(prop(field, 'controls-position', { isPageVariant: true }), '') assert.equal(prop(field, 'controls-position', { isPageVariant: false }), 'right') assert.equal(prop(field, 'min', {}), 0) } assert.equal(prop(fields[0], 'max', {}), 100) assert.equal(prop(fields[0], 'precision', {}), 0) assert.equal(prop(fields[1], 'precision', {}), undefined) assert.equal(prop(fields[2], 'precision', {}), undefined) }) test('mobile brand and alias deletion has a useful accessible name without changing desktop', () => { const buttons = elements.filter( (n) => n.tag === 'el-button' && prop(n, 'class', {}) === 'sub-card-remove' ) assert.equal(buttons.length, 2) for (const [i, button] of buttons.entries()) { const row = { brandName: '测试品牌', aliasName: '测试别名' } assert.equal( prop(button, 'aria-label', { isPageVariant: true, row, index: 0 }), i === 0 ? '删除品牌:测试品牌' : '删除别名:测试别名' ) assert.equal(prop(button, 'aria-label', { isPageVariant: false, row, index: 0 }), undefined) } }) test('production add/remove and cancel handlers retain original local state behavior', () => { const ast = ts.createSourceFile( 'form.ts', descriptor.scriptSetup!.content, ts.ScriptTarget.Latest, true ) const names = [ 'handleAddBrand', 'handleRemoveBrand', 'handleAddAlias', 'handleRemoveAlias', 'handleCancel' ] const code = ast.statements .filter((n) => ts.isFunctionDeclaration(n) && names.includes(n.name!.text)) .map((n) => n.getText(ast)) .join('\n') const formData = { brands: [] as any[], aliases: [] as any[] } const events: string[] = [] const visible = { value: true } const isPageVariant = { value: true } const handlers = new Function( 'formData', 'isPageVariant', 'emit', 'visible', ts.transpile(code) + `;return {${names.join(',')}}` )(formData, isPageVariant, (event: string) => events.push(event), visible) handlers.handleAddBrand() handlers.handleAddAlias() assert.deepEqual(formData, { brands: [{ brandName: '', status: 'on' }], aliases: [{ aliasName: '' }] }) handlers.handleRemoveBrand(0) handlers.handleRemoveAlias(0) assert.deepEqual(formData, { brands: [], aliases: [] }) handlers.handleCancel() assert.deepEqual(events, ['close']) assert.equal(visible.value, true) isPageVariant.value = false handlers.handleCancel() assert.equal(visible.value, false) }) test('product form SFC compiles', () => { const script = compileScript(descriptor, { id: 'u02' }) const result = compileTemplate({ source: descriptor.template!.content, filename, id: 'u02', compilerOptions: { bindingMetadata: script.bindings } }) assert.deepEqual(result.errors, []) })