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

4
  QUnit.module('tabs plugin')
5

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

11
  QUnit.module('tabs', {
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.bootstrapTab = $.fn.tab.noConflict()
    },
16
    afterEach: function () {
17
18
19
20
21
      $.fn.tab = $.fn.bootstrapTab
      delete $.fn.bootstrapTab
    }
  })

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

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

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

47
  QUnit.test('should activate element by tab id', function (assert) {
48
    assert.expect(2)
49
    var tabsHTML = '<ul class="nav">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
50
51
52
        + '<li><a href="#home">Home</a></li>'
        + '<li><a href="#profile">Profile</a></li>'
        + '</ul>'
53

Heinrich Fenkart's avatar
Heinrich Fenkart committed
54
    $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
55

56
    $(tabsHTML).find('li:last-child a').bootstrapTab('show')
57
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
58

59
    $(tabsHTML).find('li:first-child a').bootstrapTab('show')
60
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
XhmikosR's avatar
XhmikosR committed
61
  })
62

63
  QUnit.test('should activate element by tab id', function (assert) {
64
    assert.expect(2)
65
    var pillsHTML = '<ul class="nav nav-pills">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
66
67
68
        + '<li><a href="#home">Home</a></li>'
        + '<li><a href="#profile">Profile</a></li>'
        + '</ul>'
69

Heinrich Fenkart's avatar
Heinrich Fenkart committed
70
    $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
71

72
    $(pillsHTML).find('li:last-child a').bootstrapTab('show')
73
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
74

75
    $(pillsHTML).find('li:first-child a').bootstrapTab('show')
76
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
XhmikosR's avatar
XhmikosR committed
77
  })
78

79
80
  QUnit.test('should activate element by tab id in ordered list', function (assert) {
    assert.expect(2)
81
    var pillsHTML = '<ol class="nav nav-pills">'
82
83
84
85
86
87
        + '<li><a href="#home">Home</a></li>'
        + '<li><a href="#profile">Profile</a></li>'
        + '</ol>'

    $('<ol><li id="home"/><li id="profile"/></ol>').appendTo('#qunit-fixture')

88
    $(pillsHTML).find('li:last-child a').bootstrapTab('show')
89
90
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')

91
    $(pillsHTML).find('li:first-child a').bootstrapTab('show')
92
93
94
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
  })

Johann-S's avatar
Johann-S committed
95
96
97
98
99
100
101
102
103
  QUnit.test('should activate element by tab id in nav list', function (assert) {
    assert.expect(2)
    var tabsHTML =  '<nav class="nav">' +
                      '<a href="#home">Home</a>' +
                      '<a href="#profile">Profile</a>' +
                    '</nav>'

    $('<nav><div id="home"></div><div id="profile"></div></nav>').appendTo('#qunit-fixture')

104
    $(tabsHTML).find('a:last-child').bootstrapTab('show')
Johann-S's avatar
Johann-S committed
105
106
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')

107
    $(tabsHTML).find('a:first-child').bootstrapTab('show')
Johann-S's avatar
Johann-S committed
108
109
110
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
  })

111
  QUnit.test('should activate element by tab id in list group', function (assert) {
112
    assert.expect(2)
113
114
115
116
    var tabsHTML =  '<div class="list-group">' +
                      '<a href="#home">Home</a>' +
                      '<a href="#profile">Profile</a>' +
                    '</div>'
117

118
    $('<nav><div id="home"></div><div id="profile"></div></nav>').appendTo('#qunit-fixture')
119

120
    $(tabsHTML).find('a:last-child').bootstrapTab('show')
121
122
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')

123
    $(tabsHTML).find('a:first-child').bootstrapTab('show')
124
125
126
    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
  })

