diff --git a/packages/editor/src/layouts/sidebar/code-block/CodeBlockList.vue b/packages/editor/src/layouts/sidebar/code-block/CodeBlockList.vue
index 57724c66..5feb2ef3 100644
--- a/packages/editor/src/layouts/sidebar/code-block/CodeBlockList.vue
+++ b/packages/editor/src/layouts/sidebar/code-block/CodeBlockList.vue
@@ -20,12 +20,29 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -37,9 +54,8 @@ import { Close, Edit, View } from '@element-plus/icons-vue';
import type { Id, MNode } from '@tmagic/core';
import { DepTargetType } from '@tmagic/core';
-import { tMagicMessage, tMagicMessageBox, TMagicTooltip } from '@tmagic/design';
+import { TMagicButton, tMagicMessage, TMagicPopconfirm, TMagicTooltip } from '@tmagic/design';
-import Icon from '@editor/components/Icon.vue';
import Tree from '@editor/components/Tree.vue';
import { useFilter } from '@editor/hooks/use-filter';
import { useNodeStatus } from '@editor/hooks/use-node-status';
@@ -142,29 +158,38 @@ const editCode = (id: string) => {
emit('edit', id);
};
-const deleteCode = async (id: string, { historySource }: { historySource?: HistoryOpSource } = {}) => {
+/** 返回不能删除的原因,可删除时返回 undefined */
+const getDeleteErrorType = (id: string): CodeDeleteErrorType | undefined => {
const currentCode = codeList.value.find((codeItem) => codeItem.id === id);
- const existBinds = Boolean(currentCode?.items?.length);
- const undeleteableList = codeBlockService.getUndeletableList() || [];
- if (!existBinds && !undeleteableList.includes(id)) {
- await tMagicMessageBox.confirm('确定删除该代码块吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- });
+ if (currentCode?.items?.length) {
+ return CodeDeleteErrorType.BIND;
+ }
- // 无绑定关系,且不在不可删除列表中
- emit('remove', id, { historySource });
- } else {
+ return (codeBlockService.getUndeletableList() || []).includes(id) ? CodeDeleteErrorType.UNDELETEABLE : undefined;
+};
+
+/** 删除确认由 TMagicPopconfirm 完成,这里只做校验与删除 */
+const deleteCode = (id: string, { historySource }: { historySource?: HistoryOpSource } = {}) => {
+ const errorType = getDeleteErrorType(id);
+
+ if (errorType) {
if (typeof props.customError === 'function') {
- props.customError(id, existBinds ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
+ props.customError(id, errorType);
+ } else if (errorType === CodeDeleteErrorType.BIND) {
+ tMagicMessage.error('代码块存在绑定关系,不可删除');
} else {
- if (existBinds) {
- tMagicMessage.error('代码块存在绑定关系,不可删除');
- } else {
- tMagicMessage.error('代码块不可删除');
- }
+ tMagicMessage.error('代码块不可删除');
}
+ return;
+ }
+
+ emit('remove', id, { historySource });
+};
+
+/** 不可删除的代码块点击后直接说明原因,无需等待确认 */
+const deleteClickHandler = (id: string) => {
+ if (getDeleteErrorType(id)) {
+ deleteCode(id, { historySource: 'tree' });
}
};
diff --git a/packages/editor/src/layouts/sidebar/data-source/DataSourceList.vue b/packages/editor/src/layouts/sidebar/data-source/DataSourceList.vue
index 1c09da0c..b4324001 100644
--- a/packages/editor/src/layouts/sidebar/data-source/DataSourceList.vue
+++ b/packages/editor/src/layouts/sidebar/data-source/DataSourceList.vue
@@ -19,12 +19,29 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -35,9 +52,8 @@ import { computed } from 'vue';
import { Close, Edit, View } from '@element-plus/icons-vue';
import { DepData, DepTargetType, Id, MNode } from '@tmagic/core';
-import { TMagicTooltip } from '@tmagic/design';
+import { TMagicButton, TMagicPopconfirm, TMagicTooltip } from '@tmagic/design';
-import Icon from '@editor/components/Icon.vue';
import Tree from '@editor/components/Tree.vue';
import { useFilter } from '@editor/hooks/use-filter';
import { useNodeStatus } from '@editor/hooks/use-node-status';
@@ -156,7 +172,7 @@ const editHandler = (id: string) => {
emit('edit', id);
};
-const removeHandler = async (id: string) => {
+const removeHandler = (id: string) => {
emit('remove', id);
};
diff --git a/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue b/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue
index 1b2115b8..529fd803 100644
--- a/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue
+++ b/packages/editor/src/layouts/sidebar/data-source/DataSourceListPanel.vue
@@ -50,7 +50,7 @@
import { computed, inject, ref, useTemplateRef, watch } from 'vue';
import { mergeWith } from 'lodash-es';
-import { tMagicMessageBox, TMagicScrollbar } from '@tmagic/design';
+import { TMagicScrollbar } from '@tmagic/design';
import ContentMenu from '@editor/components/ContentMenu.vue';
import SearchInput from '@editor/components/SearchInput.vue';
@@ -133,13 +133,8 @@ const addHandler = (type: string) => {
editDialog.value.show();
};
-const removeHandler = async (id: string) => {
- await tMagicMessageBox.confirm('确定删除?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- });
-
+/** 删除确认由 DataSourceList 中的 TMagicPopconfirm 完成,这里只负责执行删除 */
+const removeHandler = (id: string) => {
dataSourceService.remove(id, { historySource: 'tree-contextmenu' });
};
diff --git a/packages/editor/src/theme/tree.scss b/packages/editor/src/theme/tree.scss
index d57e7d63..1c1d522e 100644
--- a/packages/editor/src/theme/tree.scss
+++ b/packages/editor/src/theme/tree.scss
@@ -76,9 +76,21 @@
display: flex;
align-items: center;
+ // Element Plus 的 link 按钮左右 padding 是 2px,TDesign 的 text 变体默认
+ // 为 calc(var(--td-comp-paddingLR-l) - 1px)(15px),会把工具栏图标按钮撑宽。
+ .t-button--variant-text {
+ padding-left: 2px;
+ padding-right: 2px;
+ }
+
.tmagic-design-icon {
margin-right: 10px;
}
+
+ .delete-icon-wrapper {
+ display: inline-flex;
+ align-items: center;
+ }
}
}
}
diff --git a/packages/editor/tests/unit/layouts/sidebar/code-block/CodeBlockList.spec.ts b/packages/editor/tests/unit/layouts/sidebar/code-block/CodeBlockList.spec.ts
index 24ff68c6..599bf21c 100644
--- a/packages/editor/tests/unit/layouts/sidebar/code-block/CodeBlockList.spec.ts
+++ b/packages/editor/tests/unit/layouts/sidebar/code-block/CodeBlockList.spec.ts
@@ -50,6 +50,21 @@ vi.mock('@tmagic/design', () => ({
return () => h('div', { class: 'fake-tooltip' }, slots.default?.());
},
}),
+ TMagicPopconfirm: defineComponent({
+ name: 'TMagicPopconfirm',
+ props: ['title', 'placement', 'width'],
+ emits: ['confirm', 'cancel'],
+ setup(_p, { slots }) {
+ return () => h('div', { class: 'fake-popconfirm' }, slots.reference?.());
+ },
+ }),
+ TMagicButton: defineComponent({
+ name: 'TMagicButton',
+ props: ['icon', 'link'],
+ setup(_p, { slots, attrs }) {
+ return () => h('button', { ...attrs, class: 'edit-icon' }, slots.default?.());
+ },
+ }),
}));
vi.mock('@editor/components/Icon.vue', () => ({
@@ -90,6 +105,7 @@ beforeEach(() => {
codeBlockService.getCodeDsl.mockReturnValue({ c1: { name: 'C1' } });
codeBlockService.getEditStatus.mockReturnValue(true);
codeBlockService.getUndeletableList.mockReturnValue([]);
+ depService.getTarget.mockReturnValue(null);
editorService.get.mockImplementation((k: string) => {
if (k === 'root') return { items: [{ id: 'p1', name: 'page1' }] };
if (k === 'stage') return { select: vi.fn() };
@@ -109,12 +125,20 @@ describe('CodeBlockList', () => {
expect(wrapper.emitted('edit')?.[0]?.[0]).toBe('c1');
});
- test('删除按钮 弹窗确认后 emit remove', async () => {
+ test('删除图标由 Popconfirm 包裹,确认后 emit remove', async () => {
const wrapper = mount(CodeBlockList);
+ const popconfirm = wrapper.findComponent({ name: 'TMagicPopconfirm' });
+ expect(popconfirm.exists()).toBe(true);
+ expect(popconfirm.props('title')).toBe('确定删除该代码块吗?');
+ expect(popconfirm.props('placement')).toBe('right');
+
await wrapper.findAll('.edit-icon')[1].trigger('click');
- await new Promise((r) => setTimeout(r, 0));
- expect(messageBoxConfirm).toHaveBeenCalled();
+ expect(wrapper.emitted('remove')).toBeFalsy();
+ expect(messageBoxConfirm).not.toHaveBeenCalled();
+
+ popconfirm.vm.$emit('confirm');
expect(wrapper.emitted('remove')?.[0]?.[0]).toBe('c1');
+ expect(wrapper.emitted('remove')?.[0]?.[1]).toEqual({ historySource: 'tree' });
});
test('点击 Tree 节点选中组件', async () => {
@@ -136,21 +160,53 @@ describe('CodeBlockList', () => {
expect(wrapper.emitted('node-contextmenu')).toBeTruthy();
});
- test('删除按钮: 在不可删除列表 提示错误', async () => {
+ test('删除按钮: 在不可删除列表 点击时提示错误', async () => {
codeBlockService.getUndeletableList.mockReturnValue(['c1']);
const wrapper = mount(CodeBlockList);
await wrapper.findAll('.edit-icon')[1].trigger('click');
- await new Promise((r) => setTimeout(r, 0));
expect(wrapper.emitted('remove')).toBeFalsy();
expect(messageError).toHaveBeenCalledWith('代码块不可删除');
});
+ test('Popconfirm 确认时仍校验不可删除列表', () => {
+ codeBlockService.getUndeletableList.mockReturnValue(['c1']);
+ const wrapper = mount(CodeBlockList);
+ wrapper.findComponent({ name: 'TMagicPopconfirm' }).vm.$emit('confirm');
+ expect(wrapper.emitted('remove')).toBeFalsy();
+ expect(messageError).toHaveBeenCalledWith('代码块不可删除');
+ });
+
+ test('删除按钮: 存在绑定关系 提示错误', async () => {
+ depService.getTarget.mockReturnValue({
+ id: 'c1',
+ deps: { n1: { name: 'N1', keys: ['k'], data: { pageId: 'p1' } } },
+ } as any);
+ const wrapper = mount(CodeBlockList);
+ await wrapper.findAll('.edit-icon')[1].trigger('click');
+ expect(wrapper.emitted('remove')).toBeFalsy();
+ expect(messageError).toHaveBeenCalledWith('代码块存在绑定关系,不可删除');
+ });
+
test('customError 函数被调用', async () => {
codeBlockService.getUndeletableList.mockReturnValue(['c1']);
const customError = vi.fn();
const wrapper = mount(CodeBlockList, { props: { customError } as any });
await wrapper.findAll('.edit-icon')[1].trigger('click');
- await new Promise((r) => setTimeout(r, 0));
expect(customError).toHaveBeenCalledWith('c1', 'undeleteable');
});
+
+ test('customError 在 Popconfirm 确认时被调用', () => {
+ codeBlockService.getUndeletableList.mockReturnValue(['c1']);
+ const customError = vi.fn();
+ const wrapper = mount(CodeBlockList, { props: { customError } as any });
+ wrapper.findComponent({ name: 'TMagicPopconfirm' }).vm.$emit('confirm');
+ expect(customError).toHaveBeenCalledWith('c1', 'undeleteable');
+ });
+
+ test('editable=false 时不显示删除图标和 Popconfirm', () => {
+ codeBlockService.getEditStatus.mockReturnValue(false);
+ const wrapper = mount(CodeBlockList);
+ expect(wrapper.findAll('.edit-icon').length).toBe(1);
+ expect(wrapper.findComponent({ name: 'TMagicPopconfirm' }).exists()).toBe(false);
+ });
});
diff --git a/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceList.spec.ts b/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceList.spec.ts
index b725ce42..a294c2b0 100644
--- a/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceList.spec.ts
+++ b/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceList.spec.ts
@@ -29,7 +29,9 @@ vi.mock('@editor/hooks/use-node-status', () => ({
}));
vi.mock('@editor/hooks/use-filter', () => ({
- useFilter: () => ({ filterTextChangeHandler: vi.fn() }),
+ useFilter: (list: any, _nodeStatusMap: any, filterNode: any) => ({
+ filterTextChangeHandler: (value: string) => list.value.forEach((item: any) => filterNode(value, item)),
+ }),
}));
vi.mock('@editor/components/Tree.vue', () => ({
@@ -74,10 +76,26 @@ vi.mock('@tmagic/design', () => ({
return () => h('div', { class: 'fake-tooltip' }, slots.default?.());
},
}),
+ TMagicPopconfirm: defineComponent({
+ name: 'TMagicPopconfirm',
+ props: ['title', 'placement', 'width'],
+ emits: ['confirm', 'cancel'],
+ setup(_p, { slots }) {
+ return () => h('div', { class: 'fake-popconfirm' }, slots.reference?.());
+ },
+ }),
+ TMagicButton: defineComponent({
+ name: 'TMagicButton',
+ props: ['icon', 'link'],
+ setup(_p, { slots, attrs }) {
+ return () => h('button', { ...attrs, class: 'edit-icon' }, slots.default?.());
+ },
+ }),
}));
beforeEach(() => {
vi.clearAllMocks();
+ depService.getTargets.mockReturnValue({});
dataSourceService.get.mockImplementation((k: string) => {
if (k === 'editable') return true;
if (k === 'dataSources') return [{ id: 'd1', title: 'D1', methods: [] }];
@@ -123,14 +141,21 @@ describe('DataSourceList', () => {
expect(wrapper.emitted('edit')?.[0]?.[0]).toBe('d1');
});
- test('点击删除图标 emit remove (editable=true)', async () => {
+ test('删除图标由 Popconfirm 包裹,确认后才 emit remove', async () => {
const wrapper = mount(DataSourceList);
- const icons = wrapper.findAll('.edit-icon');
- await icons[1].trigger('click');
+ const popconfirm = wrapper.findComponent({ name: 'TMagicPopconfirm' });
+ expect(popconfirm.exists()).toBe(true);
+ expect(popconfirm.props('title')).toBe('确定删除?');
+ expect(popconfirm.props('placement')).toBe('right');
+
+ await wrapper.findAll('.edit-icon')[1].trigger('click');
+ expect(wrapper.emitted('remove')).toBeFalsy();
+
+ popconfirm.vm.$emit('confirm');
expect(wrapper.emitted('remove')?.[0]?.[0]).toBe('d1');
});
- test('editable=false 时不显示删除图标', () => {
+ test('editable=false 时不显示删除图标和 Popconfirm', () => {
dataSourceService.get.mockImplementation((k: string) => {
if (k === 'editable') return false;
if (k === 'dataSources') return [{ id: 'd1', title: 'D1' }];
@@ -138,6 +163,7 @@ describe('DataSourceList', () => {
});
const wrapper = mount(DataSourceList);
expect(wrapper.findAll('.edit-icon').length).toBe(1);
+ expect(wrapper.findComponent({ name: 'TMagicPopconfirm' }).exists()).toBe(false);
});
test('list 计算: dataSources 为空时为空数组', () => {
@@ -149,4 +175,32 @@ describe('DataSourceList', () => {
const wrapper = mount(DataSourceList);
expect(wrapper.findComponent({ name: 'TreeStub' }).props('data').length).toBe(0);
});
+
+ test('list 计算: 合并依赖节点并按页面分类', () => {
+ depService.getTargets.mockReturnValue({
+ d1: { deps: { n1: { name: 'N1', keys: ['k1'], data: { pageId: 'p1' } } } },
+ } as any);
+ editorService.get.mockImplementation((k: string) => {
+ if (k === 'root')
+ return {
+ items: [
+ { id: 'p1', name: 'page1' },
+ { id: 'p2', name: 'page2' },
+ ],
+ };
+ return null;
+ });
+
+ const wrapper = mount(DataSourceList);
+ const list = wrapper.findComponent({ name: 'TreeStub' }).props('data') as any[];
+ expect(list[0].items).toHaveLength(1);
+ expect(list[0].items[0].items.length).toBeGreaterThan(0);
+ });
+
+ test('filter 空关键字与名称匹配', () => {
+ const wrapper = mount(DataSourceList);
+ (wrapper.vm as any).filter('');
+ (wrapper.vm as any).filter('D1');
+ expect(wrapper.findComponent({ name: 'TreeStub' }).props('data')).toHaveLength(1);
+ });
});
diff --git a/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceListPanel.spec.ts b/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceListPanel.spec.ts
index 6b0d2244..dec7dc59 100644
--- a/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceListPanel.spec.ts
+++ b/packages/editor/tests/unit/layouts/sidebar/data-source/DataSourceListPanel.spec.ts
@@ -187,8 +187,8 @@ describe('DataSourceListPanel', () => {
await wrapper.find('.edit-btn').trigger('click');
expect(editHandler).toHaveBeenCalledWith('d1');
await wrapper.find('.remove-btn').trigger('click');
- expect(messageBoxConfirm).toHaveBeenCalled();
- await new Promise((r) => setTimeout(r, 0));
+ // 确认已下沉到 DataSourceList 的 Popconfirm,面板不再弹出 MessageBox
+ expect(messageBoxConfirm).not.toHaveBeenCalled();
expect(dataSourceService.remove).toHaveBeenCalledWith('d1', { historySource: 'tree-contextmenu' });
await wrapper.find('.ctx-btn').trigger('click');
expect(nodeContentMenuHandler).toHaveBeenCalled();
@@ -217,4 +217,32 @@ describe('DataSourceListPanel', () => {
expect(events).toContain('edit-data-source');
expect(events).toContain('remove-data-source');
});
+
+ test('eventBus remove-data-source 执行删除', () => {
+ mountIt();
+ const handler = eventBusOn.mock.calls.find((c: any[]) => c[0] === 'remove-data-source')?.[1];
+ handler?.('d2');
+ expect(dataSourceService.remove).toHaveBeenCalledWith('d2', { historySource: 'tree-contextmenu' });
+ });
+
+ test('eventBus 编辑事件重置定位信息并打开编辑', () => {
+ mountIt();
+ const handlerOf = (name: string) => eventBusOn.mock.calls.find((c: any[]) => c[0] === name)?.[1];
+
+ handlerOf('edit-data-source')?.('d1');
+ handlerOf('edit-data-source-method')?.('d2', 'm1');
+ handlerOf('edit-data-source-field')?.('d3', ['f1']);
+
+ expect(editHandler).toHaveBeenCalledWith('d1');
+ expect(editHandler).toHaveBeenCalledWith('d2');
+ expect(editHandler).toHaveBeenCalledWith('d3');
+ });
+
+ test('addHandler 合并表单配置中的数组值', async () => {
+ editDialog.value = { show: editDialogShow };
+ dataSourceService.getFormValue.mockReturnValueOnce({ id: 'fv', type: 'http', fields: [{ name: 'a' }] });
+ const wrapper = mountIt();
+ await wrapper.find('.add-btn').trigger('click');
+ expect(dataSourceValues.value.fields).toEqual([{ name: 'a' }]);
+ });
});
diff --git a/packages/editor/tests/unit/layouts/sidebar/delete-popconfirm.spec.ts b/packages/editor/tests/unit/layouts/sidebar/delete-popconfirm.spec.ts
new file mode 100644
index 00000000..f215ac66
--- /dev/null
+++ b/packages/editor/tests/unit/layouts/sidebar/delete-popconfirm.spec.ts
@@ -0,0 +1,101 @@
+/*
+ * 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 { mount } from '@vue/test-utils';
+
+import { setDesignConfig } from '@tmagic/design';
+
+import CodeBlockList from '@editor/layouts/sidebar/code-block/CodeBlockList.vue';
+import DataSourceList from '@editor/layouts/sidebar/data-source/DataSourceList.vue';
+
+import elementPlusAdapter from '../../../../../element-plus-adapter/src/index';
+
+setDesignConfig(elementPlusAdapter);
+
+const editorService = {
+ get: vi.fn((key: string) => (key === 'root' ? { items: [{ id: 'p1', name: 'page1' }] } : null)),
+ select: vi.fn(),
+};
+const depService = {
+ getTargets: vi.fn(() => ({})),
+ getTarget: vi.fn(() => null),
+};
+const dataSourceService = {
+ get: vi.fn((key: string) => {
+ if (key === 'editable') return true;
+ if (key === 'dataSources') return [{ id: 'd1', title: 'D1' }];
+ return null;
+ }),
+};
+const codeBlockService = {
+ getCodeDsl: vi.fn(() => ({ c1: { name: 'C1' } })),
+ getCodeContentById: vi.fn(),
+ getEditStatus: vi.fn(() => true),
+ getUndeletableList: vi.fn(() => []),
+};
+
+vi.mock('@editor/hooks/use-services', () => ({
+ useServices: () => ({ editorService, depService, dataSourceService, codeBlockService }),
+}));
+
+/** 点击 Popconfirm 的确认按钮(Element Plus 默认文案为 Yes) */
+const clickConfirm = async () => {
+ await vi.waitFor(() => {
+ expect(document.body.textContent).toContain('Yes');
+ });
+ const confirmBtn = Array.from(document.querySelectorAll('button')).find(
+ (btn) => btn.textContent?.trim().toLowerCase() === 'yes',
+ );
+ confirmBtn?.click();
+};
+
+/** 浮层需挂载到 body,且 placement 真正作用到 popper 上 */
+const expectRightPlacement = async (wrapper: { element: Element }) => {
+ await vi.waitFor(() => {
+ expect(document.querySelector('.el-popper')?.getAttribute('data-popper-placement')).toBe('right');
+ });
+ const popper = document.querySelector('.el-popper');
+ expect(popper).toBeTruthy();
+ expect(wrapper.element.contains(popper!)).toBe(false);
+};
+
+describe('侧栏删除 Popconfirm(真实 element-plus)', () => {
+ test('数据源:点击删除图标弹出 Popconfirm,确认后 emit remove', async () => {
+ const wrapper = mount(DataSourceList, { attachTo: document.body });
+
+ await wrapper.findAll('.edit-icon')[1].trigger('click');
+ await vi.waitFor(() => {
+ expect(document.body.textContent).toContain('确定删除?');
+ });
+ await expectRightPlacement(wrapper);
+ expect(wrapper.emitted('remove')).toBeFalsy();
+
+ await clickConfirm();
+ await vi.waitFor(() => {
+ expect(wrapper.emitted('remove')?.[0]?.[0]).toBe('d1');
+ });
+
+ wrapper.unmount();
+ });
+
+ test('代码块:点击删除图标弹出 Popconfirm,确认后 emit remove', async () => {
+ const wrapper = mount(CodeBlockList, { attachTo: document.body });
+
+ await wrapper.findAll('.edit-icon')[1].trigger('click');
+ await vi.waitFor(() => {
+ expect(document.body.textContent).toContain('确定删除该代码块吗?');
+ });
+ await expectRightPlacement(wrapper);
+ expect(wrapper.emitted('remove')).toBeFalsy();
+
+ await clickConfirm();
+ await vi.waitFor(() => {
+ expect(wrapper.emitted('remove')?.[0]?.[0]).toBe('c1');
+ });
+
+ wrapper.unmount();
+ });
+});