UNPKG

bootstrap-vue

Version:

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens

435 lines (363 loc) 12.3 kB
import VueRouter from 'vue-router' import { createLocalVue, mount } from '@vue/test-utils' import { BLink } from './link' import { Vue } from '../../vue' Vue.use(VueRouter) describe('b-link', () => { it('has expected default structure', async () => { const wrapper = mount(BLink) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('#') expect(wrapper.attributes('target')).toEqual('_self') expect(wrapper.attributes('rel')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.classes().length).toBe(0) expect(wrapper.text()).toEqual('') wrapper.destroy() }) it('renders content from default slot', async () => { const wrapper = mount(BLink, { slots: { default: 'foobar' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('#') expect(wrapper.attributes('target')).toEqual('_self') expect(wrapper.attributes('rel')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.classes().length).toBe(0) expect(wrapper.text()).toEqual('foobar') wrapper.destroy() }) it('sets attribute href to user supplied value', async () => { const wrapper = mount(BLink, { propsData: { href: '/foobar' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('/foobar') expect(wrapper.attributes('target')).toEqual('_self') expect(wrapper.attributes('rel')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.classes().length).toBe(0) expect(wrapper.text()).toEqual('') wrapper.destroy() }) it('sets attribute href when user supplied href is hash target', async () => { const wrapper = mount(BLink, { propsData: { href: '#foobar' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('#foobar') expect(wrapper.attributes('target')).toEqual('_self') expect(wrapper.attributes('rel')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.classes().length).toBe(0) expect(wrapper.text()).toEqual('') wrapper.destroy() }) it('should set href to string `to` prop', async () => { const wrapper = mount(BLink, { propsData: { to: '/foobar' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('/foobar') expect(wrapper.attributes('target')).toEqual('_self') expect(wrapper.attributes('rel')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.classes().length).toBe(0) expect(wrapper.text()).toEqual('') wrapper.destroy() }) it('should set href to path from `to` prop', async () => { const wrapper = mount(BLink, { propsData: { to: { path: '/foobar' } } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('/foobar') expect(wrapper.attributes('target')).toEqual('_self') expect(wrapper.attributes('rel')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.classes().length).toBe(0) expect(wrapper.text()).toEqual('') wrapper.destroy() }) it('should default rel to `noopener` when target==="_blank"', async () => { const wrapper = mount(BLink, { propsData: { href: '/foobar', target: '_blank' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('/foobar') expect(wrapper.attributes('target')).toEqual('_blank') expect(wrapper.attributes('rel')).toEqual('noopener') expect(wrapper.classes().length).toBe(0) wrapper.destroy() }) it('should render the given rel to when target==="_blank"', async () => { const wrapper = mount(BLink, { propsData: { href: '/foobar', target: '_blank', rel: 'alternate' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toEqual('/foobar') expect(wrapper.attributes('target')).toEqual('_blank') expect(wrapper.attributes('rel')).toEqual('alternate') expect(wrapper.classes().length).toBe(0) wrapper.destroy() }) it('should add "active" class when prop active=true', async () => { const wrapper = mount(BLink, { propsData: { active: true } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.classes()).toContain('active') expect(wrapper.classes().length).toBe(1) wrapper.destroy() }) it('should add aria-disabled="true" when disabled', async () => { const wrapper = mount(BLink, { propsData: { disabled: true } }) expect(wrapper.attributes('aria-disabled')).toBeDefined() expect(wrapper.attributes('aria-disabled')).toEqual('true') wrapper.destroy() }) it("should add '.disabled' class when prop disabled=true", async () => { const wrapper = mount(BLink, { propsData: { disabled: true } }) expect(wrapper.classes()).toContain('disabled') wrapper.destroy() }) it('focus and blur methods work', async () => { const wrapper = mount(BLink, { attachTo: document.body, propsData: { href: '#foobar' } }) expect(wrapper.element.tagName).toBe('A') expect(document.activeElement).not.toBe(wrapper.element) wrapper.vm.focus() expect(document.activeElement).toBe(wrapper.element) wrapper.vm.blur() expect(document.activeElement).not.toBe(wrapper.element) wrapper.destroy() }) describe('click handling', () => { it('should invoke click handler bound by Vue when clicked on', async () => { let called = 0 let event = null const wrapper = mount(BLink, { listeners: { click: e => { event = e called++ } } }) expect(wrapper.element.tagName).toBe('A') expect(called).toBe(0) expect(event).toEqual(null) await wrapper.find('a').trigger('click') expect(called).toBe(1) expect(event).toBeInstanceOf(MouseEvent) wrapper.destroy() }) it('should invoke multiple click handlers bound by Vue when clicked on', async () => { const spy1 = jest.fn() const spy2 = jest.fn() const wrapper = mount(BLink, { listeners: { click: [spy1, spy2] } }) expect(wrapper.element.tagName).toBe('A') expect(spy1).not.toHaveBeenCalled() expect(spy2).not.toHaveBeenCalled() await wrapper.find('a').trigger('click') expect(spy1).toHaveBeenCalled() expect(spy2).toHaveBeenCalled() wrapper.destroy() }) it('should NOT invoke click handler bound by Vue when disabled and clicked', async () => { let called = 0 let event = null const wrapper = mount(BLink, { propsData: { disabled: true }, listeners: { click: e => { event = e called++ } } }) expect(wrapper.element.tagName).toBe('A') expect(called).toBe(0) expect(event).toEqual(null) await wrapper.find('a').trigger('click') expect(called).toBe(0) expect(event).toEqual(null) wrapper.destroy() }) it('should NOT invoke click handler bound via "addEventListener" when disabled and clicked', async () => { const wrapper = mount(BLink, { propsData: { disabled: true } }) const spy = jest.fn() expect(wrapper.element.tagName).toBe('A') wrapper.find('a').element.addEventListener('click', spy) await wrapper.find('a').trigger('click') expect(spy).not.toHaveBeenCalled() wrapper.destroy() }) it('should emit "bv::link::clicked" on $root when clicked on', async () => { const spy = jest.fn() const App = { render(h) { return h('div', [h(BLink, { props: { href: '/foo' } }, 'link')]) } } const wrapper = mount(App) expect(wrapper.vm).toBeDefined() wrapper.vm.$root.$on('bv::link::clicked', spy) await wrapper.find('a').trigger('click') expect(spy).toHaveBeenCalled() wrapper.destroy() }) it('should not emit "bv::link::clicked" on $root when clicked on when disabled', async () => { const spy = jest.fn() const App = { render(h) { return h('div', [h(BLink, { props: { href: '/foo', disabled: true } }, 'link')]) } } const wrapper = mount(App) expect(wrapper.vm).toBeDefined() wrapper.vm.$root.$on('bv::link::clicked', spy) await wrapper.find('a').trigger('click') expect(spy).not.toHaveBeenCalled() wrapper.destroy() }) it('should emit "clicked::link" on $root when clicked on', async () => { const spy = jest.fn() const App = { render(h) { return h('div', [h(BLink, { props: { href: '/foo' } }, 'link')]) } } const wrapper = mount(App) expect(wrapper.vm).toBeDefined() wrapper.vm.$root.$on('clicked::link', spy) await wrapper.find('a').trigger('click') expect(spy).toHaveBeenCalled() wrapper.destroy() }) it('should not emit "clicked::link" on $root when clicked on when disabled', async () => { const spy = jest.fn() const App = { render(h) { return h('div', [h(BLink, { props: { href: '/foo', disabled: true } }, 'link')]) } } const wrapper = mount(App) expect(wrapper.vm).toBeDefined() wrapper.vm.$root.$on('clicked::link', spy) await wrapper.find('a').trigger('click') expect(spy).not.toHaveBeenCalled() wrapper.destroy() }) }) describe('router-link support', () => { it('works', async () => { const localVue = createLocalVue() const router = new VueRouter({ mode: 'abstract', routes: [ { path: '/', component: { name: 'R', template: '<div class="r">ROOT</div>' } }, { path: '/a', component: { name: 'A', template: '<div class="a">A</div>' } }, { path: '/b', component: { name: 'B', template: '<div class="a">B</div>' } } ] }) // Fake Gridsome `<g-link>` component const GLink = { name: 'GLink', props: { to: { type: [String, Object], default: '' } }, render(h) { // We just us a simple A tag to render the // fake `<g-link>` and assume `to` is a string return h('a', { attrs: { href: this.to } }, [this.$slots.default]) } } localVue.component('GLink', GLink) const App = { router, components: { BLink }, render(h) { return h('main', [ // router-link h('b-link', { props: { to: '/a' } }, ['to-a']), // regular link h('b-link', { props: { href: '/a' } }, ['href-a']), // router-link h('b-link', { props: { to: { path: '/b' } } }, ['to-path-b']), // g-link h('b-link', { props: { routerComponentName: 'g-link', to: '/a' } }, ['g-link-a']), h('router-view') ]) } } const wrapper = mount(App, { localVue, attachTo: document.body }) expect(wrapper.vm).toBeDefined() expect(wrapper.element.tagName).toBe('MAIN') expect(wrapper.findAll('a').length).toBe(4) const $links = wrapper.findAllComponents('a') $links.wrappers.forEach($link => { expect($link.vm).toBeDefined() expect($links.at(0).vm.$options.name).toBe('BLink') }) expect( $links.wrappers.map($link => $link.findComponent({ name: 'RouterLink' }).exists()) ).toStrictEqual([true, false, true, false]) expect( $links .at(3) .findComponent(GLink) .exists() ).toBe(true) wrapper.destroy() }) }) })