127
  QUnit.test('should not fire shown when show is prevented', function (assert) {
128
    assert.expect(1)
129
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
130

131
    $('<div class="nav"/>')
XhmikosR's avatar
XhmikosR committed
132
      .on('show.bs.tab', function (e) {
133
        e.preventDefault()
134
        assert.ok(true, 'show event fired')
135
        done()
136
      })
XhmikosR's avatar
XhmikosR committed
137
      .on('shown.bs.tab', function () {
138
        assert.ok(false, 'shown event fired')
XhmikosR's avatar
XhmikosR committed
139
      })
140
      .bootstrapTab('show')
XhmikosR's avatar
XhmikosR committed
141
142
  })

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  QUnit.test('should not fire shown when tab is already active', function (assert) {
    assert.expect(0)
    var tabsHTML = '<ul class="nav nav-tabs" role="tablist">'
      + '<li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>'
      + '<li class="nav-item"><a href="#profile" class="nav-link" role="tab">Profile</a></li>'
      + '</ul>'
      + '<div class="tab-content">'
      + '<div class="tab-pane active" id="home" role="tabpanel"></div>'
      + '<div class="tab-pane" id="profile" role="tabpanel"></div>'
      + '</div>'

    $(tabsHTML)
      .find('a.active')
      .on('shown.bs.tab', function () {
        assert.ok(true, 'shown event fired')
      })
      .bootstrapTab('show')
  })

  QUnit.test('should not fire shown when tab is disabled', function (assert) {
    assert.expect(0)
    var tabsHTML = '<ul class="nav nav-tabs" role="tablist">'
      + '<li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>'
      + '<li class="nav-item"><a href="#profile" class="nav-link disabled" role="tab">Profile</a></li>'
      + '</ul>'
      + '<div class="tab-content">'
      + '<div class="tab-pane active" id="home" role="tabpanel"></div>'
      + '<div class="tab-pane" id="profile" role="tabpanel"></div>'
      + '</div>'

    $(tabsHTML)
      .find('a.disabled')
      .on('shown.bs.tab', function () {
        assert.ok(true, 'shown event fired')
      })
      .bootstrapTab('show')
  })

181
  QUnit.test('show and shown events should reference correct relatedTarget', function (assert) {
182
    assert.expect(2)
183
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
184

185
186
187
188
189
190
191
192
    var dropHTML =
          '<ul class="drop nav">'
        + '  <li class="dropdown"><a data-toggle="dropdown" href="#">1</a>'
        + '    <ul class="dropdown-menu nav">'
        + '      <li><a href="#1-1" data-toggle="tab">1-1</a></li>'
        + '      <li><a href="#1-2" data-toggle="tab">1-2</a></li>'
        + '    </ul>'
        + '  </li>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
193
        + '</ul>'
XhmikosR's avatar
XhmikosR committed
194

Heinrich Fenkart's avatar
Heinrich Fenkart committed
195
    $(dropHTML)
196
      .find('ul > li:first-child a')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
197
198
        .bootstrapTab('show')
      .end()
199
      .find('ul > li:last-child a')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
200
        .on('show.bs.tab', function (e) {
201
          assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
202
203
        })
        .on('shown.bs.tab', function (e) {
204
          assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
205
          done()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
206
207
        })
        .bootstrapTab('show')
XhmikosR's avatar
XhmikosR committed
208
  })
Kevin Attfield's avatar
Kevin Attfield committed
209

210
  QUnit.test('should fire hide and hidden events', function (assert) {
211
    assert.expect(2)
212
    var done = assert.async()
213

214
    var tabsHTML = '<ul class="nav">'
215
216
217
218
219
        + '<li><a href="#home">Home</a></li>'
        + '<li><a href="#profile">Profile</a></li>'
        + '</ul>'

    $(tabsHTML)
220
      .find('li:first-child a')
221
        .on('hide.bs.tab', function () {
222
          assert.ok(true, 'hide event fired')
223
224
225
        })
        .bootstrapTab('show')
      .end()
226
      .find('li:last-child a')
227
228
229
        .bootstrapTab('show')

    $(tabsHTML)
230
      .find('li:first-child a')
231
        .on('hidden.bs.tab', function () {
232
          assert.ok(true, 'hidden event fired')
233
          done()
234
235
236
        })
        .bootstrapTab('show')
      .end()
237
      .find('li:last-child a')
238
239
240
        .bootstrapTab('show')
  })

