From 0d6b0239317e09e4491c0a3c0f5637afb9fc26ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 27 Mar 2019 14:44:33 +0100 Subject: [PATCH 01/38] fix(collapse): prevent state event to be triggered multiple times --- src/directives/toggle/toggle.js | 56 ++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/directives/toggle/toggle.js b/src/directives/toggle/toggle.js index 6f5a065ae6e..294c8c45a03 100644 --- a/src/directives/toggle/toggle.js +++ b/src/directives/toggle/toggle.js @@ -1,24 +1,25 @@ -import target from '../../utils/target' -import { setAttr, addClass, removeClass } from '../../utils/dom' +import { setAttr, addClass, removeClass, hasClass } from '../../utils/dom' +import { inBrowser } from '../../utils/env' +import { bindTargets, unbindTargets } from '../../utils/target' -// Are we client side? -const inBrowser = typeof window !== 'undefined' - -// target listen types +// Target listen types const listenTypes = { click: true } // Property key for handler storage -const BVT = '__BV_toggle__' +const BV_TOGGLE = '__BV_toggle__' -// Emitted Control Event for collapse (emitted to collapse) +// Emitted control Event for collapse (emitted to collapse) const EVENT_TOGGLE = 'bv::toggle::collapse' -// Listen to Event for toggle state update (Emited by collapse) +// Listen to event for toggle state update (emitted by collapse) const EVENT_STATE = 'bv::collapse::state' +/* + * Export our directive + */ export default { bind(el, binding, vnode) { - const targets = target(vnode, binding, listenTypes, ({ targets, vnode }) => { + const targets = bindTargets(vnode, binding, listenTypes, ({ targets, vnode }) => { targets.forEach(target => { vnode.context.$root.$emit(EVENT_TOGGLE, target) }) @@ -28,34 +29,37 @@ export default { // Add aria attributes to element setAttr(el, 'aria-controls', targets.join(' ')) setAttr(el, 'aria-expanded', 'false') + // If element is not a button, we add `role="button"` for accessibility if (el.tagName !== 'BUTTON') { - // If element is not a button, we add `role="button"` for accessibility setAttr(el, 'role', 'button') } - // Toggle state hadnler, stored on element - el[BVT] = function toggleDirectiveHandler(id, state) { - if (targets.indexOf(id) !== -1) { - // Set aria-expanded state - setAttr(el, 'aria-expanded', state ? 'true' : 'false') - // Set/Clear 'collapsed' class state - if (state) { - removeClass(el, 'collapsed') - } else { - addClass(el, 'collapsed') - } + // Toggle state handler, stored on element + el[BV_TOGGLE] = function toggleDirectiveHandler(id, state) { + // Exit early when unknown target or state hasn't changed + if (targets.indexOf(id) === -1 || hasClass(el, 'collapsed') !== state) { + return + } + // Set aria-expanded state + setAttr(el, 'aria-expanded', state ? 'true' : 'false') + // Set/clear 'collapsed' class state + if (state) { + removeClass(el, 'collapsed') + } else { + addClass(el, 'collapsed') } } // Listen for toggle state changes - vnode.context.$root.$on(EVENT_STATE, el[BVT]) + vnode.context.$root.$on(EVENT_STATE, el[BV_TOGGLE]) } }, unbind(el, binding, vnode) /* istanbul ignore next */ { - if (el[BVT]) { + unbindTargets(vnode, binding, listenTypes) + if (el[BV_TOGGLE]) { // Remove our $root listener - vnode.context.$root.$off(EVENT_STATE, el[BVT]) - el[BVT] = null + vnode.context.$root.$off(EVENT_STATE, el[BV_TOGGLE]) + el[BV_TOGGLE] = null } } } From e3d474d706bae73e99ae28638432b95b376eda91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 27 Mar 2019 14:45:13 +0100 Subject: [PATCH 02/38] minor tweaks to other directives --- src/directives/modal/modal.js | 15 ++-- src/directives/popover/popover.js | 73 +++++++++----------- src/directives/scrollspy/scrollspy.js | 99 ++++++++++++++------------- src/directives/tooltip/tooltip.js | 75 ++++++++++---------- 4 files changed, 131 insertions(+), 131 deletions(-) diff --git a/src/directives/modal/modal.js b/src/directives/modal/modal.js index 6b26c4e54c0..e4cb4b11d3a 100644 --- a/src/directives/modal/modal.js +++ b/src/directives/modal/modal.js @@ -1,25 +1,32 @@ -import { bindTargets, unbindTargets } from '../../utils/target' import { setAttr, removeAttr } from '../../utils/dom' +import { bindTargets, unbindTargets } from '../../utils/target' +// Target listen types const listenTypes = { click: true } +// Emitted show event for modal +const EVENT_SHOW = 'bv::show::modal' + +/* + * Export our directive + */ export default { // eslint-disable-next-line no-shadow-restricted-names bind(el, binding, vnode) { bindTargets(vnode, binding, listenTypes, ({ targets, vnode }) => { targets.forEach(target => { - vnode.context.$root.$emit('bv::show::modal', target, vnode.elm) + vnode.context.$root.$emit(EVENT_SHOW, target, vnode.elm) }) }) + // If element is not a button, we add `role="button"` for accessibility if (el.tagName !== 'BUTTON') { - // If element is not a button, we add `role="button"` for accessibility setAttr(el, 'role', 'button') } }, unbind(el, binding, vnode) { unbindTargets(vnode, binding, listenTypes) + // If element is not a button, we add `role="button"` for accessibility if (el.tagName !== 'BUTTON') { - // If element is not a button, we add `role="button"` for accessibility removeAttr(el, 'role', 'button') } } diff --git a/src/directives/popover/popover.js b/src/directives/popover/popover.js index 5991f7ddd77..514e420045b 100644 --- a/src/directives/popover/popover.js +++ b/src/directives/popover/popover.js @@ -1,12 +1,11 @@ import Popper from 'popper.js' import PopOver from '../../utils/popover.class' +import { inBrowser } from '../../utils/env' import { keys } from '../../utils/object' import warn from '../../utils/warn' -const inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' - // Key which we use to store tooltip object on element -const BVPO = '__BV_PopOver__' +const BV_POPOVER = '__BV_PopOver__' // Valid event triggers const validTriggers = { @@ -17,9 +16,9 @@ const validTriggers = { } // Build a PopOver config based on bindings (if any) -// Arguments and modifiers take precedence over pased value config object +// Arguments and modifiers take precedence over passed value config object /* istanbul ignore next: not easy to test */ -function parseBindings(bindings) { +const parseBindings = bindings => { // We start out with a blank config let config = {} @@ -35,9 +34,10 @@ function parseBindings(bindings) { config = { ...config, ...bindings.value } } - // If Argument, assume element ID of container element + // If argument, assume element ID of container element if (bindings.arg) { - // Element ID specified as arg. We must prepend '#' to become a CSS selector + // Element ID specified as arg + // We must prepend '#' to become a CSS selector config.container = `#${bindings.arg}` } @@ -55,16 +55,16 @@ function parseBindings(bindings) { // placement of popover config.placement = mod } else if (/^(window|viewport)$/.test(mod)) { - // bounday of popover + // Boundary of popover config.boundary = mod } else if (/^d\d+$/.test(mod)) { - // delay value + // Delay value const delay = parseInt(mod.slice(1), 10) || 0 if (delay) { config.delay = delay } } else if (/^o-?\d+$/.test(mod)) { - // offset value (negative allowed) + // Offset value (negative allowed) const offset = parseInt(mod.slice(1), 10) || 0 if (offset) { config.offset = offset @@ -72,10 +72,11 @@ function parseBindings(bindings) { } }) - // Special handling of event trigger modifiers Trigger is a space separated list + // Special handling of event trigger modifiers trigger is + // a space separated list const selectedTriggers = {} - // parse current config object trigger + // Parse current config object trigger let triggers = typeof config.trigger === 'string' ? config.trigger.trim().split(/\s+/) : [] triggers.forEach(trigger => { if (validTriggers[trigger]) { @@ -83,7 +84,7 @@ function parseBindings(bindings) { } }) - // Parse Modifiers for triggers + // Parse modifiers for triggers keys(validTriggers).forEach(trigger => { if (bindings.modifiers[trigger]) { selectedTriggers[trigger] = true @@ -97,45 +98,39 @@ function parseBindings(bindings) { config.trigger = 'focus' } if (!config.trigger) { - // remove trigger config + // Remove trigger config delete config.trigger } return config } -// -// Add or Update popover on our element -// +// Add or update PopOver on our element /* istanbul ignore next: not easy to test */ -function applyBVPO(el, bindings, vnode) { +const applyPopover = (el, bindings, vnode) => { if (!inBrowser) { return } + // Popper is required for PopOvers to work if (!Popper) { - // Popper is required for tooltips to work - warn('v-b-popover: Popper.js is required for popovers to work') + warn('v-b-popover: Popper.js is required for PopOvers to work') return } - if (el[BVPO]) { - el[BVPO].updateConfig(parseBindings(bindings)) + const config = parseBindings(bindings) + if (el[BV_POPOVER]) { + el[BV_POPOVER].updateConfig(config) } else { - el[BVPO] = new PopOver(el, parseBindings(bindings), vnode.context.$root) + el[BV_POPOVER] = new PopOver(el, config, vnode.context.$root) } } -// -// Remove popover on our element -// +// Remove PopOver on our element /* istanbul ignore next */ -function removeBVPO(el) { - if (!inBrowser) { - return - } - if (el[BVPO]) { - el[BVPO].destroy() - el[BVPO] = null - delete el[BVPO] +const removePopover = el => { + if (el[BV_POPOVER]) { + el[BV_POPOVER].destroy() + el[BV_POPOVER] = null + delete el[BV_POPOVER] } } @@ -145,22 +140,22 @@ function removeBVPO(el) { /* istanbul ignore next: not easy to test */ export default { bind(el, bindings, vnode) { - applyBVPO(el, bindings, vnode) + applyPopover(el, bindings, vnode) }, inserted(el, bindings, vnode) { - applyBVPO(el, bindings, vnode) + applyPopover(el, bindings, vnode) }, update(el, bindings, vnode) { if (bindings.value !== bindings.oldValue) { - applyBVPO(el, bindings, vnode) + applyPopover(el, bindings, vnode) } }, componentUpdated(el, bindings, vnode) { if (bindings.value !== bindings.oldValue) { - applyBVPO(el, bindings, vnode) + applyPopover(el, bindings, vnode) } }, unbind(el) { - removeBVPO(el) + removePopover(el) } } diff --git a/src/directives/scrollspy/scrollspy.js b/src/directives/scrollspy/scrollspy.js index 60e252c1e55..c9cc7757ea6 100644 --- a/src/directives/scrollspy/scrollspy.js +++ b/src/directives/scrollspy/scrollspy.js @@ -1,28 +1,27 @@ -/* - * ScrollSpy directive v-b-scrollspy - */ - import ScrollSpy from './scrollspy.class' +import { inBrowser } from '../../utils/env' import { keys } from '../../utils/object' -import { isServer } from '../../utils/env' -// Key we use to store our Instance -const BVSS = '__BV_ScrollSpy__' +// Key we use to store our instance +const BV_SCROLLSPY = '__BV_ScrollSpy__' -// Generate config from bindings -function makeConfig(binding) /* istanbul ignore next: not easy to test */ { +// Build a ScrollSpy config based on bindings (if any) +// Arguments and modifiers take precedence over passed value config object +/* istanbul ignore next: not easy to test */ +const parseBindings = bindings => { const config = {} - // If Argument, assume element ID - if (binding.arg) { - // Element ID specified as arg. We must pre-pend # - config.element = '#' + binding.arg + // If argument, assume element ID + if (bindings.arg) { + // Element ID specified as arg + // We must prepend '#' to become a CSS selector + config.element = `#${bindings.arg}` } // Process modifiers - keys(binding.modifiers).forEach(mod => { + keys(bindings.modifiers).forEach(mod => { if (/^\d+$/.test(mod)) { - // Offest value + // Offset value config.offset = parseInt(mod, 10) } else if (/^(auto|position|offset)$/.test(mod)) { // Offset method @@ -31,67 +30,71 @@ function makeConfig(binding) /* istanbul ignore next: not easy to test */ { }) // Process value - if (typeof binding.value === 'string') { + if (typeof bindings.value === 'string') { // Value is a CSS ID or selector - config.element = binding.value - } else if (typeof binding.value === 'number') { + config.element = bindings.value + } else if (typeof bindings.value === 'number') { // Value is offset - config.offset = Math.round(binding.value) - } else if (typeof binding.value === 'object') { + config.offset = Math.round(bindings.value) + } else if (typeof bindings.value === 'object') { // Value is config object // Filter the object based on our supported config options - keys(binding.value) + keys(bindings.value) .filter(k => Boolean(ScrollSpy.DefaultType[k])) .forEach(k => { - config[k] = binding.value[k] + config[k] = bindings.value[k] }) } return config } -function addBVSS(el, binding, vnode) /* istanbul ignore next: not easy to test */ { - if (isServer) { +// Add or update ScrollSpy on our element +/* istanbul ignore next: not easy to test */ +const applyScrollspy = (el, bindings, vnode) => { + if (!inBrowser) { return } - const cfg = makeConfig(binding) - if (!el[BVSS]) { - el[BVSS] = new ScrollSpy(el, cfg, vnode.context.$root) + const config = parseBindings(bindings) + if (el[BV_SCROLLSPY]) { + el[BV_SCROLLSPY].updateConfig(config, vnode.context.$root) } else { - el[BVSS].updateConfig(cfg, vnode.context.$root) + el[BV_SCROLLSPY] = new ScrollSpy(el, config, vnode.context.$root) } - return el[BVSS] } -function removeBVSS(el) /* istanbul ignore next: not easy to test */ { - if (el[BVSS]) { - el[BVSS].dispose() - el[BVSS] = null +// Remove ScrollSpy on our element +/* istanbul ignore next: not easy to test */ +const removeScrollspy = el => { + if (el[BV_SCROLLSPY]) { + el[BV_SCROLLSPY].dispose() + el[BV_SCROLLSPY] = null + delete el[BV_SCROLLSPY] } } /* * Export our directive */ - +/* istanbul ignore next: not easy to test */ export default { - bind(el, binding, vnode) /* istanbul ignore next: not easy to test */ { - addBVSS(el, binding, vnode) + bind(el, bindings, vnode) { + applyScrollspy(el, bindings, vnode) }, - inserted(el, binding, vnode) /* istanbul ignore next: not easy to test */ { - addBVSS(el, binding, vnode) + inserted(el, bindings, vnode) { + applyScrollspy(el, bindings, vnode) }, - update(el, binding, vnode) /* istanbul ignore next: not easy to test */ { - addBVSS(el, binding, vnode) - }, - componentUpdated(el, binding, vnode) /* istanbul ignore next: not easy to test */ { - addBVSS(el, binding, vnode) + update(el, bindings, vnode) { + if (bindings.value !== bindings.oldValue) { + applyScrollspy(el, bindings, vnode) + } }, - unbind(el) /* istanbul ignore next: not easy to test */ { - if (isServer) { - return + componentUpdated(el, bindings, vnode) { + if (bindings.value !== bindings.oldValue) { + applyScrollspy(el, bindings, vnode) } - // Remove scroll event listener on scrollElId - removeBVSS(el) + }, + unbind(el) { + removeScrollspy(el) } } diff --git a/src/directives/tooltip/tooltip.js b/src/directives/tooltip/tooltip.js index a16e447a79f..9c4632240ff 100644 --- a/src/directives/tooltip/tooltip.js +++ b/src/directives/tooltip/tooltip.js @@ -1,12 +1,11 @@ import Popper from 'popper.js' import ToolTip from '../../utils/tooltip.class' +import { inBrowser } from '../../utils/env' import { keys } from '../../utils/object' import warn from '../../utils/warn' -const inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' - // Key which we use to store tooltip object on element -const BVTT = '__BV_ToolTip__' +const BV_TOOLTIP = '__BV_ToolTip__' // Valid event triggers const validTriggers = { @@ -19,7 +18,7 @@ const validTriggers = { // Build a ToolTip config based on bindings (if any) // Arguments and modifiers take precedence over passed value config object /* istanbul ignore next: not easy to test */ -function parseBindings(bindings) { +const parseBindings = bindings => { // We start out with a blank config let config = {} @@ -35,9 +34,10 @@ function parseBindings(bindings) { config = { ...config, ...bindings.value } } - // If Argument, assume element ID of container element + // If argument, assume element ID of container element if (bindings.arg) { - // Element ID specified as arg. We must prepend '#' to become a CSS selector + // Element ID specified as arg + // We must prepend '#' to become a CSS selector config.container = `#${bindings.arg}` } @@ -47,24 +47,24 @@ function parseBindings(bindings) { // Title allows HTML config.html = true } else if (/^nofade$/.test(mod)) { - // no animation + // No animation config.animation = false } else if ( /^(auto|top(left|right)?|bottom(left|right)?|left(top|bottom)?|right(top|bottom)?)$/.test(mod) ) { - // placement of tooltip + // Placement of tooltip config.placement = mod } else if (/^(window|viewport)$/.test(mod)) { - // bounday of tooltip + // Boundary of tooltip config.boundary = mod } else if (/^d\d+$/.test(mod)) { - // delay value + // Delay value const delay = parseInt(mod.slice(1), 10) || 0 if (delay) { config.delay = delay } } else if (/^o-?\d+$/.test(mod)) { - // offset value. Negative allowed + // Offset value, negative allowed const offset = parseInt(mod.slice(1), 10) || 0 if (offset) { config.offset = offset @@ -72,10 +72,11 @@ function parseBindings(bindings) { } }) - // Special handling of event trigger modifiers Trigger is a space separated list + // Special handling of event trigger modifiers trigger is + // a space separated list const selectedTriggers = {} - // parse current config object trigger + // Parse current config object trigger let triggers = typeof config.trigger === 'string' ? config.trigger.trim().split(/\s+/) : [] triggers.forEach(trigger => { if (validTriggers[trigger]) { @@ -83,7 +84,7 @@ function parseBindings(bindings) { } }) - // Parse Modifiers for triggers + // Parse modifiers for triggers keys(validTriggers).forEach(trigger => { if (bindings.modifiers[trigger]) { selectedTriggers[trigger] = true @@ -97,45 +98,39 @@ function parseBindings(bindings) { config.trigger = 'focus' } if (!config.trigger) { - // remove trigger config + // Remove trigger config delete config.trigger } return config } -// -// Add or Update tooltip on our element -// +// Add or update ToolTip on our element /* istanbul ignore next: not easy to test */ -function applyBVTT(el, bindings, vnode) { +const applyTooltip = (el, bindings, vnode) => { if (!inBrowser) { return } if (!Popper) { - // Popper is required for tooltips to work - warn('v-b-tooltip: Popper.js is required for tooltips to work') + // Popper is required for ToolTips to work + warn('v-b-tooltip: Popper.js is required for ToolTips to work') return } - if (el[BVTT]) { - el[BVTT].updateConfig(parseBindings(bindings)) + const config = parseBindings(bindings) + if (el[BV_TOOLTIP]) { + el[BV_TOOLTIP].updateConfig(config) } else { - el[BVTT] = new ToolTip(el, parseBindings(bindings), vnode.context.$root) + el[BV_TOOLTIP] = new ToolTip(el, config, vnode.context.$root) } } -// -// Remove tooltip on our element -// +// Remove ToolTip on our element /* istanbul ignore next: not easy to test */ -function removeBVTT(el) { - if (!inBrowser) { - return - } - if (el[BVTT]) { - el[BVTT].destroy() - el[BVTT] = null - delete el[BVTT] +const removeTooltip = el => { + if (el[BV_TOOLTIP]) { + el[BV_TOOLTIP].destroy() + el[BV_TOOLTIP] = null + delete el[BV_TOOLTIP] } } @@ -145,22 +140,22 @@ function removeBVTT(el) { /* istanbul ignore next: not easy to test */ export default { bind(el, bindings, vnode) { - applyBVTT(el, bindings, vnode) + applyTooltip(el, bindings, vnode) }, inserted(el, bindings, vnode) { - applyBVTT(el, bindings, vnode) + applyTooltip(el, bindings, vnode) }, update(el, bindings, vnode) { if (bindings.value !== bindings.oldValue) { - applyBVTT(el, bindings, vnode) + applyTooltip(el, bindings, vnode) } }, componentUpdated(el, bindings, vnode) { if (bindings.value !== bindings.oldValue) { - applyBVTT(el, bindings, vnode) + applyTooltip(el, bindings, vnode) } }, unbind(el) { - removeBVTT(el) + removeTooltip(el) } } From 256af51d14a6e70ac722c1c432082b3d6a502799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 27 Mar 2019 15:51:11 +0100 Subject: [PATCH 03/38] Update toggle.js --- src/directives/toggle/toggle.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/directives/toggle/toggle.js b/src/directives/toggle/toggle.js index 5991e9fb693..8d3ec7add3a 100644 --- a/src/directives/toggle/toggle.js +++ b/src/directives/toggle/toggle.js @@ -16,7 +16,8 @@ const EVENT_TOGGLE = 'bv::toggle::collapse' // Listen to event for toggle state update (emitted by collapse) const EVENT_STATE = 'bv::collapse::state' -/* istanbul ignore next */ +// Handle directive updates +/* istanbul ignore next: not easy to test */ const handleUpdate = (el, binding, vnode) => { if (!inBrowser) { return @@ -34,6 +35,9 @@ const handleUpdate = (el, binding, vnode) => { setAttr(el, 'aria-controls', el[BV_TOGGLE_CONTROLS]) } +/* + * Export our directive + */ export default { bind(el, binding, vnode) { const targets = bindTargets(vnode, binding, listenTypes, ({ targets, vnode }) => { From 6f26596209e2cf35efab8f0576158e3d3907b077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 27 Mar 2019 16:00:23 +0100 Subject: [PATCH 04/38] Update toggle.js --- src/directives/toggle/toggle.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/directives/toggle/toggle.js b/src/directives/toggle/toggle.js index 8d3ec7add3a..b8a0d066d72 100644 --- a/src/directives/toggle/toggle.js +++ b/src/directives/toggle/toggle.js @@ -16,6 +16,12 @@ const EVENT_TOGGLE = 'bv::toggle::collapse' // Listen to event for toggle state update (emitted by collapse) const EVENT_STATE = 'bv::collapse::state' +// Reset and remove a property from the provided element +const resetProp = (el, prop) => { + el[prop] = null + delete el[prop] +} + // Handle directive updates /* istanbul ignore next: not easy to test */ const handleUpdate = (el, binding, vnode) => { @@ -81,16 +87,18 @@ export default { updated: handleUpdate, unbind(el, binding, vnode) /* istanbul ignore next */ { unbindTargets(vnode, binding, listenTypes) + // Remove our $root listener if (el[BV_TOGGLE]) { - // Remove our $root listener vnode.context.$root.$off(EVENT_STATE, el[BV_TOGGLE]) - el[BV_TOGGLE] = null - el[BV_TOGGLE_STATE] = null - el[BV_TOGGLE_CONTROLS] = null - removeClass(el, 'collapsed') - removeAttr(el, 'aria-expanded') - removeAttr(el, 'aria-controls') - removeAttr(el, 'role') } + // Reset custom props + resetProp(el, BV_TOGGLE) + resetProp(el, BV_TOGGLE_STATE) + resetProp(el, BV_TOGGLE_CONTROLS) + // Reset classes/attrs + removeClass(el, 'collapsed') + removeAttr(el, 'aria-expanded') + removeAttr(el, 'aria-controls') + removeAttr(el, 'role') } } From 193ea889523474bc56a53d5721bd51605495a886 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:08:28 -0300 Subject: [PATCH 05/38] Create modal.spec.js --- src/directives/modal/modal.spec.js | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/directives/modal/modal.spec.js diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js new file mode 100644 index 00000000000..f02f3638e22 --- /dev/null +++ b/src/directives/modal/modal.spec.js @@ -0,0 +1,40 @@ +import modalDirective from './modal' +import { mount, createLocalVue } from '@vue/test-utils' + +const EVENT_SHOW = 'bv::show::modal' + +describe('v-b-modal directive', () => { + it('works on buttons', async () => { + const Vue = new createLocalVue() + const spy = jest.fn() + const App = Vue.extend({ + directives: { + bModal: modalDirective + } + data() { + return {} + }, + mounted() { + this.$root.on(EVENT_SHOW, spy) + }, + beforeDestroy() { + this.$root.off(EVENT_SHOW, spy) + }, + template: '' + }) + const wrapper = mount(App, { + localVue: Vue, + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('button')).toBe(true) + expect(spy).not.toHaveBeenCalled() + + const $button = wrapper.find('button') + $button.trigger('click') + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toBeCalledWith('test', $button.element); + + wrapper.destroy() + }) +}) From 6b2eba709c314873d8a332d17a8326e24337c4d8 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:10:40 -0300 Subject: [PATCH 06/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index f02f3638e22..2462bef9f5a 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -7,10 +7,11 @@ describe('v-b-modal directive', () => { it('works on buttons', async () => { const Vue = new createLocalVue() const spy = jest.fn() + const App = Vue.extend({ directives: { bModal: modalDirective - } + }, data() { return {} }, From 8014fa7d5673d161192170d53eec57c3fcf35d60 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:13:04 -0300 Subject: [PATCH 07/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index 2462bef9f5a..232ea20a89e 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -5,7 +5,7 @@ const EVENT_SHOW = 'bv::show::modal' describe('v-b-modal directive', () => { it('works on buttons', async () => { - const Vue = new createLocalVue() + const localVue = new createLocalVue() const spy = jest.fn() const App = Vue.extend({ @@ -24,7 +24,7 @@ describe('v-b-modal directive', () => { template: '' }) const wrapper = mount(App, { - localVue: Vue, + localVue: localVue }) expect(wrapper.isVueInstance()).toBe(true) @@ -34,7 +34,7 @@ describe('v-b-modal directive', () => { const $button = wrapper.find('button') $button.trigger('click') expect(spy).toHaveBeenCalledTimes(1) - expect(spy).toBeCalledWith('test', $button.element); + expect(spy).toBeCalledWith('test', $button.element) wrapper.destroy() }) From 456331ce386edfd8efe53bbce787f30574bdf526 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:15:12 -0300 Subject: [PATCH 08/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index 232ea20a89e..f15727583f6 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -1,11 +1,11 @@ import modalDirective from './modal' -import { mount, createLocalVue } from '@vue/test-utils' +import { mount, createLocalVue as CreateLocalVue} from '@vue/test-utils' const EVENT_SHOW = 'bv::show::modal' describe('v-b-modal directive', () => { it('works on buttons', async () => { - const localVue = new createLocalVue() + const localVue = new CreateLocalVue() const spy = jest.fn() const App = Vue.extend({ From e7de9501219b107a4388566a6b34f549cc49e399 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:16:31 -0300 Subject: [PATCH 09/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index f15727583f6..23d336f55c4 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -1,5 +1,5 @@ import modalDirective from './modal' -import { mount, createLocalVue as CreateLocalVue} from '@vue/test-utils' +import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' const EVENT_SHOW = 'bv::show::modal' From 911e1a96c20f9e132adf7933433a2a986c438e34 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:18:32 -0300 Subject: [PATCH 10/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index 23d336f55c4..de0eaafd0ff 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -8,7 +8,7 @@ describe('v-b-modal directive', () => { const localVue = new CreateLocalVue() const spy = jest.fn() - const App = Vue.extend({ + const App = localVue.extend({ directives: { bModal: modalDirective }, From c01143c02805a84400e0b4cedcc8531d75db3274 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:20:19 -0300 Subject: [PATCH 11/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index de0eaafd0ff..9740626611d 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -16,10 +16,10 @@ describe('v-b-modal directive', () => { return {} }, mounted() { - this.$root.on(EVENT_SHOW, spy) + this.$root.$on(EVENT_SHOW, spy) }, beforeDestroy() { - this.$root.off(EVENT_SHOW, spy) + this.$root.$off(EVENT_SHOW, spy) }, template: '' }) From e321fb324bb7754949a2310e59cabb52450e808c Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:24:51 -0300 Subject: [PATCH 12/38] Update modal.js --- src/directives/modal/modal.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/directives/modal/modal.js b/src/directives/modal/modal.js index e4cb4b11d3a..0b64b7828eb 100644 --- a/src/directives/modal/modal.js +++ b/src/directives/modal/modal.js @@ -7,6 +7,12 @@ const listenTypes = { click: true } // Emitted show event for modal const EVENT_SHOW = 'bv::show::modal' +const setRole = (el, binding, vnode) => { + if (el.tagName !== 'BUTTON') { + setAttr(el, 'role', 'button') + } +} + /* * Export our directive */ @@ -19,10 +25,10 @@ export default { }) }) // If element is not a button, we add `role="button"` for accessibility - if (el.tagName !== 'BUTTON') { - setAttr(el, 'role', 'button') - } + setRole(el, binding, vnode) }, + updated: setRole, + componentUpdated: setRole, unbind(el, binding, vnode) { unbindTargets(vnode, binding, listenTypes) // If element is not a button, we add `role="button"` for accessibility From 0aafcfb8fa171503c12d1038880c78eeab107f9e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:27:30 -0300 Subject: [PATCH 13/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index 9740626611d..f0f483243c6 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -38,4 +38,41 @@ describe('v-b-modal directive', () => { wrapper.destroy() }) + + it('works on non-buttons', async () => { + const localVue = new CreateLocalVue() + const spy = jest.fn() + + const App = localVue.extend({ + directives: { + bModal: modalDirective + }, + data() { + return {} + }, + mounted() { + this.$root.$on(EVENT_SHOW, spy) + }, + beforeDestroy() { + this.$root.$off(EVENT_SHOW, spy) + }, + template: 'span' + }) + const wrapper = mount(App, { + localVue: localVue + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('span')).toBe(true) + expect(spy).not.toHaveBeenCalled() + expect(wrapper.find('span').attributes('role').toBe('button') + + const $span = wrapper.find('span') + $span.trigger('click') + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toBeCalledWith('test', $span.element) + expect(wrapper.find('span').attributes('role').toBe('button') + + wrapper.destroy() + }) }) From 3fcfcf8b53b937082f5f09c406fc3b7595f4aec3 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:30:20 -0300 Subject: [PATCH 14/38] Update modal.spec.js --- src/directives/modal/modal.spec.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/directives/modal/modal.spec.js b/src/directives/modal/modal.spec.js index f0f483243c6..530cff5dc32 100644 --- a/src/directives/modal/modal.spec.js +++ b/src/directives/modal/modal.spec.js @@ -48,7 +48,9 @@ describe('v-b-modal directive', () => { bModal: modalDirective }, data() { - return {} + return { + text: 'span' + } }, mounted() { this.$root.$on(EVENT_SHOW, spy) @@ -56,7 +58,7 @@ describe('v-b-modal directive', () => { beforeDestroy() { this.$root.$off(EVENT_SHOW, spy) }, - template: 'span' + template: '{{ text }}' }) const wrapper = mount(App, { localVue: localVue @@ -65,13 +67,21 @@ describe('v-b-modal directive', () => { expect(wrapper.isVueInstance()).toBe(true) expect(wrapper.is('span')).toBe(true) expect(spy).not.toHaveBeenCalled() - expect(wrapper.find('span').attributes('role').toBe('button') + expect(wrapper.find('span').attributes('role')).toBe('button') + expect(wrapper.find('span').text()).toBe('span') const $span = wrapper.find('span') $span.trigger('click') expect(spy).toHaveBeenCalledTimes(1) expect(spy).toBeCalledWith('test', $span.element) - expect(wrapper.find('span').attributes('role').toBe('button') + expect(wrapper.find('span').attributes('role')).toBe('button') + + // Test updating component. should maintain role attribute + wrapper.setData({ + text: 'foobar' + }) + expect(wrapper.find('span').text()).toBe('foobar') + expect(wrapper.find('span').attributes('role')).toBe('button') wrapper.destroy() }) From 78c83eeeec33a96c52637427bd6200f6abbace35 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:39:13 -0300 Subject: [PATCH 15/38] Create toggle.spec.js --- src/directives/toggle/toggle.spec.js | 107 +++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/directives/toggle/toggle.spec.js diff --git a/src/directives/toggle/toggle.spec.js b/src/directives/toggle/toggle.spec.js new file mode 100644 index 00000000000..3012acddf2b --- /dev/null +++ b/src/directives/toggle/toggle.spec.js @@ -0,0 +1,107 @@ +import toggleDirective from './toggle' +import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' + +// Emitted control event for collapse (emitted to collapse) +const EVENT_TOGGLE = 'bv::toggle::collapse' + +// Listen to event for toggle state update (emitted by collapse) +// const EVENT_STATE = 'bv::collapse::state' + +describe('v-b-toggle directive', () => { + it('works on buttons', async () => { + const localVue = new CreateLocalVue() + const spy = jest.fn() + + const App = localVue.extend({ + directives: { + bToggle: toggleDirective + }, + data() { + return {} + }, + mounted() { + this.$root.$on(EVENT_TOGLE, spy) + }, + beforeDestroy() { + this.$root.$off(EVENT_TOGGLE, spy) + }, + template: '' + }) + + const wrapper = mount(App, { + localVue: localVue + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('button')).toBe(true) + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + expect(spy).not.toHaveBeenCalled() + + const $button = wrapper.find('button') + $button.trigger('click') + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toBeCalledWith('test') + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + + wrapper.destroy() + }) + + it('works on non-buttons', async () => { + const localVue = new CreateLocalVue() + const spy = jest.fn() + + const App = localVue.extend({ + directives: { + bToggle: toggleDirective + }, + data() { + return {} + }, + mounted() { + this.$root.$on(EVENT_TOGLE, spy) + }, + beforeDestroy() { + this.$root.$off(EVENT_TOGGLE, spy) + }, + template: '{{ text }}' + }) + + const wrapper = mount(App, { + localVue: localVue + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('span')).toBe(true) + expect(spy).not.toHaveBeenCalled() + expect(wrapper.find('span').attributes('role')).toBe('button') + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + expect(wrapper.find('span').text()).toBe('span') + + const $span = wrapper.find('span') + $span.trigger('click') + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toBeCalledWith('test') + expect(wrapper.find('span').attributes('role')).toBe('button') + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + + // Test updating component. should maintain role attribute + wrapper.setData({ + text: 'foobar' + }) + expect(wrapper.find('span').text()).toBe('foobar') + expect(wrapper.find('span').attributes('role')).toBe('button') + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + + wrapper.destroy() + }) +}) From c9bc9e3660053bcb0d0aceb20698d789d379a857 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:40:11 -0300 Subject: [PATCH 16/38] lint --- src/directives/toggle/toggle.spec.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/directives/toggle/toggle.spec.js b/src/directives/toggle/toggle.spec.js index 3012acddf2b..73754a799ec 100644 --- a/src/directives/toggle/toggle.spec.js +++ b/src/directives/toggle/toggle.spec.js @@ -78,9 +78,9 @@ describe('v-b-toggle directive', () => { expect(wrapper.is('span')).toBe(true) expect(spy).not.toHaveBeenCalled() expect(wrapper.find('span').attributes('role')).toBe('button') - expect(wrapper.find('button').attributes('aria-controls')).toBe('test') - expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') - expect(wrapper.find('button').classes()).not.toContain('collapsed') + expect(wrapper.find('span').attributes('aria-controls')).toBe('test') + expect(wrapper.find('span').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('span').classes()).not.toContain('collapsed') expect(wrapper.find('span').text()).toBe('span') const $span = wrapper.find('span') @@ -88,9 +88,9 @@ describe('v-b-toggle directive', () => { expect(spy).toHaveBeenCalledTimes(1) expect(spy).toBeCalledWith('test') expect(wrapper.find('span').attributes('role')).toBe('button') - expect(wrapper.find('button').attributes('aria-controls')).toBe('test') - expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') - expect(wrapper.find('button').classes()).not.toContain('collapsed') + expect(wrapper.find('span').attributes('aria-controls')).toBe('test') + expect(wrapper.find('span').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('span').classes()).not.toContain('collapsed') // Test updating component. should maintain role attribute wrapper.setData({ @@ -98,9 +98,9 @@ describe('v-b-toggle directive', () => { }) expect(wrapper.find('span').text()).toBe('foobar') expect(wrapper.find('span').attributes('role')).toBe('button') - expect(wrapper.find('button').attributes('aria-controls')).toBe('test') - expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') - expect(wrapper.find('button').classes()).not.toContain('collapsed') + expect(wrapper.find('span').attributes('aria-controls')).toBe('test') + expect(wrapper.find('span').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('span').classes()).not.toContain('collapsed') wrapper.destroy() }) From 8491076e1cd1e48e48476acfbf304f4e8e3831bf Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:44:39 -0300 Subject: [PATCH 17/38] Update toggle.spec.js --- src/directives/toggle/toggle.spec.js | 48 ++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/directives/toggle/toggle.spec.js b/src/directives/toggle/toggle.spec.js index 73754a799ec..3d200906d65 100644 --- a/src/directives/toggle/toggle.spec.js +++ b/src/directives/toggle/toggle.spec.js @@ -5,7 +5,7 @@ import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' const EVENT_TOGGLE = 'bv::toggle::collapse' // Listen to event for toggle state update (emitted by collapse) -// const EVENT_STATE = 'bv::collapse::state' +const EVENT_STATE = 'bv::collapse::state' describe('v-b-toggle directive', () => { it('works on buttons', async () => { @@ -20,7 +20,7 @@ describe('v-b-toggle directive', () => { return {} }, mounted() { - this.$root.$on(EVENT_TOGLE, spy) + this.$root.$on(EVENT_TOGGLE, spy) }, beforeDestroy() { this.$root.$off(EVENT_TOGGLE, spy) @@ -62,7 +62,7 @@ describe('v-b-toggle directive', () => { return {} }, mounted() { - this.$root.$on(EVENT_TOGLE, spy) + this.$root.$on(EVENT_TOGGLE, spy) }, beforeDestroy() { this.$root.$off(EVENT_TOGGLE, spy) @@ -102,6 +102,48 @@ describe('v-b-toggle directive', () => { expect(wrapper.find('span').attributes('aria-expanded')).toBe('false') expect(wrapper.find('span').classes()).not.toContain('collapsed') + wrapper.destroy() + }) + it('responds to state update events', async () => { + const localVue = new CreateLocalVue() + const spy = jest.fn() + + const App = localVue.extend({ + directives: { + bToggle: toggleDirective + }, + data() { + return {} + }, + template: '' + }) + + const wrapper = mount(App, { + localVue: localVue + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('button')).toBe(true) + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + + const $root = wrapper.vm.$root + + const $button = wrapper.find('button') + + $root.$emit(EVENT_STATE, 'test', true) + + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('true') + expect(wrapper.find('button').classes()).toContain('collapsed') + + $root.$emit(EVENT_STATE, 'test', false) + + expect(wrapper.find('button').attributes('aria-controls')).toBe('test') + expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') + expect(wrapper.find('button').classes()).not.toContain('collapsed') + wrapper.destroy() }) }) From b02866c9e1887b9150798730214cfe450d9decbb Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:48:51 -0300 Subject: [PATCH 18/38] Update toggle.spec.js --- src/directives/toggle/toggle.spec.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/directives/toggle/toggle.spec.js b/src/directives/toggle/toggle.spec.js index 3d200906d65..ebd7e69a5e1 100644 --- a/src/directives/toggle/toggle.spec.js +++ b/src/directives/toggle/toggle.spec.js @@ -59,7 +59,9 @@ describe('v-b-toggle directive', () => { bToggle: toggleDirective }, data() { - return {} + return { + text: 'span' + } }, mounted() { this.$root.$on(EVENT_TOGGLE, spy) @@ -106,7 +108,6 @@ describe('v-b-toggle directive', () => { }) it('responds to state update events', async () => { const localVue = new CreateLocalVue() - const spy = jest.fn() const App = localVue.extend({ directives: { @@ -130,8 +131,6 @@ describe('v-b-toggle directive', () => { const $root = wrapper.vm.$root - const $button = wrapper.find('button') - $root.$emit(EVENT_STATE, 'test', true) expect(wrapper.find('button').attributes('aria-controls')).toBe('test') From a74023fa7cf0444b49acfb8f8317b59df65e2d60 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:51:38 -0300 Subject: [PATCH 19/38] Update toggle.spec.js --- src/directives/toggle/toggle.spec.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/directives/toggle/toggle.spec.js b/src/directives/toggle/toggle.spec.js index ebd7e69a5e1..7baaeac3a66 100644 --- a/src/directives/toggle/toggle.spec.js +++ b/src/directives/toggle/toggle.spec.js @@ -132,16 +132,18 @@ describe('v-b-toggle directive', () => { const $root = wrapper.vm.$root $root.$emit(EVENT_STATE, 'test', true) + await wrapper.vm.$nextTick() expect(wrapper.find('button').attributes('aria-controls')).toBe('test') expect(wrapper.find('button').attributes('aria-expanded')).toBe('true') - expect(wrapper.find('button').classes()).toContain('collapsed') + expect(wrapper.find('button').classes()).not.toContain('collapsed') $root.$emit(EVENT_STATE, 'test', false) + await wrapper.vm.$nextTick() expect(wrapper.find('button').attributes('aria-controls')).toBe('test') expect(wrapper.find('button').attributes('aria-expanded')).toBe('false') - expect(wrapper.find('button').classes()).not.toContain('collapsed') + expect(wrapper.find('button').classes()).toContain('collapsed') wrapper.destroy() }) From 8a889b061c1e2d34feffa92581659fd624ba5399 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:54:30 -0300 Subject: [PATCH 20/38] Update scrollspy.js --- src/directives/scrollspy/scrollspy.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/directives/scrollspy/scrollspy.js b/src/directives/scrollspy/scrollspy.js index c9cc7757ea6..9d60197684e 100644 --- a/src/directives/scrollspy/scrollspy.js +++ b/src/directives/scrollspy/scrollspy.js @@ -76,25 +76,24 @@ const removeScrollspy = el => { /* * Export our directive */ -/* istanbul ignore next: not easy to test */ export default { - bind(el, bindings, vnode) { + bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyScrollspy(el, bindings, vnode) }, - inserted(el, bindings, vnode) { + inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyScrollspy(el, bindings, vnode) }, - update(el, bindings, vnode) { + update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyScrollspy(el, bindings, vnode) } }, - componentUpdated(el, bindings, vnode) { + componentUpdated(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyScrollspy(el, bindings, vnode) } }, - unbind(el) { + unbind(el) /* istanbul ignore next: not easy to test */ { removeScrollspy(el) } } From 00848983c6c70448e2f233758566f114f271df91 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:58:06 -0300 Subject: [PATCH 21/38] Update tooltip.js --- src/directives/tooltip/tooltip.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/directives/tooltip/tooltip.js b/src/directives/tooltip/tooltip.js index 9c4632240ff..d91895fe401 100644 --- a/src/directives/tooltip/tooltip.js +++ b/src/directives/tooltip/tooltip.js @@ -18,7 +18,7 @@ const validTriggers = { // Build a ToolTip config based on bindings (if any) // Arguments and modifiers take precedence over passed value config object /* istanbul ignore next: not easy to test */ -const parseBindings = bindings => { +const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { // We start out with a blank config let config = {} @@ -107,7 +107,7 @@ const parseBindings = bindings => { // Add or update ToolTip on our element /* istanbul ignore next: not easy to test */ -const applyTooltip = (el, bindings, vnode) => { +const applyTooltip = (el, bindings, vnode) => /* istanbul ignore next: not easy to test */ { if (!inBrowser) { return } @@ -127,6 +127,7 @@ const applyTooltip = (el, bindings, vnode) => { // Remove ToolTip on our element /* istanbul ignore next: not easy to test */ const removeTooltip = el => { + /* istanbul ignore next: not easy to test */ if (el[BV_TOOLTIP]) { el[BV_TOOLTIP].destroy() el[BV_TOOLTIP] = null @@ -137,25 +138,24 @@ const removeTooltip = el => { /* * Export our directive */ -/* istanbul ignore next: not easy to test */ export default { - bind(el, bindings, vnode) { + bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyTooltip(el, bindings, vnode) }, - inserted(el, bindings, vnode) { + inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyTooltip(el, bindings, vnode) }, - update(el, bindings, vnode) { + update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyTooltip(el, bindings, vnode) } }, - componentUpdated(el, bindings, vnode) { + componentUpdated(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyTooltip(el, bindings, vnode) } }, - unbind(el) { + unbind(el) /* istanbul ignore next: not easy to test */ { removeTooltip(el) } } From d58a200ef6658658a50502ca91e67438a924dbcf Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 13:59:33 -0300 Subject: [PATCH 22/38] Update popover.js --- src/directives/popover/popover.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/directives/popover/popover.js b/src/directives/popover/popover.js index 514e420045b..5315ead953d 100644 --- a/src/directives/popover/popover.js +++ b/src/directives/popover/popover.js @@ -18,7 +18,7 @@ const validTriggers = { // Build a PopOver config based on bindings (if any) // Arguments and modifiers take precedence over passed value config object /* istanbul ignore next: not easy to test */ -const parseBindings = bindings => { +const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { // We start out with a blank config let config = {} @@ -107,7 +107,7 @@ const parseBindings = bindings => { // Add or update PopOver on our element /* istanbul ignore next: not easy to test */ -const applyPopover = (el, bindings, vnode) => { +const applyPopover = (el, bindings, vnode) => /* istanbul ignore next: not easy to test */ { if (!inBrowser) { return } @@ -127,6 +127,7 @@ const applyPopover = (el, bindings, vnode) => { // Remove PopOver on our element /* istanbul ignore next */ const removePopover = el => { + /* istanbul ignore next: not easy to test */ if (el[BV_POPOVER]) { el[BV_POPOVER].destroy() el[BV_POPOVER] = null @@ -139,23 +140,23 @@ const removePopover = el => { */ /* istanbul ignore next: not easy to test */ export default { - bind(el, bindings, vnode) { + bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyPopover(el, bindings, vnode) }, - inserted(el, bindings, vnode) { + inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { applyPopover(el, bindings, vnode) }, - update(el, bindings, vnode) { + update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyPopover(el, bindings, vnode) } }, - componentUpdated(el, bindings, vnode) { + componentUpdated(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { if (bindings.value !== bindings.oldValue) { applyPopover(el, bindings, vnode) } }, - unbind(el) { + unbind(el) /* istanbul ignore next: not easy to test */ { removePopover(el) } } From eff59e6983f364fb31e262067fe585c8725b44ac Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:09:26 -0300 Subject: [PATCH 23/38] Create tooltip.spec.js --- src/directives/tooltip/tooltip.spec.js | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/directives/tooltip/tooltip.spec.js diff --git a/src/directives/tooltip/tooltip.spec.js b/src/directives/tooltip/tooltip.spec.js new file mode 100644 index 00000000000..c1ebe188560 --- /dev/null +++ b/src/directives/tooltip/tooltip.spec.js @@ -0,0 +1,36 @@ +import tooltipDirective from './tooltip' +import ToolTip from '../../utils/tooltip.class' +import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' + +// Key which we use to store tooltip object on element +const BV_TOOLTIP = '__BV_ToolTip__' + +describe('v-b-tooltip directive', () => { + it('should have ToolTip class instance', async () => { + const localVue = new CreateLocalVue() + + const App = localVue.extend({ + directives: { + bTooltip: tooltipDirective + }, + data() { + return {} + }, + template: '' + }) + + const wrapper = mount(App, { + localVue: localVue + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('button')).toBe(true) + const $button = wrapper.find('button') + + // Should have instance of popover class on it + expect($button.element[BV_TOOLTIP]).toBeDefined() + expect($button.element[BV_TOOLTIP]).toBeInstanceOf(ToolTip) + + wrapper.destroy() + }) +}) From 583bd6b72df2df64e6cc45b26af545a573fee4d7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:10:37 -0300 Subject: [PATCH 24/38] Update tooltip.js --- src/directives/tooltip/tooltip.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/directives/tooltip/tooltip.js b/src/directives/tooltip/tooltip.js index d91895fe401..508fc326556 100644 --- a/src/directives/tooltip/tooltip.js +++ b/src/directives/tooltip/tooltip.js @@ -106,8 +106,7 @@ const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { } // Add or update ToolTip on our element -/* istanbul ignore next: not easy to test */ -const applyTooltip = (el, bindings, vnode) => /* istanbul ignore next: not easy to test */ { +const applyTooltip = (el, bindings, vnode) => { if (!inBrowser) { return } @@ -139,10 +138,10 @@ const removeTooltip = el => { * Export our directive */ export default { - bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { + bind(el, bindings, vnode) { applyTooltip(el, bindings, vnode) }, - inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { + inserted(el, bindings, vnode) { applyTooltip(el, bindings, vnode) }, update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { @@ -155,7 +154,7 @@ export default { applyTooltip(el, bindings, vnode) } }, - unbind(el) /* istanbul ignore next: not easy to test */ { + unbind(el) { removeTooltip(el) } } From f963355059e08457330f18490f2e5caa672b51b7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:11:08 -0300 Subject: [PATCH 25/38] Update tooltip.spec.js --- src/directives/tooltip/tooltip.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/directives/tooltip/tooltip.spec.js b/src/directives/tooltip/tooltip.spec.js index c1ebe188560..08eb172d9b1 100644 --- a/src/directives/tooltip/tooltip.spec.js +++ b/src/directives/tooltip/tooltip.spec.js @@ -20,7 +20,8 @@ describe('v-b-tooltip directive', () => { }) const wrapper = mount(App, { - localVue: localVue + localVue: localVue, + attachToDocument: true }) expect(wrapper.isVueInstance()).toBe(true) From eddc2cc639e388cf0f86a7e114e1d6fc0ca82a9e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:14:35 -0300 Subject: [PATCH 26/38] Update tooltip.js --- src/directives/tooltip/tooltip.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/directives/tooltip/tooltip.js b/src/directives/tooltip/tooltip.js index 508fc326556..7ba00fc3a8b 100644 --- a/src/directives/tooltip/tooltip.js +++ b/src/directives/tooltip/tooltip.js @@ -108,11 +108,14 @@ const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { // Add or update ToolTip on our element const applyTooltip = (el, bindings, vnode) => { if (!inBrowser) { + /* istanbul ignore next */ return } if (!Popper) { // Popper is required for ToolTips to work + /* istanbul ignore next */ warn('v-b-tooltip: Popper.js is required for ToolTips to work') + /* istanbul ignore next */ return } const config = parseBindings(bindings) From 0f22b16f8633096a524525ebc68eab4c7ef7ee38 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:18:28 -0300 Subject: [PATCH 27/38] Create popover.spec.js --- src/directives/popover/popover.spec.js | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/directives/popover/popover.spec.js diff --git a/src/directives/popover/popover.spec.js b/src/directives/popover/popover.spec.js new file mode 100644 index 00000000000..e1002572786 --- /dev/null +++ b/src/directives/popover/popover.spec.js @@ -0,0 +1,37 @@ +import popoverDirective from './popover' +import PopOver from '../../utils/popover.class' +import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' + +// Key which we use to store tooltip object on element +const BV_POPOVER = '__BV_PopOver__' + +describe('v-b-popover directive', () => { + it('should have PopOver class instance', async () => { + const localVue = new CreateLocalVue() + + const App = localVue.extend({ + directives: { + bPopover: popoverDirective + }, + data() { + return {} + }, + template: '' + }) + + const wrapper = mount(App, { + localVue: localVue, + attachToDocument: true + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('button')).toBe(true) + const $button = wrapper.find('button') + + // Should have instance of popover class on it + expect($button.element[BV_POPOVER]).toBeDefined() + expect($button.element[BV_POPOVER]).toBeInstanceOf(PopOver) + + wrapper.destroy() + }) +}) From eb8564b3e72b2dc9359319daa4d88a6ba28e0113 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:20:02 -0300 Subject: [PATCH 28/38] Update popover.js --- src/directives/popover/popover.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/directives/popover/popover.js b/src/directives/popover/popover.js index 5315ead953d..36337ee8c62 100644 --- a/src/directives/popover/popover.js +++ b/src/directives/popover/popover.js @@ -106,14 +106,16 @@ const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { } // Add or update PopOver on our element -/* istanbul ignore next: not easy to test */ -const applyPopover = (el, bindings, vnode) => /* istanbul ignore next: not easy to test */ { +const applyPopover = (el, bindings, vnode) => { if (!inBrowser) { + /* istanbul ignore next */ return } // Popper is required for PopOvers to work if (!Popper) { + /* istanbul ignore next */ warn('v-b-popover: Popper.js is required for PopOvers to work') + /* istanbul ignore next */ return } const config = parseBindings(bindings) @@ -125,9 +127,7 @@ const applyPopover = (el, bindings, vnode) => /* istanbul ignore next: not easy } // Remove PopOver on our element -/* istanbul ignore next */ const removePopover = el => { - /* istanbul ignore next: not easy to test */ if (el[BV_POPOVER]) { el[BV_POPOVER].destroy() el[BV_POPOVER] = null @@ -138,12 +138,11 @@ const removePopover = el => { /* * Export our directive */ -/* istanbul ignore next: not easy to test */ export default { - bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { + bind(el, bindings, vnode) { applyPopover(el, bindings, vnode) }, - inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { + inserted(el, bindings, vnode) { applyPopover(el, bindings, vnode) }, update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { @@ -156,7 +155,7 @@ export default { applyPopover(el, bindings, vnode) } }, - unbind(el) /* istanbul ignore next: not easy to test */ { + unbind(el) { removePopover(el) } } From 2c04fe4e3df9df961d4e7ba8db2b62cd9b02eef0 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:20:41 -0300 Subject: [PATCH 29/38] Update tooltip.js --- src/directives/tooltip/tooltip.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/directives/tooltip/tooltip.js b/src/directives/tooltip/tooltip.js index 7ba00fc3a8b..60b20cd53d8 100644 --- a/src/directives/tooltip/tooltip.js +++ b/src/directives/tooltip/tooltip.js @@ -127,9 +127,7 @@ const applyTooltip = (el, bindings, vnode) => { } // Remove ToolTip on our element -/* istanbul ignore next: not easy to test */ const removeTooltip = el => { - /* istanbul ignore next: not easy to test */ if (el[BV_TOOLTIP]) { el[BV_TOOLTIP].destroy() el[BV_TOOLTIP] = null From f56a18e5c4f29642aa65c61f84629f5b0085579c Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:22:54 -0300 Subject: [PATCH 30/38] Update popover.spec.js --- src/directives/popover/popover.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/directives/popover/popover.spec.js b/src/directives/popover/popover.spec.js index e1002572786..b301c23db2d 100644 --- a/src/directives/popover/popover.spec.js +++ b/src/directives/popover/popover.spec.js @@ -16,7 +16,7 @@ describe('v-b-popover directive', () => { data() { return {} }, - template: '' + template: `` }) const wrapper = mount(App, { From a287ca23c866c82faeca4740d4c9728ed57e8ec3 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:34:34 -0300 Subject: [PATCH 31/38] Update nuxt.config.js --- docs/nuxt.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/nuxt.config.js b/docs/nuxt.config.js index a6eeedc4f1c..5f1ba52ead1 100644 --- a/docs/nuxt.config.js +++ b/docs/nuxt.config.js @@ -117,6 +117,7 @@ module.exports = { .readdirSync(`${root}/${dir}`) .filter(c => c !== 'index.js' && c[0] !== '_') .filter(c => excludeDirs.indexOf(c) === -1) + .filter(c => !c.test(/\.scss/)) .map(page => `/docs/${dir}/${page}`) return [] From 079af09f71f42ce0034f2540b5f75504d2faebf3 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:36:11 -0300 Subject: [PATCH 32/38] Update nuxt.config.js --- docs/nuxt.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nuxt.config.js b/docs/nuxt.config.js index 5f1ba52ead1..f3453176fe6 100644 --- a/docs/nuxt.config.js +++ b/docs/nuxt.config.js @@ -117,7 +117,7 @@ module.exports = { .readdirSync(`${root}/${dir}`) .filter(c => c !== 'index.js' && c[0] !== '_') .filter(c => excludeDirs.indexOf(c) === -1) - .filter(c => !c.test(/\.scss/)) + .filter(c => !/\.scss/.test(c)) .map(page => `/docs/${dir}/${page}`) return [] From bb0fb34fcb4b17c1334ffd2d6c156a550a8b91a3 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:37:35 -0300 Subject: [PATCH 33/38] Update nuxt.config.js --- docs/nuxt.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/nuxt.config.js b/docs/nuxt.config.js index f3453176fe6..5fe90f2b7c9 100644 --- a/docs/nuxt.config.js +++ b/docs/nuxt.config.js @@ -117,7 +117,7 @@ module.exports = { .readdirSync(`${root}/${dir}`) .filter(c => c !== 'index.js' && c[0] !== '_') .filter(c => excludeDirs.indexOf(c) === -1) - .filter(c => !/\.scss/.test(c)) + .filter(c => !/\.s?css$/.test(c)) .map(page => `/docs/${dir}/${page}`) return [] From 3374e6570bd173a9a392e4fc690a098180da4140 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:50:34 -0300 Subject: [PATCH 34/38] Create scrollspy.spec.js --- src/directives/scrollspy/scrollspy.spec.js | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/directives/scrollspy/scrollspy.spec.js diff --git a/src/directives/scrollspy/scrollspy.spec.js b/src/directives/scrollspy/scrollspy.spec.js new file mode 100644 index 00000000000..9d0b1dfbb63 --- /dev/null +++ b/src/directives/scrollspy/scrollspy.spec.js @@ -0,0 +1,38 @@ +import scrollspyDirective from './scrollspy' +import ScrollSpy from '../../utils/scrollspy.class' +import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' + +// Key we use to store our instance +const BV_SCROLLSPY = '__BV_ScrollSpy__' + +describe('v-b-scrollspy directive', () => { + it('should have ScrollSpy class instance', async () => { + const localVue = new CreateLocalVue() + + const App = localVue.extend({ + directives: { + bScrollspy: scrollspyDirective + }, + data() { + return {} + }, + // Assumes watching body element for scrolls + template: '
content
' + }) + + const wrapper = mount(App, { + localVue: localVue, + attachToDocument: true + }) + + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.is('div')).toBe(true) + const $div = wrapper.find('div') + + // Should have instance of popover class on it + expect($div.element[BV_TOOLTIP]).toBeDefined() + expect($div.element[BV_TOOLTIP]).toBeInstanceOf(ScrollSpy) + + wrapper.destroy() + }) +}) From 7d4d78bc5850a933ce7f001200f72eb04eb0cccc Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:51:56 -0300 Subject: [PATCH 35/38] Update scrollspy.js --- src/directives/scrollspy/scrollspy.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/directives/scrollspy/scrollspy.js b/src/directives/scrollspy/scrollspy.js index 9d60197684e..d356ad4e6fb 100644 --- a/src/directives/scrollspy/scrollspy.js +++ b/src/directives/scrollspy/scrollspy.js @@ -8,7 +8,7 @@ const BV_SCROLLSPY = '__BV_ScrollSpy__' // Build a ScrollSpy config based on bindings (if any) // Arguments and modifiers take precedence over passed value config object /* istanbul ignore next: not easy to test */ -const parseBindings = bindings => { +const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { const config = {} // If argument, assume element ID @@ -50,7 +50,6 @@ const parseBindings = bindings => { } // Add or update ScrollSpy on our element -/* istanbul ignore next: not easy to test */ const applyScrollspy = (el, bindings, vnode) => { if (!inBrowser) { return @@ -64,7 +63,6 @@ const applyScrollspy = (el, bindings, vnode) => { } // Remove ScrollSpy on our element -/* istanbul ignore next: not easy to test */ const removeScrollspy = el => { if (el[BV_SCROLLSPY]) { el[BV_SCROLLSPY].dispose() @@ -77,10 +75,10 @@ const removeScrollspy = el => { * Export our directive */ export default { - bind(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { + bind(el, bindings, vnode) { applyScrollspy(el, bindings, vnode) }, - inserted(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { + inserted(el, bindings, vnode) { applyScrollspy(el, bindings, vnode) }, update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { @@ -93,7 +91,7 @@ export default { applyScrollspy(el, bindings, vnode) } }, - unbind(el) /* istanbul ignore next: not easy to test */ { + unbind(el) { removeScrollspy(el) } } From 3ea45e1b10a248159ddeae073c228373248399e9 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:53:06 -0300 Subject: [PATCH 36/38] Update scrollspy.spec.js --- src/directives/scrollspy/scrollspy.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/directives/scrollspy/scrollspy.spec.js b/src/directives/scrollspy/scrollspy.spec.js index 9d0b1dfbb63..93db2855590 100644 --- a/src/directives/scrollspy/scrollspy.spec.js +++ b/src/directives/scrollspy/scrollspy.spec.js @@ -1,5 +1,5 @@ import scrollspyDirective from './scrollspy' -import ScrollSpy from '../../utils/scrollspy.class' +import ScrollSpy from './scrollspy.class' import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' // Key we use to store our instance @@ -30,8 +30,8 @@ describe('v-b-scrollspy directive', () => { const $div = wrapper.find('div') // Should have instance of popover class on it - expect($div.element[BV_TOOLTIP]).toBeDefined() - expect($div.element[BV_TOOLTIP]).toBeInstanceOf(ScrollSpy) + expect($div.element[BV_SCROLLSPY]).toBeDefined() + expect($div.element[BV_SCROLLSPY]).toBeInstanceOf(ScrollSpy) wrapper.destroy() }) From 7822d4052671e4a066158c9b8fe2b34c65de232e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:55:06 -0300 Subject: [PATCH 37/38] lint --- src/directives/scrollspy/scrollspy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/directives/scrollspy/scrollspy.js b/src/directives/scrollspy/scrollspy.js index d356ad4e6fb..ccd98b41f0a 100644 --- a/src/directives/scrollspy/scrollspy.js +++ b/src/directives/scrollspy/scrollspy.js @@ -78,7 +78,7 @@ export default { bind(el, bindings, vnode) { applyScrollspy(el, bindings, vnode) }, - inserted(el, bindings, vnode) { + inserted(el, bindings, vnode) { applyScrollspy(el, bindings, vnode) }, update(el, bindings, vnode) /* istanbul ignore next: not easy to test */ { From eb842608d16893ef9853c7c6ba0b8740fc88ba3f Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 27 Mar 2019 14:56:29 -0300 Subject: [PATCH 38/38] Update scrollspy.js --- src/directives/scrollspy/scrollspy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/directives/scrollspy/scrollspy.js b/src/directives/scrollspy/scrollspy.js index ccd98b41f0a..e5ea5d74864 100644 --- a/src/directives/scrollspy/scrollspy.js +++ b/src/directives/scrollspy/scrollspy.js @@ -52,6 +52,7 @@ const parseBindings = bindings => /* istanbul ignore next: not easy to test */ { // Add or update ScrollSpy on our element const applyScrollspy = (el, bindings, vnode) => { if (!inBrowser) { + /* istanbul ignore next */ return } const config = parseBindings(bindings)