mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-05-15 13:04:29 +00:00
188 lines
6.4 KiB
TypeScript
188 lines
6.4 KiB
TypeScript
/*
|
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
*
|
|
* Copyright (C) 2025 Tencent.
|
|
*/
|
|
import { afterEach, describe, expect, test, vi } from 'vitest';
|
|
import { mount } from '@vue/test-utils';
|
|
|
|
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
|
|
const provideServices = () => ({
|
|
global: {
|
|
provide: {
|
|
services: {
|
|
editorService: {},
|
|
uiService: {},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
describe('ContentMenu.vue', () => {
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
test('show 后触发 show 事件', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: {
|
|
menuData: [{ id: '1', type: 'button', text: 'a' }] as any,
|
|
},
|
|
});
|
|
(wrapper.vm as any).show({ clientX: 10, clientY: 20 });
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
expect(wrapper.emitted('show')).toBeTruthy();
|
|
});
|
|
|
|
test('show 之后调用 hide 触发 hide 事件', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any },
|
|
});
|
|
(wrapper.vm as any).show();
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
(wrapper.vm as any).hide();
|
|
expect(wrapper.emitted('hide')).toBeTruthy();
|
|
});
|
|
|
|
test('未显示时调用 hide 不触发事件', () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any },
|
|
});
|
|
(wrapper.vm as any).hide();
|
|
expect(wrapper.emitted('hide')).toBeFalsy();
|
|
});
|
|
|
|
test('setPosition 计算超出底部时回拢', () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any },
|
|
});
|
|
Object.defineProperty(document.body, 'clientHeight', { value: 100, configurable: true });
|
|
(wrapper.vm as any).setPosition({ clientX: 10, clientY: 90 });
|
|
expect((wrapper.vm as any).menuPosition.left).toBe(10);
|
|
expect((wrapper.vm as any).menuPosition.top).toBeLessThanOrEqual(100);
|
|
});
|
|
|
|
test('contains 判断 DOM 是否在菜单内部', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any },
|
|
});
|
|
(wrapper.vm as any).show({ clientX: 0, clientY: 0 });
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
const outside = document.createElement('div');
|
|
expect((wrapper.vm as any).contains(outside)).toBeFalsy();
|
|
});
|
|
|
|
test('autoHide=false 时点击不会隐藏', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [{ id: '1', type: 'button', text: 'a' }] as any, autoHide: false },
|
|
});
|
|
(wrapper.vm as any).show();
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
expect(wrapper.emitted('hide')).toBeFalsy();
|
|
});
|
|
|
|
test('isSubMenu=true 不监听 mousedown', () => {
|
|
const addSpy = vi.spyOn(globalThis, 'addEventListener');
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any, isSubMenu: true },
|
|
});
|
|
expect(addSpy).not.toHaveBeenCalledWith('mousedown', expect.any(Function), true);
|
|
wrapper.unmount();
|
|
addSpy.mockRestore();
|
|
});
|
|
|
|
test('卸载时移除 mousedown 监听', () => {
|
|
const removeSpy = vi.spyOn(globalThis, 'removeEventListener');
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any },
|
|
});
|
|
wrapper.unmount();
|
|
expect(removeSpy).toHaveBeenCalledWith('mousedown', expect.any(Function), true);
|
|
removeSpy.mockRestore();
|
|
});
|
|
|
|
test('外部点击触发 hide', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [{ id: '1', type: 'button', text: 'a' }] as any },
|
|
attachTo: document.body,
|
|
});
|
|
(wrapper.vm as any).show({ clientX: 0, clientY: 0 });
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
const outside = document.createElement('div');
|
|
document.body.appendChild(outside);
|
|
const event = new MouseEvent('mousedown');
|
|
Object.defineProperty(event, 'target', { value: outside });
|
|
globalThis.dispatchEvent(event);
|
|
expect(wrapper.emitted('hide')).toBeTruthy();
|
|
});
|
|
|
|
test('外部点击在菜单内部时不 hide', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [{ id: '1', type: 'button', text: 'a' }] as any },
|
|
attachTo: document.body,
|
|
});
|
|
(wrapper.vm as any).show({ clientX: 0, clientY: 0 });
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
const inside = wrapper.find('.magic-editor-content-menu').element as HTMLElement;
|
|
const event = new MouseEvent('mousedown');
|
|
Object.defineProperty(event, 'target', { value: inside });
|
|
globalThis.dispatchEvent(event);
|
|
expect(wrapper.emitted('hide')).toBeFalsy();
|
|
});
|
|
|
|
test('autoHide=false 时外部点击不 hide', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any, autoHide: false },
|
|
attachTo: document.body,
|
|
});
|
|
(wrapper.vm as any).show({ clientX: 0, clientY: 0 });
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
const outside = document.createElement('div');
|
|
document.body.appendChild(outside);
|
|
const event = new MouseEvent('mousedown');
|
|
Object.defineProperty(event, 'target', { value: outside });
|
|
globalThis.dispatchEvent(event);
|
|
expect(wrapper.emitted('hide')).toBeFalsy();
|
|
});
|
|
|
|
test('mouseenter 触发 mouseenter 事件', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: { menuData: [] as any },
|
|
});
|
|
(wrapper.vm as any).show();
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
await wrapper.find('.magic-editor-content-menu').trigger('mouseenter');
|
|
expect(wrapper.emitted('mouseenter')).toBeTruthy();
|
|
});
|
|
|
|
test('showSubMenu 设置 subMenuData', async () => {
|
|
const wrapper = mount(ContentMenu as any, {
|
|
...provideServices(),
|
|
props: {
|
|
menuData: [{ id: '1', type: 'button', text: 'a', items: [{ id: '2', type: 'button', text: 'b' }] }] as any,
|
|
},
|
|
});
|
|
(wrapper.vm as any).show({ clientX: 10, clientY: 20 });
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
const buttons = wrapper.findAll('.tool-button');
|
|
if (buttons.length > 0) {
|
|
await buttons[0].trigger('mouseenter');
|
|
await new Promise((r) => setTimeout(r, 10));
|
|
}
|
|
expect(true).toBe(true);
|
|
});
|
|
});
|