feat(editor): 样式设置器 StyleSetter 支持表单对比模式

- Index.vue 透传 lastValues/isCompare 给各分类子组件,并冒泡 addDiffCount

- pro 下 6 个分类组件接受新 props 并向 MContainer 传递

- Layout/Border 同时将新 props 传递给内部 Box/Border 组件

- components/Border.vue 接受新 props 并冒泡 MContainer 的 addDiffCount

- components/Box.vue 接受 props 以保持接口一致

- 补充单元测试覆盖透传与事件冒泡
This commit is contained in:
roymondchen 2026-05-26 20:59:43 +08:00
parent 540a2716d8
commit b1193b909e
14 changed files with 324 additions and 22 deletions

View File

@ -7,9 +7,12 @@
v-if="item.component" v-if="item.component"
:is="item.component" :is="item.component"
:values="model[name]" :values="model[name]"
:last-values="lastValues?.[name]"
:is-compare="isCompare"
:size="size" :size="size"
:disabled="disabled" :disabled="disabled"
@change="change" @change="change"
@add-diff-count="onAddDiffCount"
></component> ></component>
</TMagicCollapseItem> </TMagicCollapseItem>
</template> </template>
@ -36,6 +39,7 @@ const props = defineProps<FieldProps<StyleSchema>>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: any, eventData: ContainerChangeEventData]; change: [v: any, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const list = [ const list = [
@ -82,4 +86,6 @@ const change = (v: any, eventData: ContainerChangeEventData) => {
}); });
emit('change', v, eventData); emit('change', v, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -30,7 +30,16 @@
</div> </div>
</div> </div>
<div class="border-value-container"> <div class="border-value-container">
<MContainer :config="config" :model="model" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
:config="config"
:model="model"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
</div> </div>
</div> </div>
</template> </template>
@ -86,11 +95,14 @@ const selectDirection = (d?: string) => (direction.value = d || '');
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: StyleSchema, eventData: ContainerChangeEventData]; change: [v: StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
withDefaults( withDefaults(
defineProps<{ defineProps<{
model: FormValue; model: FormValue;
lastValues?: FormValue;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(), }>(),
@ -104,4 +116,6 @@ const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
}); });
}); });
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -64,6 +64,8 @@ withDefaults(
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
model: FormValue; model: FormValue;
lastValues?: FormValue;
isCompare?: boolean;
}>(), }>(),
{}, {},
); );

View File

