'
+ ].join('')
+
+ const btnGroupEl = fixtureEl.querySelector('.btn-group')
+ const btnDanger = fixtureEl.querySelector('.btn-danger')
+ const input = fixtureEl.querySelector('input')
+
+ const button = new Button(btnGroupEl)
+
+ button.toggle()
+
+ expect(btnDanger.hasAttribute('disabled')).toEqual(true)
+ expect(input.checked).toEqual(false)
+ })
+ })
+
+ describe('dispose', () => {
+ it('should dispose a button', () => {
+ fixtureEl.innerHTML = ''
+
+ const btnEl = fixtureEl.querySelector('.btn')
+ const button = new Button(btnEl)
+
+ expect(Button._getInstance(btnEl)).toBeDefined()
+
+ button.dispose()
+
+ expect(Button._getInstance(btnEl)).toBeNull()
+ })
+ })
+
+ describe('_jQueryInterface', () => {
+ it('should handle config passed and toggle existing button', () => {
+ fixtureEl.innerHTML = ''
+
+ const btnEl = fixtureEl.querySelector('.btn')
+ const button = new Button(btnEl)
+
+ spyOn(button, 'toggle')
+
+ jQueryMock.fn.button = Button._jQueryInterface
+ jQueryMock.elements = [btnEl]
+
+ jQueryMock.fn.button.call(jQueryMock, 'toggle')
+
+ expect(button.toggle).toHaveBeenCalled()
+ })
+
+ it('should create new button instance and call toggle', () => {
+ fixtureEl.innerHTML = ''
+
+ const btnEl = fixtureEl.querySelector('.btn')
+
+ jQueryMock.fn.button = Button._jQueryInterface
+ jQueryMock.elements = [btnEl]
+
+ jQueryMock.fn.button.call(jQueryMock, 'toggle')
+
+ expect(Button._getInstance(btnEl)).toBeDefined()
+ expect(btnEl.classList.contains('active')).toEqual(true)
+ })
+
+ it('should just create a button instance without calling toggle', () => {
+ fixtureEl.innerHTML = ''
+
+ const btnEl = fixtureEl.querySelector('.btn')
+
+ jQueryMock.fn.button = Button._jQueryInterface
+ jQueryMock.elements = [btnEl]
+
+ jQueryMock.fn.button.call(jQueryMock)
+
+ expect(Button._getInstance(btnEl)).toBeDefined()
+ expect(btnEl.classList.contains('active')).toEqual(false)
+ })
+ })
+})
diff --git a/js/tests/helpers/fixture.js b/js/tests/helpers/fixture.js
index 524d544448..e7240ee181 100644
--- a/js/tests/helpers/fixture.js
+++ b/js/tests/helpers/fixture.js
@@ -18,3 +18,21 @@ export const clearFixture = () => {
fixtureEl.innerHTML = ''
}
+
+export const createEvent = (eventName, params) => {
+ params = params || {}
+ const e = document.createEvent('Event')
+
+ e.initEvent(eventName, Boolean(params.bubbles), Boolean(params.cancelable))
+ return e
+}
+
+export const jQueryMock = {
+ elements: undefined,
+ fn: {},
+ each(fn) {
+ this.elements.forEach(el => {
+ fn.call(el)
+ })
+ }
+}
diff --git a/js/tests/unit/button.js b/js/tests/unit/button.js
deleted file mode 100644
index d351cc7705..0000000000
--- a/js/tests/unit/button.js
+++ /dev/null
@@ -1,225 +0,0 @@
-$(function () {
- 'use strict'
-
- var Button = typeof window.bootstrap === 'undefined' ? window.Button : window.bootstrap.Button
-
- QUnit.module('button plugin')
-
- QUnit.test('should be defined on jquery object', function (assert) {
- assert.expect(1)
- assert.ok($(document.body).button, 'button method is defined')
- })
-
- QUnit.module('button', {
- beforeEach: function () {
- // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
- $.fn.bootstrapButton = $.fn.button.noConflict()
- },
- afterEach: function () {
- $.fn.button = $.fn.bootstrapButton
- delete $.fn.bootstrapButton
- $('#qunit-fixture').html('')
- }
- })
-
- QUnit.test('should provide no conflict', function (assert) {
- assert.expect(1)
- assert.strictEqual(typeof $.fn.button, 'undefined', 'button was set back to undefined (org value)')
- })
-
- QUnit.test('should return jquery collection containing the element', function (assert) {
- assert.expect(2)
- var $el = $('')
- var $button = $el.bootstrapButton()
- assert.ok($button instanceof $, 'returns jquery collection')
- assert.strictEqual($button[0], $el[0], 'collection contains element')
- })
-
- QUnit.test('should toggle active', function (assert) {
- assert.expect(2)
- var $btn = $('')
- assert.ok(!$btn.hasClass('active'), 'btn does not have active class')
- $btn.bootstrapButton('toggle')
- assert.ok($btn.hasClass('active'), 'btn has class active')
- })
-
- QUnit.test('should toggle active when btn children are clicked', function (assert) {
- assert.expect(2)
- var $btn = $('')
- var $inner = $('')
- $btn
- .append($inner)
- .appendTo('#qunit-fixture')
- assert.ok(!$btn.hasClass('active'), 'btn does not have active class')
- $inner.trigger('click')
- assert.ok($btn.hasClass('active'), 'btn has class active')
- })
-
- QUnit.test('should toggle aria-pressed', function (assert) {
- assert.expect(2)
- var $btn = $('')
- assert.strictEqual($btn.attr('aria-pressed'), 'false', 'btn aria-pressed state is false')
- $btn.bootstrapButton('toggle')
- assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true')
- })
-
- QUnit.test('should toggle aria-pressed on buttons with container', function (assert) {
- assert.expect(1)
- var groupHTML = '
' +
- '' +
- '' +
- '
'
- $('#qunit-fixture').append(groupHTML)
- $('#btn1').bootstrapButton('toggle')
- assert.strictEqual($('#btn1').attr('aria-pressed'), 'true')
- })
-
- QUnit.test('should toggle aria-pressed when btn children are clicked', function (assert) {
- assert.expect(2)
- var $btn = $('')
- var $inner = $('')
- $btn
- .append($inner)
- .appendTo('#qunit-fixture')
- assert.strictEqual($btn.attr('aria-pressed'), 'false', 'btn aria-pressed state is false')
- $inner.trigger('click')
- assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true')
- })
-
- QUnit.test('should trigger input change event when toggled button has input field', function (assert) {
- assert.expect(1)
- var done = assert.async()
-
- var groupHTML = '
' +
- '' +
- '
'
- var $group = $(groupHTML).appendTo('#qunit-fixture')
-
- $group.find('input').on('change', function (e) {
- e.preventDefault()
- assert.ok(true, 'change event fired')
- done()
- })
-
- $group.find('label').trigger('click')
- })
-
- QUnit.test('should check for closest matching toggle', function (assert) {
- assert.expect(12)
- var groupHTML =
- '
' +
- ' ' +
- ' ' +
- ' ' +
- '
'
-
- var $group = $(groupHTML).appendTo('#qunit-fixture')
-
- var $btn1 = $group.children().eq(0)
- var $btn2 = $group.children().eq(1)
- var inputBtn2 = $btn2.find('input')[0]
-
- assert.ok($btn1.hasClass('active'), 'btn1 has active class')
- assert.ok($btn1.find('input').prop('checked'), 'btn1 is checked')
- assert.ok(!$btn2.hasClass('active'), 'btn2 does not have active class')
- assert.ok(!inputBtn2.checked, 'btn2 is not checked')
-
- inputBtn2.dispatchEvent(new Event('click'))
-
- assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
- assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked')
- assert.ok($btn2.hasClass('active'), 'btn2 has active class')
- assert.ok(inputBtn2.checked, 'btn2 is checked')
-
- inputBtn2.dispatchEvent(new Event('click')) // clicking an already checked radio should not un-check it
-
- assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
- assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked')
- assert.ok($btn2.hasClass('active'), 'btn2 has active class')
- assert.ok(inputBtn2.checked, 'btn2 is checked')
- })
-
- QUnit.test('should only toggle selectable inputs', function (assert) {
- assert.expect(6)
- var groupHTML = '
' +
- '' +
- '
'
- var $group = $(groupHTML).appendTo('#qunit-fixture')
-
- var $btn = $group.children().eq(0)
- var $hidden = $btn.find('input#option1-default')
- var $cb = $btn.find('input#option1')
-
- assert.ok($btn.hasClass('active'), 'btn has active class')
- assert.ok($cb.prop('checked'), 'btn is checked')
- assert.ok(!$hidden.prop('checked'), 'hidden is not checked')
- $btn.trigger('click')
- assert.ok(!$btn.hasClass('active'), 'btn does not have active class')
- assert.ok(!$cb.prop('checked'), 'btn is not checked')
- assert.ok(!$hidden.prop('checked'), 'hidden is not checked') // should not be changed
- })
-
- QUnit.test('should not add aria-pressed on labels for radio/checkbox inputs in a data-toggle="buttons" group', function (assert) {
- assert.expect(2)
- var groupHTML = '
' +
- '' +
- '' +
- '
'
- var $group = $(groupHTML).appendTo('#qunit-fixture')
-
- var $btn1 = $group.children().eq(0)
- var $btn2 = $group.children().eq(1)
-
- $btn1.find('input').trigger('click')
- assert.ok($btn1.is(':not([aria-pressed])'), 'label for nested checkbox input has not been given an aria-pressed attribute')
-
- $btn2.find('input').trigger('click')
- assert.ok($btn2.is(':not([aria-pressed])'), 'label for nested radio input has not been given an aria-pressed attribute')
- })
-
- QUnit.test('should handle disabled attribute on non-button elements', function (assert) {
- assert.expect(2)
- var groupHTML = '
' +
- '' +
- '
'
- var $group = $(groupHTML).appendTo('#qunit-fixture')
-
- var $btn = $group.children().eq(0)
- var $input = $btn.children().eq(0)
-
- $btn.trigger('click')
- assert.ok($btn.is(':not(.active)'), 'button did not become active')
- assert.ok(!$input.is(':checked'), 'checkbox did not get checked')
- })
-
- QUnit.test('dispose should remove data and the element', function (assert) {
- assert.expect(2)
-
- var $el = $('')
- var $button = $el.bootstrapButton()
-
- assert.ok(typeof Button._getInstance($button[0]) !== 'undefined')
-
- Button._getInstance($button[0]).dispose()
-
- assert.ok(Button._getInstance($button[0]) === null)
- })
-
- QUnit.test('should return the version', function (assert) {
- assert.expect(1)
- assert.strictEqual(typeof Button.VERSION, 'string')
- })
-})