/* eslint-disable vue/one-component-per-file */ import { mount } from '@vue/test-utils' import { describe, expect, it } from 'vitest' import { computed, defineComponent, inject, readonly, ref, type DeepReadonly, type Ref } from 'vue' import { registerSubMenuKey } from '../conts' import useHandleSubMenus from '../useHandleSubMenus' describe('useHandleSubMenus', () => { const TestParentComponent = defineComponent({ setup() { const openStatus = ref(false) const { haveOpenSubMenu } = useHandleSubMenus(readonly(openStatus)) const rootClasses = computed(() => ({ 'parent-open': openStatus.value, 'has-open-submenu': haveOpenSubMenu.value, })) return { rootClasses, openStatus } }, template: `
`, }) const TestChildrenComponent = defineComponent({ setup() { const openStatus = ref(false) const registerSubMenu = inject<((r: DeepReadonly>, c: () => void) => void) | undefined>(registerSubMenuKey)! registerSubMenu(readonly(openStatus), () => { openStatus.value = false }) const rootClasses = computed(() => ({ 'children-open': openStatus.value, })) return { rootClasses, openStatus } }, template: `
`, }) it('if close the submenu if the parent menu is closed', async () => { const wrapper = mount({ components: { TestParentComponent, TestChildrenComponent, }, template: ` `, }) expect(wrapper.find('.parent-open').exists()).toBe(false) expect(wrapper.find('.children-open').exists()).toBe(false) const parentBtn = wrapper.find('.parent-menu-btn') await parentBtn.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(true) expect(wrapper.find('.children-open').exists()).toBe(false) const childBtn = wrapper.find('.child-menu-btn') await childBtn.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(true) expect(wrapper.find('.children-open').exists()).toBe(true) await parentBtn.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(false) expect(wrapper.find('.children-open').exists()).toBe(false) await parentBtn.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(true) expect(wrapper.find('.children-open').exists()).toBe(false) }) it('if close the submenu if another submenu is opened', async () => { const wrapper = mount({ components: { TestParentComponent, TestChildrenComponent, }, template: ` `, }) expect(wrapper.find('.parent-open').exists()).toBe(false) expect(wrapper.findAll('.children-open').length).toBe(0) const parentBtn = wrapper.find('.parent-menu-btn') await parentBtn.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(true) expect(wrapper.findAll('.children-open').length).toBe(0) const childBtns = wrapper.findAll('.child-menu-btn') await childBtns[0]!.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(true) expect(wrapper.findAll('.children-open').length).toBe(1) await childBtns[1]!.trigger('click') expect(wrapper.find('.parent-open').exists()).toBe(true) expect(wrapper.findAll('.children-open').length).toBe(1) }) it('return haveOpenSubMenu and update it when the component have a submenu open', async () => { const wrapper = mount({ components: { TestParentComponent, TestChildrenComponent, }, template: ` `, }) const parentBtn = wrapper.find('.parent-menu-btn') await parentBtn.trigger('click') const parentMenu = wrapper.find('.parent-open') expect(parentMenu!.classes()).not.toContain('has-open-submenu') const childBtns = wrapper.findAll('.child-menu-btn') await childBtns[0]!.trigger('click') expect(parentMenu!.classes()).toContain('has-open-submenu') await childBtns[0]!.trigger('click') expect(parentMenu!.classes()).not.toContain('has-open-submenu') await childBtns[1]!.trigger('click') expect(parentMenu!.classes()).toContain('has-open-submenu') }) })