From c192d4f62017effd8abd2b42dbc23fadf302cb80 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 20:37:56 -0300 Subject: [PATCH 01/19] chore(unit tests): more test conversion --- .../button-group/button-group.spec.js | 72 ++++++++++++++----- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/src/components/button-group/button-group.spec.js b/src/components/button-group/button-group.spec.js index 11d92493954..cc7784e886c 100644 --- a/src/components/button-group/button-group.spec.js +++ b/src/components/button-group/button-group.spec.js @@ -1,30 +1,64 @@ -import { loadFixture, testVM } from '../../../tests/utils' +import ButtonGroup from './button-group' +import { mount } from '@vue/test-utils' describe('button-group', () => { - beforeEach(loadFixture(__dirname, 'button-group')) - testVM() - - it('basic should contain base class', async () => { - const { - app: { $refs } - } = window - - expect($refs.basic).toHaveClass('btn-group') + it('has expected default structure', async () => { + const wrapper = mount(ButtonGroup) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toBe('group') }) it('should apply vertical class', async () => { - const { - app: { $refs } - } = window - - expect($refs.vertical).toHaveClass('btn-group-vertical') + const wrapper = mount(ButtonGroup, { + propsData: { + vertical: true + } + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes()).toContain('btn-group-vertical') + expect(wrapper.classes().length).toBe(2) }) it('should apply size class', async () => { - const { - app: { $refs } - } = window + const wrapper = mount(ButtonGroup, { + propsData: { + size: 'sm' + } + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes()).toContain('btn-group-sm') + expect(wrapper.classes().length).toBe(2) + }) + + it('should apply size class when vertical', async () => { + const wrapper = mount(ButtonGroup, { + propsData: { + size: 'sm', + vertical: true + } + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes()).toContain('btn-group-sm') + expect(wrapper.classes()).toContain('btn-group-vertical') + expect(wrapper.classes().length).toBe(3) + }) - expect($refs.size).toHaveClass('btn-group-sm') + it('has custom role when aria-role prop set', async () => { + const wrapper = mount(ButtonGroup, { + propsData: { + ariaRole: 'foobar' + } + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toBe('foobar') }) }) From 9c81abf3409403a727e7f8cdd9c20623408eaf63 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 20:39:03 -0300 Subject: [PATCH 02/19] Delete button-group.html --- .../button-group/fixtures/button-group.html | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/components/button-group/fixtures/button-group.html diff --git a/src/components/button-group/fixtures/button-group.html b/src/components/button-group/fixtures/button-group.html deleted file mode 100644 index 87e5159c641..00000000000 --- a/src/components/button-group/fixtures/button-group.html +++ /dev/null @@ -1,27 +0,0 @@ -
-
- -
- - Top - Middle - Bottom - -
- -
- - Left - Middle - Right - -
-
- - Left - Middle - Right - -
-
-
From b4bd37cb821f6254afe8d633fe7fdf6bd266bd8e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 20:39:12 -0300 Subject: [PATCH 03/19] Delete button-group.js --- src/components/button-group/fixtures/button-group.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 src/components/button-group/fixtures/button-group.js diff --git a/src/components/button-group/fixtures/button-group.js b/src/components/button-group/fixtures/button-group.js deleted file mode 100644 index 0bae7b95202..00000000000 --- a/src/components/button-group/fixtures/button-group.js +++ /dev/null @@ -1,3 +0,0 @@ -window.app = new Vue({ - el: '#app' -}) From 43eda8cbe91ddf63040f01c96787db04822247ca Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 20:41:08 -0300 Subject: [PATCH 04/19] Update button-group.spec.js --- src/components/button-group/button-group.spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/button-group/button-group.spec.js b/src/components/button-group/button-group.spec.js index cc7784e886c..f3bdbe3a5a9 100644 --- a/src/components/button-group/button-group.spec.js +++ b/src/components/button-group/button-group.spec.js @@ -9,6 +9,22 @@ describe('button-group', () => { expect(wrapper.classes().length).toBe(1) expect(wrapper.attributes('role')).toBeDefined() expect(wrapper.attributes('role')).toBe('group') + expect(wrapper.text()).toBe('') + }) + + it('should render default slot', async () => { + const wrapper = mount(ButtonGroup, { + slots: { + default: 'foobar' + } + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toBe('group') + expect(wrapper.find('span').exists()).toBe(true) + expect(wrapper.text()).toBe('foobar') }) it('should apply vertical class', async () => { From 8d02a1a0e31ec00be47b0fb7fecc8f03843a34c8 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 20:42:31 -0300 Subject: [PATCH 05/19] Update button-group.spec.js --- src/components/button-group/button-group.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/button-group/button-group.spec.js b/src/components/button-group/button-group.spec.js index f3bdbe3a5a9..ea67a4864bc 100644 --- a/src/components/button-group/button-group.spec.js +++ b/src/components/button-group/button-group.spec.js @@ -34,9 +34,9 @@ describe('button-group', () => { } }) expect(wrapper.is('div')).toBe(true) - expect(wrapper.classes()).toContain('btn-group') expect(wrapper.classes()).toContain('btn-group-vertical') - expect(wrapper.classes().length).toBe(2) + expect(wrapper.classes()).not.toContain('btn-group') + expect(wrapper.classes().length).toBe(1) }) it('should apply size class', async () => { @@ -59,10 +59,10 @@ describe('button-group', () => { } }) expect(wrapper.is('div')).toBe(true) - expect(wrapper.classes()).toContain('btn-group') expect(wrapper.classes()).toContain('btn-group-sm') expect(wrapper.classes()).toContain('btn-group-vertical') - expect(wrapper.classes().length).toBe(3) + expect(wrapper.classes()).not.toContain('btn-group') + expect(wrapper.classes().length).toBe(2) }) it('has custom role when aria-role prop set', async () => { From 4ec24b8c8e763aa388d4dbab82cc83f921a5da5c Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:25:24 -0300 Subject: [PATCH 06/19] Update button.spec.js --- src/components/button/button.spec.js | 369 +++++++++++++++++---------- 1 file changed, 231 insertions(+), 138 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index c9525e0d00e..632594b5ce8 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -1,191 +1,284 @@ -import { loadFixture, testVM, nextTick, setData } from '../../../tests/utils' +import Button from './button' +import Link from '../link/link' +import { mount } from '@vue/test-utils' -/** - * Button functionality to test: - * - Style variants: [ 'primary','secondary','success','outline-success','warning','danger','link' ] - * - Sizes: [ 'sm','','lg' ] - * - Props: [ disabled, block ] - * - elements: [ , ] - */ -const colorVariants = ['primary', 'secondary', 'success', 'warning', 'danger'] -const outlineVariants = colorVariants.map(v => `outline-${v}`) -const variants = colorVariants.concat(outlineVariants, 'link') -const sizes = ['sm', '', 'lg'] - -const btnRefs = variants.reduce( - (memo, variant) => - memo.concat( - sizes.map(size => { - return { - variant, - size, - ref: `btn${size ? `_${size}` : ''}_${variant.replace(/-/g, '_')}` - } - }) - ), - [] -) +import { loadFixture, testVM, nextTick, setData } from '../../../tests/utils' describe('button', () => { - beforeEach(loadFixture(__dirname, 'button')) - testVM() + it('has default structure and classes', async () => { + const wrapper = mount(Button) + + expect(wrapper.is('button')).toBe(true) + 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')).not.toBeDefined() + expect(wrapper.attributes('role')).not.toBeDefined() + expect(wrapper.attributes('disabled')).not.toBeDefined() + expect(wrapper.attributes('aria-disabled')).not.toBeDefined() + expect(wrapper.attributes('aria-pressed')).not.toBeDefined() + expect(wrapper.attributes('autocomplete')).not.toBeDefined() + expect(wrapper.attributes('tabindex')).not.toBeDefined() + }) + + it('renders a link when href provided', async () => { + const wrapper = mount(Button, { + propsData: { + href: '/foo/bar' + } + }) - it('should contain class names', async () => { - const { - app: { $refs } - } = window + expect(wrapper.is('a')).toBe(true) + expect(wrapper.is(Link)).toBe(true) + expect(wrapper.attributes('href')).toBeDefined() + expect(wrapper.attributes('href')).toBe('/foo/bar') + expect(wrapper.attributes('type')).not.toBeDefined() + expect(wrapper.classes()).toContain('btn') + expect(wrapper.classes()).toContain('btn-secondary') + expect(wrapper.classes().length).toBe(2) + expect(wrapper.attributes('role')).not.toBeDefined() + expect(wrapper.attributes('disabled')).not.toBeDefined() + expect(wrapper.attributes('aria-disabled')).not.toBeDefined() + expect(wrapper.attributes('aria-pressed')).not.toBeDefined() + expect(wrapper.attributes('autocomplete')).not.toBeDefined() + expect(wrapper.attributes('tabindex')).not.toBeDefined() + }) - btnRefs.forEach(({ ref, variant, size }) => { - // ref will contain an array of children because of v-for - const vm = $refs[ref][0] + it('renders default slot content', async () => { + const wrapper = mount(Button, { + slots: { + default: 'foobar' + } + }) - let classList = ['btn', `btn-${variant}`] - if (size) classList.push(`btn-${size}`) + expect(wrapper.is('button')).toBe(true) + 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') + }) - expect(vm).toHaveAllClasses(classList) + it('applies variant class', async () => { + const wrapper = mount(Button, { + propsData: { + variant: 'danger' + } }) - const vmBlockDisabled = $refs.btn_block_disabled - expect(vmBlockDisabled).toHaveAllClasses(['btn', 'btn-block', 'disabled']) + expect(wrapper.is('button')).toBe(true) + 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) }) - it('should use when given href', async () => { - const { - app: { $refs } - } = window - const btnRootNode = $refs.btn_href + it('applies block class', async () => { + const wrapper = mount(Button, { + propsData: { + block: true + } + }) - expect(btnRootNode).toBeElement('a') - expect(btnRootNode.href).toBe('https://github.com/bootstrap-vue/bootstrap-vue') + expect(wrapper.is('button')).toBe(true) + 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) }) - it('should use the given tag', async () => { - const { - app: { $refs } - } = window - const btnRootNode = $refs.btn_div + it('renders custom root element', async () => { + const wrapper = mount(Button, { + propsData: { + tag: 'div' + } + }) - expect(btnRootNode).toBeElement('div') + expect(wrapper.is('div')).toBe(true) + expect(wrapper.attributes('type')).not.toBeDefined() + expect(wrapper.classes()).toContain('btn') + expect(wrapper.classes()).toContain('btn-secondary') + expect(wrapper.classes().length).toBe(3) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toBe('button') + expect(wrapper.attributes('tabindex')).toBeDefined() + expect(wrapper.attributes('tabindex')).toBe('0') + expect(wrapper.attributes('disabled')).not.toBeDefined() + expect(wrapper.attributes('aria-disabled')).not.toBeDefined() + expect(wrapper.attributes('aria-pressed')).not.toBeDefined() + expect(wrapper.attributes('autocomplete')).not.toBeDefined() }) - it('should use button when no tag is given', async () => { - const { - app: { $refs } - } = window - const btnRootNode = $refs.btn_no_tag + it('button has attribute disabled when disabled set', async () => { + const wrapper = mount(Button, { + propsData: { + disabled: true + } + }) - expect(btnRootNode).toBeElement('button') + expect(wrapper.is('button')).toBe(true) + 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')).not.toBeDefined() }) - it('should emit "click" event when clicked', async () => { - const { - app: { $refs } - } = window - const btn = $refs.btn_click - const spy = jest.fn() + it('link has attribute aria-disabled when disabled set', async () => { + const wrapper = mount(Button, { + propsData: { + href: '/foo/bar', + disabled: true + } + }) - btn.addEventListener('click', spy) - btn.click() + expect(wrapper.is('a')).toBe(true) + 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')).toBeDefined() + expect(wrapper.attributes('aria-disabled')).toBe('true') + }) + it('should emit click event when clicked', async () => { + const spy = jest.fn() + const wrapper = mount(Button, { + listeners: { + click: spy + } + }) + + expect(wrapper.is('button')).toBe(true) + expect(spy).not.toHaveBeenCalled() + wrapper.find('button').trigger('click') expect(spy).toHaveBeenCalled() }) - it('should "click" event should emit with native event object', async () => { - const { - app: { $refs } - } = window - const btn = $refs.btn_click - let event = null - - btn.addEventListener('click', e => (event = e)) - btn.click() + it('should emit click event when clicked', async () => { + const evt = null + const wrapper = mount(Button, { + listeners: { + click: e => { evt = e } + } + }) - expect(event).toBeInstanceOf(MouseEvent) + expect(wrapper.is('button')).toBe(true) + expect(evt).toEqual(null) + wrapper.find('button').trigger('click') + expect(evt).toBeInstanceOf(MouseEvent) }) - it('should be disabled and not emit click event with `disabled` prop true', async () => { - const { - app: { $refs } - } = window - const btn = $refs.btn_block_disabled + it('should not emit click event when clicked and disabled', async () => { const spy = jest.fn() + const wrapper = mount(Button, { + propsData: { + disabled: true + }, + listeners: { + click: spy + } + }) - btn.addEventListener('click', spy) - btn.click() - - expect(btn.disabled).toBe(true) + expect(wrapper.is('button')).toBe(true) + expect(spy).not.toHaveBeenCalled() + wrapper.find('button').trigger('click') expect(spy).not.toHaveBeenCalled() }) it('should not have `.active` class and `aria-pressed` when pressed is null', async () => { - const { app } = window - const vm = app.$refs.btn_pressed - - await setData(app, 'btnToggle', null) - await nextTick() + const wrapper = mount(Button, { + propsData: { + pressed: null + } + }) - expect(vm).not.toHaveClass('active') - expect(vm.getAttribute('aria-pressed')).toBeNull() - vm.click() - expect(app.btnToggle).toBeNull() + expect(wrapper.classes()).not.toContain('active') + expect(wrapper.attributes('aria-pressed')).not.toBeDefined() + wrapper.find('button').trigger('click') + expect(wrapper.classes()).not.toContain('active') + expect(wrapper.attributes('aria-pressed')).not.toBeDefined() + expect(wrapper.attributes('autocomplete')).not.toBeDefined() }) it('should not have `.active` class and have `aria-pressed="false"` when pressed is false', async () => { - const { app } = window - const vm = app.$refs.btn_pressed - - await setData(app, 'btnToggle', false) - await nextTick() + const wrapper = mount(Button, { + propsData: { + pressed: false + } + }) - expect(vm).not.toHaveClass('active') - expect(vm.getAttribute('aria-pressed')).toBe('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') }) it('should have `.active` class and have `aria-pressed="true"` when pressed is true', async () => { - const { app } = window - const vm = app.$refs.btn_pressed + const wrapper = mount(Button, { + propsData: { + pressed: true + } + }) - await setData(app, 'btnToggle', true) - await nextTick() + 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') + }) - vm.click() + it('pressed should have `.focus` class when focused', async () => { + const wrapper = mount(Button, { + propsData: { + pressed: false + } + }) - expect(vm).toHaveClass('active') - expect(vm.getAttribute('aria-pressed')).toBe('true') + expect(wrapper.classes()).not.toContain('focus') + wrapper.trigger('focusin') + expect(wrapper.classes()).toContain('focus') + wrapper.trigger('focusout') + expect(wrapper.classes()).not.toContain('focus') }) - it('pressed should have `.focus` class when focused', async () => { - const { app } = window - const btn = app.$refs.btn_pressed + it('should update the parent sync value on click and when pressed is not null', async () => { + const wrapper = mount(Button, { + propsData: { + pressed: false + } + }) - await setData(app, 'btnToggle', false) - await nextTick() + expect(wrapper.classes()).not.toContain('active') + expect(wrapper.attributes('aria-pressed')).toBeDefined() + expect(wrapper.attributes('aria-pressed')).toBe('false') + expect(wrapper.emitted('update:pressed')).not.toBeDefined() - const focusinEvt = new FocusEvent('focusin') - btn.dispatchEvent(focusinEvt) - await nextTick() - expect(btn).toHaveClass('focus') + wrapper.find('button').trigger('click') - const focusoutEvt = new FocusEvent('focusout') - btn.dispatchEvent(focusoutEvt) - await nextTick() - expect(btn).not.toHaveClass('focus') - }) + expect(wrapper.classes()).toContain('active') + expect(wrapper.attributes('aria-pressed')).toBeDefined() + expect(wrapper.attributes('aria-pressed')).toBe('true') + expect(wrapper.emitted('update:pressed')).toBeDefined() + expect(wrapper.emitted('update:pressed').length).toBe(1) + expect(wrapper.emitted('update:pressed')[0][0]).toBe(true) - it('should update the parent sync value on click and when pressed is not null', async () => { - const { app } = window - const vm = app.$refs.btn_pressed - - await setData(app, 'btnToggle', false) - await nextTick() - - expect(app.btnToggle).toBe(false) - expect(vm).not.toHaveClass('active') - expect(vm.getAttribute('aria-pressed')).toBe('false') - vm.click() - await nextTick() - expect(app.btnToggle).toBe(true) - expect(vm).toHaveClass('active') - expect(vm.getAttribute('aria-pressed')).toBe('true') + wrapper.find('button').trigger('click') + + expect(wrapper.classes()).not.toContain('active') + expect(wrapper.attributes('aria-pressed')).toBeDefined() + expect(wrapper.attributes('aria-pressed')).toBe('false') + expect(wrapper.emitted('update:pressed')).toBeDefined() + expect(wrapper.emitted('update:pressed').length).toBe(2) + expect(wrapper.emitted('update:pressed')[1][0]).toBe(false) }) }) From 84649cf8c312170e4cdadffb0456c0c299fe411a Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:26:20 -0300 Subject: [PATCH 07/19] Delete button-close.html --- src/components/button/fixtures/button-close.html | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/components/button/fixtures/button-close.html diff --git a/src/components/button/fixtures/button-close.html b/src/components/button/fixtures/button-close.html deleted file mode 100644 index f1192872cab..00000000000 --- a/src/components/button/fixtures/button-close.html +++ /dev/null @@ -1,8 +0,0 @@ -
- - close - - - - -
From 61d8887cd29d96ddea914587d6142a7a65cfa399 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:26:32 -0300 Subject: [PATCH 08/19] Delete button-close.js --- src/components/button/fixtures/button-close.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 src/components/button/fixtures/button-close.js diff --git a/src/components/button/fixtures/button-close.js b/src/components/button/fixtures/button-close.js deleted file mode 100644 index 94343157bdb..00000000000 --- a/src/components/button/fixtures/button-close.js +++ /dev/null @@ -1,11 +0,0 @@ -window.app = new Vue({ - el: '#app', - data: { - spies: [] - }, - methods: { - handleClick() { - this.spies.forEach(spy => spy.apply(undefined, arguments)) - } - } -}) From e9c33647b6f9d04be84965f925d4a7ae04ec7488 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:26:42 -0300 Subject: [PATCH 09/19] Delete button.html --- src/components/button/fixtures/button.html | 63 ---------------------- 1 file changed, 63 deletions(-) delete mode 100644 src/components/button/fixtures/button.html diff --git a/src/components/button/fixtures/button.html b/src/components/button/fixtures/button.html deleted file mode 100644 index 971755303ea..00000000000 --- a/src/components/button/fixtures/button.html +++ /dev/null @@ -1,63 +0,0 @@ -
-
- -
- - - Link button! - github - -
-
- - I am a div - -
-
- - I am a button - -
-
- - Click me! - -
-
- - Can't touch this - -
-
- - Toggle Me - -
-
-
From ddebf972ed90a056de89f071062cfefcfa1ab896 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:26:53 -0300 Subject: [PATCH 10/19] Delete button.js --- src/components/button/fixtures/button.js | 25 ------------------------ 1 file changed, 25 deletions(-) delete mode 100644 src/components/button/fixtures/button.js diff --git a/src/components/button/fixtures/button.js b/src/components/button/fixtures/button.js deleted file mode 100644 index 8e1172350b1..00000000000 --- a/src/components/button/fixtures/button.js +++ /dev/null @@ -1,25 +0,0 @@ -window.app = new Vue({ - el: '#app', - data: { - variants: [ - 'primary', - 'secondary', - 'success', - 'warning', - 'danger', - 'outline-primary', - 'outline-secondary', - 'outline-success', - 'outline-warning', - 'outline-danger', - 'link' - ], - sizes: ['sm', '', 'lg'], - btnToggle: null - }, - methods: { - handleClick(event) { - // STUB! - } - } -}) From 09dcd38bd4e69ba546aa7f1e0a74874d0f8d23b7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:27:11 -0300 Subject: [PATCH 11/19] Update button.spec.js --- src/components/button/button.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 632594b5ce8..b8b69287872 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -2,8 +2,6 @@ import Button from './button' import Link from '../link/link' import { mount } from '@vue/test-utils' -import { loadFixture, testVM, nextTick, setData } from '../../../tests/utils' - describe('button', () => { it('has default structure and classes', async () => { const wrapper = mount(Button) From 079c7166f78d237fbfed57fe377b28fba0635d5e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:41:23 -0300 Subject: [PATCH 12/19] Update button.spec.js --- src/components/button/button.spec.js | 58 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index b8b69287872..6fd63ad77f7 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -1,5 +1,4 @@ import Button from './button' -import Link from '../link/link' import { mount } from '@vue/test-utils' describe('button', () => { @@ -29,7 +28,6 @@ describe('button', () => { }) expect(wrapper.is('a')).toBe(true) - expect(wrapper.is(Link)).toBe(true) expect(wrapper.attributes('href')).toBeDefined() expect(wrapper.attributes('href')).toBe('/foo/bar') expect(wrapper.attributes('type')).not.toBeDefined() @@ -103,7 +101,7 @@ describe('button', () => { expect(wrapper.attributes('type')).not.toBeDefined() expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') - expect(wrapper.classes().length).toBe(3) + expect(wrapper.classes().length).toBe(2) expect(wrapper.attributes('role')).toBeDefined() expect(wrapper.attributes('role')).toBe('button') expect(wrapper.attributes('tabindex')).toBeDefined() @@ -148,48 +146,42 @@ describe('button', () => { }) it('should emit click event when clicked', async () => { - const spy = jest.fn() - const wrapper = mount(Button, { - listeners: { - click: spy - } - }) - - expect(wrapper.is('button')).toBe(true) - expect(spy).not.toHaveBeenCalled() - wrapper.find('button').trigger('click') - expect(spy).toHaveBeenCalled() - }) - - it('should emit click event when clicked', async () => { + const called = 0 const evt = null const wrapper = mount(Button, { listeners: { - click: e => { evt = e } + click: e => { + evt = e + called++ + } } }) expect(wrapper.is('button')).toBe(true) - expect(evt).toEqual(null) + expect(called).toBe(0) + expect(called).toEqual(null) wrapper.find('button').trigger('click') + expect(called).toBe(1) expect(evt).toBeInstanceOf(MouseEvent) }) it('should not emit click event when clicked and disabled', async () => { - const spy = jest.fn() + const called = 0 const wrapper = mount(Button, { propsData: { disabled: true }, listeners: { - click: spy + click: e => { + called++ + } } }) expect(wrapper.is('button')).toBe(true) - expect(spy).not.toHaveBeenCalled() + expect(called).toBe(0) wrapper.find('button').trigger('click') - expect(spy).not.toHaveBeenCalled() + expect(called).toBe(0) }) it('should not have `.active` class and `aria-pressed` when pressed is null', async () => { @@ -250,33 +242,39 @@ describe('button', () => { }) it('should update the parent sync value on click and when pressed is not null', async () => { + const called = 0 + const values = [] const wrapper = mount(Button, { propsData: { pressed: false + }, + listeners: { + 'update:pressed': val => { + values.push(val) + called++ + } } }) expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('false') - expect(wrapper.emitted('update:pressed')).not.toBeDefined() + expect(called).toBe(0) wrapper.find('button').trigger('click') expect(wrapper.classes()).toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('true') - expect(wrapper.emitted('update:pressed')).toBeDefined() - expect(wrapper.emitted('update:pressed').length).toBe(1) - expect(wrapper.emitted('update:pressed')[0][0]).toBe(true) + expect(called).toBe(1) + expect(values[0]).toBe(true) wrapper.find('button').trigger('click') expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('false') - expect(wrapper.emitted('update:pressed')).toBeDefined() - expect(wrapper.emitted('update:pressed').length).toBe(2) - expect(wrapper.emitted('update:pressed')[1][0]).toBe(false) + expect(called).toBe(2) + expect(values[1]).toBe(false) }) }) From 304147c95b8e97847bbefe2d1f7214257c8323ad Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:46:27 -0300 Subject: [PATCH 13/19] Update button.spec.js --- src/components/button/button.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 6fd63ad77f7..66e137b6e19 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -140,7 +140,10 @@ describe('button', () => { expect(wrapper.classes()).toContain('btn') expect(wrapper.classes()).toContain('btn-secondary') expect(wrapper.classes()).toContain('disabled') - expect(wrapper.classes().length).toBe(3) + // Both b-button and b-link add hte 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') }) From 14774432f65354617503d26241194755eb5cb2bb Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:48:07 -0300 Subject: [PATCH 14/19] Update button.spec.js --- src/components/button/button.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 66e137b6e19..4be0cc87dc4 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -149,8 +149,8 @@ describe('button', () => { }) it('should emit click event when clicked', async () => { - const called = 0 - const evt = null + let called = 0 + let evt = null const wrapper = mount(Button, { listeners: { click: e => { From f947ee29ef0e88372290d6ecb684866a34df0070 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:50:16 -0300 Subject: [PATCH 15/19] Update button.spec.js --- src/components/button/button.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 4be0cc87dc4..96ae8e4238b 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -169,7 +169,7 @@ describe('button', () => { }) it('should not emit click event when clicked and disabled', async () => { - const called = 0 + let called = 0 const wrapper = mount(Button, { propsData: { disabled: true @@ -245,7 +245,7 @@ describe('button', () => { }) it('should update the parent sync value on click and when pressed is not null', async () => { - const called = 0 + let called = 0 const values = [] const wrapper = mount(Button, { propsData: { From b4cea23c9b337edfff632f1c9fa03ccfaf67514d Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 21:58:43 -0300 Subject: [PATCH 16/19] Update button.spec.js --- src/components/button/button.spec.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 96ae8e4238b..27e416d2d80 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -104,10 +104,11 @@ describe('button', () => { expect(wrapper.classes().length).toBe(2) expect(wrapper.attributes('role')).toBeDefined() expect(wrapper.attributes('role')).toBe('button') + expect(wrapper.attributes('aria-disabled')).toBeDefined() + expect(wrapper.attributes('aria-disabled')).toBe('false') expect(wrapper.attributes('tabindex')).toBeDefined() expect(wrapper.attributes('tabindex')).toBe('0') expect(wrapper.attributes('disabled')).not.toBeDefined() - expect(wrapper.attributes('aria-disabled')).not.toBeDefined() expect(wrapper.attributes('aria-pressed')).not.toBeDefined() expect(wrapper.attributes('autocomplete')).not.toBeDefined() }) @@ -162,7 +163,7 @@ describe('button', () => { expect(wrapper.is('button')).toBe(true) expect(called).toBe(0) - expect(called).toEqual(null) + expect(evt).toEqual(null) wrapper.find('button').trigger('click') expect(called).toBe(1) expect(evt).toBeInstanceOf(MouseEvent) @@ -259,14 +260,12 @@ describe('button', () => { } }) - expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('false') expect(called).toBe(0) wrapper.find('button').trigger('click') - expect(wrapper.classes()).toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('true') expect(called).toBe(1) @@ -274,7 +273,6 @@ describe('button', () => { wrapper.find('button').trigger('click') - expect(wrapper.classes()).not.toContain('active') expect(wrapper.attributes('aria-pressed')).toBeDefined() expect(wrapper.attributes('aria-pressed')).toBe('false') expect(called).toBe(2) From e7482a7c6260cf2c3466d605b0e94aaac328b5bb Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 22:01:21 -0300 Subject: [PATCH 17/19] Update button.spec.js --- src/components/button/button.spec.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 27e416d2d80..6cce05365fb 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -260,21 +260,15 @@ describe('button', () => { } }) - expect(wrapper.attributes('aria-pressed')).toBeDefined() - expect(wrapper.attributes('aria-pressed')).toBe('false') expect(called).toBe(0) wrapper.find('button').trigger('click') - expect(wrapper.attributes('aria-pressed')).toBeDefined() - expect(wrapper.attributes('aria-pressed')).toBe('true') expect(called).toBe(1) expect(values[0]).toBe(true) wrapper.find('button').trigger('click') - expect(wrapper.attributes('aria-pressed')).toBeDefined() - expect(wrapper.attributes('aria-pressed')).toBe('false') expect(called).toBe(2) expect(values[1]).toBe(false) }) From 292e42608561092389f6796abe027af278d94e04 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 22:24:14 -0300 Subject: [PATCH 18/19] Update button.spec.js --- src/components/button/button.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 6cce05365fb..1c3c9504740 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -266,6 +266,10 @@ describe('button', () => { expect(called).toBe(1) expect(values[0]).toBe(true) + // Emulate prop updating + wrapper.setProps({ + pressed: true + }) wrapper.find('button').trigger('click') From 1eee23ab6c55a96ed316e7c519719a9184128938 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 22:32:43 -0300 Subject: [PATCH 19/19] Update button.spec.js --- src/components/button/button.spec.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 1c3c9504740..7047262b12c 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -266,14 +266,5 @@ describe('button', () => { expect(called).toBe(1) expect(values[0]).toBe(true) - // Emulate prop updating - wrapper.setProps({ - pressed: true - }) - - wrapper.find('button').trigger('click') - - expect(called).toBe(2) - expect(values[1]).toBe(false) }) })