collapse.js 34.9 KB
Newer Older
1
$(function () {
2
  'use strict'
3

4
  QUnit.module('collapse plugin')
XhmikosR's avatar
XhmikosR committed
5

6
  QUnit.test('should be defined on jquery object', function (assert) {
7
    assert.expect(1)
8
    assert.ok($(document.body).collapse, 'collapse method is defined')
XhmikosR's avatar
XhmikosR committed
9
10
  })

11
  QUnit.module('collapse', {
12
    beforeEach: function () {
13
14
15
      // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
      $.fn.bootstrapCollapse = $.fn.collapse.noConflict()
    },
16
    afterEach: function () {
17
18
      $.fn.collapse = $.fn.bootstrapCollapse
      delete $.fn.bootstrapCollapse
19
      $('#qunit-fixture').html('')
20
21
22
    }
  })

23
  QUnit.test('should provide no conflict', function (assert) {
24
    assert.expect(1)
XhmikosR's avatar
XhmikosR committed
25
    assert.strictEqual(typeof $.fn.collapse, 'undefined', 'collapse was set back to undefined (org value)')
26
27
  })

28
29
30
31
32
33
  QUnit.test('should throw explicit error on undefined method', function (assert) {
    assert.expect(1)
    var $el = $('<div/>')
    $el.bootstrapCollapse()
    try {
      $el.bootstrapCollapse('noMethod')
XhmikosR's avatar
XhmikosR committed
34
    } catch (err) {
35
36
37
38
      assert.strictEqual(err.message, 'No method named "noMethod"')
    }
  })

39
  QUnit.test('should return jquery collection containing the element', function (assert) {
40
    assert.expect(2)
41
42
    var $el = $('<div/>')
    var $collapse = $el.bootstrapCollapse()
43
44
    assert.ok($collapse instanceof $, 'returns jquery collection')
    assert.strictEqual($collapse[0], $el[0], 'collection contains element')
XhmikosR's avatar
XhmikosR committed
45
46
  })

47
  QUnit.test('should show a collapsed element', function (assert) {
48
    assert.expect(2)
49
50
    var done = assert.async()
    var $el = $('<div class="collapse"/>')
51

52
53
54
55
56
    $el.one('shown.bs.collapse', function () {
      assert.ok($el.hasClass('show'), 'has class "show"')
      assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
      done()
    }).bootstrapCollapse('show')
XhmikosR's avatar
XhmikosR committed
57
58
  })

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  QUnit.test('should show multiple collapsed elements', function (assert) {
    assert.expect(4)
    var done = assert.async()
    var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href=".multi"/>').appendTo('#qunit-fixture')
    var $el = $('<div class="collapse multi"/>').appendTo('#qunit-fixture')
    var $el2 = $('<div class="collapse multi"/>').appendTo('#qunit-fixture')
    $el.one('shown.bs.collapse', function () {
      assert.ok($el.hasClass('show'), 'has class "show"')
      assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
    })
    $el2.one('shown.bs.collapse', function () {
      assert.ok($el2.hasClass('show'), 'has class "show"')
      assert.ok(!/height/i.test($el2.attr('style')), 'has height reset')
      done()
    })
Johann-S's avatar
Johann-S committed
74
    EventHandler.trigger($target[0], 'click')
75
76
  })

77
78
  QUnit.test('should collapse only the first collapse', function (assert) {
    assert.expect(2)
79
    var done = assert.async()
80
81
    var html = [
      '<div class="panel-group" id="accordion1">',
82
83
84
      '<div class="panel">',
      '<div id="collapse1" class="collapse"/>',
      '</div>',
85
86
      '</div>',
      '<div class="panel-group" id="accordion2">',
87
      '<div class="panel">',
Starsam80's avatar
Starsam80 committed
88
      '<div id="collapse2" class="collapse show"/>',
89
      '</div>',
90
91
92
93
94
      '</div>'
    ].join('')
    $(html).appendTo('#qunit-fixture')
    var $el1 = $('#collapse1')
    var $el2 = $('#collapse2')
95
96
97
98
99
    $el1.one('shown.bs.collapse', function () {
      assert.ok($el1.hasClass('show'))
      assert.ok($el2.hasClass('show'))
      done()
    }).bootstrapCollapse('show')
100
101
  })

102
  QUnit.test('should hide a collapsed element', function (assert) {
103
    assert.expect(1)
104
105
    var $el = $('<div class="collapse"/>').bootstrapCollapse('hide')

Starsam80's avatar
Starsam80 committed
106
    assert.ok(!$el.hasClass('show'), 'does not have class "show"')
XhmikosR's avatar
XhmikosR committed
107
108
  })

109
  QUnit.test('should not fire shown when show is prevented', function (assert) {
110
    assert.expect(1)
111
    var done = assert.async()
112

XhmikosR's avatar
XhmikosR committed
113
114
    $('<div class="collapse"/>')
      .on('show.bs.collapse', function (e) {
115
        e.preventDefault()
116
        assert.ok(true, 'show event fired')
117
        done()
118
      })
XhmikosR's avatar
XhmikosR committed
119
      .on('shown.bs.collapse', function () {
120
        assert.ok(false, 'shown event fired')
121
      })
122
      .bootstrapCollapse('show')
XhmikosR's avatar
XhmikosR committed
123
124
  })

125
  QUnit.test('should reset style to auto after finishing opening collapse', function (assert) {
126
    assert.expect(2)
127
    var done = assert.async()
128

XhmikosR's avatar
XhmikosR committed
129
130
    $('<div class="collapse" style="height: 0px"/>')
      .on('show.bs.collapse', function () {
131
        assert.strictEqual(this.style.height, '0px', 'height is 0px')
132
      })
XhmikosR's avatar
XhmikosR committed
133
      .on('shown.bs.collapse', function () {
134
        assert.strictEqual(this.style.height, '', 'height is auto')
135
        done()
136
      })
137
      .bootstrapCollapse('show')
XhmikosR's avatar
XhmikosR committed
138
  })
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  QUnit.test('should reset style to auto after finishing closing collapse', function (assert) {
    assert.expect(1)
    var done = assert.async()

    $('<div class="collapse"/>')
      .on('shown.bs.collapse', function () {
        $(this).bootstrapCollapse('hide')
      })
      .on('hidden.bs.collapse', function () {
        assert.strictEqual(this.style.height, '', 'height is auto')
        done()
      })
      .bootstrapCollapse('show')
  })

155
  QUnit.test('should remove "collapsed" class from target when collapse is shown', function (assert) {
156
    assert.expect(1)
157
    var done = assert.async()
158

159
    var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
160

161
162
    $('<div id="test1"/>')
      .appendTo('#qunit-fixture')
163
      .on('shown.bs.collapse', function () {
164
        assert.ok(!$target.hasClass('collapsed'), 'target does not have collapsed class')
165
        done()
166
167
      })

Johann-S's avatar
Johann-S committed
168
    EventHandler.trigger($target[0], 'click')
XhmikosR's avatar
XhmikosR committed
169
  })
170

171
  QUnit.test('should add "collapsed" class to target when collapse is hidden', function (assert) {
172
    assert.expect(1)
173
    var done = assert.async()
174

175
    var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
176

Starsam80's avatar
Starsam80 committed
177
    $('<div id="test1" class="show"/>')
178
      .appendTo('#qunit-fixture')
179
      .on('hidden.bs.collapse', function () {
180
        assert.ok($target.hasClass('collapsed'), 'target has collapsed class')
181
        done()
182
183
      })

Johann-S's avatar
Johann-S committed
184
    EventHandler.trigger($target[0], 'click')
XhmikosR's avatar
XhmikosR committed
185
  })
186

187
  QUnit.test('should remove "collapsed" class from all triggers targeting the collapse when the collapse is shown', function (assert) {
188
    assert.expect(2)
189
    var done = assert.async()
190

191
192
    var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
    var $alt = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
193
194
195
196
197
198
199
200
201

    $('<div id="test1"/>')
      .appendTo('#qunit-fixture')
      .on('shown.bs.collapse', function () {
        assert.ok(!$target.hasClass('collapsed'), 'target trigger does not have collapsed class')
        assert.ok(!$alt.hasClass('collapsed'), 'alt trigger does not have collapsed class')
        done()
      })

Johann-S's avatar
Johann-S committed
202
    EventHandler.trigger($target[0], 'click')
203
204
205
  })

  QUnit.test('should add "collapsed" class to all triggers targeting the collapse when the collapse is hidden', function (assert) {
206
    assert.expect(2)
207
208
    var done = assert.async()

209
210
    var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
    var $alt = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
211

Starsam80's avatar
Starsam80 committed
212
    $('<div id="test1" class="show"/>')
213
214
215
216
      .appendTo('#qunit-fixture')
      .on('hidden.bs.collapse', function () {
        assert.ok($target.hasClass('collapsed'), 'target has collapsed class')
        assert.ok($alt.hasClass('collapsed'), 'alt trigger has collapsed class')
217
        done()
218
219
      })

Johann-S's avatar
Johann-S committed
220
    EventHandler.trigger($target[0], 'click')
XhmikosR's avatar
XhmikosR committed
221
  })
222

223
  QUnit.test('should not close a collapse when initialized with "show" option if already shown', function (assert) {
224
    assert.expect(0)
225
    var done = assert.async()
226

Starsam80's avatar
Starsam80 committed
227
    var $test = $('<div id="test1" class="show"/>')
228
229
      .appendTo('#qunit-fixture')
      .on('hide.bs.collapse', function () {
230
        assert.ok(false)
231
232
233
234
      })

    $test.bootstrapCollapse('show')

235
    setTimeout(done, 0)
236
237
  })

238
  QUnit.test('should open a collapse when initialized with "show" option if not already shown', function (assert) {
239
    assert.expect(1)
240
    var done = assert.async()
241
242
243
244

    var $test = $('<div id="test1" />')
      .appendTo('#qunit-fixture')
      .on('show.bs.collapse', function () {
245
        assert.ok(true)
246
247
248
249
      })

    $test.bootstrapCollapse('show')

250
    setTimeout(done, 0)
251
252
  })

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  QUnit.test('should not show a collapse when initialized with "hide" option if already hidden', function (assert) {
    assert.expect(0)
    var done = assert.async()

    $('<div class="collapse"></div>')
      .appendTo('#qunit-fixture')
      .on('show.bs.collapse', function () {
        assert.ok(false, 'showing a previously-uninitialized hidden collapse when the "hide" method is called')
      })
      .bootstrapCollapse('hide')

    setTimeout(done, 0)
  })

  QUnit.test('should hide a collapse when initialized with "hide" option if not already hidden', function (assert) {
    assert.expect(1)
    var done = assert.async()

Starsam80's avatar
Starsam80 committed
271
    $('<div class="collapse show"></div>')
272
273
274
275
276
277
278
279
280
      .appendTo('#qunit-fixture')
      .on('hide.bs.collapse', function () {
        assert.ok(true, 'hiding a previously-uninitialized shown collapse when the "hide" method is called')
      })
      .bootstrapCollapse('hide')

    setTimeout(done, 0)
  })

281
  QUnit.test('should remove "collapsed" class from active accordion target', function (assert) {
282
    assert.expect(3)
283
    var done = assert.async()
284

XhmikosR's avatar
XhmikosR committed
285
286
287
288
289
    var accordionHTML = '<div id="accordion">' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '</div>'
Johann-S's avatar
Johann-S committed
290
    var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
291

292
    var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" />').appendTo($groups.eq(0))
293

294
    $('<div id="body1" class="show" data-parent="#accordion"/>').appendTo($groups.eq(0))
295

296
    var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" />').appendTo($groups.eq(1))
297

298
    $('<div id="body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
299

300
    var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" />').appendTo($groups.eq(2))
301

302
    $('<div id="body3" data-parent="#accordion"/>')
303
      .appendTo($groups.eq(2))
304
      .on('shown.bs.collapse', function () {
305
306
307
        assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
        assert.ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
        assert.ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
308

309
        done()
310
311
      })

Johann-S's avatar
Johann-S committed
312
    EventHandler.trigger($target3[0], 'click')
XhmikosR's avatar
XhmikosR committed
313
  })
314

315
  QUnit.test('should allow dots in data-parent', function (assert) {
316
    assert.expect(3)
317
    var done = assert.async()
318

XhmikosR's avatar
XhmikosR committed
319
320
321
322
323
    var accordionHTML = '<div class="accordion">' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '</div>'
Johann-S's avatar
Johann-S committed
324
    var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
325

326
    var $target1 = $('<a role="button" data-toggle="collapse" href="#body1"/>').appendTo($groups.eq(0))
327

328
    $('<div id="body1" class="show" data-parent=".accordion"/>').appendTo($groups.eq(0))
329

330
    var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2"/>').appendTo($groups.eq(1))
331

332
    $('<div id="body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
333

334
    var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3"/>').appendTo($groups.eq(2))
335

336
    $('<div id="body3" data-parent=".accordion"/>')
337
      .appendTo($groups.eq(2))
338
      .on('shown.bs.collapse', function () {
339
340
341
        assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
        assert.ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
        assert.ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
342

343
        done()
344
345
      })

Johann-S's avatar
Johann-S committed
346
    EventHandler.trigger($target3[0], 'click')
XhmikosR's avatar
XhmikosR committed
347
348
  })

349
  QUnit.test('should set aria-expanded="true" on trigger/control when collapse is shown', function (assert) {
350
    assert.expect(1)
351
    var done = assert.async()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
352

353
    var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
354
355
356

    $('<div id="test1"/>')
      .appendTo('#qunit-fixture')
357
      .on('shown.bs.collapse', function () {
358
        assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
359
        done()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
360
361
      })

Johann-S's avatar
Johann-S committed
362
    EventHandler.trigger($target[0], 'click')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
363
364
  })

365
  QUnit.test('should set aria-expanded="false" on trigger/control when collapse is hidden', function (assert) {
366
    assert.expect(1)
367
    var done = assert.async()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
368

369
    var $target = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
370

Starsam80's avatar
Starsam80 committed
371
    $('<div id="test1" class="show"/>')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
372
      .appendTo('#qunit-fixture')
373
      .on('hidden.bs.collapse', function () {
374
        assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
375
        done()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
376
377
      })

Johann-S's avatar
Johann-S committed
378
    EventHandler.trigger($target[0], 'click')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
379
380
  })

381
  QUnit.test('should set aria-expanded="true" on all triggers targeting the collapse when the collapse is shown', function (assert) {
382
    assert.expect(2)
383
    var done = assert.async()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
384

385
386
    var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
    var $alt = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
387
388
389

    $('<div id="test1"/>')
      .appendTo('#qunit-fixture')
390
      .on('shown.bs.collapse', function () {
391
392
        assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on trigger/control is "true"')
        assert.strictEqual($alt.attr('aria-expanded'), 'true', 'aria-expanded on alternative trigger/control is "true"')
393
        done()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
394
395
      })

Johann-S's avatar
Johann-S committed
396
    EventHandler.trigger($target[0], 'click')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
397
398
  })

399
  QUnit.test('should set aria-expanded="false" on all triggers targeting the collapse when the collapse is hidden', function (assert) {
400
    assert.expect(2)
401
    var done = assert.async()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
402

403
404
    var $target = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
    var $alt = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
405

Starsam80's avatar
Starsam80 committed
406
    $('<div id="test1" class="show"/>')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
407
      .appendTo('#qunit-fixture')
408
      .on('hidden.bs.collapse', function () {
409
410
        assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on trigger/control is "false"')
        assert.strictEqual($alt.attr('aria-expanded'), 'false', 'aria-expanded on alternative trigger/control is "false"')
411
        done()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
412
413
      })

Johann-S's avatar
Johann-S committed
414
    EventHandler.trigger($target[0], 'click')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
415
416
  })

417
  QUnit.test('should change aria-expanded from active accordion trigger/control to "false" and set the trigger/control for the newly active one to "true"', function (assert) {
418
    assert.expect(3)
419
    var done = assert.async()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
420

XhmikosR's avatar
XhmikosR committed
421
422
423
424
425
    var accordionHTML = '<div id="accordion">' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '</div>'
Johann-S's avatar
Johann-S committed
426
    var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
427

428
    var $target1 = $('<a role="button" data-toggle="collapse" aria-expanded="true" href="#body1"/>').appendTo($groups.eq(0))
Patrick H. Lauke's avatar
Patrick H. Lauke committed
429

430
    $('<div id="body1" class="show" data-parent="#accordion"/>').appendTo($groups.eq(0))
Patrick H. Lauke's avatar
Patrick H. Lauke committed
431

432
    var $target2 = $('<a role="button" data-toggle="collapse" aria-expanded="false" href="#body2" class="collapsed" aria-expanded="false" />').appendTo($groups.eq(1))
Patrick H. Lauke's avatar
Patrick H. Lauke committed
433

434
    $('<div id="body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
Patrick H. Lauke's avatar
Patrick H. Lauke committed
435

436
    var $target3 = $('<a class="collapsed" data-toggle="collapse" aria-expanded="false" role="button" href="#body3"/>').appendTo($groups.eq(2))
Patrick H. Lauke's avatar
Patrick H. Lauke committed
437

438
    $('<div id="body3" data-parent="#accordion"/>')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
439
      .appendTo($groups.eq(2))
440
      .on('shown.bs.collapse', function () {
441
442
443
        assert.strictEqual($target1.attr('aria-expanded'), 'false', 'inactive trigger/control 1 has aria-expanded="false"')
        assert.strictEqual($target2.attr('aria-expanded'), 'false', 'inactive trigger/control 2 has aria-expanded="false"')
        assert.strictEqual($target3.attr('aria-expanded'), 'true', 'active trigger/control 3 has aria-expanded="true"')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
444

445
        done()
Patrick H. Lauke's avatar
Patrick H. Lauke committed
446
447
      })

Johann-S's avatar
Johann-S committed
448
    EventHandler.trigger($target3[0], 'click')
Patrick H. Lauke's avatar
Patrick H. Lauke committed
449
450
  })

451
  QUnit.test('should not fire show event if show is prevented because other element is still transitioning', function (assert) {
452
    assert.expect(1)
453
    var done = assert.async()
454

XhmikosR's avatar
XhmikosR committed
455
456
457
458
    var accordionHTML = '<div id="accordion">' +
        '<div class="card"/>' +
        '<div class="card"/>' +
        '</div>'
459
    var showFired = false
Johann-S's avatar
Johann-S committed
460
    var $groups   = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
461

462
    var $target1 = $('<a role="button" data-toggle="collapse" href="#body1"/>').appendTo($groups.eq(0))
463

464
    $('<div id="body1" class="collapse" data-parent="#accordion"/>')
465
466
467
468
469
      .appendTo($groups.eq(0))
      .on('show.bs.collapse', function () {
        showFired = true
      })

470
471
    var $target2 = $('<a role="button" data-toggle="collapse" href="#body2"/>').appendTo($groups.eq(1))
    var $body2   = $('<div id="body2" class="collapse" data-parent="#accordion"/>').appendTo($groups.eq(1))
472

Johann-S's avatar
Johann-S committed
473
    EventHandler.trigger($target2[0], 'click')
474

Johann-S's avatar
Johann-S committed
475
476
    $body2.toggleClass('show collapsing')
    Data.getData($body2[0], 'bs.collapse')._isTransitioning = true
477

Johann-S's avatar
Johann-S committed
478
    EventHandler.trigger($target1[0], 'click')
479
480

    setTimeout(function () {
481
      assert.ok(!showFired, 'show event did not fire')
482
      done()
483
484
485
    }, 1)
  })

486
  QUnit.test('should add "collapsed" class to target when collapse is hidden via manual invocation', function (assert) {
487
    assert.expect(1)
488
    var done = assert.async()
489

490
    var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
491

Starsam80's avatar
Starsam80 committed
492
    $('<div id="test1" class="show"/>')
493
494
      .appendTo('#qunit-fixture')
      .on('hidden.bs.collapse', function () {
495
        assert.ok($target.hasClass('collapsed'))
496
        done()
497
498
499
500
      })
      .bootstrapCollapse('hide')
  })

501
  QUnit.test('should remove "collapsed" class from target when collapse is shown via manual invocation', function (assert) {
502
    assert.expect(1)
503
    var done = assert.async()
504

505
    var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
506
507
508
509

    $('<div id="test1"/>')
      .appendTo('#qunit-fixture')
      .on('shown.bs.collapse', function () {
510
        assert.ok(!$target.hasClass('collapsed'))
511
        done()
512
513
514
515
      })
      .bootstrapCollapse('show')
  })

Johann-S's avatar
Johann-S committed
516
  QUnit.test('should allow accordion to use children other than card', function (assert) {
517
    assert.expect(4)
Johann-S's avatar
Johann-S committed
518
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
519
520
521
522
523
524
525
526
527
528
    var accordionHTML = '<div id="accordion">' +
        '<div class="item">' +
        '<a id="linkTrigger" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>' +
        '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-parent="#accordion"></div>' +
        '</div>' +
        '<div class="item">' +
        '<a id="linkTriggerTwo" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>' +
        '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo" data-parent="#accordion"></div>' +
        '</div>' +
        '</div>'
529
530
531
532
533
534
535
536
537
538
539
540
541
542

    $(accordionHTML).appendTo('#qunit-fixture')
    var $trigger = $('#linkTrigger')
    var $triggerTwo = $('#linkTriggerTwo')
    var $collapseOne = $('#collapseOne')
    var $collapseTwo = $('#collapseTwo')
    $collapseOne.on('shown.bs.collapse', function () {
      assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
      assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
      $collapseTwo.on('shown.bs.collapse', function () {
        assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
        assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
        done()
      })
Johann-S's avatar
Johann-S committed
543
      EventHandler.trigger($triggerTwo[0], 'click')
544
    })
Johann-S's avatar
Johann-S committed
545
    EventHandler.trigger($trigger[0], 'click')
546
547
548
549
550
  })

  QUnit.test('should allow accordion to contain nested elements', function (assert) {
    assert.expect(4)
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
    var accordionHTML = '<div id="accordion">' +
        '<div class="row">' +
        '<div class="col-lg-6">' +
        '<div class="item">' +
        '<a id="linkTrigger" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>' +
        '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-parent="#accordion"></div>' +
        '</div>' +
        '</div>' +
        '<div class="col-lg-6">' +
        '<div class="item">' +
        '<a id="linkTriggerTwo" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>' +
        '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo" data-parent="#accordion"></div>' +
        '</div>' +
        '</div>' +
        '</div>' +
        '</div>'
Johann-S's avatar
Johann-S committed
567
568

    $(accordionHTML).appendTo('#qunit-fixture')
569
570
571
572
573
574
575
576
577
578
579
580
581
    var $trigger = $('#linkTrigger')
    var $triggerTwo = $('#linkTriggerTwo')
    var $collapseOne = $('#collapseOne')
    var $collapseTwo = $('#collapseTwo')
    $collapseOne.on('shown.bs.collapse', function () {
      assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
      assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
      $collapseTwo.on('shown.bs.collapse', function () {
        assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
        assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
        done()
      })
      $triggerTwo.trigger($.Event('click'))
Johann-S's avatar
Johann-S committed
582
    })
583
584
585
    $trigger.trigger($.Event('click'))
  })

586
587
588
  QUnit.test('should allow accordion to target multiple elements', function (assert) {
    assert.expect(8)
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
589
590
591
592
593
594
595
596
    var accordionHTML = '<div id="accordion">' +
      '<a id="linkTriggerOne" data-toggle="collapse" data-target=".collapseOne" href="#" aria-expanded="false" aria-controls="collapseOne"></a>' +
      '<a id="linkTriggerTwo" data-toggle="collapse" data-target=".collapseTwo" href="#" aria-expanded="false" aria-controls="collapseTwo"></a>' +
      '<div id="collapseOneOne" class="collapse collapseOne" role="tabpanel" data-parent="#accordion"></div>' +
      '<div id="collapseOneTwo" class="collapse collapseOne" role="tabpanel" data-parent="#accordion"></div>' +
      '<div id="collapseTwoOne" class="collapse collapseTwo" role="tabpanel" data-parent="#accordion"></div>' +
      '<div id="collapseTwoTwo" class="collapse collapseTwo" role="tabpanel" data-parent="#accordion"></div>' +
      '</div>'
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660

    $(accordionHTML).appendTo('#qunit-fixture')
    var $trigger = $('#linkTriggerOne')
    var $triggerTwo = $('#linkTriggerTwo')
    var $collapseOneOne = $('#collapseOneOne')
    var $collapseOneTwo = $('#collapseOneTwo')
    var $collapseTwoOne = $('#collapseTwoOne')
    var $collapseTwoTwo = $('#collapseTwoTwo')
    var collapsedElements = {
      one : false,
      two : false
    }

    function firstTest() {
      assert.ok($collapseOneOne.hasClass('show'), '#collapseOneOne is shown')
      assert.ok($collapseOneTwo.hasClass('show'), '#collapseOneTwo is shown')
      assert.ok(!$collapseTwoOne.hasClass('show'), '#collapseTwoOne is not shown')
      assert.ok(!$collapseTwoTwo.hasClass('show'), '#collapseTwoTwo is not shown')
      $triggerTwo.trigger($.Event('click'))
    }

    function secondTest() {
      assert.ok(!$collapseOneOne.hasClass('show'), '#collapseOneOne is not shown')
      assert.ok(!$collapseOneTwo.hasClass('show'), '#collapseOneTwo is not shown')
      assert.ok($collapseTwoOne.hasClass('show'), '#collapseTwoOne is shown')
      assert.ok($collapseTwoTwo.hasClass('show'), '#collapseTwoTwo is shown')
      done()
    }

    $collapseOneOne.on('shown.bs.collapse', function () {
      if (collapsedElements.one) {
        firstTest()
      } else {
        collapsedElements.one = true
      }
    })

    $collapseOneTwo.on('shown.bs.collapse', function () {
      if (collapsedElements.one) {
        firstTest()
      } else {
        collapsedElements.one = true
      }
    })

    $collapseTwoOne.on('shown.bs.collapse', function () {
      if (collapsedElements.two) {
        secondTest()
      } else {
        collapsedElements.two = true
      }
    })

    $collapseTwoTwo.on('shown.bs.collapse', function () {
      if (collapsedElements.two) {
        secondTest()
      } else {
        collapsedElements.two = true
      }
    })

    $trigger.trigger($.Event('click'))
  })

661
662
663
  QUnit.test('should collapse accordion children but not nested accordion children', function (assert) {
    assert.expect(9)
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    $('<div id="accordion">' +
        '<div class="item">' +
        '<a id="linkTrigger" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>' +
        '<div id="collapseOne" data-parent="#accordion" class="collapse" role="tabpanel" aria-labelledby="headingThree">' +
        '<div id="nestedAccordion">' +
        '<div class="item">' +
        '<a id="nestedLinkTrigger" data-toggle="collapse" href="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>' +
        '<div id="nestedCollapseOne" data-parent="#nestedAccordion" class="collapse" role="tabpanel" aria-labelledby="headingThree">' +
        '</div>' +
        '</div>' +
        '</div>' +
        '</div>' +
        '</div>' +
        '<div class="item">' +
        '<a id="linkTriggerTwo" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>' +
        '<div id="collapseTwo" data-parent="#accordion" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>' +
        '</div>' +
        '</div>').appendTo('#qunit-fixture')
682
683
684
685
686
687
688
    var $trigger = $('#linkTrigger')
    var $triggerTwo = $('#linkTriggerTwo')
    var $nestedTrigger = $('#nestedLinkTrigger')
    var $collapseOne = $('#collapseOne')
    var $collapseTwo = $('#collapseTwo')
    var $nestedCollapseOne = $('#nestedCollapseOne')

Johann-S's avatar
Johann-S committed
689
    EventHandler.one($collapseOne[0], 'shown.bs.collapse', function () {
690
691
692
      assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
      assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
      assert.ok(!$('#nestedCollapseOne').hasClass('show'), '#nestedCollapseOne is not shown')
Johann-S's avatar
Johann-S committed
693
694

      EventHandler.one($nestedCollapseOne[0], 'shown.bs.collapse', function () {
695
696
697
        assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
        assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
        assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
Johann-S's avatar
Johann-S committed
698
        EventHandler.one($collapseTwo[0], 'shown.bs.collapse', function () {
699
700
701
702
703
          assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
          assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
          assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
          done()
        })
Johann-S's avatar
Johann-S committed
704
        EventHandler.trigger($triggerTwo[0], 'click')
705
      })
Johann-S's avatar
Johann-S committed
706
      EventHandler.trigger($nestedTrigger[0], 'click')
707
    })
Johann-S's avatar
Johann-S committed
708
    EventHandler.trigger($trigger[0], 'click')
Johann-S's avatar
Johann-S committed
709
  })
710
711

  QUnit.test('should not prevent event for input', function (assert) {
712
    assert.expect(3)
713
714
    var done = assert.async()
    var $target = $('<input type="checkbox" data-toggle="collapse" data-target="#collapsediv1" />').appendTo('#qunit-fixture')
Johann-S's avatar
Johann-S committed
715
    var $collapse = $('<div id="collapsediv1"/>').appendTo('#qunit-fixture')
716

Johann-S's avatar
Johann-S committed
717
718
719
720
721
722
    EventHandler.one($collapse[0], 'shown.bs.collapse', function () {
      assert.ok($collapse.hasClass('show'))
      assert.ok($target.attr('aria-expanded') === 'true')
      assert.ok($target.prop('checked'))
      done()
    })
723
724
725

    $target.trigger($.Event('click'))
  })
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

  QUnit.test('should add "collapsed" class to triggers only when all the targeted collapse are hidden', function (assert) {
    assert.expect(9)
    var done = assert.async()

    var $trigger1 = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
    var $trigger2 = $('<a role="button" data-toggle="collapse" href="#test2"/>').appendTo('#qunit-fixture')
    var $trigger3 = $('<a role="button" data-toggle="collapse" href=".multi"/>').appendTo('#qunit-fixture')

    var $target1 = $('<div id="test1" class="multi"/>').appendTo('#qunit-fixture')
    var $target2 = $('<div id="test2" class="multi"/>').appendTo('#qunit-fixture')

    $target2.one('shown.bs.collapse', function () {
      assert.ok(!$trigger1.hasClass('collapsed'), 'trigger1 does not have collapsed class')
      assert.ok(!$trigger2.hasClass('collapsed'), 'trigger2 does not have collapsed class')
      assert.ok(!$trigger3.hasClass('collapsed'), 'trigger3 does not have collapsed class')
      $target2.one('hidden.bs.collapse', function () {
        assert.ok(!$trigger1.hasClass('collapsed'), 'trigger1 does not have collapsed class')
        assert.ok($trigger2.hasClass('collapsed'), 'trigger2 has collapsed class')
        assert.ok(!$trigger3.hasClass('collapsed'), 'trigger3 does not have collapsed class')
        $target1.one('hidden.bs.collapse', function () {
          assert.ok($trigger1.hasClass('collapsed'), 'trigger1 has collapsed class')
          assert.ok($trigger2.hasClass('collapsed'), 'trigger2 has collapsed class')
          assert.ok($trigger3.hasClass('collapsed'), 'trigger3 has collapsed class')
          done()
        })
Johann-S's avatar
Johann-S committed
752
        EventHandler.trigger($trigger1[0], 'click')
753
      })
Johann-S's avatar
Johann-S committed
754
      EventHandler.trigger($trigger2[0], 'click')
755
    })
Johann-S's avatar
Johann-S committed
756
    EventHandler.trigger($trigger3[0], 'click')
757
758
  })

759
  QUnit.test('should set aria-expanded="true" to triggers targeting shown collaspe and aria-expanded="false" only when all the targeted collapses are shown', function (assert) {
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
    assert.expect(9)
    var done = assert.async()

    var $trigger1 = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
    var $trigger2 = $('<a role="button" data-toggle="collapse" href="#test2"/>').appendTo('#qunit-fixture')
    var $trigger3 = $('<a role="button" data-toggle="collapse" href=".multi"/>').appendTo('#qunit-fixture')

    var $target1 = $('<div id="test1" class="multi collapse"/>').appendTo('#qunit-fixture')
    var $target2 = $('<div id="test2" class="multi collapse"/>').appendTo('#qunit-fixture')

    $target2.one('shown.bs.collapse', function () {
      assert.strictEqual($trigger1.attr('aria-expanded'), 'true', 'aria-expanded on trigger1 is "true"')
      assert.strictEqual($trigger2.attr('aria-expanded'), 'true', 'aria-expanded on trigger2 is "true"')
      assert.strictEqual($trigger3.attr('aria-expanded'), 'true', 'aria-expanded on trigger3 is "true"')
      $target2.one('hidden.bs.collapse', function () {
        assert.strictEqual($trigger1.attr('aria-expanded'), 'true', 'aria-expanded on trigger1 is "true"')
        assert.strictEqual($trigger2.attr('aria-expanded'), 'false', 'aria-expanded on trigger2 is "false"')
        assert.strictEqual($trigger3.attr('aria-expanded'), 'true', 'aria-expanded on trigger3 is "true"')
        $target1.one('hidden.bs.collapse', function () {
          assert.strictEqual($trigger1.attr('aria-expanded'), 'false', 'aria-expanded on trigger1 is "fasle"')
          assert.strictEqual($trigger2.attr('aria-expanded'), 'false', 'aria-expanded on trigger2 is "false"')
          assert.strictEqual($trigger3.attr('aria-expanded'), 'false', 'aria-expanded on trigger3 is "false"')
          done()
        })
Johann-S's avatar
Johann-S committed
784
        EventHandler.trigger($trigger1[0], 'click')
785
      })
Johann-S's avatar
Johann-S committed
786
      EventHandler.trigger($trigger2[0], 'click')
787
    })
Johann-S's avatar
Johann-S committed
788
    EventHandler.trigger($trigger3[0], 'click')
789
  })
790
791
792
793
794
795
796
797
798
799

  QUnit.test('should not prevent interactions inside the collapse element', function (assert) {
    assert.expect(2)
    var done = assert.async()

    var $target = $('<input type="checkbox" data-toggle="collapse" data-target="#collapsediv1" />').appendTo('#qunit-fixture')
    var htmlCollapse =
      '<div id="collapsediv1" class="collapse">' +
      ' <input type="checkbox" id="testCheckbox" />' +
      '</div>'
Johann-S's avatar
Johann-S committed
800
801
802
803
804
805
806
807
808
809
810
    var $collapse = $(htmlCollapse).appendTo('#qunit-fixture')

    EventHandler.one($collapse[0], 'shown.bs.collapse', function () {
      assert.ok($target.prop('checked'), '$trigger is checked')
      var $testCheckbox = $('#testCheckbox')
      $testCheckbox.trigger($.Event('click'))
      setTimeout(function () {
        assert.ok($testCheckbox.prop('checked'), '$testCheckbox is checked too')
        done()
      }, 5)
    })
811
812
    $target.trigger($.Event('click'))
  })
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829

  QUnit.test('should allow jquery object in parent config', function (assert) {
    assert.expect(1)
    var html =
    '<div class="my-collapse">' +
    '  <div class="item">' +
    '    <a data-toggle="collapse" href="#">Toggle item</a>' +
    '    <div class="collapse">Lorem ipsum</div>' +
    '  </div>' +
    '</div>'

    $(html).appendTo('#qunit-fixture')
    try {
      $('[data-toggle="collapse"]').bootstrapCollapse({
        parent: $('.my-collapse')
      })
      assert.ok(true, 'collapse correctly created')
XhmikosR's avatar
XhmikosR committed
830
    } catch (err) {
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
      assert.ok(false, 'collapse not created')
    }
  })

  QUnit.test('should allow DOM object in parent config', function (assert) {
    assert.expect(1)
    var html =
    '<div class="my-collapse">' +
    '  <div class="item">' +
    '    <a data-toggle="collapse" href="#">Toggle item</a>' +
    '    <div class="collapse">Lorem ipsum</div>' +
    '  </div>' +
    '</div>'

    $(html).appendTo('#qunit-fixture')
    try {
      $('[data-toggle="collapse"]').bootstrapCollapse({
        parent: $('.my-collapse')[0]
      })
      assert.ok(true, 'collapse correctly created')
XhmikosR's avatar
XhmikosR committed
851
    } catch (err) {
852
853
854
      assert.ok(false, 'collapse not created')
    }
  })
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888

  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 =
    '<div class="my-collapse">' +
    '  <div class="item">' +
    '    <a data-toggle="collapse" href="#">Toggle item 1</a>' +
    '    <div id="collapse1" class="collapse show">Lorem ipsum 1</div>' +
    '  </div>' +
    '  <div class="item">' +
    '    <a id="triggerCollapse2" data-toggle="collapse" href="#">Toggle item 2</a>' +
    '    <div id="collapse2" class="collapse">Lorem ipsum 2</div>' +
    '  </div>' +
    '</div>'

    $(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')
  })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
889
})