import { beforeAll, describe, expect, it, vi } from 'vitest'
import { App, ComponentPublicInstance, createApp, defineComponent, h, nextTick, ref } from 'vue'
import { AddFormConfig } from '../../../../components/form/addForm'
import { FormRule } from '../../../../components/form/formConfig'
const ElTabsStub = defineComponent({
name: 'ElTabsStub',
props: {
modelValue: { type: String, default: '' },
closable: { type: Boolean, default: false },
addable: { type: Boolean, default: false }
},
emits: ['update:modelValue', 'edit', 'tab-click'],
template: `
`
})
const ElTabPaneStub = defineComponent({
name: 'ElTabPaneStub',
props: {
label: { type: String, default: '' },
name: { type: String, default: '' }
},
template: '{{ label }}
'
})
const ElFormItemStub = defineComponent({
name: 'ElFormItemStub',
template: '
'
})
const InfoInputStub = defineComponent({
name: 'InfoInputStub',
props: {
row: {
type: Object,
required: true
}
},
template: ''
})
vi.mock('../../../../script/useComponent', () => ({
default: () => ({})
}))
vi.mock('../../../../components/form/dynamic/index.vue', () => ({
default: defineComponent({
name: 'InfoDynamicStub',
template: ''
})
}))
let AddForm: any
interface RenderResult {
app: App
el: HTMLDivElement
vm: ComponentPublicInstance
addFormRef: {
handleTabsEdit: (targetName: string, action: string) => void
} | null
modelData: {
list: Array>
}
afterAdd: ReturnType
afterRemove: ReturnType
}
const renderedApps: RenderResult[] = []
beforeAll(async () => {
AddForm = (await import('../../../../components/form/addForm/index.vue')).default
})
const renderAddForm = async () => {
const afterAdd = vi.fn()
const afterRemove = vi.fn()
const modelData = {
list: [] as Array>
}
const row = new AddFormConfig({
type: 'infoAddForm',
model: 'list',
label: '子表单',
addable: true,
afterAdd,
afterRemove,
rule: (formRule: FormRule) => {
formRule.setInputRule({
type: 'infoInput',
model: 'name',
label: '名称'
})
}
})
const el = document.createElement('div')
document.body.appendChild(el)
const addFormRef = ref(null)
const app = createApp({
setup () {
return {
addFormRef
}
},
render () {
return h(AddForm, {
ref: 'addFormRef',
row,
modelData
})
}
})
app.config.globalProperties.$t = (key: string) => key
app.component('el-tabs', ElTabsStub)
app.component('el-tab-pane', ElTabPaneStub)
app.component('el-form-item', ElFormItemStub)
app.component('infoInput', InfoInputStub)
app.component('infoDynamic', defineComponent({ template: '' }))
const vm = app.mount(el)
await nextTick()
const result = { app, el, vm, addFormRef: addFormRef.value, modelData, afterAdd, afterRemove }
renderedApps.push(result)
return result
}
describe('components/form/addForm/index.vue', () => {
it('支持新增和删除子表单项,并同步回调与 modelData', async () => {
const rendered = await renderAddForm()
expect(rendered.modelData.list).toHaveLength(1)
expect(rendered.modelData.list[0]).toMatchObject({
rule: 'set_1',
name: ''
})
expect(document.body.querySelectorAll('.info-input-stub')).toHaveLength(1)
expect(rendered.addFormRef).not.toBeNull()
rendered.addFormRef?.handleTabsEdit('1', 'add')
await nextTick()
expect(rendered.modelData.list).toHaveLength(2)
expect(rendered.modelData.list[1]).toMatchObject({
rule: 'set_2',
name: ''
})
expect(rendered.afterAdd).toHaveBeenCalledTimes(1)
expect(rendered.afterAdd).toHaveBeenCalledWith(rendered.modelData.list[1])
expect(document.body.querySelectorAll('.info-input-stub')).toHaveLength(1)
rendered.addFormRef?.handleTabsEdit('2', 'remove')
await nextTick()
expect(rendered.modelData.list).toHaveLength(1)
expect(rendered.modelData.list[0]).toMatchObject({
rule: 'set_1',
name: ''
})
expect(rendered.afterRemove).toHaveBeenCalledTimes(1)
expect(rendered.afterRemove).toHaveBeenCalledWith(1)
expect(document.body.querySelectorAll('.info-input-stub')).toHaveLength(1)
})
})