collapse.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. $(function () {
  2. 'use strict';
  3. QUnit.module('collapse plugin')
  4. QUnit.test('should be defined on jquery object', function (assert) {
  5. assert.expect(1)
  6. assert.ok($(document.body).collapse, 'collapse method is defined')
  7. })
  8. QUnit.module('collapse', {
  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.bootstrapCollapse = $.fn.collapse.noConflict()
  12. },
  13. afterEach: function () {
  14. $.fn.collapse = $.fn.bootstrapCollapse
  15. delete $.fn.bootstrapCollapse
  16. }
  17. })
  18. QUnit.test('should provide no conflict', function (assert) {
  19. assert.expect(1)
  20. assert.strictEqual($.fn.collapse, undefined, 'collapse was set back to undefined (org value)')
  21. })
  22. QUnit.test('should return jquery collection containing the element', function (assert) {
  23. assert.expect(2)
  24. var $el = $('<div/>')
  25. var $collapse = $el.bootstrapCollapse()
  26. assert.ok($collapse instanceof $, 'returns jquery collection')
  27. assert.strictEqual($collapse[0], $el[0], 'collection contains element')
  28. })
  29. QUnit.test('should show a collapsed element', function (assert) {
  30. assert.expect(2)
  31. var done = assert.async()
  32. $('<div class="collapse"/>')
  33. .on('shown.bs.collapse', function () {
  34. assert.ok($(this).hasClass('in'), 'has class "in"')
  35. assert.ok(!/height/i.test($(this).attr('style')), 'has height reset')
  36. done()
  37. })
  38. .bootstrapCollapse('show')
  39. })
  40. QUnit.test('should hide a collapsed element', function (assert) {
  41. assert.expect(1)
  42. var $el = $('<div class="collapse"/>').bootstrapCollapse('hide')
  43. assert.ok(!$el.hasClass('in'), 'does not have class "in"')
  44. })
  45. QUnit.test('should not fire shown when show is prevented', function (assert) {
  46. assert.expect(1)
  47. var done = assert.async()
  48. $('<div class="collapse"/>')
  49. .on('show.bs.collapse', function (e) {
  50. e.preventDefault()
  51. assert.ok(true, 'show event fired')
  52. done()
  53. })
  54. .on('shown.bs.collapse', function () {
  55. assert.ok(false, 'shown event fired')
  56. })
  57. .bootstrapCollapse('show')
  58. })
  59. QUnit.test('should reset style to auto after finishing opening collapse', function (assert) {
  60. assert.expect(2)
  61. var done = assert.async()
  62. $('<div class="collapse" style="height: 0px"/>')
  63. .on('show.bs.collapse', function () {
  64. assert.strictEqual(this.style.height, '0px', 'height is 0px')
  65. })
  66. .on('shown.bs.collapse', function () {
  67. assert.strictEqual(this.style.height, '', 'height is auto')
  68. done()
  69. })
  70. .bootstrapCollapse('show')
  71. })
  72. QUnit.test('should remove "collapsed" class from target when collapse is shown', function (assert) {
  73. assert.expect(1)
  74. var done = assert.async()
  75. var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
  76. $('<div id="test1"/>')
  77. .appendTo('#qunit-fixture')
  78. .on('shown.bs.collapse', function () {
  79. assert.ok(!$target.hasClass('collapsed'), 'target does not have collapsed class')
  80. done()
  81. })
  82. $target.trigger('click')
  83. })
  84. QUnit.test('should add "collapsed" class to target when collapse is hidden', function (assert) {
  85. assert.expect(1)
  86. var done = assert.async()
  87. var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
  88. $('<div id="test1" class="in"/>')
  89. .appendTo('#qunit-fixture')
  90. .on('hidden.bs.collapse', function () {
  91. assert.ok($target.hasClass('collapsed'), 'target has collapsed class')
  92. done()
  93. })
  94. $target.trigger('click')
  95. })
  96. QUnit.test('should remove "collapsed" class from all triggers targeting the collapse when the collapse is shown', function (assert) {
  97. assert.expect(2)
  98. var done = assert.async()
  99. var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
  100. var $alt = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
  101. $('<div id="test1"/>')
  102. .appendTo('#qunit-fixture')
  103. .on('shown.bs.collapse', function () {
  104. assert.ok(!$target.hasClass('collapsed'), 'target trigger does not have collapsed class')
  105. assert.ok(!$alt.hasClass('collapsed'), 'alt trigger does not have collapsed class')
  106. done()
  107. })
  108. $target.trigger('click')
  109. })
  110. QUnit.test('should add "collapsed" class to all triggers targeting the collapse when the collapse is hidden', function (assert) {
  111. assert.expect(2)
  112. var done = assert.async()
  113. var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
  114. var $alt = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
  115. $('<div id="test1" class="in"/>')
  116. .appendTo('#qunit-fixture')
  117. .on('hidden.bs.collapse', function () {
  118. assert.ok($target.hasClass('collapsed'), 'target has collapsed class')
  119. assert.ok($alt.hasClass('collapsed'), 'alt trigger has collapsed class')
  120. done()
  121. })
  122. $target.trigger('click')
  123. })
  124. QUnit.test('should not close a collapse when initialized with "show" option if already shown', function (assert) {
  125. assert.expect(0)
  126. var done = assert.async()
  127. var $test = $('<div id="test1" class="in"/>')
  128. .appendTo('#qunit-fixture')
  129. .on('hide.bs.collapse', function () {
  130. assert.ok(false)
  131. })
  132. $test.bootstrapCollapse('show')
  133. setTimeout(done, 0)
  134. })
  135. QUnit.test('should open a collapse when initialized with "show" option if not already shown', function (assert) {
  136. assert.expect(1)
  137. var done = assert.async()
  138. var $test = $('<div id="test1" />')
  139. .appendTo('#qunit-fixture')
  140. .on('show.bs.collapse', function () {
  141. assert.ok(true)
  142. })
  143. $test.bootstrapCollapse('show')
  144. setTimeout(done, 0)
  145. })
  146. QUnit.test('should not show a collapse when initialized with "hide" option if already hidden', function (assert) {
  147. assert.expect(0)
  148. var done = assert.async()
  149. $('<div class="collapse"></div>')
  150. .appendTo('#qunit-fixture')
  151. .on('show.bs.collapse', function () {
  152. assert.ok(false, 'showing a previously-uninitialized hidden collapse when the "hide" method is called')
  153. })
  154. .bootstrapCollapse('hide')
  155. setTimeout(done, 0)
  156. })
  157. QUnit.test('should hide a collapse when initialized with "hide" option if not already hidden', function (assert) {
  158. assert.expect(1)
  159. var done = assert.async()
  160. $('<div class="collapse in"></div>')
  161. .appendTo('#qunit-fixture')
  162. .on('hide.bs.collapse', function () {
  163. assert.ok(true, 'hiding a previously-uninitialized shown collapse when the "hide" method is called')
  164. })
  165. .bootstrapCollapse('hide')
  166. setTimeout(done, 0)
  167. })
  168. QUnit.test('should remove "collapsed" class from active accordion target', function (assert) {
  169. assert.expect(3)
  170. var done = assert.async()
  171. var accordionHTML = '<div class="panel-group" id="accordion">'
  172. + '<div class="panel"/>'
  173. + '<div class="panel"/>'
  174. + '<div class="panel"/>'
  175. + '</div>'
  176. var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
  177. var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
  178. $('<div id="body1" class="in"/>').appendTo($groups.eq(0))
  179. var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
  180. $('<div id="body2"/>').appendTo($groups.eq(1))
  181. var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
  182. $('<div id="body3"/>')
  183. .appendTo($groups.eq(2))
  184. .on('shown.bs.collapse', function () {
  185. assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
  186. assert.ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
  187. assert.ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
  188. done()
  189. })
  190. $target3.trigger('click')
  191. })
  192. QUnit.test('should allow dots in data-parent', function (assert) {
  193. assert.expect(3)
  194. var done = assert.async()
  195. var accordionHTML = '<div class="panel-group accordion">'
  196. + '<div class="panel"/>'
  197. + '<div class="panel"/>'
  198. + '<div class="panel"/>'
  199. + '</div>'
  200. var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
  201. var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
  202. $('<div id="body1" class="in"/>').appendTo($groups.eq(0))
  203. var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
  204. $('<div id="body2"/>').appendTo($groups.eq(1))
  205. var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent=".accordion"/>').appendTo($groups.eq(2))
  206. $('<div id="body3"/>')
  207. .appendTo($groups.eq(2))
  208. .on('shown.bs.collapse', function () {
  209. assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
  210. assert.ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
  211. assert.ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
  212. done()
  213. })
  214. $target3.trigger('click')
  215. })
  216. QUnit.test('should set aria-expanded="true" on target when collapse is shown', function (assert) {
  217. assert.expect(1)
  218. var done = assert.async()
  219. var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
  220. $('<div id="test1"/>')
  221. .appendTo('#qunit-fixture')
  222. .on('shown.bs.collapse', function () {
  223. assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
  224. done()
  225. })
  226. $target.trigger('click')
  227. })
  228. QUnit.test('should set aria-expanded="false" on target when collapse is hidden', function (assert) {
  229. assert.expect(1)
  230. var done = assert.async()
  231. var $target = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
  232. $('<div id="test1" class="in"/>')
  233. .appendTo('#qunit-fixture')
  234. .on('hidden.bs.collapse', function () {
  235. assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
  236. done()
  237. })
  238. $target.trigger('click')
  239. })
  240. QUnit.test('should set aria-expanded="true" on all triggers targeting the collapse when the collapse is shown', function (assert) {
  241. assert.expect(2)
  242. var done = assert.async()
  243. var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
  244. var $alt = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
  245. $('<div id="test1"/>')
  246. .appendTo('#qunit-fixture')
  247. .on('shown.bs.collapse', function () {
  248. assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
  249. assert.strictEqual($alt.attr('aria-expanded'), 'true', 'aria-expanded on alt is "true"')
  250. done()
  251. })
  252. $target.trigger('click')
  253. })
  254. QUnit.test('should set aria-expanded="false" on all triggers targeting the collapse when the collapse is hidden', function (assert) {
  255. assert.expect(2)
  256. var done = assert.async()
  257. var $target = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
  258. var $alt = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
  259. $('<div id="test1" class="in"/>')
  260. .appendTo('#qunit-fixture')
  261. .on('hidden.bs.collapse', function () {
  262. assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
  263. assert.strictEqual($alt.attr('aria-expanded'), 'false', 'aria-expanded on alt is "false"')
  264. done()
  265. })
  266. $target.trigger('click')
  267. })
  268. QUnit.test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function (assert) {
  269. assert.expect(3)
  270. var done = assert.async()
  271. var accordionHTML = '<div class="panel-group" id="accordion">'
  272. + '<div class="panel"/>'
  273. + '<div class="panel"/>'
  274. + '<div class="panel"/>'
  275. + '</div>'
  276. var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
  277. var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
  278. $('<div id="body1" aria-expanded="true" class="in"/>').appendTo($groups.eq(0))
  279. var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
  280. $('<div id="body2" aria-expanded="false"/>').appendTo($groups.eq(1))
  281. var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
  282. $('<div id="body3" aria-expanded="false"/>')
  283. .appendTo($groups.eq(2))
  284. .on('shown.bs.collapse', function () {
  285. assert.strictEqual($target1.attr('aria-expanded'), 'false', 'inactive target 1 has aria-expanded="false"')
  286. assert.strictEqual($target2.attr('aria-expanded'), 'false', 'inactive target 2 has aria-expanded="false"')
  287. assert.strictEqual($target3.attr('aria-expanded'), 'true', 'active target 3 has aria-expanded="false"')
  288. done()
  289. })
  290. $target3.trigger('click')
  291. })
  292. QUnit.test('should not fire show event if show is prevented because other element is still transitioning', function (assert) {
  293. assert.expect(1)
  294. var done = assert.async()
  295. var accordionHTML = '<div id="accordion">'
  296. + '<div class="panel"/>'
  297. + '<div class="panel"/>'
  298. + '</div>'
  299. var showFired = false
  300. var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
  301. var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
  302. $('<div id="body1" class="collapse"/>')
  303. .appendTo($groups.eq(0))
  304. .on('show.bs.collapse', function () {
  305. showFired = true
  306. })
  307. var $target2 = $('<a role="button" data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
  308. var $body2 = $('<div id="body2" class="collapse"/>').appendTo($groups.eq(1))
  309. $target2.trigger('click')
  310. $body2
  311. .toggleClass('in collapsing')
  312. .data('bs.collapse').transitioning = 1
  313. $target1.trigger('click')
  314. setTimeout(function () {
  315. assert.ok(!showFired, 'show event did not fire')
  316. done()
  317. }, 1)
  318. })
  319. QUnit.test('should add "collapsed" class to target when collapse is hidden via manual invocation', function (assert) {
  320. assert.expect(1)
  321. var done = assert.async()
  322. var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
  323. $('<div id="test1" class="in"/>')
  324. .appendTo('#qunit-fixture')
  325. .on('hidden.bs.collapse', function () {
  326. assert.ok($target.hasClass('collapsed'))
  327. done()
  328. })
  329. .bootstrapCollapse('hide')
  330. })
  331. QUnit.test('should remove "collapsed" class from target when collapse is shown via manual invocation', function (assert) {
  332. assert.expect(1)
  333. var done = assert.async()
  334. var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
  335. $('<div id="test1"/>')
  336. .appendTo('#qunit-fixture')
  337. .on('shown.bs.collapse', function () {
  338. assert.ok(!$target.hasClass('collapsed'))
  339. done()
  340. })
  341. .bootstrapCollapse('show')
  342. })
  343. })