button.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. $(function () {
  2. 'use strict'
  3. QUnit.module('button plugin')
  4. QUnit.test('should be defined on jquery object', function (assert) {
  5. assert.expect(1)
  6. assert.ok($(document.body).button, 'button method is defined')
  7. })
  8. QUnit.module('button', {
  9. beforeEach: function () {
  10. // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
  11. $.fn.bootstrapButton = $.fn.button.noConflict()
  12. },
  13. afterEach: function () {
  14. $.fn.button = $.fn.bootstrapButton
  15. delete $.fn.bootstrapButton
  16. $('#qunit-fixture').html('')
  17. }
  18. })
  19. QUnit.test('should provide no conflict', function (assert) {
  20. assert.expect(1)
  21. assert.strictEqual(typeof $.fn.button, 'undefined', 'button was set back to undefined (org value)')
  22. })
  23. QUnit.test('should return jquery collection containing the element', function (assert) {
  24. assert.expect(2)
  25. var $el = $('<div/>')
  26. var $button = $el.bootstrapButton()
  27. assert.ok($button instanceof $, 'returns jquery collection')
  28. assert.strictEqual($button[0], $el[0], 'collection contains element')
  29. })
  30. QUnit.test('should toggle active', function (assert) {
  31. assert.expect(2)
  32. var $btn = $('<button class="btn" data-toggle="button">mdo</button>')
  33. assert.ok(!$btn.hasClass('active'), 'btn does not have active class')
  34. $btn.bootstrapButton('toggle')
  35. assert.ok($btn.hasClass('active'), 'btn has class active')
  36. })
  37. QUnit.test('should toggle active when btn children are clicked', function (assert) {
  38. assert.expect(2)
  39. var $btn = $('<button class="btn" data-toggle="button">mdo</button>')
  40. var $inner = $('<i/>')
  41. $btn
  42. .append($inner)
  43. .appendTo('#qunit-fixture')
  44. assert.ok(!$btn.hasClass('active'), 'btn does not have active class')
  45. $inner.trigger('click')
  46. assert.ok($btn.hasClass('active'), 'btn has class active')
  47. })
  48. QUnit.test('should toggle aria-pressed', function (assert) {
  49. assert.expect(2)
  50. var $btn = $('<button class="btn" data-toggle="button" aria-pressed="false">redux</button>')
  51. assert.strictEqual($btn.attr('aria-pressed'), 'false', 'btn aria-pressed state is false')
  52. $btn.bootstrapButton('toggle')
  53. assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true')
  54. })
  55. QUnit.test('should toggle aria-pressed on buttons with container', function (assert) {
  56. assert.expect(1)
  57. var groupHTML = '<div class="btn-group" data-toggle="buttons">' +
  58. '<button id="btn1" class="btn btn-secondary" type="button">One</button>' +
  59. '<button class="btn btn-secondary" type="button">Two</button>' +
  60. '</div>'
  61. $('#qunit-fixture').append(groupHTML)
  62. $('#btn1').bootstrapButton('toggle')
  63. assert.strictEqual($('#btn1').attr('aria-pressed'), 'true')
  64. })
  65. QUnit.test('should toggle aria-pressed when btn children are clicked', function (assert) {
  66. assert.expect(2)
  67. var $btn = $('<button class="btn" data-toggle="button" aria-pressed="false">redux</button>')
  68. var $inner = $('<i/>')
  69. $btn
  70. .append($inner)
  71. .appendTo('#qunit-fixture')
  72. assert.strictEqual($btn.attr('aria-pressed'), 'false', 'btn aria-pressed state is false')
  73. $inner.trigger('click')
  74. assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true')
  75. })
  76. QUnit.test('should trigger input change event when toggled button has input field', function (assert) {
  77. assert.expect(1)
  78. var done = assert.async()
  79. var groupHTML = '<div class="btn-group" data-toggle="buttons">' +
  80. '<label class="btn btn-primary">' +
  81. '<input type="radio" id="radio" autocomplete="off">Radio' +
  82. '</label>' +
  83. '</div>'
  84. var $group = $(groupHTML).appendTo('#qunit-fixture')
  85. $group.find('input').on('change', function (e) {
  86. e.preventDefault()
  87. assert.ok(true, 'change event fired')
  88. done()
  89. })
  90. $group.find('label').trigger('click')
  91. })
  92. QUnit.test('should check for closest matching toggle', function (assert) {
  93. assert.expect(12)
  94. var groupHTML = '<div class="btn-group" data-toggle="buttons">' +
  95. '<label class="btn btn-primary active">' +
  96. '<input type="radio" name="options" id="option1" checked="true"> Option 1' +
  97. '</label>' +
  98. '<label class="btn btn-primary">' +
  99. '<input type="radio" name="options" id="option2"> Option 2' +
  100. '</label>' +
  101. '<label class="btn btn-primary">' +
  102. '<input type="radio" name="options" id="option3"> Option 3' +
  103. '</label>' +
  104. '</div>'
  105. var $group = $(groupHTML).appendTo('#qunit-fixture')
  106. var $btn1 = $group.children().eq(0)
  107. var $btn2 = $group.children().eq(1)
  108. assert.ok($btn1.hasClass('active'), 'btn1 has active class')
  109. assert.ok($btn1.find('input').prop('checked'), 'btn1 is checked')
  110. assert.ok(!$btn2.hasClass('active'), 'btn2 does not have active class')
  111. assert.ok(!$btn2.find('input').prop('checked'), 'btn2 is not checked')
  112. $btn2.find('input').trigger('click')
  113. assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
  114. assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked')
  115. assert.ok($btn2.hasClass('active'), 'btn2 has active class')
  116. assert.ok($btn2.find('input').prop('checked'), 'btn2 is checked')
  117. $btn2.find('input').trigger('click') // Clicking an already checked radio should not un-check it
  118. assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class')
  119. assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked')
  120. assert.ok($btn2.hasClass('active'), 'btn2 has active class')
  121. assert.ok($btn2.find('input').prop('checked'), 'btn2 is checked')
  122. })
  123. QUnit.test('should only toggle selectable inputs', function (assert) {
  124. assert.expect(6)
  125. var groupHTML = '<div class="btn-group" data-toggle="buttons">' +
  126. '<label class="btn btn-primary active">' +
  127. '<input type="hidden" name="option1" id="option1-default" value="false">' +
  128. '<input type="checkbox" name="option1" id="option1" checked="true"> Option 1' +
  129. '</label>' +
  130. '</div>'
  131. var $group = $(groupHTML).appendTo('#qunit-fixture')
  132. var $btn = $group.children().eq(0)
  133. var $hidden = $btn.find('input#option1-default')
  134. var $cb = $btn.find('input#option1')
  135. assert.ok($btn.hasClass('active'), 'btn has active class')
  136. assert.ok($cb.prop('checked'), 'btn is checked')
  137. assert.ok(!$hidden.prop('checked'), 'hidden is not checked')
  138. $btn.trigger('click')
  139. assert.ok(!$btn.hasClass('active'), 'btn does not have active class')
  140. assert.ok(!$cb.prop('checked'), 'btn is not checked')
  141. assert.ok(!$hidden.prop('checked'), 'hidden is not checked') // should not be changed
  142. })
  143. QUnit.test('should not add aria-pressed on labels for radio/checkbox inputs in a data-toggle="buttons" group', function (assert) {
  144. assert.expect(2)
  145. var groupHTML = '<div class="btn-group" data-toggle="buttons">' +
  146. '<label class="btn btn-primary"><input type="checkbox" autocomplete="off"> Checkbox</label>' +
  147. '<label class="btn btn-primary"><input type="radio" name="options" autocomplete="off"> Radio</label>' +
  148. '</div>'
  149. var $group = $(groupHTML).appendTo('#qunit-fixture')
  150. var $btn1 = $group.children().eq(0)
  151. var $btn2 = $group.children().eq(1)
  152. $btn1.find('input').trigger('click')
  153. assert.ok($btn1.is(':not([aria-pressed])'), 'label for nested checkbox input has not been given an aria-pressed attribute')
  154. $btn2.find('input').trigger('click')
  155. assert.ok($btn2.is(':not([aria-pressed])'), 'label for nested radio input has not been given an aria-pressed attribute')
  156. })
  157. QUnit.test('should handle disabled attribute on non-button elements', function (assert) {
  158. assert.expect(2)
  159. var groupHTML = '<div class="btn-group disabled" data-toggle="buttons" aria-disabled="true" disabled>' +
  160. '<label class="btn btn-danger disabled" aria-disabled="true" disabled>' +
  161. '<input type="checkbox" aria-disabled="true" autocomplete="off" disabled class="disabled"/>' +
  162. '</label>' +
  163. '</div>'
  164. var $group = $(groupHTML).appendTo('#qunit-fixture')
  165. var $btn = $group.children().eq(0)
  166. var $input = $btn.children().eq(0)
  167. $btn.trigger('click')
  168. assert.ok($btn.is(':not(.active)'), 'button did not become active')
  169. assert.ok(!$input.is(':checked'), 'checkbox did not get checked')
  170. })
  171. QUnit.test('dispose should remove data and the element', function (assert) {
  172. assert.expect(2)
  173. var $el = $('<div/>')
  174. var $button = $el.bootstrapButton()
  175. assert.ok(typeof $button.data('bs.button') !== 'undefined')
  176. $button.data('bs.button').dispose()
  177. assert.ok(typeof $button.data('bs.button') === 'undefined')
  178. })
  179. QUnit.test('should return button version', function (assert) {
  180. assert.expect(1)
  181. if (typeof Button !== 'undefined') {
  182. assert.ok(typeof Button.VERSION === 'string')
  183. } else {
  184. assert.notOk()
  185. }
  186. })
  187. })