2026-05-14 15:26:22 +08:00

114 lines
3.3 KiB
TypeScript

/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2025 Tencent.
*/
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { defineComponent, h, nextTick } from 'vue';
import { mount } from '@vue/test-utils';
import CodeParams from '@editor/components/CodeParams.vue';
import * as utilsMod from '@editor/utils';
const submitMock = vi.fn();
let lastConfig: any;
vi.mock('@tmagic/form', () => ({
MForm: defineComponent({
name: 'MFormStub',
props: ['config', 'initValues', 'disabled', 'size', 'watchProps'],
emits: ['change'],
setup(props, { expose, emit }) {
lastConfig = props.config;
expose({ submitForm: submitMock });
return () =>
h('div', {
class: 'form-stub',
onClick: () => emit('change', { ok: true }, { changeRecords: [] }),
});
},
}),
}));
vi.mock('@editor/utils', () => ({
error: vi.fn(),
}));
describe('CodeParams.vue', () => {
beforeEach(() => {
submitMock.mockReset();
lastConfig = null;
});
afterEach(() => {
vi.clearAllMocks();
});
test('config 中包含 vs-code 类型时直接保留', () => {
mount(CodeParams as any, {
props: {
model: { p: {} },
name: 'p',
paramsConfig: [{ name: 'a', text: 'A', type: 'vs-code' }] as any,
},
});
expect(lastConfig[0].items[0].type).toBe('vs-code');
});
test('config 中其它类型会包装成 data-source-field-select', () => {
mount(CodeParams as any, {
props: {
model: { p: {} },
name: 'p',
paramsConfig: [{ name: 'a', text: 'A', type: 'text' }] as any,
},
});
expect(lastConfig[0].items[0].type).toBe('data-source-field-select');
expect(lastConfig[0].items[0].fieldConfig.type).toBe('text');
});
test('config.type 为函数时执行函数判断类型', () => {
const typeFn = vi.fn(() => 'vs-code');
mount(CodeParams as any, {
props: {
model: { p: { x: 1 } },
name: 'p',
paramsConfig: [{ name: 'a', text: 'A', type: typeFn }] as any,
},
});
expect(typeFn).toHaveBeenCalledWith(undefined, { model: { x: 1 } });
expect(lastConfig[0].items[0].name).toBe('a');
});
test('change 事件成功时 emit change 携带值', async () => {
submitMock.mockResolvedValueOnce({ p: { a: 1 } });
const wrapper = mount(CodeParams as any, {
props: {
model: { p: {} },
name: 'p',
paramsConfig: [{ name: 'a', text: 'A', type: 'vs-code' }] as any,
},
});
await wrapper.find('.form-stub').trigger('click');
await nextTick();
await new Promise((r) => setTimeout(r, 0));
const events = wrapper.emitted('change') as any[];
expect(events?.[0]?.[0]).toEqual({ p: { a: 1 } });
});
test('submitForm 抛错时调用 error 不抛出', async () => {
submitMock.mockRejectedValueOnce(new Error('bad'));
const wrapper = mount(CodeParams as any, {
props: {
model: { p: {} },
name: 'p',
paramsConfig: [{ name: 'a', text: 'A', type: 'vs-code' }] as any,
},
});
await wrapper.find('.form-stub').trigger('click');
await nextTick();
await new Promise((r) => setTimeout(r, 0));
expect((utilsMod as any).error).toHaveBeenCalled();
});
});