collapse.js 16 KB

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