241
  QUnit.test('should not fire hidden when hide is prevented', function (assert) {
242
    assert.expect(1)
243
    var done = assert.async()
244

245
    var tabsHTML = '<ul class="nav">'
246
247
248
249
250
        + '<li><a href="#home">Home</a></li>'
        + '<li><a href="#profile">Profile</a></li>'
        + '</ul>'

    $(tabsHTML)
251
      .find('li:first-child a')
252
253
        .on('hide.bs.tab', function (e) {
          e.preventDefault()
254
          assert.ok(true, 'hide event fired')
255
          done()
256
257
        })
        .on('hidden.bs.tab', function () {
258
          assert.ok(false, 'hidden event fired')
259
260
261
        })
        .bootstrapTab('show')
      .end()
262
      .find('li:last-child a')
263
264
265
        .bootstrapTab('show')
  })

266
  QUnit.test('hide and hidden events contain correct relatedTarget', function (assert) {
267
    assert.expect(2)
268
    var done = assert.async()
269

270
    var tabsHTML = '<ul class="nav">'
271
272
273
274
275
        + '<li><a href="#home">Home</a></li>'
        + '<li><a href="#profile">Profile</a></li>'
        + '</ul>'

    $(tabsHTML)
276
      .find('li:first-child a')
277
        .on('hide.bs.tab', function (e) {
278
          assert.strictEqual(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
279
280
        })
        .on('hidden.bs.tab', function (e) {
281
          assert.strictEqual(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
282
          done()
283
284
285
        })
        .bootstrapTab('show')
      .end()
286
      .find('li:last-child a')
287
288
289
        .bootstrapTab('show')
  })

290
  QUnit.test('selected tab should have aria-selected', function (assert) {
291
    assert.expect(8)
Cameron Little's avatar
Cameron Little committed
292
    var tabsHTML = '<ul class="nav nav-tabs">'
293
294
        + '<li><a class="nav-item active" href="#home" toggle="tab" aria-selected="true">Home</a></li>'
        + '<li><a class="nav-item" href="#profile" toggle="tab" aria-selected="false">Profile</a></li>'
Cameron Little's avatar
Cameron Little committed
295
296
297
        + '</ul>'
    var $tabs = $(tabsHTML).appendTo('#qunit-fixture')

298
    $tabs.find('li:first-child a').bootstrapTab('show')
299
300
    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'shown tab has aria-selected = true')
    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'hidden tab has aria-selected = false')
Cameron Little's avatar
Cameron Little committed
301

302
    $tabs.find('li:last-child a').trigger('click')
303
304
    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'after click, shown tab has aria-selected = true')
    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'after click, hidden tab has aria-selected = false')
Cameron Little's avatar
Cameron Little committed
305

306
    $tabs.find('li:first-child a').bootstrapTab('show')
307
308
    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'shown tab has aria-selected = true')
    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'hidden tab has aria-selected = false')
Cameron Little's avatar
Cameron Little committed
309

310
    $tabs.find('li:first-child a').trigger('click')
311
312
    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'after second show event, shown tab still has aria-selected = true')
    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'after second show event, hidden tab has aria-selected = false')
Cameron Little's avatar
Cameron Little committed
313
314
  })

315
316
317
318
319
320
321
322
  QUnit.test('selected tab should deactivate previous selected tab', function (assert) {
    assert.expect(2)
    var tabsHTML = '<ul class="nav nav-tabs">'
        + '<li class="nav-item"><a class="nav-link active" href="#home" data-toggle="tab">Home</a></li>'
        + '<li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>'
        + '</ul>'
    var $tabs = $(tabsHTML).appendTo('#qunit-fixture')

323
324
325
    $tabs.find('li:last-child a').trigger('click')
    assert.notOk($tabs.find('li:first-child a').hasClass('active'))
    assert.ok($tabs.find('li:last-child a').hasClass('active'))
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  })

  QUnit.test('selected tab should deactivate previous selected link in dropdown', function (assert) {
    assert.expect(3)
    var tabsHTML = '<ul class="nav nav-tabs">'
        + '<li class="nav-item"><a class="nav-link" href="#home" data-toggle="tab">Home</a></li>'
        + '<li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>'
        + '<li class="nav-item dropdown"><a class="nav-link dropdown-toggle active" data-toggle="dropdown" href="#">Dropdown</a>'
        + '<div class="dropdown-menu">'
        + '<a class="dropdown-item active" href="#dropdown1" id="dropdown1-tab" data-toggle="tab">@fat</a>'
        + '<a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-toggle="tab">@mdo</a>'
        + '</div>'
        + '</li>'
        + '</ul>'
    var $tabs = $(tabsHTML).appendTo('#qunit-fixture')

342
343
344
345
    $tabs.find('li:first-child a').trigger('click')
    assert.ok($tabs.find('li:first-child a').hasClass('active'))
    assert.notOk($tabs.find('li:last-child a').hasClass('active'))
    assert.notOk($tabs.find('li:last-child .dropdown-menu a:first-child').hasClass('active'))
346
  })
