carousel.js 30 KB
Newer Older
1
$(function () {
XhmikosR's avatar
XhmikosR committed
2
  'use strict';
3

fat's avatar
fat committed
4
  QUnit.module('carousel plugin')
5

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

fat's avatar
fat committed
11
12
  QUnit.module('carousel', {
    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.bootstrapCarousel = $.fn.carousel.noConflict()
    },
fat's avatar
fat committed
16
    afterEach: function () {
17
18
19
20
21
      $.fn.carousel = $.fn.bootstrapCarousel
      delete $.fn.bootstrapCarousel
    }
  })

fat's avatar
fat committed
22
23
24
  QUnit.test('should provide no conflict', function (assert) {
    assert.expect(1)
    assert.strictEqual($.fn.carousel, undefined, 'carousel was set back to undefined (orig 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.bootstrapCarousel()
    try {
      $el.bootstrapCarousel('noMethod')
    }
    catch (err) {
      assert.strictEqual(err.message, 'No method named "noMethod"')
    }
  })

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

fat's avatar
fat committed
47
  QUnit.test('should type check config options', function (assert) {
48
49
    assert.expect(2)

fat's avatar
fat committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    var message
    var expectedMessage = 'CAROUSEL: Option "interval" provided type "string" but expected type "(number|boolean)".'
    var config = {
      interval: 'fat sux'
    }

    try {
      $('<div/>').bootstrapCarousel(config)
    } catch (e) {
      message = e.message
    }

    assert.ok(message === expectedMessage, 'correct error message')

    config = {
65
      keyboard: document.createElement('div')
fat's avatar
fat committed
66
67
68
69
70
71
72
73
74
75
76
77
78
    }
    expectedMessage = 'CAROUSEL: Option "keyboard" provided type "element" but expected type "boolean".'

    try {
      $('<div/>').bootstrapCarousel(config)
    } catch (e) {
      message = e.message
    }

    assert.ok(message === expectedMessage, 'correct error message')
  })


fat's avatar
fat committed
79
80
  QUnit.test('should not fire slid when slide is prevented', function (assert) {
    assert.expect(1)
81
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
82
83
    $('<div class="carousel"/>')
      .on('slide.bs.carousel', function (e) {
84
        e.preventDefault()
fat's avatar
fat committed
85
        assert.ok(true, 'slide event fired')
86
        done()
XhmikosR's avatar
XhmikosR committed
87
88
      })
      .on('slid.bs.carousel', function () {
fat's avatar
fat committed
89
        assert.ok(false, 'slid event fired')
90
      })
91
      .bootstrapCarousel('next')
XhmikosR's avatar
XhmikosR committed
92
  })
93

fat's avatar
fat committed
94
95
  QUnit.test('should reset when slide is prevented', function (assert) {
    assert.expect(6)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
96
97
98
99
100
101
102
    var carouselHTML = '<div id="carousel-example-generic" class="carousel slide">'
        + '<ol class="carousel-indicators">'
        + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
        + '</ol>'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
103
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
104
105
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
106
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
107
108
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
109
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
110
111
112
113
114
115
        + '<div class="carousel-caption"/>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
        + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
        + '</div>'
116
117
    var $carousel = $(carouselHTML)

118
    var done = assert.async()
119
120
121
122
    $carousel
      .one('slide.bs.carousel', function (e) {
        e.preventDefault()
        setTimeout(function () {
fat's avatar
fat committed
123
          assert.ok($carousel.find('.carousel-item:eq(0)').is('.active'), 'first item still active')
fat's avatar
fat committed
124
          assert.ok($carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
125
126
127
128
129
          $carousel.bootstrapCarousel('next')
        }, 0)
      })
      .one('slid.bs.carousel', function () {
        setTimeout(function () {
fat's avatar
fat committed
130
          assert.ok(!$carousel.find('.carousel-item:eq(0)').is('.active'), 'first item still active')
fat's avatar
fat committed
131
          assert.ok(!$carousel.find('.carousel-indicators li:eq(0)').is('.active'), 'first indicator still active')
fat's avatar
fat committed
132
          assert.ok($carousel.find('.carousel-item:eq(1)').is('.active'), 'second item active')
fat's avatar
fat committed
133
          assert.ok($carousel.find('.carousel-indicators li:eq(1)').is('.active'), 'second indicator active')
134
          done()
135
136
137
        }, 0)
      })
      .bootstrapCarousel('next')
XhmikosR's avatar
XhmikosR committed
138
  })
139

fat's avatar
fat committed
140
141
  QUnit.test('should fire slide event with direction', function (assert) {
    assert.expect(4)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
142
143
    var carouselHTML = '<div id="myCarousel" class="carousel slide">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
144
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
145
146
147
148
149
150
151
152
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>First Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
153
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
154
155
156
157
158
159
160
161
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Second Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
162
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
163
164
165
166
167
168
169
170
171
172
173
174
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Third Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
        + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
        + '</div>'
175
176
    var $carousel = $(carouselHTML)

177
    var done = assert.async()
178
179
180

    $carousel
      .one('slide.bs.carousel', function (e) {
fat's avatar
fat committed
181
182
        assert.ok(e.direction, 'direction present on next')
        assert.strictEqual(e.direction, 'left', 'direction is left on next')
183
184
185

        $carousel
          .one('slide.bs.carousel', function (e) {
fat's avatar
fat committed
186
187
            assert.ok(e.direction, 'direction present on prev')
            assert.strictEqual(e.direction, 'right', 'direction is right on prev')
188
            done()
189
190
191
192
          })
          .bootstrapCarousel('prev')
      })
      .bootstrapCarousel('next')
XhmikosR's avatar
XhmikosR committed
193
  })
194

fat's avatar
fat committed
195
196
  QUnit.test('should fire slid event with direction', function (assert) {
    assert.expect(4)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
197
198
    var carouselHTML = '<div id="myCarousel" class="carousel slide">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
199
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
200
201
202
203
204
205
206
207
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>First Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
208
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
209
210
211
212
213
214
215
216
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Second Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
217
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
218
219
220
221
222
223
224
225
226
227
228
229
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Third Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
        + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
        + '</div>'
230
231
    var $carousel = $(carouselHTML)

232
    var done = assert.async()
233
234
235

    $carousel
      .one('slid.bs.carousel', function (e) {
fat's avatar
fat committed
236
237
        assert.ok(e.direction, 'direction present on next')
        assert.strictEqual(e.direction, 'left', 'direction is left on next')
238
239
240

        $carousel
          .one('slid.bs.carousel', function (e) {
fat's avatar
fat committed
241
242
            assert.ok(e.direction, 'direction present on prev')
            assert.strictEqual(e.direction, 'right', 'direction is right on prev')
243
            done()
244
245
246
247
          })
          .bootstrapCarousel('prev')
      })
      .bootstrapCarousel('next')
248
249
  })

fat's avatar
fat committed
250
251
  QUnit.test('should fire slide event with relatedTarget', function (assert) {
    assert.expect(2)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
252
253
    var template = '<div id="myCarousel" class="carousel slide">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
254
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
255
256
257
258
259
260
261
262
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>First Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
263
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
264
265
266
267
268
269
270
271
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Second Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
272
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
273
274
275
276
277
278
279
280
281
282
283
284
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Third Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
        + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
        + '</div>'
285

286
    var done = assert.async()
287

XhmikosR's avatar
XhmikosR committed
288
289
    $(template)
      .on('slide.bs.carousel', function (e) {
fat's avatar
fat committed
290
        assert.ok(e.relatedTarget, 'relatedTarget present')
fat's avatar
fat committed
291
        assert.ok($(e.relatedTarget).hasClass('carousel-item'), 'relatedTarget has class "item"')
292
        done()
Dmitriy Budnik's avatar
Dmitriy Budnik committed
293
      })
294
      .bootstrapCarousel('next')
XhmikosR's avatar
XhmikosR committed
295
  })
296

fat's avatar
fat committed
297
298
  QUnit.test('should fire slid event with relatedTarget', function (assert) {
    assert.expect(2)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
299
300
    var template = '<div id="myCarousel" class="carousel slide">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
301
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
302
303
304
305
306
307
308
309
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>First Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
310
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
311
312
313
314
315
316
317
318
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Second Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
319
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
320
321
322
323
324
325
326
327
328
329
330
331
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Third Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
        + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
        + '</div>'
332

333
    var done = assert.async()
334

335
336
    $(template)
      .on('slid.bs.carousel', function (e) {
fat's avatar
fat committed
337
        assert.ok(e.relatedTarget, 'relatedTarget present')
fat's avatar
fat committed
338
        assert.ok($(e.relatedTarget).hasClass('carousel-item'), 'relatedTarget has class "item"')
339
        done()
340
      })
341
      .bootstrapCarousel('next')
342
  })
343

fat's avatar
fat committed
344
345
  QUnit.test('should set interval from data attribute', function (assert) {
    assert.expect(4)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
346
347
    var templateHTML = '<div id="myCarousel" class="carousel slide">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
348
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
349
350
351
352
353
354
355
356
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>First Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
357
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
358
359
360
361
362
363
364
365
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Second Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
fat's avatar
fat committed
366
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
367
368
369
370
371
372
373
374
375
376
377
378
        + '<img alt="">'
        + '<div class="carousel-caption">'
        + '<h4>Third Thumbnail label</h4>'
        + '<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec '
        + 'id elit non mi porta gravida at eget metus. Nullam id dolor id nibh '
        + 'ultricies vehicula ut id elit.</p>'
        + '</div>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
        + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
        + '</div>'
379
380
    var $carousel = $(templateHTML)
    $carousel.attr('data-interval', 1814)
Dmitriy Budnik's avatar
Dmitriy Budnik committed
381

382
    $carousel.appendTo('body')
fat's avatar
fat committed
383
    $('[data-slide]').first().trigger('click')
fat's avatar
fat committed
384
    assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814)
385
    $carousel.remove()
dmitriybudnik's avatar
dmitriybudnik committed
386

387
    $carousel.appendTo('body').attr('data-modal', 'foobar')
fat's avatar
fat committed
388
    $('[data-slide]').first().trigger('click')
fat's avatar
fat committed
389
    assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814, 'even if there is an data-modal attribute set')
390
    $carousel.remove()
Dmitriy Budnik's avatar
Dmitriy Budnik committed
391

392
    $carousel.appendTo('body')
fat's avatar
fat committed
393
    $('[data-slide]').first().trigger('click')
394
    $carousel.attr('data-interval', 1860)
fat's avatar
fat committed
395
    $('[data-slide]').first().trigger('click')
fat's avatar
fat committed
396
    assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814, 'attributes should be read only on initialization')
397
398
399
400
401
    $carousel.remove()

    $carousel.attr('data-interval', false)
    $carousel.appendTo('body')
    $carousel.bootstrapCarousel(1)
fat's avatar
fat committed
402
    assert.strictEqual($carousel.data('bs.carousel')._config.interval, false, 'data attribute has higher priority than default options')
403
    $carousel.remove()
XhmikosR's avatar
XhmikosR committed
404
  })
