From c9e650a56f84a1f8526806b6fa9874aa6d258d24 Mon Sep 17 00:00:00 2001 From: Johann-S Date: Wed, 8 May 2019 21:32:50 +0200 Subject: rewrite popover unit tests --- build/build-plugins.js | 2 +- js/index.esm.js | 2 +- js/index.umd.js | 2 +- js/src/popover.js | 192 ----------------- js/src/popover/popover.js | 192 +++++++++++++++++ js/src/popover/popover.spec.js | 251 ++++++++++++++++++++++ js/tests/unit/popover.js | 474 ----------------------------------------- 7 files changed, 446 insertions(+), 669 deletions(-) delete mode 100644 js/src/popover.js create mode 100644 js/src/popover/popover.js create mode 100644 js/src/popover/popover.spec.js delete mode 100644 js/tests/unit/popover.js diff --git a/build/build-plugins.js b/build/build-plugins.js index d0d473f666..2995e638e0 100644 --- a/build/build-plugins.js +++ b/build/build-plugins.js @@ -38,7 +38,7 @@ const bsPlugins = { Collapse: path.resolve(__dirname, '../js/src/collapse/collapse.js'), Dropdown: path.resolve(__dirname, '../js/src/dropdown/dropdown.js'), Modal: path.resolve(__dirname, '../js/src/modal/modal.js'), - Popover: path.resolve(__dirname, '../js/src/popover.js'), + Popover: path.resolve(__dirname, '../js/src/popover/popover.js'), ScrollSpy: path.resolve(__dirname, '../js/src/scrollspy.js'), Tab: path.resolve(__dirname, '../js/src/tab.js'), Toast: path.resolve(__dirname, '../js/src/toast/toast.js'), diff --git a/js/index.esm.js b/js/index.esm.js index c2912d1910..0f48d63b4e 100644 --- a/js/index.esm.js +++ b/js/index.esm.js @@ -11,7 +11,7 @@ import Carousel from './src/carousel/carousel' import Collapse from './src/collapse/collapse' import Dropdown from './src/dropdown/dropdown' import Modal from './src/modal/modal' -import Popover from './src/popover' +import Popover from './src/popover/popover' import ScrollSpy from './src/scrollspy' import Tab from './src/tab' import Toast from './src/toast/toast' diff --git a/js/index.umd.js b/js/index.umd.js index eafc90141d..03b58715ef 100644 --- a/js/index.umd.js +++ b/js/index.umd.js @@ -11,7 +11,7 @@ import Carousel from './src/carousel/carousel' import Collapse from './src/collapse/collapse' import Dropdown from './src/dropdown/dropdown' import Modal from './src/modal/modal' -import Popover from './src/popover' +import Popover from './src/popover/popover' import ScrollSpy from './src/scrollspy' import Tab from './src/tab' import Toast from './src/toast/toast' diff --git a/js/src/popover.js b/js/src/popover.js deleted file mode 100644 index 3cb5549df0..0000000000 --- a/js/src/popover.js +++ /dev/null @@ -1,192 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.3.1): popover.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { jQuery as $ } from './util/index' -import Data from './dom/data' -import SelectorEngine from './dom/selector-engine' -import Tooltip from './tooltip' - -/** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - -const NAME = 'popover' -const VERSION = '4.3.1' -const DATA_KEY = 'bs.popover' -const EVENT_KEY = `.${DATA_KEY}` -const CLASS_PREFIX = 'bs-popover' -const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') - -const Default = { - ...Tooltip.Default, - placement: 'right', - trigger: 'click', - content: '', - template: '' -} - -const DefaultType = { - ...Tooltip.DefaultType, - content: '(string|element|function)' -} - -const ClassName = { - FADE: 'fade', - SHOW: 'show' -} - -const Selector = { - TITLE: '.popover-header', - CONTENT: '.popover-body' -} - -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}` -} - -/** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - -class Popover extends Tooltip { - // 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 - } - - // Overrides - - isWithContent() { - return this.getTitle() || this._getContent() - } - - addAttachmentClass(attachment) { - this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`) - } - - setContent() { - const tip = this.getTipElement() - - // we use append for html objects to maintain js events - this.setElementContent(SelectorEngine.findOne(Selector.TITLE, tip), this.getTitle()) - let content = this._getContent() - if (typeof content === 'function') { - content = content.call(this.element) - } - - this.setElementContent(SelectorEngine.findOne(Selector.CONTENT, tip), content) - - tip.classList.remove(ClassName.FADE) - tip.classList.remove(ClassName.SHOW) - } - - // Private - - _getContent() { - return this.element.getAttribute('data-content') || - this.config.content - } - - _cleanTipClass() { - const tip = this.getTipElement() - const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX) - - if (tabClass !== null && tabClass.length > 0) { - tabClass.map(token => token.trim()) - .forEach(tClass => tip.classList.remove(tClass)) - } - } - - // Static - - static _jQueryInterface(config) { - return this.each(function () { - let data = Data.getData(this, DATA_KEY) - const _config = typeof config === 'object' ? config : null - - if (!data && /dispose|hide/.test(config)) { - return - } - - if (!data) { - data = new Popover(this, _config) - Data.setData(this, DATA_KEY, data) - } - - 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) - } -} - -/** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - -if (typeof $ !== 'undefined') { - const JQUERY_NO_CONFLICT = $.fn[NAME] - $.fn[NAME] = Popover._jQueryInterface - $.fn[NAME].Constructor = Popover - $.fn[NAME].noConflict = () => { - $.fn[NAME] = JQUERY_NO_CONFLICT - return Popover._jQueryInterface - } -} - -export default Popover diff --git a/js/src/popover/popover.js b/js/src/popover/popover.js new file mode 100644 index 0000000000..3a55083c43 --- /dev/null +++ b/js/src/popover/popover.js @@ -0,0 +1,192 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.3.1): popover.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +import { jQuery as $ } from '../util/index' +import Data from '../dom/data' +import SelectorEngine from '../dom/selector-engine' +import Tooltip from '../tooltip' + +/** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + +const NAME = 'popover' +const VERSION = '4.3.1' +const DATA_KEY = 'bs.popover' +const EVENT_KEY = `.${DATA_KEY}` +const CLASS_PREFIX = 'bs-popover' +const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') + +const Default = { + ...Tooltip.Default, + placement: 'right', + trigger: 'click', + content: '', + template: '' +} + +const DefaultType = { + ...Tooltip.DefaultType, + content: '(string|element|function)' +} + +const ClassName = { + FADE: 'fade', + SHOW: 'show' +} + +const Selector = { + TITLE: '.popover-header', + CONTENT: '.popover-body' +} + +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}` +} + +/** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + +class Popover extends Tooltip { + // 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 + } + + // Overrides + + isWithContent() { + return this.getTitle() || this._getContent() + } + + addAttachmentClass(attachment) { + this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`) + } + + setContent() { + const tip = this.getTipElement() + + // we use append for html objects to maintain js events + this.setElementContent(SelectorEngine.findOne(Selector.TITLE, tip), this.getTitle()) + let content = this._getContent() + if (typeof content === 'function') { + content = content.call(this.element) + } + + this.setElementContent(SelectorEngine.findOne(Selector.CONTENT, tip), content) + + tip.classList.remove(ClassName.FADE) + tip.classList.remove(ClassName.SHOW) + } + + // Private + + _getContent() { + return this.element.getAttribute('data-content') || + this.config.content + } + + _cleanTipClass() { + const tip = this.getTipElement() + const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX) + + if (tabClass !== null && tabClass.length > 0) { + tabClass.map(token => token.trim()) + .forEach(tClass => tip.classList.remove(tClass)) + } + } + + // Static + + static _jQueryInterface(config) { + return this.each(function () { + let data = Data.getData(this, DATA_KEY) + const _config = typeof config === 'object' ? config : null + + if (!data && /dispose|hide/.test(config)) { + return + } + + if (!data) { + data = new Popover(this, _config) + Data.setData(this, DATA_KEY, data) + } + + 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) + } +} + +/** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ +/* istanbul ignore if */ +if (typeof $ !== 'undefined') { + const JQUERY_NO_CONFLICT = $.fn[NAME] + $.fn[NAME] = Popover._jQueryInterface + $.fn[NAME].Constructor = Popover + $.fn[NAME].noConflict = () => { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Popover._jQueryInterface + } +} + +export default Popover diff --git a/js/src/popover/popover.spec.js b/js/src/popover/popover.spec.js new file mode 100644 index 0000000000..cb16bf271a --- /dev/null +++ b/js/src/popover/popover.spec.js @@ -0,0 +1,251 @@ +import Popover from './popover' +import { makeArray } from '../util/index' + +/** Test helpers */ +import { getFixture, clearFixture, jQueryMock } from '../../tests/helpers/fixture' + +describe('Popover', () => { + let fixtureEl + + beforeAll(() => { + fixtureEl = getFixture() + }) + + afterEach(() => { + clearFixture() + + const popoverList = makeArray(document.querySelectorAll('.popover')) + + popoverList.forEach(backdrop => { + document.body.removeChild(backdrop) + }) + }) + + describe('VERSION', () => { + it('should return plugin version', () => { + expect(Popover.VERSION).toEqual(jasmine.any(String)) + }) + }) + + describe('Default', () => { + it('should return plugin default config', () => { + expect(Popover.Default).toEqual(jasmine.any(Object)) + }) + }) + + describe('NAME', () => { + it('should return plugin name', () => { + expect(Popover.NAME).toEqual(jasmine.any(String)) + }) + }) + + describe('DATA_KEY', () => { + it('should return plugin data key', () => { + expect(Popover.DATA_KEY).toEqual('bs.popover') + }) + }) + + describe('Event', () => { + it('should return plugin events', () => { + expect(Popover.Event).toEqual(jasmine.any(Object)) + }) + }) + + describe('EVENT_KEY', () => { + it('should return plugin event key', () => { + expect(Popover.EVENT_KEY).toEqual('.bs.popover') + }) + }) + + describe('DefaultType', () => { + it('should return plugin default type', () => { + expect(Popover.DefaultType).toEqual(jasmine.any(Object)) + }) + }) + + describe('show', () => { + it('should show a popover', done => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl) + + popoverEl.addEventListener('shown.bs.popover', () => { + expect(document.querySelector('.popover')).toBeDefined() + done() + }) + + popover.show() + }) + + it('should set title and content from functions', done => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl, { + title: () => 'Bootstrap', + content: () => 'loves writing tests (╯°□°)╯︵ ┻━┻' + }) + + popoverEl.addEventListener('shown.bs.popover', () => { + const popoverDisplayed = document.querySelector('.popover') + + expect(popoverDisplayed).toBeDefined() + expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('Bootstrap') + expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('loves writing tests (╯°□°)╯︵ ┻━┻') + done() + }) + + popover.show() + }) + + it('should show a popover with just content', done => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl, { + content: 'Popover content' + }) + + popoverEl.addEventListener('shown.bs.popover', () => { + const popoverDisplayed = document.querySelector('.popover') + + expect(popoverDisplayed).toBeDefined() + expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('Popover content') + done() + }) + + popover.show() + }) + }) + + describe('hide', () => { + it('should hide a popover', done => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl) + + popoverEl.addEventListener('shown.bs.popover', () => { + popover.hide() + }) + + popoverEl.addEventListener('hidden.bs.popover', () => { + expect(document.querySelector('.popover')).toBeNull() + done() + }) + + popover.show() + }) + }) + + describe('_jQueryInterface', () => { + it('should create a popover', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + + jQueryMock.fn.popover = Popover._jQueryInterface + jQueryMock.elements = [popoverEl] + + jQueryMock.fn.popover.call(jQueryMock) + + expect(Popover._getInstance(popoverEl)).toBeDefined() + }) + + it('should create a popover with a config object', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + + jQueryMock.fn.popover = Popover._jQueryInterface + jQueryMock.elements = [popoverEl] + + jQueryMock.fn.popover.call(jQueryMock, { + content: 'Popover content' + }) + + expect(Popover._getInstance(popoverEl)).toBeDefined() + }) + + it('should not re create a popover', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl) + + jQueryMock.fn.popover = Popover._jQueryInterface + jQueryMock.elements = [popoverEl] + + jQueryMock.fn.popover.call(jQueryMock) + + expect(Popover._getInstance(popoverEl)).toEqual(popover) + }) + + it('should throw error on undefined method', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const action = 'undefinedMethod' + + jQueryMock.fn.popover = Popover._jQueryInterface + jQueryMock.elements = [popoverEl] + + try { + jQueryMock.fn.popover.call(jQueryMock, action) + } catch (error) { + expect(error.message).toEqual(`No method named "${action}"`) + } + }) + + it('should should call show method', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl) + + jQueryMock.fn.popover = Popover._jQueryInterface + jQueryMock.elements = [popoverEl] + + spyOn(popover, 'show') + + jQueryMock.fn.popover.call(jQueryMock, 'show') + + expect(popover.show).toHaveBeenCalled() + }) + + it('should do nothing if dipose is called when a popover do not exist', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + + jQueryMock.fn.popover = Popover._jQueryInterface + jQueryMock.elements = [popoverEl] + + spyOn(Popover.prototype, 'dispose') + + jQueryMock.fn.popover.call(jQueryMock, 'dispose') + + expect(Popover.prototype.dispose).not.toHaveBeenCalled() + }) + }) + + describe('_getInstance', () => { + it('should return popover instance', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + const popover = new Popover(popoverEl) + + expect(Popover._getInstance(popoverEl)).toEqual(popover) + }) + + it('should return null when there is no popover instance', () => { + fixtureEl.innerHTML = 'BS twitter' + + const popoverEl = fixtureEl.querySelector('a') + + expect(Popover._getInstance(popoverEl)).toEqual(null) + }) + }) +}) diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js deleted file mode 100644 index 3782ed7eed..0000000000 --- a/js/tests/unit/popover.js +++ /dev/null @@ -1,474 +0,0 @@ -$(function () { - 'use strict' - - var Popover = typeof window.bootstrap === 'undefined' ? window.Popover : window.bootstrap.Popover - - QUnit.module('popover plugin') - - QUnit.test('should be defined on jquery object', function (assert) { - assert.expect(1) - assert.ok($(document.body).popover, 'popover method is defined') - }) - - QUnit.module('popover', { - beforeEach: function () { - // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode - $.fn.bootstrapPopover = $.fn.popover.noConflict() - }, - afterEach: function () { - $.fn.popover = $.fn.bootstrapPopover - delete $.fn.bootstrapPopover - $('.popover').remove() - $('#qunit-fixture').html('') - } - }) - - QUnit.test('should provide no conflict', function (assert) { - assert.expect(1) - assert.strictEqual(typeof $.fn.popover, 'undefined', 'popover was set back to undefined (org value)') - }) - - QUnit.test('should throw explicit error on undefined method', function (assert) { - assert.expect(1) - var $el = $('
') - $el.bootstrapPopover() - try { - $el.bootstrapPopover('noMethod') - } catch (error) { - assert.strictEqual(error.message, 'No method named "noMethod"') - } - }) - - QUnit.test('should return jquery collection containing the element', function (assert) { - assert.expect(2) - var $el = $('
') - var $popover = $el.bootstrapPopover() - assert.ok($popover instanceof $, 'returns jquery collection') - assert.strictEqual($popover[0], $el[0], 'collection contains element') - }) - - QUnit.test('should render popover element', function (assert) { - assert.expect(2) - var done = assert.async() - $('@mdo') - .appendTo('#qunit-fixture') - .on('shown.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - $(this).bootstrapPopover('hide') - }) - .on('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover removed') - done() - }) - .bootstrapPopover('show') - }) - - QUnit.test('should store popover instance in popover data object', function (assert) { - assert.expect(1) - var $popover = $('@mdo').bootstrapPopover() - - assert.ok(Popover._getInstance($popover[0]), 'popover instance exists') - }) - - QUnit.test('should store popover trigger in popover instance data object', function (assert) { - assert.expect(1) - var $popover = $('@ResentedHook') - .appendTo('#qunit-fixture') - .bootstrapPopover() - - $popover.bootstrapPopover('show') - - assert.ok(Popover._getInstance($('.popover')[0]), 'popover trigger stored in instance data') - }) - - QUnit.test('should get title and content from options', function (assert) { - assert.expect(4) - var done = assert.async() - var $popover = $('@fat') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - title: function () { - return '@fat' - }, - content: function () { - return 'loves writing tests (╯°□°)╯︵ ┻━┻' - } - }) - - $popover - .one('shown.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - assert.strictEqual($('.popover .popover-header').text(), '@fat', 'title correctly inserted') - assert.strictEqual($('.popover .popover-body').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted') - $popover.bootstrapPopover('hide') - }) - .one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - done() - }) - .bootstrapPopover('show') - }) - - QUnit.test('should allow DOMElement title and content (html: true)', function (assert) { - assert.expect(5) - var title = document.createTextNode('@glebm <3 writing tests') - var content = $('¯\\_(ツ)_/¯').get(0) - var $popover = $('') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - html: true, - title: title, - content: content - }) - - $popover.bootstrapPopover('show') - - assert.notEqual($('.popover').length, 0, 'popover inserted') - assert.strictEqual($('.popover .popover-header').text(), '@glebm <3 writing tests', 'title inserted') - assert.ok($.contains($('.popover').get(0), title), 'title node moved, not copied') - // toLowerCase because IE8 will return ... - assert.strictEqual($('.popover .popover-body').html().toLowerCase(), '¯\\_(ツ)_/¯', 'content inserted') - assert.ok($.contains($('.popover').get(0), content), 'content node moved, not copied') - }) - - QUnit.test('should allow DOMElement title and content (html: false)', function (assert) { - assert.expect(5) - var title = document.createTextNode('@glebm <3 writing tests') - var content = $('¯\\_(ツ)_/¯').get(0) - var $popover = $('') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - title: title, - content: content - }) - - $popover.bootstrapPopover('show') - - assert.notEqual($('.popover').length, 0, 'popover inserted') - assert.strictEqual($('.popover .popover-header').text(), '@glebm <3 writing tests', 'title inserted') - assert.ok(!$.contains($('.popover').get(0), title), 'title node copied, not moved') - assert.strictEqual($('.popover .popover-body').html(), '¯\\_(ツ)_/¯', 'content inserted') - assert.ok(!$.contains($('.popover').get(0), content), 'content node copied, not moved') - }) - - QUnit.test('should not duplicate HTML object', function (assert) { - assert.expect(6) - var done = assert.async() - var $div = $('
').html('loves writing tests (╯°□°)╯︵ ┻━┻') - - var $popover = $('@fat') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - html: true, - content: function () { - return $div - } - }) - - function popoverInserted() { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted') - } - - $popover - .one('shown.bs.popover', function () { - popoverInserted() - - $popover.one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - - $popover.one('shown.bs.popover', function () { - popoverInserted() - - $popover.one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - done() - }).bootstrapPopover('hide') - }).bootstrapPopover('show') - }).bootstrapPopover('hide') - }) - .bootstrapPopover('show') - }) - - QUnit.test('should get title and content from attributes', function (assert) { - assert.expect(4) - var done = assert.async() - var $popover = $('@mdo') - .appendTo('#qunit-fixture') - .bootstrapPopover() - .one('shown.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted') - assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted') - $popover.bootstrapPopover('hide') - }) - .one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - done() - }) - .bootstrapPopover('show') - }) - - QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) { - assert.expect(4) - var done = assert.async() - var $popover = $('@mdo') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - title: 'ignored title option', - content: 'ignored content option' - }) - .one('shown.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted') - assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted') - $popover.bootstrapPopover('hide') - }) - .one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - done() - }) - .bootstrapPopover('show') - }) - - QUnit.test('should respect custom template', function (assert) { - assert.expect(3) - var done = assert.async() - var $popover = $('@fat') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - title: 'Test', - content: 'Test', - template: '

' - }) - .one('shown.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - assert.ok($('.popover').hasClass('foobar'), 'custom class is present') - $popover.bootstrapPopover('hide') - }) - .one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - done() - }) - .bootstrapPopover('show') - }) - - QUnit.test('should destroy popover', function (assert) { - assert.expect(3) - var $popover = $('
') - .bootstrapPopover({ - trigger: 'hover' - }) - .on('click.foo', $.noop) - - assert.ok(Popover._getInstance($popover[0]), 'popover has data') - - $popover.bootstrapPopover('show') - $popover.bootstrapPopover('dispose') - - assert.ok(!$popover.hasClass('show'), 'popover is hidden') - assert.ok(!Popover._getInstance($popover[0]), 'popover does not have data') - }) - - QUnit.test('should render popover element using delegated selector', function (assert) { - assert.expect(2) - var done = assert.async() - var $div = $('') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - selector: 'a', - trigger: 'click' - }) - .one('shown.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - $div.find('a')[0].click() - }) - .one('hidden.bs.popover', function () { - assert.strictEqual($('.popover').length, 0, 'popover was removed') - done() - }) - - $div.find('a')[0].click() - }) - - QUnit.test('should detach popover content rather than removing it so that event handlers are left intact', function (assert) { - assert.expect(1) - var $content = $('').appendTo('#qunit-fixture') - - var handlerCalled = false - $('.content-with-handler .btn').on('click', function () { - handlerCalled = true - }) - - var $div = $('') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - html: true, - trigger: 'manual', - container: 'body', - animation: false, - content: function () { - return $content - } - }) - - var done = assert.async() - $div - .one('shown.bs.popover', function () { - $div - .one('hidden.bs.popover', function () { - $div - .one('shown.bs.popover', function () { - $('.content-with-handler .btn').trigger('click') - assert.ok(handlerCalled, 'content\'s event handler still present') - $div.bootstrapPopover('dispose') - done() - }) - .bootstrapPopover('show') - }) - .bootstrapPopover('hide') - }) - .bootstrapPopover('show') - }) - - QUnit.test('should do nothing when an attempt is made to hide an uninitialized popover', function (assert) { - assert.expect(1) - - var $popover = $('some text') - .appendTo('#qunit-fixture') - .on('hidden.bs.popover shown.bs.popover', function () { - assert.ok(false, 'should not fire any popover events') - }) - .bootstrapPopover('hide') - assert.ok(Popover._getInstance($popover[0]) === null, 'should not initialize the popover') - }) - - QUnit.test('should fire inserted event', function (assert) { - assert.expect(2) - var done = assert.async() - - $('@Johann-S') - .appendTo('#qunit-fixture') - .on('inserted.bs.popover', function () { - assert.notEqual($('.popover').length, 0, 'popover was inserted') - assert.ok(true, 'inserted event fired') - done() - }) - .bootstrapPopover({ - title: 'Test', - content: 'Test' - }) - .bootstrapPopover('show') - }) - - QUnit.test('should throw an error when show is called on hidden elements', function (assert) { - assert.expect(1) - var done = assert.async() - - try { - $('
').bootstrapPopover('show') - } catch (error) { - assert.strictEqual(error.message, 'Please use show on visible elements') - done() - } - }) - - QUnit.test('should hide popovers when their containing modal is closed', function (assert) { - assert.expect(1) - var done = assert.async() - var templateHTML = '' - - $(templateHTML).appendTo('#qunit-fixture') - $('#popover-test') - .on('shown.bs.popover', function () { - $('#modal-test').modal('hide') - }) - .on('hide.bs.popover', function () { - assert.ok(true, 'popover hide') - done() - }) - - $('#modal-test') - .on('shown.bs.modal', function () { - $('#popover-test').bootstrapPopover('show') - }) - .modal('show') - }) - - QUnit.test('should convert number to string without error for content and title', function (assert) { - assert.expect(2) - var done = assert.async() - var $popover = $('@mdo') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - title: 5, - content: 7 - }) - .on('shown.bs.popover', function () { - assert.strictEqual($('.popover .popover-header').text(), '5') - assert.strictEqual($('.popover .popover-body').text(), '7') - done() - }) - - $popover.bootstrapPopover('show') - }) - - QUnit.test('popover should be shown right away after the call of disable/enable', function (assert) { - assert.expect(2) - var done = assert.async() - var $popover = $('@mdo') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - title: 'Test popover', - content: 'with disable/enable' - }) - .on('shown.bs.popover', function () { - assert.strictEqual($('.popover').hasClass('show'), true) - done() - }) - - $popover.bootstrapPopover('disable') - $popover[0].click() - setTimeout(function () { - assert.strictEqual($('.popover').length === 0, true) - $popover.bootstrapPopover('enable') - $popover[0].click() - }, 200) - }) - - QUnit.test('popover should call content function only once', function (assert) { - assert.expect(1) - var done = assert.async() - var nbCall = 0 - $('').appendTo('#qunit-fixture') - var $popover = $('@Johann-S') - .appendTo('#qunit-fixture') - .bootstrapPopover({ - content: function () { - nbCall++ - return $('#popover').clone().show().get(0) - } - }) - .on('shown.bs.popover', function () { - assert.strictEqual(nbCall, 1) - done() - }) - - $popover[0].click() - }) - - QUnit.test('should return the version', function (assert) { - assert.expect(1) - assert.strictEqual(typeof Popover.VERSION, 'string') - }) -}) -- cgit v1.2.3