Johann-S's avatar
Johann-S committed
347
348
349
350
351
352
353

  QUnit.test('Nested tabs', function (assert) {
    assert.expect(2)
    var done = assert.async()
    var tabsHTML =
          '<nav class="nav nav-tabs" role="tablist">'
        + '  <a id="tab1" href="#x-tab1" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab1">Tab 1</a>'
354
        + '  <a href="#x-tab2" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-selected="true">Tab 2</a>'
Johann-S's avatar
Johann-S committed
355
356
357
358
359
        + '  <a href="#x-tab3" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab3">Tab 3</a>'
        + '</nav>'
        + '<div class="tab-content">'
        + '  <div class="tab-pane" id="x-tab1" role="tabpanel">'
        + '    <nav class="nav nav-tabs" role="tablist">'
360
        + '      <a href="#nested-tab1" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-selected="true">Nested Tab 1</a>'
Johann-S's avatar
Johann-S committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
        + '      <a id="tabNested2" href="#nested-tab2" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-profile">Nested Tab2</a>'
        + '    </nav>'
        + '    <div class="tab-content">'
        + '      <div class="tab-pane active" id="nested-tab1" role="tabpanel">Nested Tab1 Content</div>'
        + '      <div class="tab-pane" id="nested-tab2" role="tabpanel">Nested Tab2 Content</div>'
        + '    </div>'
        + '  </div>'
        + '  <div class="tab-pane active" id="x-tab2" role="tabpanel">Tab2 Content</div>'
        + '  <div class="tab-pane" id="x-tab3" role="tabpanel">Tab3 Content</div>'
        + '</div>'

    $(tabsHTML).appendTo('#qunit-fixture')

    $('#tabNested2').on('shown.bs.tab', function () {
      assert.ok($('#x-tab1').hasClass('active'))
      done()
    })

    $('#tab1').on('shown.bs.tab', function () {
      assert.ok($('#x-tab1').hasClass('active'))
      $('#tabNested2').trigger($.Event('click'))
    })
    .trigger($.Event('click'))
  })
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

  QUnit.test('should not remove fade class if no active pane is present', function (assert) {
    assert.expect(6)
    var done = assert.async()
    var tabsHTML = '<ul class="nav nav-tabs" role="tablist">'
      + '<li class="nav-item"><a id="tab-home" href="#home" class="nav-link" data-toggle="tab" role="tab">Home</a></li>'
      + '<li class="nav-item"><a id="tab-profile" href="#profile" class="nav-link" data-toggle="tab" role="tab">Profile</a></li>'
      + '</ul>'
      + '<div class="tab-content">'
      + '<div class="tab-pane fade" id="home" role="tabpanel"></div>'
      + '<div class="tab-pane fade" id="profile" role="tabpanel"></div>'
      + '</div>'


    $(tabsHTML).appendTo('#qunit-fixture')
    $('#tab-profile')
      .on('shown.bs.tab', function () {
        assert.ok($('#profile').hasClass('fade'))
        assert.ok($('#profile').hasClass('show'))

        $('#tab-home')
          .on('shown.bs.tab', function () {
            assert.ok($('#profile').hasClass('fade'))
            assert.notOk($('#profile').hasClass('show'))
            assert.ok($('#home').hasClass('fade'))
            assert.ok($('#home').hasClass('show'))

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