Files
workspace/code/fms/fms-vue/tests/unit/formula-designer.spec.js
T
2026-09-27 21:59:13 +08:00

123 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 计算公式 · 设计器集成测试。
* 覆盖:JSON 适配层往返(formula / overridable 不丢失)、公式编辑器实时校验与提交、
* 属性面板 emit 上抛(父级据此写入草稿)。
*/
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import {
editorToSchema,
schemaToEditor,
} from '@/views/module/module-management/components/design-editor/common/schemaModel'
import FormulaEditor from '@/views/module/module-management/components/design-editor/common/FormulaEditor.vue'
import FormInspector from '@/views/module/module-management/components/design-editor/form/FormInspector.vue'
const FIELDS = [
{ b_field: 'b_qty', b_name: '数量', b_type: 'number' },
{ b_field: 'b_price', b_name: '单价', b_type: 'money' },
{ b_field: 'b_amount', b_name: '金额', b_type: 'money' },
]
function editSchemaWithFormula(node = {}) {
return {
schemaVersion: 2,
children: [
{ type: 'row', children: [{ field: 'b_qty' }, { field: 'b_price' }] },
{
type: 'row',
children: [{ field: 'b_amount', readonly: true, ...node }],
},
],
}
}
describe('公式设计器 · JSON 适配层', () => {
it('加载时带出 formula / overridable,回写时原样保留', () => {
const schema = editSchemaWithFormula({
formula: 'ROUND(b_qty * b_price, 2)',
overridable: true,
})
const { rows, groups } = schemaToEditor('edit', schema, 'mod1')
const amountRow = rows.find((row) => row.b_field === 'b_amount')
expect(amountRow.b_formula).toBe('ROUND(b_qty * b_price, 2)')
expect(amountRow.b_overridable).toBe(1)
const back = editorToSchema('edit', rows, groups, schema)
const node = back.children[1].children[0]
expect(node.formula).toBe('ROUND(b_qty * b_price, 2)')
expect(node.overridable).toBe(true)
})
it('清空公式时同时清掉 overridable,不留残属性', () => {
const schema = editSchemaWithFormula({ formula: 'b_qty * 2', overridable: true })
const { rows, groups } = schemaToEditor('edit', schema, 'mod1')
const amountRow = rows.find((row) => row.b_field === 'b_amount')
amountRow.b_formula = ''
amountRow.b_overridable = 0
const back = editorToSchema('edit', rows, groups, schema)
const node = back.children[1].children[0]
expect('formula' in node).toBe(false)
expect('overridable' in node).toBe(false)
})
})
describe('公式设计器 · 公式编辑器', () => {
it('输入实时校验,失焦才提交给父级(撤销以一次落定的编辑为粒度)', async () => {
const wrapper = mount(FormulaEditor, {
props: { modelValue: '', fields: FIELDS },
})
const textarea = wrapper.find('textarea')
// 只派发 input(setValue 会连带 change,测不出"提交时机"):输入过程不提交
textarea.element.value = 'b_qty * b_price'
await textarea.trigger('input')
expect(wrapper.emitted('update:modelValue')).toBeFalsy()
expect(wrapper.text()).toContain('语法与字段引用检查通过')
await textarea.trigger('change')
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['b_qty * b_price'])
})
it('未知函数与未知字段给出可读错误', async () => {
const wrapper = mount(FormulaEditor, {
props: { modelValue: 'FOO(b_qty) + b_nope', fields: FIELDS },
})
const text = wrapper.text()
expect(text).toContain('未知函数「FOO」')
expect(text).toContain('字段「b_nope」不存在')
})
it('子表阶段函数不可插入(面板中标注)', () => {
const wrapper = mount(FormulaEditor, { props: { modelValue: '', fields: FIELDS } })
expect(wrapper.html()).toBeTruthy()
expect(wrapper.text()).not.toContain('语法与字段引用检查通过')
})
})
describe('公式设计器 · 属性面板', () => {
it('公式与可覆写开关变更均 emit 上抛给父级写草稿', async () => {
const wrapper = mount(FormInspector, {
props: {
selectedRow: {
b_field: 'b_amount',
b_colspan: 24,
b_formula: 'b_qty * 2',
b_overridable: 0,
},
fieldName: () => '金额',
controlTypeLabel: () => '金额',
spanOf: () => 24,
isTextarea: () => false,
heightOf: () => 48,
formula: 'b_qty * 2',
formulaOverridable: false,
fields: FIELDS,
},
})
const editor = wrapper.findComponent(FormulaEditor)
expect(editor.exists()).toBe(true)
editor.vm.$emit('update:modelValue', 'b_qty * 3')
expect(wrapper.emitted('formula-change')?.at(-1)).toEqual(['b_qty * 3'])
})
})