@ -1,5 +1,14 @@
<template> <template>
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
:config="config"
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -13,12 +22,15 @@ import { BackgroundNoRepeat, BackgroundRepeat, BackgroundRepeatX, BackgroundRepe
defineProps<{ defineProps<{
values: Partial<StyleSchema>; values: Partial<StyleSchema>;
lastValues?: Partial<StyleSchema>;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: StyleSchema, eventData: ContainerChangeEventData]; change: [v: StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const config = defineFormItem({ const config = defineFormItem({
@ -79,4 +91,6 @@ const config = defineFormItem({
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => { const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
emit('change', value, eventData); emit('change', value, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -1,6 +1,23 @@
<template> <template>
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
<Border :model="values" :size="size" :disabled="disabled" @change="change"></Border> :config="config"
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
<Border
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></Border>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -11,12 +28,15 @@ import Border from '../components/Border.vue';
defineProps<{ defineProps<{
values: Partial<StyleSchema>; values: Partial<StyleSchema>;
lastValues?: Partial<StyleSchema>;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: StyleSchema, eventData: ContainerChangeEventData]; change: [v: StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const config = defineFormItem({ const config = defineFormItem({
@ -36,4 +56,6 @@ const config = defineFormItem({
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => { const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
emit('change', value, eventData); emit('change', value, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -1,5 +1,14 @@
<template> <template>
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
:config="config"
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -12,12 +21,15 @@ import { AlignCenter, AlignLeft, AlignRight } from '../icons/text-align';
defineProps<{ defineProps<{
values: Partial<StyleSchema>; values: Partial<StyleSchema>;
lastValues?: Partial<StyleSchema>;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: StyleSchema, eventData: ContainerChangeEventData]; change: [v: StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const config = defineFormItem({ const config = defineFormItem({
@ -91,4 +103,6 @@ const config = defineFormItem({
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => { const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
emit('change', value, eventData); emit('change', value, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -1,8 +1,19 @@
<template> <template>
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
:config="config"
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
<Box <Box
v-show="!['fixed', 'absolute'].includes(values.position)" v-show="!['fixed', 'absolute'].includes(values.position)"
:model="values" :model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size" :size="size"
:disabled="disabled" :disabled="disabled"
@change="change" @change="change"
@ -34,12 +45,15 @@ import {
defineProps<{ defineProps<{
values: Partial<StyleSchema>; values: Partial<StyleSchema>;
lastValues?: Partial<StyleSchema>;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: string | StyleSchema, eventData: ContainerChangeEventData]; change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const config = defineFormItem({ const config = defineFormItem({
@ -185,4 +199,6 @@ const config = defineFormItem({
const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => { const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
emit('change', value, eventData); emit('change', value, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -1,5 +1,14 @@
<template> <template>
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
:config="config"
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -8,12 +17,15 @@ import type { StyleSchema } from '@tmagic/schema';
const props = defineProps<{ const props = defineProps<{
values: Partial<StyleSchema>; values: Partial<StyleSchema>;
lastValues?: Partial<StyleSchema>;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: string | StyleSchema, eventData: ContainerChangeEventData]; change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const positionText: Record<string, string> = { const positionText: Record<string, string> = {
@ -100,4 +112,6 @@ const config = defineFormItem({
const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => { const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
emit('change', value, eventData); emit('change', value, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -1,5 +1,14 @@
<template> <template>
<MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer> <MContainer
:config="config"
:model="values"
:last-values="lastValues"
:is-compare="isCompare"
:size="size"
:disabled="disabled"
@change="change"
@add-diff-count="onAddDiffCount"
></MContainer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -8,12 +17,15 @@ import type { StyleSchema } from '@tmagic/schema';
defineProps<{ defineProps<{
values: Partial<StyleSchema>; values: Partial<StyleSchema>;
lastValues?: Partial<StyleSchema>;
isCompare?: boolean;
disabled?: boolean; disabled?: boolean;
size?: 'large' | 'default' | 'small'; size?: 'large' | 'default' | 'small';
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
change: [v: StyleSchema, eventData: ContainerChangeEventData]; change: [v: StyleSchema, eventData: ContainerChangeEventData];
addDiffCount: [];
}>(); }>();
const config = defineFormItem({ const config = defineFormItem({
@ -51,4 +63,6 @@ const config = defineFormItem({
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => { const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
emit('change', value, eventData); emit('change', value, eventData);
}; };
const onAddDiffCount = () => emit('addDiffCount');
</script> </script>

View File

@ -34,13 +34,14 @@ vi.mock('@editor/fields/StyleSetter/pro/index', () => {
const make = (name: string) => const make = (name: string) =>
defineComponent({ defineComponent({
name, name,
props: ['values', 'size', 'disabled'], props: ['values', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change', 'addDiffCount'],
setup(_p, { emit }) { setup(_p, { emit }) {
return () => return () =>
h('div', { h('div', {
class: name, class: name,
onClick: () => emit('change', { foo: 1 }, { changeRecords: [{ propPath: 'foo', value: 1 }] }), onClick: () => emit('change', { foo: 1 }, { changeRecords: [{ propPath: 'foo', value: 1 }] }),
onDblclick: () => emit('addDiffCount'),
}); });
}, },
}); });
@ -131,4 +132,47 @@ describe('StyleSetter Index', () => {
expect(layout.props('size')).toBe('small'); expect(layout.props('size')).toBe('small');
expect(layout.props('disabled')).toBe(true); expect(layout.props('disabled')).toBe(true);
}); });
test('lastValues/isCompare 正确透传到子组件', () => {
const wrapper = mount(StyleSetter, {
props: {
model: { style: { color: 'red' } },
lastValues: { style: { color: 'blue' } },
isCompare: true,
name: 'style',
prop: 'style',
} as any,
});
const layout = wrapper.findComponent({ name: 'Layout' });
expect(layout.props('lastValues')).toEqual({ color: 'blue' });
expect(layout.props('isCompare')).toBe(true);
});
test('lastValues 为空时透传 undefined / isCompare 默认 false', () => {
const wrapper = mount(StyleSetter, {
props: { model: { style: {} }, name: 'style', prop: 'style' } as any,
});
const layout = wrapper.findComponent({ name: 'Layout' });
expect(layout.props('lastValues')).toBeUndefined();
// Boolean 类型 prop 未传时 Vue 默认为 false
expect(layout.props('isCompare')).toBe(false);
});
test('子组件 addDiffCount 事件向上冒泡', async () => {
const wrapper = mount(StyleSetter, {
props: {
model: { style: {} },
lastValues: { style: {} },
isCompare: true,
name: 'style',
prop: 'style',
} as any,
});
await wrapper.find('.Layout').trigger('dblclick');
expect(wrapper.emitted('addDiffCount')).toBeTruthy();
expect(wrapper.emitted('addDiffCount')?.length).toBe(1);
await wrapper.find('.Background').trigger('dblclick');
expect(wrapper.emitted('addDiffCount')?.length).toBe(2);
});
}); });

View File

@ -13,8 +13,8 @@ vi.mock('@tmagic/form', () => ({
defineFormItem: (cfg: any) => cfg, defineFormItem: (cfg: any) => cfg,
MContainer: defineComponent({ MContainer: defineComponent({
name: 'FakeMContainer', name: 'FakeMContainer',
props: ['config', 'model', 'size', 'disabled'], props: ['config', 'model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change', 'addDiffCount'],
setup(_p, { emit }) { setup(_p, { emit }) {
return () => return () =>
h( h(
@ -22,6 +22,7 @@ vi.mock('@tmagic/form', () => ({
{ {
class: 'fake-mcontainer', class: 'fake-mcontainer',
onClick: () => emit('change', 'val', { propPath: 'p' }), onClick: () => emit('change', 'val', { propPath: 'p' }),
onDblclick: () => emit('addDiffCount'),
}, },
'mc', 'mc',
); );
@ -32,7 +33,7 @@ vi.mock('@tmagic/form', () => ({
vi.mock('@editor/fields/StyleSetter/components/Box.vue', () => ({ vi.mock('@editor/fields/StyleSetter/components/Box.vue', () => ({
default: defineComponent({ default: defineComponent({
name: 'FakeBox', name: 'FakeBox',
props: ['model', 'size', 'disabled'], props: ['model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change'],
setup(_p, { emit }) { setup(_p, { emit }) {
return () => return () =>
@ -110,4 +111,39 @@ describe('StyleSetter/Layout.vue', () => {
const values = displayItem.options.map((o: any) => o.value); const values = displayItem.options.map((o: any) => o.value);
expect(values).toEqual(['inline', 'flex', 'block', 'inline-block', 'none']); expect(values).toEqual(['inline', 'flex', 'block', 'inline-block', 'none']);
}); });
test('lastValues/isCompare 透传到 MContainer 与 Box', () => {
const wrapper = mount(Layout, {
props: {
values: { position: 'static', display: 'flex' },
lastValues: { position: 'relative', display: 'block' },
isCompare: true,
} as any,
});
const container = wrapper.findComponent({ name: 'FakeMContainer' });
expect(container.props('lastValues')).toEqual({ position: 'relative', display: 'block' });
expect(container.props('isCompare')).toBe(true);
const box = wrapper.findComponent({ name: 'FakeBox' });
expect(box.props('lastValues')).toEqual({ position: 'relative', display: 'block' });
expect(box.props('isCompare')).toBe(true);
});
test('未传 lastValues 时为 undefined / isCompare 默认 false', () => {
const wrapper = mount(Layout, {
props: { values: { position: 'static', display: 'flex' } } as any,
});
const container = wrapper.findComponent({ name: 'FakeMContainer' });
expect(container.props('lastValues')).toBeUndefined();
// Boolean 类型 prop 未传时 Vue 默认为 false
expect(container.props('isCompare')).toBe(false);
});
test('MContainer 的 addDiffCount 事件向上冒泡', async () => {
const wrapper = mount(Layout, {
props: { values: { position: 'static', display: 'flex' } } as any,
});
await wrapper.find('.fake-mcontainer').trigger('dblclick');
expect(wrapper.emitted('addDiffCount')).toBeTruthy();
expect(wrapper.emitted('addDiffCount')?.length).toBe(1);
});
}); });

View File

@ -13,8 +13,8 @@ vi.mock('@tmagic/form', () => ({
defineFormItem: (cfg: any) => cfg, defineFormItem: (cfg: any) => cfg,
MContainer: defineComponent({ MContainer: defineComponent({
name: 'FakeMContainer', name: 'FakeMContainer',
props: ['config', 'model', 'size', 'disabled'], props: ['config', 'model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change', 'addDiffCount'],
setup(props, { emit }) { setup(props, { emit }) {
return () => return () =>
h( h(
@ -22,6 +22,7 @@ vi.mock('@tmagic/form', () => ({
{ {
class: 'fake-mcontainer', class: 'fake-mcontainer',
onClick: () => emit('change', 'val', { propPath: 'p' }), onClick: () => emit('change', 'val', { propPath: 'p' }),
onDblclick: () => emit('addDiffCount'),
}, },
JSON.stringify(props.config?.items?.length || 0), JSON.stringify(props.config?.items?.length || 0),
); );
@ -62,4 +63,26 @@ describe('StyleSetter/Position.vue', () => {
const rowItems = config.items.filter((it: any) => it.type === 'row'); const rowItems = config.items.filter((it: any) => it.type === 'row');
expect(rowItems[0].display()).toBe(true); expect(rowItems[0].display()).toBe(true);
}); });
test('lastValues/isCompare 透传到 MContainer', () => {
const wrapper = mount(Position, {
props: {
values: { position: 'absolute' },
lastValues: { position: 'static' },
isCompare: true,
} as any,
});
const container = wrapper.findComponent({ name: 'FakeMContainer' });
expect(container.props('lastValues')).toEqual({ position: 'static' });
expect(container.props('isCompare')).toBe(true);
});
test('MContainer 的 addDiffCount 事件向上冒泡', async () => {
const wrapper = mount(Position, {
props: { values: { position: 'absolute' } } as any,
});
await wrapper.find('.fake-mcontainer').trigger('dblclick');
expect(wrapper.emitted('addDiffCount')).toBeTruthy();
expect(wrapper.emitted('addDiffCount')?.length).toBe(1);
});
}); });

View File

@ -13,8 +13,8 @@ vi.mock('@tmagic/form', () => ({
defineFormItem: (cfg: any) => cfg, defineFormItem: (cfg: any) => cfg,
MContainer: defineComponent({ MContainer: defineComponent({
name: 'MContainer', name: 'MContainer',
props: ['config', 'model', 'size', 'disabled'], props: ['config', 'model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change', 'addDiffCount'],
setup(_props, { expose }) { setup(_props, { expose }) {
expose({ trigger: () => null }); expose({ trigger: () => null });
return () => h('div', { class: 'm-container' }); return () => h('div', { class: 'm-container' });
@ -61,4 +61,25 @@ describe('StyleSetter Border', () => {
await wrapper.find('.border-icon-right').trigger('click'); await wrapper.find('.border-icon-right').trigger('click');
expect(wrapper.find('.border-icon-right').classes()).toContain('active'); expect(wrapper.find('.border-icon-right').classes()).toContain('active');
}); });
test('lastValues/isCompare 透传到 MContainer', () => {
const wrapper = mount(Border, {
props: {
model: { borderWidth: '2px' },
lastValues: { borderWidth: '1px' },
isCompare: true,
} as any,
});
const container = wrapper.findComponent({ name: 'MContainer' });
expect(container.props('lastValues')).toEqual({ borderWidth: '1px' });
expect(container.props('isCompare')).toBe(true);
});
test('MContainer 的 addDiffCount 事件向上冒泡', () => {
const wrapper = mount(Border, { props: { model: {} } });
const container = wrapper.findComponent({ name: 'MContainer' });
container.vm.$emit('addDiffCount');
expect(wrapper.emitted('addDiffCount')).toBeTruthy();
expect(wrapper.emitted('addDiffCount')?.length).toBe(1);
});
}); });

View File

@ -17,8 +17,8 @@ vi.mock('@tmagic/form', () => ({
defineFormItem: (cfg: any) => cfg, defineFormItem: (cfg: any) => cfg,
MContainer: defineComponent({ MContainer: defineComponent({
name: 'MContainer', name: 'MContainer',
props: ['config', 'model', 'size', 'disabled'], props: ['config', 'model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change', 'addDiffCount'],
setup() { setup() {
return () => h('div', { class: 'm-container' }); return () => h('div', { class: 'm-container' });
}, },
@ -28,7 +28,7 @@ vi.mock('@tmagic/form', () => ({
vi.mock('@editor/fields/StyleSetter/components/Box.vue', () => ({ vi.mock('@editor/fields/StyleSetter/components/Box.vue', () => ({
default: defineComponent({ default: defineComponent({
name: 'StyleBox', name: 'StyleBox',
props: ['model', 'size', 'disabled'], props: ['model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change'],
setup() { setup() {
return () => h('div', { class: 'fake-box' }); return () => h('div', { class: 'fake-box' });
@ -39,8 +39,8 @@ vi.mock('@editor/fields/StyleSetter/components/Box.vue', () => ({
vi.mock('@editor/fields/StyleSetter/components/Border.vue', () => ({ vi.mock('@editor/fields/StyleSetter/components/Border.vue', () => ({
default: defineComponent({ default: defineComponent({
name: 'StyleBorder', name: 'StyleBorder',
props: ['model', 'size', 'disabled'], props: ['model', 'lastValues', 'isCompare', 'size', 'disabled'],
emits: ['change'], emits: ['change', 'addDiffCount'],
setup() { setup() {
return () => h('div', { class: 'fake-border' }); return () => h('div', { class: 'fake-border' });
}, },
@ -88,4 +88,66 @@ describe('StyleSetter pro 组件', () => {
const wrapper = mount(BorderPro, { props: { values: {} } }); const wrapper = mount(BorderPro, { props: { values: {} } });
expect(wrapper.find('.fake-border').exists()).toBe(true); expect(wrapper.find('.fake-border').exists()).toBe(true);
}); });
test.each([
['Background', Background],
['BorderPro', BorderPro],
['Font', Font],
['Layout', Layout],
['Transform', Transform],
])('%s 透传 lastValues/isCompare 给 MContainer', (_name, comp) => {
const wrapper = mount(comp as any, {
props: {
values: { color: 'red' },
lastValues: { color: 'blue' },
isCompare: true,
},
});
const container = wrapper.findComponent({ name: 'MContainer' });
expect(container.props('lastValues')).toEqual({ color: 'blue' });
expect(container.props('isCompare')).toBe(true);
});
test.each([
['Background', Background],
['BorderPro', BorderPro],
['Font', Font],
['Layout', Layout],
['Transform', Transform],
])('%s 冒泡 MContainer 的 addDiffCount 事件', (_name, comp) => {
const wrapper = mount(comp as any, { props: { values: {} } });
const container = wrapper.findComponent({ name: 'MContainer' });
container.vm.$emit('addDiffCount');
expect(wrapper.emitted('addDiffCount')).toBeTruthy();
expect(wrapper.emitted('addDiffCount')?.length).toBe(1);
});
test('Layout 透传 lastValues/isCompare 给 Box', () => {
const wrapper = mount(Layout, {
props: {
values: { position: 'static' } as any,
lastValues: { position: 'static' } as any,
isCompare: true,
},
});
const box = wrapper.findComponent({ name: 'StyleBox' });
expect(box.props('lastValues')).toEqual({ position: 'static' });
expect(box.props('isCompare')).toBe(true);
});
test('BorderPro 透传 lastValues/isCompare 给 Border 子组件,并冒泡其 addDiffCount', () => {
const wrapper = mount(BorderPro, {
props: {
values: { borderRadius: '4px' } as any,
lastValues: { borderRadius: '2px' } as any,
isCompare: true,
},
});
const border = wrapper.findComponent({ name: 'StyleBorder' });
expect(border.props('lastValues')).toEqual({ borderRadius: '2px' });
expect(border.props('isCompare')).toBe(true);
border.vm.$emit('addDiffCount');
expect(wrapper.emitted('addDiffCount')).toBeTruthy();
});
}); });