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

139 lines
4.6 KiB
TypeScript

/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2025 Tencent.
*/
import { describe, expect, test, vi } from 'vitest';
import { defineComponent, h, nextTick } from 'vue';
import { mount } from '@vue/test-utils';
import KeyValue from '@editor/fields/KeyValue.vue';
vi.mock('@tmagic/design', () => ({
TMagicInput: defineComponent({
name: 'TMagicInput',
props: ['modelValue', 'disabled', 'size', 'placeholder'],
emits: ['update:modelValue', 'change'],
setup(props, { emit }) {
return () =>
h('input', {
class: 'fake-input',
value: props.modelValue,
placeholder: props.placeholder,
onInput: (e: Event) => emit('update:modelValue', (e.target as HTMLInputElement).value),
onChange: (e: Event) => emit('change', (e.target as HTMLInputElement).value),
});
},
}),
TMagicButton: defineComponent({
name: 'TMagicButton',
props: ['type', 'size', 'disabled', 'plain', 'icon', 'circle', 'link'],
emits: ['click'],
setup(_p, { emit, slots }) {
return () => h('button', { onClick: () => emit('click') }, slots.default?.());
},
}),
}));
vi.mock('@editor/layouts/CodeEditor.vue', () => ({
default: defineComponent({
name: 'MagicCodeEditor',
props: ['initValues'],
emits: ['save'],
setup(_p, { emit }) {
return () =>
h('div', {
class: 'code-editor',
onClick: () => emit('save', 'function() {}'),
});
},
}),
}));
vi.mock('@editor/icons/CodeIcon.vue', () => ({
default: defineComponent({ name: 'CodeIcon', setup: () => () => h('i') }),
}));
describe('KeyValue', () => {
const baseProps = (extra: any = {}) => ({
config: { advanced: false, type: 'key-value' },
name: 'kv',
model: { kv: { foo: 'bar', baz: 'qux' } },
disabled: false,
size: 'default',
...extra,
});
test('渲染初始 records', () => {
const wrapper = mount(KeyValue, { props: baseProps() as any });
expect(wrapper.findAll('.m-fields-key-value-item').length).toBe(2);
});
test('addHandler 增加一个空 record', async () => {
const wrapper = mount(KeyValue, { props: baseProps() as any });
const buttons = wrapper.findAll('button');
await buttons[buttons.length - 1].trigger('click');
expect(wrapper.findAll('.m-fields-key-value-item').length).toBe(3);
});
test('deleteHandler 删除项并 emit change', async () => {
const wrapper = mount(KeyValue, { props: baseProps() as any });
const deleteBtns = wrapper.findAll('.m-fields-key-value-delete');
await deleteBtns[0].trigger('click');
expect(wrapper.findAll('.m-fields-key-value-item').length).toBe(1);
const evts = wrapper.emitted('change');
expect(evts?.[0]?.[0]).toEqual({ baz: 'qux' });
});
test('keyChange / valueChange emit change', async () => {
const wrapper = mount(KeyValue, { props: baseProps() as any });
const inputs = wrapper.findAll('input');
(inputs[0].element as HTMLInputElement).value = 'k1';
await inputs[0].trigger('input');
await inputs[0].trigger('change');
const evts = wrapper.emitted('change');
expect(evts?.length).toBeGreaterThan(0);
});
test('config.advanced 时显示代码编辑切换按钮,可切换 showCode', async () => {
const wrapper = mount(KeyValue, { props: baseProps({ config: { advanced: true, type: 'key-value' } }) as any });
const buttons = wrapper.findAll('button');
const last = buttons[buttons.length - 1];
await last.trigger('click');
await nextTick();
expect(wrapper.find('.code-editor').exists()).toBe(true);
});
test('当值为非字符串时自动开启代码模式', () => {
const wrapper = mount(KeyValue, {
props: baseProps({
config: { advanced: true, type: 'key-value' },
model: { kv: { foo: { x: 1 } } },
}) as any,
});
expect(wrapper.find('.code-editor').exists()).toBe(true);
});
test('当值为函数时自动开启代码模式', () => {
const wrapper = mount(KeyValue, {
props: baseProps({
config: { advanced: true, type: 'key-value' },
model: { kv: () => null },
}) as any,
});
expect(wrapper.find('.code-editor').exists()).toBe(true);
});
test('CodeEditor save emit change', async () => {
const wrapper = mount(KeyValue, {
props: baseProps({
config: { advanced: true, type: 'key-value' },
model: { kv: () => null },
}) as any,
});
await wrapper.find('.code-editor').trigger('click');
const evts = wrapper.emitted('change');
expect(evts?.[0]?.[0]).toBe('function() {}');
});
});