diff options
Diffstat (limited to 'js/src/tooltip')
| -rw-r--r-- | js/src/tooltip/tooltip.js | 827 | ||||
| -rw-r--r-- | js/src/tooltip/tooltip.spec.js | 1020 |
2 files changed, 0 insertions, 1847 deletions
diff --git a/js/src/tooltip/tooltip.js b/js/src/tooltip/tooltip.js deleted file mode 100644 index 99ac29af6..000000000 --- a/js/src/tooltip/tooltip.js +++ /dev/null @@ -1,827 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.3.1): tooltip.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { - getjQuery, - TRANSITION_END, - emulateTransitionEnd, - findShadowRoot, - getTransitionDurationFromElement, - getUID, - isElement, - makeArray, - noop, - typeCheckConfig -} from '../util/index' -import { - DefaultWhitelist, - sanitizeHtml -} from '../util/sanitizer' -import Data from '../dom/data' -import EventHandler from '../dom/event-handler' -import Manipulator from '../dom/manipulator' -import Popper from 'popper.js' -import SelectorEngine from '../dom/selector-engine' - -/** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - -const NAME = 'tooltip' -const VERSION = '4.3.1' -const DATA_KEY = 'bs.tooltip' -const EVENT_KEY = `.${DATA_KEY}` -const CLASS_PREFIX = 'bs-tooltip' -const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') -const DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'] - -const DefaultType = { - animation: 'boolean', - template: 'string', - title: '(string|element|function)', - trigger: 'string', - delay: '(number|object)', - html: 'boolean', - selector: '(string|boolean)', - placement: '(string|function)', - offset: '(number|string|function)', - container: '(string|element|boolean)', - fallbackPlacement: '(string|array)', - boundary: '(string|element)', - sanitize: 'boolean', - sanitizeFn: '(null|function)', - whiteList: 'object', - popperConfig: '(null|object)' -} - -const AttachmentMap = { - AUTO: 'auto', - TOP: 'top', - RIGHT: 'right', - BOTTOM: 'bottom', - LEFT: 'left' -} - -const Default = { - animation: true, - template: '<div class="tooltip" role="tooltip">' + - '<div class="tooltip-arrow"></div>' + - '<div class="tooltip-inner"></div></div>', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - selector: false, - placement: 'top', - offset: 0, - container: false, - fallbackPlacement: 'flip', - boundary: 'scrollParent', - sanitize: true, - sanitizeFn: null, - whiteList: DefaultWhitelist, - popperConfig: null -} - -const HoverState = { - SHOW: 'show', - OUT: 'out' -} - -const Event = { - HIDE: `hide${EVENT_KEY}`, - HIDDEN: `hidden${EVENT_KEY}`, - SHOW: `show${EVENT_KEY}`, - SHOWN: `shown${EVENT_KEY}`, - INSERTED: `inserted${EVENT_KEY}`, - CLICK: `click${EVENT_KEY}`, - FOCUSIN: `focusin${EVENT_KEY}`, - FOCUSOUT: `focusout${EVENT_KEY}`, - MOUSEENTER: `mouseenter${EVENT_KEY}`, - MOUSELEAVE: `mouseleave${EVENT_KEY}` -} - -const ClassName = { - FADE: 'fade', - SHOW: 'show' -} - -const Selector = { - TOOLTIP_INNER: '.tooltip-inner' -} - -const Trigger = { - HOVER: 'hover', - FOCUS: 'focus', - CLICK: 'click', - MANUAL: 'manual' -} - -/** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - -class Tooltip { - constructor(element, config) { - if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org)') - } - - // private - this._isEnabled = true - this._timeout = 0 - this._hoverState = '' - this._activeTrigger = {} - this._popper = null - - // Protected - this.element = element - this.config = this._getConfig(config) - this.tip = null - - this._setListeners() - Data.setData(element, this.constructor.DATA_KEY, this) - } - - // Getters - - static get VERSION() { - return VERSION - } - - static get Default() { - return Default - } - - static get NAME() { - return NAME - } - - static get DATA_KEY() { - return DATA_KEY - } - - static get Event() { - return Event - } - - static get EVENT_KEY() { - return EVENT_KEY - } - - static get DefaultType() { - return DefaultType - } - - // Public - - enable() { - this._isEnabled = true - } - - disable() { - this._isEnabled = false - } - - toggleEnabled() { - this._isEnabled = !this._isEnabled - } - - toggle(event) { - if (!this._isEnabled) { - return - } - - if (event) { - const dataKey = this.constructor.DATA_KEY - let context = Data.getData(event.delegateTarget, dataKey) - - if (!context) { - context = new this.constructor( - event.delegateTarget, - this._getDelegateConfig() - ) - Data.setData(event.delegateTarget, dataKey, context) - } - - context._activeTrigger.click = !context._activeTrigger.click - - if (context._isWithActiveTrigger()) { - context._enter(null, context) - } else { - context._leave(null, context) - } - } else { - if (this.getTipElement().classList.contains(ClassName.SHOW)) { - this._leave(null, this) - return - } - - this._enter(null, this) - } - } - - dispose() { - clearTimeout(this._timeout) - - Data.removeData(this.element, this.constructor.DATA_KEY) - - EventHandler.off(this.element, this.constructor.EVENT_KEY) - EventHandler.off(SelectorEngine.closest(this.element, '.modal'), 'hide.bs.modal', this._hideModalHandler) - - if (this.tip) { - this.tip.parentNode.removeChild(this.tip) - } - - this._isEnabled = null - this._timeout = null - this._hoverState = null - this._activeTrigger = null - if (this._popper) { - this._popper.destroy() - } - - this._popper = null - this.element = null - this.config = null - this.tip = null - } - - show() { - if (this.element.style.display === 'none') { - throw new Error('Please use show on visible elements') - } - - if (this.isWithContent() && this._isEnabled) { - const showEvent = EventHandler.trigger(this.element, this.constructor.Event.SHOW) - const shadowRoot = findShadowRoot(this.element) - const isInTheDom = shadowRoot === null ? - this.element.ownerDocument.documentElement.contains(this.element) : - shadowRoot.contains(this.element) - - if (showEvent.defaultPrevented || !isInTheDom) { - return - } - - const tip = this.getTipElement() - const tipId = getUID(this.constructor.NAME) - - tip.setAttribute('id', tipId) - this.element.setAttribute('aria-describedby', tipId) - - this.setContent() - - if (this.config.animation) { - tip.classList.add(ClassName.FADE) - } - - const placement = typeof this.config.placement === 'function' ? - this.config.placement.call(this, tip, this.element) : - this.config.placement - - const attachment = this._getAttachment(placement) - this._addAttachmentClass(attachment) - - const container = this._getContainer() - Data.setData(tip, this.constructor.DATA_KEY, this) - - if (!this.element.ownerDocument.documentElement.contains(this.tip)) { - container.appendChild(tip) - } - - EventHandler.trigger(this.element, this.constructor.Event.INSERTED) - - this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)) - - tip.classList.add(ClassName.SHOW) - - // If this is a touch-enabled device we add extra - // empty mouseover listeners to the body's immediate children; - // only needed because of broken event delegation on iOS - // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html - if ('ontouchstart' in document.documentElement) { - makeArray(document.body.children).forEach(element => { - EventHandler.on(element, 'mouseover', noop()) - }) - } - - const complete = () => { - if (this.config.animation) { - this._fixTransition() - } - - const prevHoverState = this._hoverState - this._hoverState = null - - EventHandler.trigger(this.element, this.constructor.Event.SHOWN) - - if (prevHoverState === HoverState.OUT) { - this._leave(null, this) - } - } - - if (this.tip.classList.contains(ClassName.FADE)) { - const transitionDuration = getTransitionDurationFromElement(this.tip) - EventHandler.one(this.tip, TRANSITION_END, complete) - emulateTransitionEnd(this.tip, transitionDuration) - } else { - complete() - } - } - } - - hide() { - const tip = this.getTipElement() - const complete = () => { - if (this._hoverState !== HoverState.SHOW && tip.parentNode) { - tip.parentNode.removeChild(tip) - } - - this._cleanTipClass() - this.element.removeAttribute('aria-describedby') - EventHandler.trigger(this.element, this.constructor.Event.HIDDEN) - this._popper.destroy() - } - - const hideEvent = EventHandler.trigger(this.element, this.constructor.Event.HIDE) - if (hideEvent.defaultPrevented) { - return - } - - tip.classList.remove(ClassName.SHOW) - - // If this is a touch-enabled device we remove the extra - // empty mouseover listeners we added for iOS support - if ('ontouchstart' in document.documentElement) { - makeArray(document.body.children) - .forEach(element => EventHandler.off(element, 'mouseover', noop)) - } - - this._activeTrigger[Trigger.CLICK] = false - this._activeTrigger[Trigger.FOCUS] = false - this._activeTrigger[Trigger.HOVER] = false - - if (this.tip.classList.contains(ClassName.FADE)) { - const transitionDuration = getTransitionDurationFromElement(tip) - - EventHandler.one(tip, TRANSITION_END, complete) - emulateTransitionEnd(tip, transitionDuration) - } else { - complete() - } - - this._hoverState = '' - } - - update() { - if (this._popper !== null) { - this._popper.scheduleUpdate() - } - } - - // Protected - - isWithContent() { - return Boolean(this.getTitle()) - } - - getTipElement() { - if (this.tip) { - return this.tip - } - - const element = document.createElement('div') - element.innerHTML = this.config.template - - this.tip = element.children[0] - return this.tip - } - - setContent() { - const tip = this.getTipElement() - this.setElementContent(SelectorEngine.findOne(Selector.TOOLTIP_INNER, tip), this.getTitle()) - tip.classList.remove(ClassName.FADE) - tip.classList.remove(ClassName.SHOW) - } - - setElementContent(element, content) { - if (element === null) { - return - } - - if (typeof content === 'object' && isElement(content)) { - if (content.jquery) { - content = content[0] - } - - // content is a DOM node or a jQuery - if (this.config.html) { - if (content.parentNode !== element) { - element.innerHTML = '' - element.appendChild(content) - } - } else { - element.innerText = content.textContent - } - - return - } - - if (this.config.html) { - if (this.config.sanitize) { - content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn) - } - - element.innerHTML = content - } else { - element.innerText = content - } - } - - getTitle() { - let title = this.element.getAttribute('data-original-title') - - if (!title) { - title = typeof this.config.title === 'function' ? - this.config.title.call(this.element) : - this.config.title - } - - return title - } - - // Private - - _getPopperConfig(attachment) { - const defaultBsConfig = { - placement: attachment, - modifiers: { - offset: this._getOffset(), - flip: { - behavior: this.config.fallbackPlacement - }, - arrow: { - element: `.${this.constructor.NAME}-arrow` - }, - preventOverflow: { - boundariesElement: this.config.boundary - } - }, - onCreate: data => { - if (data.originalPlacement !== data.placement) { - this._handlePopperPlacementChange(data) - } - }, - onUpdate: data => this._handlePopperPlacementChange(data) - } - - return { - ...defaultBsConfig, - ...this.config.popperConfig - } - } - - _addAttachmentClass(attachment) { - this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`) - } - - _getOffset() { - const offset = {} - - if (typeof this.config.offset === 'function') { - offset.fn = data => { - data.offsets = { - ...data.offsets, - ...this.config.offset(data.offsets, this.element) || {} - } - - return data - } - } else { - offset.offset = this.config.offset - } - - return offset - } - - _getContainer() { - if (this.config.container === false) { - return document.body - } - - if (isElement(this.config.container)) { - return this.config.container - } - - return SelectorEngine.findOne(this.config.container) - } - - _getAttachment(placement) { - return AttachmentMap[placement.toUpperCase()] - } - - _setListeners() { - const triggers = this.config.trigger.split(' ') - - triggers.forEach(trigger => { - if (trigger === 'click') { - EventHandler.on(this.element, - this.constructor.Event.CLICK, - this.config.selector, - event => this.toggle(event) - ) - } else if (trigger !== Trigger.MANUAL) { - const eventIn = trigger === Trigger.HOVER ? - this.constructor.Event.MOUSEENTER : - this.constructor.Event.FOCUSIN - const eventOut = trigger === Trigger.HOVER ? - this.constructor.Event.MOUSELEAVE : - this.constructor.Event.FOCUSOUT - - EventHandler.on(this.element, - eventIn, - this.config.selector, - event => this._enter(event) - ) - EventHandler.on(this.element, - eventOut, - this.config.selector, - event => this._leave(event) - ) - } - }) - - this._hideModalHandler = () => { - if (this.element) { - this.hide() - } - } - - EventHandler.on(SelectorEngine.closest(this.element, '.modal'), - 'hide.bs.modal', - this._hideModalHandler - ) - - if (this.config.selector) { - this.config = { - ...this.config, - trigger: 'manual', - selector: '' - } - } else { - this._fixTitle() - } - } - - _fixTitle() { - const titleType = typeof this.element.getAttribute('data-original-title') - - if (this.element.getAttribute('title') || titleType !== 'string') { - this.element.setAttribute( - 'data-original-title', - this.element.getAttribute('title') || '' - ) - - this.element.setAttribute('title', '') - } - } - - _enter(event, context) { - const dataKey = this.constructor.DATA_KEY - context = context || Data.getData(event.delegateTarget, dataKey) - - if (!context) { - context = new this.constructor( - event.delegateTarget, - this._getDelegateConfig() - ) - Data.setData(event.delegateTarget, dataKey, context) - } - - if (event) { - context._activeTrigger[ - event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER - ] = true - } - - if (context.getTipElement().classList.contains(ClassName.SHOW) || - context._hoverState === HoverState.SHOW) { - context._hoverState = HoverState.SHOW - return - } - - clearTimeout(context._timeout) - - context._hoverState = HoverState.SHOW - - if (!context.config.delay || !context.config.delay.show) { - context.show() - return - } - - context._timeout = setTimeout(() => { - if (context._hoverState === HoverState.SHOW) { - context.show() - } - }, context.config.delay.show) - } - - _leave(event, context) { - const dataKey = this.constructor.DATA_KEY - context = context || Data.getData(event.delegateTarget, dataKey) - - if (!context) { - context = new this.constructor( - event.delegateTarget, - this._getDelegateConfig() - ) - Data.setData(event.delegateTarget, dataKey, context) - } - - if (event) { - context._activeTrigger[ - event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER - ] = false - } - - if (context._isWithActiveTrigger()) { - return - } - - clearTimeout(context._timeout) - - context._hoverState = HoverState.OUT - - if (!context.config.delay || !context.config.delay.hide) { - context.hide() - return - } - - context._timeout = setTimeout(() => { - if (context._hoverState === HoverState.OUT) { - context.hide() - } - }, context.config.delay.hide) - } - - _isWithActiveTrigger() { - for (const trigger in this._activeTrigger) { - if (this._activeTrigger[trigger]) { - return true - } - } - - return false - } - - _getConfig(config) { - const dataAttributes = Manipulator.getDataAttributes(this.element) - - Object.keys(dataAttributes) - .forEach(dataAttr => { - if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { - delete dataAttributes[dataAttr] - } - }) - - if (config && typeof config.container === 'object' && config.container.jquery) { - config.container = config.container[0] - } - - config = { - ...this.constructor.Default, - ...dataAttributes, - ...typeof config === 'object' && config ? config : {} - } - - if (typeof config.delay === 'number') { - config.delay = { - show: config.delay, - hide: config.delay - } - } - - if (typeof config.title === 'number') { - config.title = config.title.toString() - } - - if (typeof config.content === 'number') { - config.content = config.content.toString() - } - - typeCheckConfig( - NAME, - config, - this.constructor.DefaultType - ) - - if (config.sanitize) { - config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn) - } - - return config - } - - _getDelegateConfig() { - const config = {} - - if (this.config) { - for (const key in this.config) { - if (this.constructor.Default[key] !== this.config[key]) { - config[key] = this.config[key] - } - } - } - - return config - } - - _cleanTipClass() { - const tip = this.getTipElement() - const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX) - if (tabClass !== null && tabClass.length) { - tabClass - .map(token => token.trim()) - .forEach(tClass => tip.classList.remove(tClass)) - } - } - - _handlePopperPlacementChange(popperData) { - const popperInstance = popperData.instance - this.tip = popperInstance.popper - this._cleanTipClass() - this._addAttachmentClass(this._getAttachment(popperData.placement)) - } - - _fixTransition() { - const tip = this.getTipElement() - const initConfigAnimation = this.config.animation - if (tip.getAttribute('x-placement') !== null) { - return - } - - tip.classList.remove(ClassName.FADE) - this.config.animation = false - this.hide() - this.show() - this.config.animation = initConfigAnimation - } - - // Static - - static jQueryInterface(config) { - return this.each(function () { - let data = Data.getData(this, DATA_KEY) - const _config = typeof config === 'object' && config - - if (!data && /dispose|hide/.test(config)) { - return - } - - if (!data) { - data = new Tooltip(this, _config) - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - } - }) - } - - static getInstance(element) { - return Data.getData(element, DATA_KEY) - } -} - -const $ = getjQuery() - -/** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - * add .tooltip to jQuery only if jQuery is present - */ -/* istanbul ignore if */ -if ($) { - const JQUERY_NO_CONFLICT = $.fn[NAME] - $.fn[NAME] = Tooltip.jQueryInterface - $.fn[NAME].Constructor = Tooltip - $.fn[NAME].noConflict = () => { - $.fn[NAME] = JQUERY_NO_CONFLICT - return Tooltip.jQueryInterface - } -} - -export default Tooltip diff --git a/js/src/tooltip/tooltip.spec.js b/js/src/tooltip/tooltip.spec.js deleted file mode 100644 index a6cbd7847..000000000 --- a/js/src/tooltip/tooltip.spec.js +++ /dev/null @@ -1,1020 +0,0 @@ -import Tooltip from './tooltip' -import EventHandler from '../dom/event-handler' -import { makeArray, noop } from '../util/index' - -/** Test helpers */ -import { getFixture, clearFixture, jQueryMock, createEvent } from '../../tests/helpers/fixture' - -describe('Tooltip', () => { - let fixtureEl - - beforeAll(() => { - fixtureEl = getFixture() - }) - - afterEach(() => { - clearFixture() - - const tooltipList = makeArray(document.querySelectorAll('.tooltip')) - - tooltipList.forEach(tooltipEl => { - document.body.removeChild(tooltipEl) - }) - }) - - describe('VERSION', () => { - it('should return plugin version', () => { - expect(Tooltip.VERSION).toEqual(jasmine.any(String)) - }) - }) - - describe('Default', () => { - it('should return plugin default config', () => { - expect(Tooltip.Default).toEqual(jasmine.any(Object)) - }) - }) - - describe('NAME', () => { - it('should return plugin name', () => { - expect(Tooltip.NAME).toEqual(jasmine.any(String)) - }) - }) - - describe('DATA_KEY', () => { - it('should return plugin data key', () => { - expect(Tooltip.DATA_KEY).toEqual('bs.tooltip') - }) - }) - - describe('Event', () => { - it('should return plugin events', () => { - expect(Tooltip.Event).toEqual(jasmine.any(Object)) - }) - }) - - describe('EVENT_KEY', () => { - it('should return plugin event key', () => { - expect(Tooltip.EVENT_KEY).toEqual('.bs.tooltip') - }) - }) - - describe('DefaultType', () => { - it('should return plugin default type', () => { - expect(Tooltip.DefaultType).toEqual(jasmine.any(Object)) - }) - }) - - describe('constructor', () => { - it('should not take care of disallowed data attributes', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-sanitize="false" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - expect(tooltip.config.sanitize).toEqual(true) - }) - - it('should convert title and content to string if numbers', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - title: 1, - content: 7 - }) - - expect(tooltip.config.title).toEqual('1') - expect(tooltip.config.content).toEqual('7') - }) - - it('should enable selector delegation', done => { - fixtureEl.innerHTML = '<div></div>' - - const containerEl = fixtureEl.querySelector('div') - const tooltipContainer = new Tooltip(containerEl, { - selector: 'a[rel="tooltip"]', - trigger: 'click' - }) - - containerEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipInContainerEl = containerEl.querySelector('a') - - tooltipInContainerEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).not.toBeNull() - tooltipContainer.dispose() - done() - }) - - tooltipInContainerEl.click() - }) - - it('should allow to pass config to popper.js with `popperConfig`', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - popperConfig: { - placement: 'left' - } - }) - - const popperConfig = tooltip._getPopperConfig('top') - - expect(popperConfig.placement).toEqual('left') - }) - }) - - describe('enable', () => { - it('should enable a tooltip', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.enable() - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeDefined() - done() - }) - - tooltip.show() - }) - }) - - describe('disable', () => { - it('should disable tooltip', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.disable() - - tooltipEl.addEventListener('show.bs.tooltip', () => { - throw new Error('should not show a disabled tooltip') - }) - - tooltip.show() - - setTimeout(() => { - expect().nothing() - done() - }, 10) - }) - }) - - describe('toggleEnabled', () => { - it('should toggle enabled', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - expect(tooltip._isEnabled).toEqual(true) - - tooltip.toggleEnabled() - - expect(tooltip._isEnabled).toEqual(false) - }) - }) - - describe('toggle', () => { - it('should do nothing if disabled', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.disable() - - tooltipEl.addEventListener('show.bs.tooltip', () => { - throw new Error('should not show a disabled tooltip') - }) - - tooltip.toggle() - - setTimeout(() => { - expect().nothing() - done() - }, 10) - }) - - it('should show a tooltip', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeDefined() - done() - }) - - tooltip.toggle() - }) - - it('should call toggle and show the tooltip when trigger is "click"', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - trigger: 'click' - }) - - spyOn(tooltip, 'toggle').and.callThrough() - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(tooltip.toggle).toHaveBeenCalled() - done() - }) - - tooltipEl.click() - }) - - it('should hide a tooltip', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - tooltip.toggle() - }) - - tooltipEl.addEventListener('hidden.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeNull() - done() - }) - - tooltip.toggle() - }) - - it('should call toggle and hide the tooltip when trigger is "click"', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - trigger: 'click' - }) - - spyOn(tooltip, 'toggle').and.callThrough() - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - tooltipEl.click() - }) - - tooltipEl.addEventListener('hidden.bs.tooltip', () => { - expect(tooltip.toggle).toHaveBeenCalled() - done() - }) - - tooltipEl.click() - }) - }) - - describe('dispose', () => { - it('should destroy a tooltip', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - expect(Tooltip.getInstance(tooltipEl)).toEqual(tooltip) - - tooltip.dispose() - - expect(Tooltip.getInstance(tooltipEl)).toEqual(null) - }) - - it('should destroy a tooltip and remove it from the dom', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeDefined() - - tooltip.dispose() - - expect(document.querySelector('.tooltip')).toBeNull() - done() - }) - - tooltip.show() - }) - }) - - describe('show', () => { - it('should show a tooltip', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - const tooltipShown = document.querySelector('.tooltip') - - expect(tooltipShown).toBeDefined() - expect(tooltipEl.getAttribute('aria-describedby')).toEqual(tooltipShown.getAttribute('id')) - expect(tooltipShown.getAttribute('id').indexOf('tooltip') !== -1).toEqual(true) - done() - }) - - tooltip.show() - }) - - it('should show a tooltip on mobile', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - document.documentElement.ontouchstart = noop - - spyOn(EventHandler, 'on') - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).not.toBeNull() - expect(EventHandler.on).toHaveBeenCalled() - document.documentElement.ontouchstart = undefined - done() - }) - - tooltip.show() - }) - - it('should show a tooltip relative to placement option', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - placement: 'bottom' - }) - - tooltipEl.addEventListener('inserted.bs.tooltip', () => { - expect(tooltip.getTipElement().classList.contains('bs-tooltip-bottom')).toEqual(true) - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - const tooltipShown = document.querySelector('.tooltip') - - expect(tooltipShown.classList.contains('bs-tooltip-bottom')).toEqual(true) - done() - }) - - tooltip.show() - }) - - it('should not error when trying to show a tooltip that has been removed from the dom', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - const firstCallback = () => { - tooltipEl.removeEventListener('shown.bs.tooltip', firstCallback) - let tooltipShown = document.querySelector('.tooltip') - - tooltipShown.parentNode.removeChild(tooltipShown) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - tooltipShown = document.querySelector('.tooltip') - - expect(tooltipShown).not.toBeNull() - done() - }) - - tooltip.show() - } - - tooltipEl.addEventListener('shown.bs.tooltip', firstCallback) - - tooltip.show() - }) - - it('should show a tooltip with a dom element container', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - container: fixtureEl - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(fixtureEl.querySelector('.tooltip')).toBeDefined() - done() - }) - - tooltip.show() - }) - - it('should show a tooltip with a jquery element container', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - container: { - 0: fixtureEl, - jquery: 'jQuery' - } - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(fixtureEl.querySelector('.tooltip')).toBeDefined() - done() - }) - - tooltip.show() - }) - - it('should show a tooltip with a selector in container', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - container: '#fixture' - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(fixtureEl.querySelector('.tooltip')).toBeDefined() - done() - }) - - tooltip.show() - }) - - it('should show a tooltip with placement as a function', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const spy = jasmine.createSpy('placement').and.returnValue('top') - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - placement: spy - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeDefined() - expect(spy).toHaveBeenCalled() - done() - }) - - tooltip.show() - }) - - it('should show a tooltip with offset as a function', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const spy = jasmine.createSpy('offset').and.returnValue({}) - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - offset: spy - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeDefined() - expect(spy).toHaveBeenCalled() - done() - }) - - tooltip.show() - }) - - it('should show a tooltip without the animation', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - animation: false - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - const tip = document.querySelector('.tooltip') - - expect(tip).toBeDefined() - expect(tip.classList.contains('fade')).toEqual(false) - done() - }) - - tooltip.show() - }) - - it('should throw an error the element is not visible', () => { - fixtureEl.innerHTML = '<a href="#" style="display: none" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - try { - tooltip.show() - } catch (error) { - expect(error.message).toEqual('Please use show on visible elements') - } - }) - - it('should not show a tooltip if show.bs.tooltip is prevented', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - const expectedDone = () => { - setTimeout(() => { - expect(document.querySelector('.tooltip')).toBeNull() - done() - }, 10) - } - - tooltipEl.addEventListener('show.bs.tooltip', ev => { - ev.preventDefault() - expectedDone() - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - throw new Error('Tooltip should not be shown') - }) - - tooltip.show() - }) - - it('should show tooltip if leave event hasn\'t occurred before delay expires', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - delay: 150 - }) - - spyOn(tooltip, 'show') - - setTimeout(() => { - expect(tooltip.show).not.toHaveBeenCalled() - }, 100) - - setTimeout(() => { - expect(tooltip.show).toHaveBeenCalled() - done() - }, 200) - - tooltipEl.dispatchEvent(createEvent('mouseover')) - }) - - it('should not show tooltip if leave event occurs before delay expires', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - delay: 150 - }) - - spyOn(tooltip, 'show') - - setTimeout(() => { - expect(tooltip.show).not.toHaveBeenCalled() - tooltipEl.dispatchEvent(createEvent('mouseover')) - }, 100) - - setTimeout(() => { - expect(tooltip.show).toHaveBeenCalled() - expect(document.querySelectorAll('.tooltip').length).toEqual(0) - done() - }, 200) - - tooltipEl.dispatchEvent(createEvent('mouseover')) - }) - - it('should not hide tooltip if leave event occurs and enter event occurs within the hide delay', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - delay: { - show: 0, - hide: 150 - } - }) - - setTimeout(() => { - expect(tooltip.getTipElement().classList.contains('show')).toEqual(true) - tooltipEl.dispatchEvent(createEvent('mouseout')) - - setTimeout(() => { - expect(tooltip.getTipElement().classList.contains('show')).toEqual(true) - tooltipEl.dispatchEvent(createEvent('mouseover')) - }, 100) - - setTimeout(() => { - expect(tooltip.getTipElement().classList.contains('show')).toEqual(true) - done() - }, 200) - }, 0) - - tooltipEl.dispatchEvent(createEvent('mouseover')) - }) - }) - - describe('hide', () => { - it('should hide a tooltip', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => tooltip.hide()) - tooltipEl.addEventListener('hidden.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeNull() - expect(tooltipEl.getAttribute('aria-describedby')).toBeNull() - done() - }) - - tooltip.show() - }) - - it('should hide a tooltip on mobile', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - document.documentElement.ontouchstart = noop - spyOn(EventHandler, 'off') - tooltip.hide() - }) - - tooltipEl.addEventListener('hidden.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeNull() - expect(EventHandler.off).toHaveBeenCalled() - document.documentElement.ontouchstart = undefined - done() - }) - - tooltip.show() - }) - - it('should hide a tooltip without animation', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - animation: false - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => tooltip.hide()) - tooltipEl.addEventListener('hidden.bs.tooltip', () => { - expect(document.querySelector('.tooltip')).toBeNull() - expect(tooltipEl.getAttribute('aria-describedby')).toBeNull() - done() - }) - - tooltip.show() - }) - - it('should not hide a tooltip if hide event is prevented', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const assertDone = () => { - setTimeout(() => { - expect(document.querySelector('.tooltip')).not.toBeNull() - done() - }, 20) - } - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - animation: false - }) - - tooltipEl.addEventListener('shown.bs.tooltip', () => tooltip.hide()) - tooltipEl.addEventListener('hide.bs.tooltip', event => { - event.preventDefault() - assertDone() - }) - tooltipEl.addEventListener('hidden.bs.tooltip', () => { - throw new Error('should not trigger hidden event') - }) - - tooltip.show() - }) - }) - - describe('update', () => { - it('should call popper schedule update', done => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltipEl.addEventListener('shown.bs.tooltip', () => { - spyOn(tooltip._popper, 'scheduleUpdate') - - tooltip.update() - - expect(tooltip._popper.scheduleUpdate).toHaveBeenCalled() - done() - }) - - tooltip.show() - }) - - it('should do nothing if the tooltip is not shown', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.update() - expect().nothing() - }) - }) - - describe('isWithContent', () => { - it('should return true if there is content', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - expect(tooltip.isWithContent()).toEqual(true) - }) - - it('should return false if there is no content', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title=""/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - expect(tooltip.isWithContent()).toEqual(false) - }) - }) - - describe('getTipElement', () => { - it('should create the tip element and return it', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - spyOn(document, 'createElement').and.callThrough() - - expect(tooltip.getTipElement()).toBeDefined() - expect(document.createElement).toHaveBeenCalled() - }) - - it('should return the created tip element', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - const spy = spyOn(document, 'createElement').and.callThrough() - - expect(tooltip.getTipElement()).toBeDefined() - expect(spy).toHaveBeenCalled() - - spy.calls.reset() - - expect(tooltip.getTipElement()).toBeDefined() - expect(spy).not.toHaveBeenCalled() - }) - }) - - describe('setContent', () => { - it('should set tip content', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.setContent() - - const tip = tooltip.getTipElement() - - expect(tip.classList.contains('show')).toEqual(false) - expect(tip.classList.contains('fade')).toEqual(false) - expect(tip.querySelector('.tooltip-inner').textContent).toEqual('Another tooltip') - }) - }) - - describe('setElementContent', () => { - it('should do nothing if the element is null', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.setElementContent(null, null) - expect().nothing() - }) - - it('should add the content as a child of the element', () => { - fixtureEl.innerHTML = [ - '<a href="#" rel="tooltip" title="Another tooltip"/>', - '<div id="childContent"></div>' - ].join('') - - const tooltipEl = fixtureEl.querySelector('a') - const childContent = fixtureEl.querySelector('div') - const tooltip = new Tooltip(tooltipEl, { - html: true - }) - - tooltip.setElementContent(tooltip.getTipElement(), childContent) - - expect(childContent.parentNode).toEqual(tooltip.getTipElement()) - }) - - it('should do nothing if the content is a child of the element', () => { - fixtureEl.innerHTML = [ - '<a href="#" rel="tooltip" title="Another tooltip"/>', - '<div id="childContent"></div>' - ].join('') - - const tooltipEl = fixtureEl.querySelector('a') - const childContent = fixtureEl.querySelector('div') - const tooltip = new Tooltip(tooltipEl, { - html: true - }) - - tooltip.getTipElement().appendChild(childContent) - tooltip.setElementContent(tooltip.getTipElement(), childContent) - - expect().nothing() - }) - - it('should add the content as a child of the element for jQuery elements', () => { - fixtureEl.innerHTML = [ - '<a href="#" rel="tooltip" title="Another tooltip"/>', - '<div id="childContent"></div>' - ].join('') - - const tooltipEl = fixtureEl.querySelector('a') - const childContent = fixtureEl.querySelector('div') - const tooltip = new Tooltip(tooltipEl, { - html: true - }) - - tooltip.setElementContent(tooltip.getTipElement(), { 0: childContent, jquery: 'jQuery' }) - - expect(childContent.parentNode).toEqual(tooltip.getTipElement()) - }) - - it('should add the child text content in the element', () => { - fixtureEl.innerHTML = [ - '<a href="#" rel="tooltip" title="Another tooltip"/>', - '<div id="childContent">Tooltip</div>' - ].join('') - - const tooltipEl = fixtureEl.querySelector('a') - const childContent = fixtureEl.querySelector('div') - const tooltip = new Tooltip(tooltipEl) - - tooltip.setElementContent(tooltip.getTipElement(), childContent) - - expect(childContent.textContent).toEqual(tooltip.getTipElement().textContent) - }) - - it('should add html without sanitize it', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - sanitize: false, - html: true - }) - - tooltip.setElementContent(tooltip.getTipElement(), '<div id="childContent">Tooltip</div>') - - expect(tooltip.getTipElement().querySelector('div').id).toEqual('childContent') - }) - - it('should add html sanitized', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - html: true - }) - - tooltip.setElementContent(tooltip.getTipElement(), [ - '<div id="childContent">', - ' <button type="button">test btn</button>', - '</div>' - ].join('')) - - expect(tooltip.getTipElement().querySelector('div').id).toEqual('childContent') - expect(tooltip.getTipElement().querySelector('button')).toEqual(null) - }) - - it('should add text content', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - tooltip.setElementContent(tooltip.getTipElement(), 'test') - - expect(tooltip.getTipElement().innerText).toEqual('test') - }) - }) - - describe('getTitle', () => { - it('should return the title', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl) - - expect(tooltip.getTitle()).toEqual('Another tooltip') - }) - - it('should call title function', () => { - fixtureEl.innerHTML = '<a href="#" rel="tooltip" />' - - const tooltipEl = fixtureEl.querySelector('a') - const tooltip = new Tooltip(tooltipEl, { - title: () => 'test' - }) - - expect(tooltip.getTitle()).toEqual('test') - }) - }) - - describe('jQueryInterface', () => { - it('should create a tooltip', () => { - fixtureEl.innerHTML = '<div></div>' - - const div = fixtureEl.querySelector('div') - - jQueryMock.fn.tooltip = Tooltip.jQueryInterface - jQueryMock.elements = [div] - - jQueryMock.fn.tooltip.call(jQueryMock) - - expect(Tooltip.getInstance(div)).toBeDefined() - }) - - it('should not re create a tooltip', () => { - fixtureEl.innerHTML = '<div></div>' - - const div = fixtureEl.querySelector('div') - const tooltip = new Tooltip(div) - - jQueryMock.fn.tooltip = Tooltip.jQueryInterface - jQueryMock.elements = [div] - - jQueryMock.fn.tooltip.call(jQueryMock) - - expect(Tooltip.getInstance(div)).toEqual(tooltip) - }) - - it('should call a tooltip method', () => { - fixtureEl.innerHTML = '<div></div>' - - const div = fixtureEl.querySelector('div') - const tooltip = new Tooltip(div) - - spyOn(tooltip, 'show') - - jQueryMock.fn.tooltip = Tooltip.jQueryInterface - jQueryMock.elements = [div] - - jQueryMock.fn.tooltip.call(jQueryMock, 'show') - - expect(Tooltip.getInstance(div)).toEqual(tooltip) - expect(tooltip.show).toHaveBeenCalled() - }) - - it('should do nothing when we call dispose or hide if there is no tooltip created', () => { - fixtureEl.innerHTML = '<div></div>' - - const div = fixtureEl.querySelector('div') - - spyOn(Tooltip.prototype, 'dispose') - - jQueryMock.fn.tooltip = Tooltip.jQueryInterface - jQueryMock.elements = [div] - - jQueryMock.fn.tooltip.call(jQueryMock, 'dispose') - - expect(Tooltip.prototype.dispose).not.toHaveBeenCalled() - }) - - it('should throw error on undefined method', () => { - fixtureEl.innerHTML = '<div></div>' - - const div = fixtureEl.querySelector('div') - const action = 'undefinedMethod' - - jQueryMock.fn.tooltip = Tooltip.jQueryInterface - jQueryMock.elements = [div] - - try { - jQueryMock.fn.tooltip.call(jQueryMock, action) - } catch (error) { - expect(error.message).toEqual(`No method named "${action}"`) - } - }) - }) -}) |