405

fat's avatar
fat committed
406
407
  QUnit.test('should skip over non-items when using item indices', function (assert) {
    assert.expect(2)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
408
409
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
410
        + '<div class="carousel-item active">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
411
412
413
        + '<img alt="">'
        + '</div>'
        + '<script type="text/x-metamorph" id="thingy"/>'
fat's avatar
fat committed
414
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
415
416
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
417
        + '<div class="carousel-item">'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
418
419
420
        + '</div>'
        + '</div>'
        + '</div>'
421
    var $template = $(templateHTML)
422

423
    $template.bootstrapCarousel()
424

fat's avatar
fat committed
425
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
426

427
    $template.bootstrapCarousel(1)
428

fat's avatar
fat committed
429
    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
430
  })
431

fat's avatar
fat committed
432
433
  QUnit.test('should skip over non-items when using next/prev methods', function (assert) {
    assert.expect(2)
434
435
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="1814">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
436
        + '<div class="carousel-item active">'
437
438
439
        + '<img alt="">'
        + '</div>'
        + '<script type="text/x-metamorph" id="thingy"/>'
fat's avatar
fat committed
440
        + '<div class="carousel-item">'
441
442
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
443
        + '<div class="carousel-item">'
444
445
446
447
448
449
450
        + '</div>'
        + '</div>'
        + '</div>'
    var $template = $(templateHTML)

    $template.bootstrapCarousel()

fat's avatar
fat committed
451
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
452
453
454

    $template.bootstrapCarousel('next')

fat's avatar
fat committed
455
    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
456
  })
