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

386 lines (323 loc) 11.6 kB
import { mount } from '@vue/test-utils' import { BButton } from './button' describe('button', () => { it('has default structure and classes', async () => { const wrapper = mount(BButton) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBeDefined() expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes().length).toBe(2) expect(wrapper.attributes('href')).toBeUndefined() expect(wrapper.attributes('role')).toBeUndefined() expect(wrapper.attributes('disabled')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.attributes('aria-pressed')).toBeUndefined() expect(wrapper.attributes('autocomplete')).toBeUndefined() expect(wrapper.attributes('tabindex')).toBeUndefined() wrapper.destroy() }) it('renders a link when href provided', async () => { const wrapper = mount(BButton, { propsData: { href: '/foo/bar' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.attributes('href')).toBeDefined() expect(wrapper.attributes('href')).toBe('/foo/bar') expect(wrapper.attributes('type')).toBeUndefined() expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes().length).toBe(2) expect(wrapper.attributes('role')).toBeUndefined() expect(wrapper.attributes('disabled')).toBeUndefined() expect(wrapper.attributes('aria-disabled')).toBeUndefined() expect(wrapper.attributes('aria-pressed')).toBeUndefined() expect(wrapper.attributes('autocomplete')).toBeUndefined() expect(wrapper.attributes('tabindex')).toBeUndefined() wrapper.destroy() }) it('renders default slot content', async () => { const wrapper = mount(BButton, { slots: { default: '<span>foobar</span>' } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBeDefined() expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes().length).toBe(2) expect(wrapper.find('span').exists()).toBe(true) expect(wrapper.text()).toBe('foobar') wrapper.destroy() }) it('applies variant class', async () => { const wrapper = mount(BButton, { propsData: { variant: 'danger' } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBeDefined() expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-danger') expect(wrapper.classes().length).toBe(2) wrapper.destroy() }) it('applies block class', async () => { const wrapper = mount(BButton, { propsData: { block: true } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBeDefined() expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).toContain('btn-block') expect(wrapper.classes().length).toBe(3) wrapper.destroy() }) it('applies rounded-pill class when pill prop set', async () => { const wrapper = mount(BButton, { propsData: { pill: true } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBeDefined() expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).toContain('rounded-pill') expect(wrapper.classes().length).toBe(3) wrapper.destroy() }) it('applies rounded-0 class when squared prop set', async () => { const wrapper = mount(BButton, { propsData: { squared: true } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBeDefined() expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).toContain('rounded-0') expect(wrapper.classes().length).toBe(3) wrapper.destroy() }) it('renders custom root element', async () => { const wrapper = mount(BButton, { propsData: { tag: 'div' } }) expect(wrapper.element.tagName).toBe('DIV') expect(wrapper.attributes('type')).toBeUndefined() expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes().length).toBe(2) expect(wrapper.attributes('role')).toBe('button') expect(wrapper.attributes('aria-disabled')).toBe('false') expect(wrapper.attributes('tabindex')).toBe('0') expect(wrapper.attributes('disabled')).toBeUndefined() expect(wrapper.attributes('aria-pressed')).toBeUndefined() expect(wrapper.attributes('autocomplete')).toBeUndefined() wrapper.destroy() }) it('button has attribute disabled when disabled set', async () => { const wrapper = mount(BButton, { propsData: { disabled: true } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(wrapper.attributes('type')).toBe('button') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).toContain('disabled') expect(wrapper.classes().length).toBe(3) expect(wrapper.attributes('aria-disabled')).toBeUndefined() wrapper.destroy() }) it('link has attribute aria-disabled when disabled set', async () => { const wrapper = mount(BButton, { propsData: { href: '/foo/bar', disabled: true } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).toContain('disabled') // Both <b-button> and <b-link> add the class 'disabled' // `vue-functional-data-merge` or Vue doesn't appear to de-dup classes // expect(wrapper.classes().length).toBe(3) // Actually returns 4, as disabled is there twice expect(wrapper.attributes('aria-disabled')).toBeDefined() expect(wrapper.attributes('aria-disabled')).toBe('true') // Shouldn't have a role with href not `#` expect(wrapper.attributes('role')).not.toEqual('button') wrapper.destroy() }) it('link with href="#" should have role="button"', async () => { const wrapper = mount(BButton, { propsData: { href: '#' } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).not.toContain('disabled') expect(wrapper.attributes('role')).toEqual('button') wrapper.destroy() }) it('should emit click event when clicked', async () => { let called = 0 let event = null const wrapper = mount(BButton, { listeners: { click: e => { event = e called++ } } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(called).toBe(0) expect(event).toEqual(null) await wrapper.find('button').trigger('click') expect(called).toBe(1) expect(event).toBeInstanceOf(MouseEvent) wrapper.destroy() }) it('link with href="#" should treat keydown.space as click', async () => { let called = 0 let event = null const wrapper = mount(BButton, { propsData: { href: '#' }, listeners: { click: e => { event = e called++ } } }) expect(wrapper.element.tagName).toBe('A') expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).not.toContain('disabled') expect(wrapper.attributes('role')).toEqual('button') expect(called).toBe(0) expect(event).toEqual(null) // We add keydown.space to make links act like buttons await wrapper.find('.btn').trigger('keydown.space') expect(called).toBe(1) expect(event).toBeInstanceOf(Event) // Links treat keydown.enter natively as a click wrapper.destroy() }) it('should not emit click event when clicked and disabled', async () => { let called = 0 const wrapper = mount(BButton, { propsData: { disabled: true }, listeners: { click: () => { called++ } } }) expect(wrapper.element.tagName).toBe('BUTTON') expect(called).toBe(0) await wrapper.find('button').trigger('click') expect(called).toBe(0) wrapper.destroy() }) it('should not have `.active` class and `aria-pressed` when pressed is null', async () => { const wrapper = mount(BButton, { propsData: { pressed: null } }) expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeUndefined() await wrapper.find('button').trigger('click') expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeUndefined() expect(wrapper.attributes('autocomplete')).toBeUndefined() wrapper.destroy() }) it('should not have `.active` class and have `aria-pressed="false"` when pressed is false', async () => { const wrapper = mount(BButton, { propsData: { pressed: false } }) expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('false') expect(wrapper.attributes('autocomplete')).toBeDefined() expect(wrapper.attributes('autocomplete')).toBe('off') wrapper.destroy() }) it('should have `.active` class and have `aria-pressed="true"` when pressed is true', async () => { const wrapper = mount(BButton, { propsData: { pressed: true } }) expect(wrapper.classes()).toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('true') expect(wrapper.attributes('autocomplete')).toBeDefined() expect(wrapper.attributes('autocomplete')).toBe('off') wrapper.destroy() }) it('pressed should have `.focus` class when focused', async () => { const wrapper = mount(BButton, { propsData: { pressed: false } }) expect(wrapper.classes()).not.toContain('focus') await wrapper.trigger('focusin') expect(wrapper.classes()).toContain('focus') await wrapper.trigger('focusout') expect(wrapper.classes()).not.toContain('focus') wrapper.destroy() }) it('should update the parent sync value on click and when pressed is not null', async () => { let called = 0 const values = [] const wrapper = mount(BButton, { propsData: { pressed: false }, listeners: { 'update:pressed': value => { values.push(value) called++ } } }) expect(called).toBe(0) await wrapper.find('button').trigger('click') expect(called).toBe(1) expect(values[0]).toBe(true) wrapper.destroy() }) })