UNPKG

buefy

Version:

Lightweight UI components for Vue.js (v3) based on Bulma

204 lines (172 loc) 6.97 kB
import { beforeEach, describe, expect, it } from 'vitest' import { defineComponent } from 'vue' import { mount } from '@vue/test-utils' import type { VueWrapper } from '@vue/test-utils' import BTabs from '@components/tabs/Tabs.vue' import BTabItem from '@components/tabs/TabItem.vue' import type { TabbedChild } from '@utils/TabbedTypes' const WrapperComp = defineComponent({ components: { BTabs, BTabItem }, data() { return { show1: true } }, template: ` <BTabs ref="tabs"> <BTabItem v-if="show1" ref="firstItem" value="tab1"/> <BTabItem ref="testItem" value="tab2"/> <BTabItem value="tab3" :visible="false"/> </BTabs>` }) let wrapper: VueWrapper<InstanceType<typeof BTabItem>> let wrapperParent: VueWrapper<InstanceType<typeof WrapperComp>> describe('BTabItem', () => { beforeEach(() => { wrapperParent = mount(WrapperComp) wrapper = wrapperParent.findComponent<InstanceType<typeof BTabItem>>({ ref: 'testItem' }) }) it('is called', () => { expect(wrapper.vm).toBeTruthy() expect(wrapper.vm.$options.name).toBe('BTabItem') expect(wrapper.vm.value).toBe('tab2') }) it('render correctly', () => { expect(wrapper.html()).toMatchSnapshot() }) it('computes its position correctly', () => { expect(wrapper.vm.index).toBe(1) }) it('will retain indexes when a sibling gets removed', async () => { expect(wrapper.vm.index).toBe(1) await wrapperParent.setData({ show1: false }) expect(wrapper.vm.index).toBe(1) }) it('should assign new index when tab is added after removal', async () => { const firstItem = wrapperParent.findComponent({ ref: 'firstItem' }) expect(firstItem.vm.index).toBe(0) await wrapperParent.setData({ show1: false }) await wrapperParent.setData({ show1: true }) const firstItem2 = wrapperParent.findComponent({ ref: 'firstItem' }) expect(firstItem2.vm.index).toBe(3) }) it('transition correctly when activate is called', () => { wrapper.vm.activate(0) expect(wrapper.vm.transitionName).toBe('slide-prev') wrapper.vm.activate(2) expect(wrapper.vm.transitionName).toBe('slide-next') }) it('transition correctly when deactivate is called', () => { wrapper.vm.deactivate(2) expect(wrapper.vm.transitionName).toBe('slide-prev') wrapper.vm.deactivate(0) expect(wrapper.vm.transitionName).toBe('slide-next') }) it('should update active state', async () => { const wrapperFirstItem = wrapperParent.findComponent({ ref: 'firstItem' }) // we need `<a>` elements corresponding to individual tab components to // activate them with 'click' const firstTabLink = wrapperParent.find(`#${wrapperFirstItem.vm.uniqueValue}-label`) const secondTabLink = wrapperParent.find(`#${wrapper.vm.uniqueValue}-label`) expect(wrapperFirstItem.vm.isActive).toBe(true) expect(wrapper.vm.isActive).toBe(false) await secondTabLink.trigger('click') expect(wrapperFirstItem.vm.isActive).toBe(false) expect(wrapper.vm.isActive).toBe(true) await firstTabLink.trigger('click') expect(wrapperFirstItem.vm.isActive).toBe(true) expect(wrapper.vm.isActive).toBe(false) }) it('doesn\'t mount when it has no parent', () => { try { mount(BTabItem) } catch (error) { expect((error as Error).message).toEqual(expect.stringMatching(/You should wrap/)) } }) it('doesn\'t render when parent has destroyOnHide', async () => { wrapper = mount(BTabItem, { props: { value: 'tab1' }, global: { provide: { btab: { // since we cannot override the computed value, // `activeItem` needs to be identical to the item // to make the item active _registerItem(item: TabbedChild) { this.activeItem = item }, activeItem: null, destroyOnHide: true } } } }) expect(wrapper.vm.isActive).toBeTruthy() expect(wrapper.vm.visible).toBeTruthy() expect(wrapper.html()).not.toBe('') await wrapper.setProps({ visible: false }) expect(wrapper.html()).toBe('') }) it('unregisters when destroyed', async () => { const wrapper = mount({ template: ` <BTabs v-model="value"> <BTabItem ref="item1"/> <BTabItem v-if="item2" ref="item2"/> </BTabs>`, props: { // we cannot directly manipulate BTabs' modelValue unless it is // directly mounted. uses indirect v-model instead value: { type: Number, default: 0 }, item2: { type: Boolean, default: true } }, components: { BTabs, BTabItem } }) expect(wrapper.findComponent({ ref: 'item2' })).toBeTruthy() expect(wrapper.findComponent(BTabs).vm.items.length).toBe(2) await wrapper.setProps({ item2: false }) expect(wrapper.findComponent(BTabs).vm.items.length).toBe(1) await wrapper.setProps({ item2: true }) await wrapper.setProps({ value: 1 }) // cannot merge with above expect(wrapper.findComponent(BTabs).vm.items.length).toBe(2) expect(wrapper.findComponent({ ref: 'item2' }).vm.isActive).toBeTruthy() }) describe('with explicit order', () => { it('should assign consistent index when tab is added after removal', async () => { const wrapper = mount({ template: ` <BTabs ref="tabs"> <BTabItem v-if="show1" ref="firstItem" :order="1" /> <BTabItem :order="2" /> <BTabItem :order="3" /> </BTabs>`, props: { show1: { type: Boolean, default: true } }, components: { BTabs, BTabItem } }) const firstItem = wrapper.findComponent({ ref: 'firstItem' }) expect(firstItem.vm.index).toBe(1) await wrapper.setProps({ show1: false }) await wrapper.setProps({ show1: true }) const firstItem2 = wrapper.findComponent({ ref: 'firstItem' }) expect(firstItem2.vm.index).toBe(1) }) }) })