457

fat's avatar
fat committed
458
459
  QUnit.test('should go to previous item if left arrow key is pressed', function (assert) {
    assert.expect(2)
460
461
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
462
        + '<div id="first" class="carousel-item">'
463
464
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
465
        + '<div id="second" class="carousel-item active">'
466
467
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
468
        + '<div id="third" class="carousel-item">'
469
470
471
472
473
474
475
476
        + '<img alt="">'
        + '</div>'
        + '</div>'
        + '</div>'
    var $template = $(templateHTML)

    $template.bootstrapCarousel()

fat's avatar
fat committed
477
    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
478
479
480

    $template.trigger($.Event('keydown', { which: 37 }))

fat's avatar
fat committed
481
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
482
483
  })

fat's avatar
fat committed
484
485
  QUnit.test('should go to next item if right arrow key is pressed', function (assert) {
    assert.expect(2)
486
487
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
488
        + '<div id="first" class="carousel-item active">'
489
490
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
491
        + '<div id="second" class="carousel-item">'
492
493
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
494
        + '<div id="third" class="carousel-item">'
495
496
497
498
499
500
501
502
        + '<img alt="">'
        + '</div>'
        + '</div>'
        + '</div>'
    var $template = $(templateHTML)

    $template.bootstrapCarousel()

fat's avatar
fat committed
503
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
504
505
506

    $template.trigger($.Event('keydown', { which: 39 }))

fat's avatar
fat committed
507
    assert.strictEqual($template.find('.carousel-item')[1], $template.find('.active')[0], 'second item active')
508
509
  })

