' +
diff --git a/vendor/twbs/bootstrap/js/tests/unit/carousel.js b/vendor/twbs/bootstrap/js/tests/unit/carousel.js
index baabcf426..d6fea2f34 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/carousel.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/carousel.js
@@ -1,6 +1,26 @@
$(function () {
'use strict'
+ window.Carousel = typeof bootstrap !== 'undefined' ? bootstrap.Carousel : Carousel
+
+ var originWinPointerEvent = window.PointerEvent
+ window.MSPointerEvent = null
+ var supportPointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)
+
+ function clearPointerEvents() {
+ window.PointerEvent = null
+ }
+
+ function restorePointerEvents() {
+ window.PointerEvent = originWinPointerEvent
+ }
+
+ var stylesCarousel = [
+ ''
+ ].join('')
+
QUnit.module('carousel plugin')
QUnit.test('should be defined on jQuery object', function (assert) {
@@ -25,6 +45,20 @@ $(function () {
assert.strictEqual(typeof $.fn.carousel, 'undefined', 'carousel was set back to undefined (orig value)')
})
+ QUnit.test('should return version', function (assert) {
+ assert.expect(1)
+
+ assert.strictEqual(typeof Carousel.VERSION, 'string')
+ })
+
+ QUnit.test('should return default parameters', function (assert) {
+ assert.expect(1)
+
+ var defaultConfig = Carousel.Default
+
+ assert.strictEqual(defaultConfig.touch, true)
+ })
+
QUnit.test('should throw explicit error on undefined method', function (assert) {
assert.expect(1)
var $el = $('
')
@@ -445,6 +479,54 @@ $(function () {
$carousel.remove()
})
+ QUnit.test('should set interval from data attribute on individual carousel-item', function (assert) {
+ assert.expect(2)
+ var templateHTML = '
'
+ var $carousel = $(templateHTML)
+
+ $carousel.appendTo('body')
+ $carousel.bootstrapCarousel(1)
+ assert.strictEqual($carousel.data('bs.carousel')._config.interval, 3814)
+ $carousel.remove()
+
+ $carousel.appendTo('body')
+ $carousel.bootstrapCarousel(2)
+ assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814, 'reverts to default interval if no data-interval is set')
+ $carousel.remove()
+ })
+
QUnit.test('should skip over non-items when using item indices', function (assert) {
assert.expect(2)
var templateHTML = '
' +
@@ -941,4 +1023,251 @@ $(function () {
}, 80)
}, 80)
})
+
+ QUnit.test('should allow swiperight and call prev with pointer events', function (assert) {
+ if (!supportPointerEvent) {
+ assert.expect(0)
+ return
+ }
+
+ document.documentElement.ontouchstart = $.noop
+ Simulator.setType('pointer')
+ assert.expect(3)
+ var $styles = $(stylesCarousel).appendTo('head')
+ var done = assert.async()
+
+ var carouselHTML =
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
'
+
+ var $carousel = $(carouselHTML).appendTo('#qunit-fixture')
+ var $item = $('#item')
+ $carousel.bootstrapCarousel()
+ var carousel = $carousel.data('bs.carousel')
+ var spy = sinon.spy(carousel, 'prev')
+
+ $carousel.one('slid.bs.carousel', function () {
+ assert.ok(true, 'slid event fired')
+ assert.ok($item.hasClass('active'))
+ assert.ok(spy.called)
+ $styles.remove()
+ delete document.documentElement.ontouchstart
+ done()
+ })
+
+ Simulator.gestures.swipe($carousel[0], {
+ deltaX: 300,
+ deltaY: 0
+ })
+ })
+
+ QUnit.test('should allow swiperight and call prev with touch events', function (assert) {
+ Simulator.setType('touch')
+ clearPointerEvents()
+
+ assert.expect(3)
+ var done = assert.async()
+ document.documentElement.ontouchstart = $.noop
+
+ var carouselHTML =
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
'
+
+ var $carousel = $(carouselHTML)
+ $carousel.appendTo('#qunit-fixture')
+ var $item = $('#item')
+ $carousel.bootstrapCarousel()
+ var carousel = $carousel.data('bs.carousel')
+ var spy = sinon.spy(carousel, 'prev')
+
+ $carousel.one('slid.bs.carousel', function () {
+ assert.ok(true, 'slid event fired')
+ assert.ok($item.hasClass('active'))
+ assert.ok(spy.called)
+ delete document.documentElement.ontouchstart
+ restorePointerEvents()
+ done()
+ })
+
+ Simulator.gestures.swipe($carousel[0], {
+ deltaX: 300,
+ deltaY: 0
+ })
+ })
+
+ QUnit.test('should allow swipeleft and call next with pointer events', function (assert) {
+ if (!supportPointerEvent) {
+ assert.expect(0)
+ return
+ }
+
+ document.documentElement.ontouchstart = $.noop
+ assert.expect(3)
+ Simulator.setType('pointer')
+
+ var $styles = $(stylesCarousel).appendTo('head')
+ var done = assert.async()
+
+ var carouselHTML =
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
'
+
+ var $carousel = $(carouselHTML)
+ $carousel.appendTo('#qunit-fixture')
+ var $item = $('#item')
+ $carousel.bootstrapCarousel()
+ var carousel = $carousel.data('bs.carousel')
+ var spy = sinon.spy(carousel, 'next')
+
+ $carousel.one('slid.bs.carousel', function () {
+ assert.ok(true, 'slid event fired')
+ assert.ok(!$item.hasClass('active'))
+ assert.ok(spy.called)
+ $styles.remove()
+ delete document.documentElement.ontouchstart
+ done()
+ })
+
+ Simulator.gestures.swipe($carousel[0], {
+ pos: [300, 10],
+ deltaX: -300,
+ deltaY: 0
+ })
+ })
+
+ QUnit.test('should allow swipeleft and call next with touch events', function (assert) {
+ assert.expect(3)
+ clearPointerEvents()
+ Simulator.setType('touch')
+ document.documentElement.ontouchstart = $.noop
+
+ var done = assert.async()
+
+ var carouselHTML =
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
'
+
+ var $carousel = $(carouselHTML)
+ $carousel.appendTo('#qunit-fixture')
+ var $item = $('#item')
+ $carousel.bootstrapCarousel()
+ var carousel = $carousel.data('bs.carousel')
+ var spy = sinon.spy(carousel, 'next')
+
+ $carousel.one('slid.bs.carousel', function () {
+ assert.ok(true, 'slid event fired')
+ assert.ok(!$item.hasClass('active'))
+ assert.ok(spy.called)
+ restorePointerEvents()
+ delete document.documentElement.ontouchstart
+ done()
+ })
+
+ Simulator.gestures.swipe($carousel[0], {
+ pos: [300, 10],
+ deltaX: -300,
+ deltaY: 0
+ })
+ })
+
+ QUnit.test('should not allow pinch with touch events', function (assert) {
+ assert.expect(0)
+ clearPointerEvents()
+
+ Simulator.setType('touch')
+ var done = assert.async()
+ document.documentElement.ontouchstart = $.noop
+
+ var carouselHTML = '
'
+ var $carousel = $(carouselHTML)
+ $carousel.appendTo('#qunit-fixture')
+ $carousel.bootstrapCarousel()
+
+ Simulator.gestures.swipe($carousel[0], {
+ pos: [300, 10],
+ deltaX: -300,
+ deltaY: 0,
+ touches: 2
+ }, function () {
+ restorePointerEvents()
+ delete document.documentElement.ontouchstart
+ done()
+ })
+ })
+
+ QUnit.test('should not call _slide if the carousel is sliding', function (assert) {
+ assert.expect(1)
+
+ var carouselHTML = '
'
+ var $carousel = $(carouselHTML)
+ $carousel.appendTo('#qunit-fixture')
+ $carousel.bootstrapCarousel()
+
+ var carousel = $carousel.data('bs.carousel')
+
+ var spy = sinon.spy(carousel, '_slide')
+
+ carousel._isSliding = true
+
+ carousel.next()
+
+ assert.strictEqual(spy.called, false)
+ })
+
+ QUnit.test('should call next when the page is visible', function (assert) {
+ assert.expect(1)
+
+ var carouselHTML = '
'
+ var $carousel = $(carouselHTML)
+ $carousel.appendTo('#qunit-fixture')
+ $carousel.bootstrapCarousel()
+
+ var carousel = $carousel.data('bs.carousel')
+
+ var spy = sinon.spy(carousel, 'next')
+ var sandbox = sinon.createSandbox()
+
+ sandbox.replaceGetter(document, 'hidden', function () {
+ return false
+ })
+ sandbox.stub($carousel, 'is').returns(true)
+ sandbox.stub($carousel, 'css').returns('block')
+
+ carousel.nextWhenVisible()
+
+ assert.strictEqual(spy.called, true)
+ sandbox.restore()
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/collapse.js b/vendor/twbs/bootstrap/js/tests/unit/collapse.js
index 7f4cedd74..e7fb8893e 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/collapse.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/collapse.js
@@ -855,4 +855,38 @@ $(function () {
assert.ok(false, 'collapse not created')
}
})
+
+ QUnit.test('should find collapse children if they have collapse class too not only data-parent', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+
+ var html =
+ '
'
+
+ $(html).appendTo('#qunit-fixture')
+
+ var $parent = $('.my-collapse')
+ var $collapse2 = $('#collapse2')
+ $parent.find('.collapse').bootstrapCollapse({
+ parent: $parent,
+ toggle: false
+ })
+
+ $collapse2.on('shown.bs.collapse', function () {
+ assert.ok($collapse2.hasClass('show'))
+ assert.ok(!$('#collapse1').hasClass('show'))
+ done()
+ })
+
+ $collapse2.bootstrapCollapse('toggle')
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/dropdown.js b/vendor/twbs/bootstrap/js/tests/unit/dropdown.js
index 81d35ff3a..fd9b7f962 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/dropdown.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/dropdown.js
@@ -216,30 +216,6 @@ $(function () {
$dropdown.trigger('click')
})
- QUnit.test('should test if element has a # before assuming it\'s a selector', function (assert) {
- assert.expect(1)
- var done = assert.async()
- var dropdownHTML = '
'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
- $dropdown
- .parent('.dropdown')
- .on('shown.bs.dropdown', function () {
- assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
- done()
- })
- $dropdown.trigger('click')
- })
-
QUnit.test('should remove "show" class if body is clicked', function (assert) {
assert.expect(2)
var done = assert.async()
@@ -1121,4 +1097,268 @@ $(function () {
assert.ok(dropdown._menu === null)
assert.ok(dropdown._element === null)
})
+
+ QUnit.test('should show dropdown', function (assert) {
+ assert.expect(2)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ var done = assert.async()
+
+ $dropdown
+ .parent('.dropdown')
+ .on('show.bs.dropdown', function () {
+ assert.ok(true, 'show was fired')
+ })
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ done()
+ })
+
+ dropdown.show()
+ })
+
+ QUnit.test('should hide dropdown', function (assert) {
+ assert.expect(2)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ var done = assert.async()
+ $dropdown.trigger('click')
+
+ $dropdown
+ .parent('.dropdown')
+ .on('hide.bs.dropdown', function () {
+ assert.ok(true, 'hide was fired')
+ })
+ .on('hidden.bs.dropdown', function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is hidden')
+ done()
+ })
+
+ dropdown.hide()
+ })
+
+ QUnit.test('should not hide dropdown', function (assert) {
+ assert.expect(1)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ $dropdown.trigger('click')
+ dropdown.show()
+
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is still shown')
+ })
+
+ QUnit.test('should not show dropdown', function (assert) {
+ assert.expect(1)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ dropdown.hide()
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is still hidden')
+ })
+
+ QUnit.test('should show dropdown', function (assert) {
+ assert.expect(2)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ var done = assert.async()
+
+ $dropdown
+ .parent('.dropdown')
+ .on('show.bs.dropdown', function () {
+ assert.ok(true, 'show was fired')
+ })
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ done()
+ })
+
+ dropdown.show()
+ })
+
+ QUnit.test('should prevent default event on show method call', function (assert) {
+ assert.expect(1)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ var done = assert.async()
+
+ $dropdown
+ .parent('.dropdown')
+ .on('show.bs.dropdown', function (event) {
+ event.preventDefault()
+ done()
+ })
+
+ dropdown.show()
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is hidden')
+ })
+
+ QUnit.test('should prevent default event on hide method call', function (assert) {
+ assert.expect(1)
+
+ var dropdownHTML =
+ '
'
+
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ var dropdown = $dropdown.data('bs.dropdown')
+ var done = assert.async()
+ $dropdown.trigger('click')
+
+ $dropdown
+ .parent('.dropdown')
+ .on('hide.bs.dropdown', function (event) {
+ event.preventDefault()
+ done()
+ })
+
+ dropdown.hide()
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ })
+
+ QUnit.test('should not open dropdown via show method if target is disabled via attribute', function (assert) {
+ assert.expect(1)
+ var dropdownHTML =
+ '
' +
+ ' Dropdown ' +
+ ' ' +
+ '
'
+ $(dropdownHTML).appendTo('#qunit-fixture')
+ var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown.show()
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
+ })
+
+ QUnit.test('should not open dropdown via show method if target is disabled via class', function (assert) {
+ assert.expect(1)
+ var dropdownHTML =
+ '
' +
+ ' Dropdown ' +
+ ' ' +
+ '
'
+
+ $(dropdownHTML).appendTo('#qunit-fixture')
+ var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown.show()
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
+ })
+
+ QUnit.test('should not hide dropdown via hide method if target is disabled via attribute', function (assert) {
+ assert.expect(1)
+ var dropdownHTML =
+ '
' +
+ ' Dropdown ' +
+ ' ' +
+ '
'
+ $(dropdownHTML).appendTo('#qunit-fixture')
+ var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown.hide()
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'))
+ })
+
+ QUnit.test('should not hide dropdown via hide method if target is disabled via class', function (assert) {
+ assert.expect(1)
+ var dropdownHTML =
+ '
' +
+ ' Dropdown ' +
+ ' ' +
+ '
'
+
+ $(dropdownHTML).appendTo('#qunit-fixture')
+ var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown.hide()
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'))
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/modal.js b/vendor/twbs/bootstrap/js/tests/unit/modal.js
index 53a2e0416..782a86eea 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/modal.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/modal.js
@@ -1,6 +1,8 @@
$(function () {
'use strict'
+ window.Util = typeof bootstrap !== 'undefined' ? bootstrap.Util : Util
+
QUnit.module('modal plugin')
QUnit.test('should be defined on jquery object', function (assert) {
@@ -13,14 +15,7 @@ $(function () {
// Enable the scrollbar measurer
$('').appendTo('head')
// Function to calculate the scrollbar width which is then compared to the padding or margin changes
- $.fn.getScrollbarWidth = function () {
- var scrollDiv = document.createElement('div')
- scrollDiv.className = 'modal-scrollbar-measure'
- document.body.appendChild(scrollDiv)
- var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
- document.body.removeChild(scrollDiv)
- return scrollbarWidth
- }
+ $.fn.getScrollbarWidth = $.fn.modal.Constructor.prototype._getScrollbarWidth
// Simulate scrollbars
$('html').css('padding-right', '16px')
@@ -285,6 +280,23 @@ $(function () {
.bootstrapModal('show')
})
+ QUnit.test('should add aria-modal attribute when shown, remove it again when hidden', function (assert) {
+ assert.expect(3)
+ var done = assert.async()
+
+ $('
')
+ .on('shown.bs.modal', function () {
+ assert.ok($('#modal-test').is('[aria-modal]'), 'aria-modal attribute added')
+ assert.strictEqual($('#modal-test').attr('aria-modal'), 'true', 'correct aria-modal="true" added')
+ $(this).bootstrapModal('hide')
+ })
+ .on('hidden.bs.modal', function () {
+ assert.notOk($('#modal-test').is('[aria-modal]'), 'aria-modal attribute removed')
+ done()
+ })
+ .bootstrapModal('show')
+ })
+
QUnit.test('should close reopened modal with [data-dismiss="modal"] click', function (assert) {
assert.expect(2)
var done = assert.async()
@@ -607,36 +619,40 @@ $(function () {
assert.expect(1)
var done = assert.async()
- var $toggleBtn = $('
')
- .appendTo('#qunit-fixture')
+ try {
+ var $toggleBtn = $('
')
+ .appendTo('#qunit-fixture')
- $toggleBtn.trigger('click')
- setTimeout(function () {
+ $toggleBtn.trigger('click')
+ } catch (e) {
assert.strictEqual($('#modal-test').length, 0, 'target has not been parsed and added to the document')
done()
- }, 1)
+ }
})
QUnit.test('should not execute js from target', function (assert) {
assert.expect(0)
var done = assert.async()
- // This toggle button contains XSS payload in its data-target
- // Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
- // a script element works in manual tests though, so here it is likely blocked by the qunit framework
- var $toggleBtn = $('
')
- .appendTo('#qunit-fixture')
- // The XSS payload above does not have a closure over this function and cannot access the assert object directly
- // However, it can send a click event to the following control button, which will then fail the assert
- $('
')
- .addClass('control')
- .on('click', function () {
- assert.notOk(true, 'XSS payload is not executed as js')
- })
- .appendTo('#qunit-fixture')
+ try {
+ // This toggle button contains XSS payload in its data-target
+ // Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
+ // a script element works in manual tests though, so here it is likely blocked by the qunit framework
+ var $toggleBtn = $(' ')
+ .appendTo('#qunit-fixture')
+ // The XSS payload above does not have a closure over this function and cannot access the assert object directly
+ // However, it can send a click event to the following control button, which will then fail the assert
+ $('')
+ .addClass('control')
+ .on('click', function () {
+ assert.notOk(true, 'XSS payload is not executed as js')
+ })
+ .appendTo('#qunit-fixture')
- $toggleBtn.trigger('click')
- setTimeout(done, 500)
+ $toggleBtn.trigger('click')
+ } catch (e) {
+ done()
+ }
})
QUnit.test('should not try to open a modal which is already visible', function (assert) {
@@ -654,4 +670,127 @@ $(function () {
.bootstrapModal('show')
.bootstrapModal('hide')
})
+
+ QUnit.test('transition duration should be the modal-dialog duration before triggering shown event', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+ var style = [
+ ''
+ ].join('')
+
+ var $style = $(style).appendTo('head')
+ var modalHTML = [
+ ''
+ ].join('')
+
+ var beginTimestamp = 0
+ var $modal = $(modalHTML).appendTo('#qunit-fixture')
+ var $modalDialog = $('.modal-dialog')
+ var transitionDuration = Util.getTransitionDurationFromElement($modalDialog[0])
+
+ assert.strictEqual(transitionDuration, 300)
+
+ $modal.on('shown.bs.modal', function () {
+ var diff = Date.now() - beginTimestamp
+ assert.ok(diff < 400)
+ $style.remove()
+ done()
+ })
+ .bootstrapModal('show')
+
+ beginTimestamp = Date.now()
+ })
+
+ QUnit.test('should dispose modal', function (assert) {
+ assert.expect(3)
+ var done = assert.async()
+
+ var $modal = $([
+ ''
+ ].join('')).appendTo('#qunit-fixture')
+
+ $modal.on('shown.bs.modal', function () {
+ var spy = sinon.spy($.fn, 'off')
+
+ $(this).bootstrapModal('dispose')
+
+ var modalDataApiEvent = []
+ $._data(document, 'events').click
+ .forEach(function (e) {
+ if (e.namespace === 'bs.data-api.modal') {
+ modalDataApiEvent.push(e)
+ }
+ })
+
+ assert.ok(typeof $(this).data('bs.modal') === 'undefined', 'modal data object was disposed')
+
+ assert.ok(spy.callCount === 4, '`jQuery.off` was called')
+
+ assert.ok(modalDataApiEvent.length === 1, '`Event.CLICK_DATA_API` on `document` was not removed')
+
+ $.fn.off.restore()
+ done()
+ }).bootstrapModal('show')
+ })
+
+ QUnit.test('should enforce focus', function (assert) {
+ assert.expect(4)
+ var done = assert.async()
+
+ var $modal = $([
+ ''
+ ].join(''))
+ .bootstrapModal()
+ .appendTo('#qunit-fixture')
+
+ var modal = $modal.data('bs.modal')
+ var spy = sinon.spy(modal, '_enforceFocus')
+ var spyDocOff = sinon.spy($(document), 'off')
+ var spyDocOn = sinon.spy($(document), 'on')
+
+ $modal.one('shown.bs.modal', function () {
+ assert.ok(spy.called, '_enforceFocus called')
+ assert.ok(spyDocOff.withArgs('focusin.bs.modal'))
+ assert.ok(spyDocOn.withArgs('focusin.bs.modal'))
+
+ var spyFocus = sinon.spy(modal._element, 'focus')
+ var event = $.Event('focusin', {
+ target: $('#qunit-fixture')[0]
+ })
+
+ $(document).one('focusin', function () {
+ assert.ok(spyFocus.called)
+ done()
+ })
+
+ $(document).trigger(event)
+ })
+ .bootstrapModal('show')
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/tab.js b/vendor/twbs/bootstrap/js/tests/unit/tab.js
index c70e0d1c9..3ce29b662 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/tab.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/tab.js
@@ -186,8 +186,8 @@ $(function () {
''
@@ -198,10 +198,10 @@ $(function () {
.end()
.find('ul > li:last-child a')
.on('show.bs.tab', function (e) {
- assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
+ assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
})
.on('shown.bs.tab', function (e) {
- assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
+ assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
done()
})
.bootstrapTab('show')
@@ -414,4 +414,49 @@ $(function () {
})
.trigger($.Event('click'))
})
+
+ QUnit.test('should handle removed tabs', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ var html = [
+ '',
+ ' ',
+ ' ',
+ ' × ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' × ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' × ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ '
test 1
',
+ '
test 2
',
+ '
test 3
',
+ '
'
+ ].join('')
+
+ $(html).appendTo('#qunit-fixture')
+
+ $('#secondNav').on('shown.bs.tab', function () {
+ assert.strictEqual($('.nav-tab').length, 2)
+ done()
+ })
+
+ $('#btnClose').one('click', function () {
+ var tabId = $(this).parents('a').attr('href')
+ $(this).parents('li').remove()
+ $(tabId).remove()
+ $('.nav-tabs a:last').bootstrapTab('show')
+ })
+ .trigger($.Event('click'))
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/toast.js b/vendor/twbs/bootstrap/js/tests/unit/toast.js
new file mode 100644
index 000000000..e6bd6be1e
--- /dev/null
+++ b/vendor/twbs/bootstrap/js/tests/unit/toast.js
@@ -0,0 +1,239 @@
+$(function () {
+ 'use strict'
+
+ if (typeof bootstrap !== 'undefined') {
+ window.Toast = bootstrap.Toast
+ }
+
+ QUnit.module('toast plugin')
+
+ QUnit.test('should be defined on jquery object', function (assert) {
+ assert.expect(1)
+ assert.ok($(document.body).toast, 'toast method is defined')
+ })
+
+ QUnit.module('toast', {
+ beforeEach: function () {
+ // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
+ $.fn.bootstrapToast = $.fn.toast.noConflict()
+ },
+ afterEach: function () {
+ $.fn.toast = $.fn.bootstrapToast
+ delete $.fn.bootstrapToast
+ $('#qunit-fixture').html('')
+ }
+ })
+
+ QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
+ assert.strictEqual(typeof $.fn.toast, 'undefined', 'toast was set back to undefined (org value)')
+ })
+
+ QUnit.test('should return the current version', function (assert) {
+ assert.expect(1)
+ assert.strictEqual(typeof Toast.VERSION, 'string')
+ })
+
+ QUnit.test('should throw explicit error on undefined method', function (assert) {
+ assert.expect(1)
+ var $el = $('
')
+ $el.bootstrapToast()
+
+ try {
+ $el.bootstrapToast('noMethod')
+ } catch (err) {
+ assert.strictEqual(err.message, 'No method named "noMethod"')
+ }
+ })
+
+ QUnit.test('should return jquery collection containing the element', function (assert) {
+ assert.expect(2)
+
+ var $el = $('
')
+ var $toast = $el.bootstrapToast()
+ assert.ok($toast instanceof $, 'returns jquery collection')
+ assert.strictEqual($toast[0], $el[0], 'collection contains element')
+ })
+
+ QUnit.test('should auto hide', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ var toastHtml =
+ '' +
+ '
' +
+ 'a simple toast' +
+ '
' +
+ '
'
+
+ var $toast = $(toastHtml)
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ $toast.on('hidden.bs.toast', function () {
+ assert.strictEqual($toast.hasClass('show'), false)
+ done()
+ })
+ .bootstrapToast('show')
+ })
+
+ QUnit.test('should not add fade class', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ var toastHtml =
+ '' +
+ '
' +
+ 'a simple toast' +
+ '
' +
+ '
'
+
+ var $toast = $(toastHtml)
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ $toast.on('shown.bs.toast', function () {
+ assert.strictEqual($toast.hasClass('fade'), false)
+ done()
+ })
+ .bootstrapToast('show')
+ })
+
+ QUnit.test('should allow to hide toast manually', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ var toastHtml =
+ '' +
+ '
' +
+ 'a simple toast' +
+ '
' +
+ '
'
+
+ var $toast = $(toastHtml)
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ $toast
+ .on('shown.bs.toast', function () {
+ $toast.bootstrapToast('hide')
+ })
+ .on('hidden.bs.toast', function () {
+ assert.strictEqual($toast.hasClass('show'), false)
+ done()
+ })
+ .bootstrapToast('show')
+ })
+
+ QUnit.test('should do nothing when we call hide on a non shown toast', function (assert) {
+ assert.expect(1)
+
+ var $toast = $('
')
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ var spy = sinon.spy($toast[0].classList, 'contains')
+
+ $toast.bootstrapToast('hide')
+
+ assert.strictEqual(spy.called, true)
+ })
+
+ QUnit.test('should allow to destroy toast', function (assert) {
+ assert.expect(2)
+
+ var $toast = $('
')
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ assert.ok(typeof $toast.data('bs.toast') !== 'undefined')
+
+ $toast.bootstrapToast('dispose')
+
+ assert.ok(typeof $toast.data('bs.toast') === 'undefined')
+ })
+
+ QUnit.test('should allow to destroy toast and hide it before that', function (assert) {
+ assert.expect(4)
+ var done = assert.async()
+
+ var toastHtml =
+ '' +
+ '
' +
+ 'a simple toast' +
+ '
' +
+ '
'
+
+ var $toast = $(toastHtml)
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ $toast.one('shown.bs.toast', function () {
+ setTimeout(function () {
+ assert.ok($toast.hasClass('show'))
+ assert.ok(typeof $toast.data('bs.toast') !== 'undefined')
+
+ $toast.bootstrapToast('dispose')
+
+ assert.ok(typeof $toast.data('bs.toast') === 'undefined')
+ assert.ok($toast.hasClass('show') === false)
+
+ done()
+ }, 1)
+ })
+ .bootstrapToast('show')
+ })
+
+ QUnit.test('should allow to config in js', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ var toastHtml =
+ '' +
+ '
' +
+ 'a simple toast' +
+ '
' +
+ '
'
+
+ var $toast = $(toastHtml)
+ .bootstrapToast({
+ delay: 1
+ })
+ .appendTo($('#qunit-fixture'))
+
+ $toast.on('shown.bs.toast', function () {
+ assert.strictEqual($toast.hasClass('show'), true)
+ done()
+ })
+ .bootstrapToast('show')
+ })
+
+
+ QUnit.test('should close toast when close element with data-dismiss attribute is set', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+
+ var toastHtml =
+ '' +
+ '' +
+ 'close' +
+ ' ' +
+ '
'
+
+ var $toast = $(toastHtml)
+ .bootstrapToast()
+ .appendTo($('#qunit-fixture'))
+
+ $toast
+ .on('shown.bs.toast', function () {
+ assert.strictEqual($toast.hasClass('show'), true)
+ var button = $toast.find('.close')
+ button.trigger('click')
+ })
+ .on('hidden.bs.toast', function () {
+ assert.strictEqual($toast.hasClass('show'), false)
+ done()
+ })
+ .bootstrapToast('show')
+ })
+})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/tooltip.js b/vendor/twbs/bootstrap/js/tests/unit/tooltip.js
index 9cf3068a3..54dbe57bd 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/tooltip.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/tooltip.js
@@ -414,6 +414,52 @@ $(function () {
.bootstrapTooltip('show')
})
+ QUnit.test('should place tooltips inside a specific container when container is an element', function (assert) {
+ assert.expect(3)
+ var done = assert.async()
+ var $container = $('
').appendTo('#qunit-fixture')
+ var $tooltip = $(' ')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({
+ container: $container[0]
+ })
+
+ $tooltip
+ .one('shown.bs.tooltip', function () {
+ assert.strictEqual($container.find('.tooltip').length, 1)
+ assert.strictEqual($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')
+ $tooltip.bootstrapTooltip('hide')
+ })
+ .one('hidden.bs.tooltip', function () {
+ assert.strictEqual($container.find('.tooltip').length, 0, 'tooltip was removed from dom')
+ done()
+ })
+ .bootstrapTooltip('show')
+ })
+
+ QUnit.test('should place tooltips inside a specific container when container is a selector', function (assert) {
+ assert.expect(3)
+ var done = assert.async()
+ var $container = $('
').appendTo('#qunit-fixture')
+ var $tooltip = $(' ')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip({
+ container: '#container'
+ })
+
+ $tooltip
+ .one('shown.bs.tooltip', function () {
+ assert.strictEqual($container.find('.tooltip').length, 1)
+ assert.strictEqual($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')
+ $tooltip.bootstrapTooltip('hide')
+ })
+ .one('hidden.bs.tooltip', function () {
+ assert.strictEqual($container.find('.tooltip').length, 0, 'tooltip was removed from dom')
+ done()
+ })
+ .bootstrapTooltip('show')
+ })
+
QUnit.test('should add position class before positioning so that position-specific styles are taken into account', function (assert) {
assert.expect(2)
var done = assert.async()
@@ -517,7 +563,6 @@ $(function () {
$tooltip.bootstrapTooltip('show')
} catch (err) {
passed = false
- console.log(err)
}
assert.ok(passed, '.tooltip(\'show\') should not throw an error if element no longer is in dom')
@@ -862,6 +907,44 @@ $(function () {
.modal('show')
})
+ QUnit.test('should allow to close modal if the tooltip element is detached', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+ var templateHTML = [
+ ''
+ ].join('')
+
+ $(templateHTML).appendTo('#qunit-fixture')
+ var $tooltip = $('#tooltipTest')
+ var $modal = $('#modal-test')
+
+ $tooltip.on('shown.bs.tooltip', function () {
+ $tooltip.detach()
+ $tooltip.bootstrapTooltip('dispose')
+ $modal.modal('hide')
+ })
+
+ $modal.on('shown.bs.modal', function () {
+ $tooltip.bootstrapTooltip({
+ trigger: 'manuel'
+ })
+ .bootstrapTooltip('show')
+ })
+ .on('hidden.bs.modal', function () {
+ assert.ok(true, 'modal hidden')
+ done()
+ })
+ .modal('show')
+ })
+
QUnit.test('should reset tip classes when hidden event triggered', function (assert) {
assert.expect(2)
var done = assert.async()
@@ -966,4 +1049,24 @@ $(function () {
assert.ok(tooltip.tip === $tipTest[0])
})
+
+ QUnit.test('should toggle enabled', function (assert) {
+ assert.expect(3)
+
+ var $tooltip = $(' ')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip()
+
+ var tooltip = $tooltip.data('bs.tooltip')
+
+ assert.strictEqual(tooltip._isEnabled, true)
+
+ tooltip.toggleEnabled()
+
+ assert.strictEqual(tooltip._isEnabled, false)
+
+ tooltip.toggleEnabled()
+
+ assert.strictEqual(tooltip._isEnabled, true)
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/unit/util.js b/vendor/twbs/bootstrap/js/tests/unit/util.js
index 37327b868..cb9383143 100644
--- a/vendor/twbs/bootstrap/js/tests/unit/util.js
+++ b/vendor/twbs/bootstrap/js/tests/unit/util.js
@@ -20,6 +20,19 @@ $(function () {
assert.strictEqual(Util.getSelectorFromElement($el2[0]), null)
})
+ QUnit.test('Util.getSelectorFromElement should throw error when there is a bad selector', function (assert) {
+ assert.expect(2)
+
+ var $el = $('
').appendTo($('#qunit-fixture'))
+
+ try {
+ assert.ok(true, 'trying to use a bad selector')
+ Util.getSelectorFromElement($el[0])
+ } catch (e) {
+ assert.ok(e instanceof DOMException)
+ }
+ })
+
QUnit.test('Util.typeCheckConfig should thrown an error when a bad config is passed', function (assert) {
assert.expect(1)
var namePlugin = 'collapse'
@@ -62,6 +75,16 @@ $(function () {
assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 400)
})
+ QUnit.test('Util.getTransitionDurationFromElement should return the addition of transition-delay and transition-duration', function (assert) {
+ assert.expect(2)
+ var $fixture = $('#qunit-fixture')
+ var $div = $('
').appendTo($fixture)
+ var $div2 = $('
').appendTo($fixture)
+
+ assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 150)
+ assert.strictEqual(Util.getTransitionDurationFromElement($div2[0]), 280)
+ })
+
QUnit.test('Util.getTransitionDurationFromElement should get the first transition duration if multiple transition durations are defined', function (assert) {
assert.expect(1)
var $div = $('
').appendTo($('#qunit-fixture'))
@@ -101,4 +124,41 @@ $(function () {
assert.expect(1)
assert.ok(Util.supportsTransitionEnd())
})
+
+ QUnit.test('Util.findShadowRoot should find the shadow DOM root', function (assert) {
+ // Only for newer browsers
+ if (!document.documentElement.attachShadow) {
+ assert.expect(0)
+ return
+ }
+
+ assert.expect(2)
+ var $div = $('
').appendTo($('#qunit-fixture'))
+ var shadowRoot = $div[0].attachShadow({
+ mode: 'open'
+ })
+
+ assert.equal(shadowRoot, Util.findShadowRoot(shadowRoot))
+ shadowRoot.innerHTML = 'Shadow Button '
+ assert.equal(shadowRoot, Util.findShadowRoot(shadowRoot.firstChild))
+ })
+
+ QUnit.test('Util.findShadowRoot should return null when attachShadow is not available', function (assert) {
+ assert.expect(1)
+
+ var $div = $('
').appendTo($('#qunit-fixture'))
+ if (!document.documentElement.attachShadow) {
+ assert.equal(null, Util.findShadowRoot($div[0]))
+ } else {
+ var sandbox = sinon.createSandbox()
+
+ sandbox.replace(document.documentElement, 'attachShadow', function () {
+ // to avoid empty function
+ return $div
+ })
+
+ assert.equal(null, Util.findShadowRoot($div[0]))
+ sandbox.restore()
+ }
+ })
})
diff --git a/vendor/twbs/bootstrap/js/tests/visual/alert.html b/vendor/twbs/bootstrap/js/tests/visual/alert.html
index 67cafa900..7cb48b346 100644
--- a/vendor/twbs/bootstrap/js/tests/visual/alert.html
+++ b/vendor/twbs/bootstrap/js/tests/visual/alert.html
@@ -51,7 +51,7 @@