fat's avatar
fat committed
510
511
  QUnit.test('should support disabling the keyboard navigation', function (assert) {
    assert.expect(3)
512
513
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-keyboard="false">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
514
        + '<div id="first" class="carousel-item active">'
515
516
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
517
        + '<div id="second" class="carousel-item">'
518
519
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
520
        + '<div id="third" class="carousel-item">'
521
522
523
524
525
526
527
528
        + '<img alt="">'
        + '</div>'
        + '</div>'
        + '</div>'
    var $template = $(templateHTML)

    $template.bootstrapCarousel()

fat's avatar
fat committed
529
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
530
531
532

    $template.trigger($.Event('keydown', { which: 39 }))

fat's avatar
fat committed
533
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after right arrow press')
534
535
536

    $template.trigger($.Event('keydown', { which: 37 }))

fat's avatar
fat committed
537
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press')
538
539
  })

fat's avatar
fat committed
540
541
  QUnit.test('should ignore keyboard events within <input>s and <textarea>s', function (assert) {
    assert.expect(7)
542
543
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
544
        + '<div id="first" class="carousel-item active">'
545
546
547
548
        + '<img alt="">'
        + '<input type="text" id="in-put">'
        + '<textarea id="text-area"></textarea>'
        + '</div>'
fat's avatar
fat committed
549
        + '<div id="second" class="carousel-item">'
550
551
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
552
        + '<div id="third" class="carousel-item">'
553
554
555
556
557
558
559
560
        + '<img alt="">'
        + '</div>'
        + '</div>'
        + '</div>'
    var $template = $(templateHTML)
    var $input = $template.find('#in-put')
    var $textarea = $template.find('#text-area')

fat's avatar
fat committed
561
562
    assert.strictEqual($input.length, 1, 'found <input>')
    assert.strictEqual($textarea.length, 1, 'found <textarea>')
563
564
565

    $template.bootstrapCarousel()

fat's avatar
fat committed
566
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item active')
567
568
569


    $input.trigger($.Event('keydown', { which: 39 }))
fat's avatar
fat committed
570
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <input>')
571
572

    $input.trigger($.Event('keydown', { which: 37 }))
fat's avatar
fat committed
573
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <input>')
574
575
576


    $textarea.trigger($.Event('keydown', { which: 39 }))
fat's avatar
fat committed
577
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after right arrow press in <textarea>')
578
579

    $textarea.trigger($.Event('keydown', { which: 37 }))
fat's avatar
fat committed
580
    assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <textarea>')
581
582
  })

fat's avatar
fat committed
583
584
  QUnit.test('should only add mouseenter and mouseleave listeners when not on mobile', function (assert) {
    assert.expect(2)
585
586
587
    var isMobile     = 'ontouchstart' in document.documentElement
    var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-pause="hover">'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
588
        + '<div id="first" class="carousel-item active">'
589
590
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
591
        + '<div id="second" class="carousel-item">'
592
593
        + '<img alt="">'
        + '</div>'
fat's avatar
fat committed
594
        + '<div id="third" class="carousel-item">'
595
596
597
598
599
600
601
        + '<img alt="">'
        + '</div>'
        + '</div>'
        + '</div>'
    var $template = $(templateHTML).bootstrapCarousel()

    $.each(['mouseover', 'mouseout'], function (i, type) {
fat's avatar
fat committed
602
      assert.strictEqual(type in $._data($template[0], 'events'), !isMobile, 'does' + (isMobile ? ' not' : '') + ' listen for ' + type + ' events')
603
604
    })
  })
605

fat's avatar
fat committed
606
607
  QUnit.test('should wrap around from end to start when wrap option is true', function (assert) {
    assert.expect(3)
608
609
610
611
612
613
614
    var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="true">'
        + '<ol class="carousel-indicators">'
        + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
        + '</ol>'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
615
        + '<div class="carousel-item active" id="one">'
616
617
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
618
        + '<div class="carousel-item" id="two">'
619
620
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
621
        + '<div class="carousel-item" id="three">'
622
623
624
625
626
627
628
        + '<div class="carousel-caption"/>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
        + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
        + '</div>'
    var $carousel = $(carouselHTML)
fat's avatar
fat committed
629
    var getActiveId = function () { return $carousel.find('.carousel-item.active').attr('id') }
630

631
    var done = assert.async()
632
633
634

    $carousel
      .one('slid.bs.carousel', function () {
fat's avatar
fat committed
635
        assert.strictEqual(getActiveId(), 'two', 'carousel slid from 1st to 2nd slide')
636
637
        $carousel
          .one('slid.bs.carousel', function () {
fat's avatar
fat committed
638
            assert.strictEqual(getActiveId(), 'three', 'carousel slid from 2nd to 3rd slide')
639
640
            $carousel
              .one('slid.bs.carousel', function () {
fat's avatar
fat committed
641
                assert.strictEqual(getActiveId(), 'one', 'carousel wrapped around and slid from 3rd to 1st slide')
642
                done()
643
644
645
646
647
648
649
650
              })
              .bootstrapCarousel('next')
          })
          .bootstrapCarousel('next')
      })
      .bootstrapCarousel('next')
  })

fat's avatar
fat committed
651
652
  QUnit.test('should wrap around from start to end when wrap option is true', function (assert) {
    assert.expect(1)
653
654
655
656
657
658
659
    var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="true">'
        + '<ol class="carousel-indicators">'
        + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
        + '</ol>'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
660
        + '<div class="carousel-item active" id="one">'
661
662
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
663
        + '<div class="carousel-item" id="two">'
664
665
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
666
        + '<div class="carousel-item" id="three">'
667
668
669
670
671
672
673
674
        + '<div class="carousel-caption"/>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
        + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
        + '</div>'
    var $carousel = $(carouselHTML)

675
    var done = assert.async()
676
677
678

    $carousel
      .on('slid.bs.carousel', function () {
fat's avatar
fat committed
679
        assert.strictEqual($carousel.find('.carousel-item.active').attr('id'), 'three', 'carousel wrapped around and slid from 1st to 3rd slide')
680
        done()
681
682
683
684
      })
      .bootstrapCarousel('prev')
  })

fat's avatar
fat committed
685
686
  QUnit.test('should stay at the end when the next method is called and wrap is false', function (assert) {
    assert.expect(3)
687
688
689
690
691
692
693
    var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="false">'
        + '<ol class="carousel-indicators">'
        + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
        + '</ol>'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
694
        + '<div class="carousel-item active" id="one">'
695
696
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
697
        + '<div class="carousel-item" id="two">'
698
699
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
700
        + '<div class="carousel-item" id="three">'
701
702
703
704
705
706
707
        + '<div class="carousel-caption"/>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
        + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
        + '</div>'
    var $carousel = $(carouselHTML)
fat's avatar
fat committed
708
    var getActiveId = function () { return $carousel.find('.carousel-item.active').attr('id') }
709

710
    var done = assert.async()
711
712
713

    $carousel
      .one('slid.bs.carousel', function () {
fat's avatar
fat committed
714
        assert.strictEqual(getActiveId(), 'two', 'carousel slid from 1st to 2nd slide')
715
716
        $carousel
          .one('slid.bs.carousel', function () {
fat's avatar
fat committed
717
            assert.strictEqual(getActiveId(), 'three', 'carousel slid from 2nd to 3rd slide')
718
719
            $carousel
              .one('slid.bs.carousel', function () {
fat's avatar
fat committed
720
                assert.ok(false, 'carousel slid when it should not have slid')
721
722
              })
              .bootstrapCarousel('next')
fat's avatar
fat committed
723
            assert.strictEqual(getActiveId(), 'three', 'carousel did not wrap around and stayed on 3rd slide')
724
            done()
725
726
727
728
729
730
          })
          .bootstrapCarousel('next')
      })
      .bootstrapCarousel('next')
  })

fat's avatar
fat committed
731
732
  QUnit.test('should stay at the start when the prev method is called and wrap is false', function (assert) {
    assert.expect(1)
733
734
735
736
737
738
739
    var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="false">'
        + '<ol class="carousel-indicators">'
        + '<li data-target="#carousel-example-generic" data-slide-to="0" class="active"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="1"/>'
        + '<li data-target="#carousel-example-generic" data-slide-to="2"/>'
        + '</ol>'
        + '<div class="carousel-inner">'
fat's avatar
fat committed
740
        + '<div class="carousel-item active" id="one">'
741
742
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
743
        + '<div class="carousel-item" id="two">'
744
745
        + '<div class="carousel-caption"/>'
        + '</div>'
fat's avatar
fat committed
746
        + '<div class="carousel-item" id="three">'
747
748
749
750
751
752
753
754
755
756
        + '<div class="carousel-caption"/>'
        + '</div>'
        + '</div>'
        + '<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"/>'
        + '<a class="right carousel-control" href="#carousel-example-generic" data-slide="next"/>'
        + '</div>'
    var $carousel = $(carouselHTML)

    $carousel
      .on('slid.bs.carousel', function () {
fat's avatar
fat committed
757
        assert.ok(false, 'carousel slid when it should not have slid')
758
759
      })
      .bootstrapCarousel('prev')
fat's avatar
fat committed
760
    assert.strictEqual($carousel.find('.carousel-item.active').attr('id'), 'one', 'carousel did not wrap around and stayed on 1st slide')
761
  })
762
})