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

4
  QUnit.module('popover 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).popover, 'popover method is defined')
XhmikosR's avatar
XhmikosR committed
9
10
  })

11
  QUnit.module('popover', {
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.bootstrapPopover = $.fn.popover.noConflict()
    },
16
    afterEach: function () {
17
18
      $.fn.popover = $.fn.bootstrapPopover
      delete $.fn.bootstrapPopover
fat's avatar
fat committed
19
      $('.popover').remove()
20
      $('#qunit-fixture').html('')
21
22
23
    }
  })

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

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

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

48
  QUnit.test('should render popover element', function (assert) {
49
    assert.expect(2)
50
51
    var done = assert.async()
    $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>')
XhmikosR's avatar
XhmikosR committed
52
      .appendTo('#qunit-fixture')
53
54
55
56
57
58
59
60
      .on('shown.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        $(this).bootstrapPopover('hide')
      })
      .on('hidden.bs.popover', function () {
        assert.strictEqual($('.popover').length, 0, 'popover removed')
        done()
      })
61
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
62
63
  })

64
  QUnit.test('should store popover instance in popover data object', function (assert) {
65
    assert.expect(1)
66
    var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>').bootstrapPopover()
XhmikosR's avatar
XhmikosR committed
67

68
    assert.ok(Data.getData($popover[0], 'bs.popover'), 'popover instance exists')
XhmikosR's avatar
XhmikosR committed
69
70
  })

71
  QUnit.test('should store popover trigger in popover instance data object', function (assert) {
72
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
73
    var $popover = $('<a href="#" title="ResentedHook">@ResentedHook</a>')
74
75
      .appendTo('#qunit-fixture')
      .bootstrapPopover()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
76
77
78

    $popover.bootstrapPopover('show')

79
    assert.ok(Data.getData($('.popover')[0], 'bs.popover'), 'popover trigger stored in instance data')
80
81
  })

82
  QUnit.test('should get title and content from options', function (assert) {
83
    assert.expect(4)
84
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
85
    var $popover = $('<a href="#">@fat</a>')
XhmikosR's avatar
XhmikosR committed
86
      .appendTo('#qunit-fixture')
87
      .bootstrapPopover({
XhmikosR's avatar
XhmikosR committed
88
89
90
91
92
93
        title: function () {
          return '@fat'
        },
        content: function () {
          return 'loves writing tests (╯°□°)╯︵ ┻━┻'
        }
94
95
      })

96
97
98
99
100
101
102
103
104
105
106
107
    $popover
      .one('shown.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        assert.strictEqual($('.popover .popover-header').text(), '@fat', 'title correctly inserted')
        assert.strictEqual($('.popover .popover-body').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
        $popover.bootstrapPopover('hide')
      })
      .one('hidden.bs.popover', function () {
        assert.strictEqual($('.popover').length, 0, 'popover was removed')
        done()
      })
      .bootstrapPopover('show')
Stefan Neculai's avatar
Stefan Neculai committed
108
109
  })

110
111
112
113
114
115
  QUnit.test('should allow DOMElement title and content (html: true)', function (assert) {
    assert.expect(5)
    var title = document.createTextNode('@glebm <3 writing tests')
    var content = $('<i>¯\\_(ツ)_/¯</i>').get(0)
    var $popover = $('<a href="#" rel="tooltip"/>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
116
117
118
119
120
      .bootstrapPopover({
        html: true,
        title: title,
        content: content
      })
121
122
123
124

    $popover.bootstrapPopover('show')

    assert.notEqual($('.popover').length, 0, 'popover inserted')
Mark Otto's avatar
Mark Otto committed
125
    assert.strictEqual($('.popover .popover-header').text(), '@glebm <3 writing tests', 'title inserted')
126
127
    assert.ok($.contains($('.popover').get(0), title), 'title node moved, not copied')
    // toLowerCase because IE8 will return <I>...</I>
Mark Otto's avatar
Mark Otto committed
128
    assert.strictEqual($('.popover .popover-body').html().toLowerCase(), '<i>¯\\_(ツ)_/¯</i>', 'content inserted')
129
130
131
132
133
134
135
136
137
    assert.ok($.contains($('.popover').get(0), content), 'content node moved, not copied')
  })

  QUnit.test('should allow DOMElement title and content (html: false)', function (assert) {
    assert.expect(5)
    var title = document.createTextNode('@glebm <3 writing tests')
    var content = $('<i>¯\\_(ツ)_/¯</i>').get(0)
    var $popover = $('<a href="#" rel="tooltip"/>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
138
139
140
141
      .bootstrapPopover({
        title: title,
        content: content
      })
142
143
144
145

    $popover.bootstrapPopover('show')

    assert.notEqual($('.popover').length, 0, 'popover inserted')
Mark Otto's avatar
Mark Otto committed
146
    assert.strictEqual($('.popover .popover-header').text(), '@glebm <3 writing tests', 'title inserted')
147
    assert.ok(!$.contains($('.popover').get(0), title), 'title node copied, not moved')
Mark Otto's avatar
Mark Otto committed
148
    assert.strictEqual($('.popover .popover-body').html(), '¯\\_(ツ)_/¯', 'content inserted')
149
150
151
    assert.ok(!$.contains($('.popover').get(0), content), 'content node copied, not moved')
  })

152
  QUnit.test('should not duplicate HTML object', function (assert) {
153
    assert.expect(6)
154
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
155
    var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
Stefan Neculai's avatar
Stefan Neculai committed
156

Heinrich Fenkart's avatar
Heinrich Fenkart committed
157
    var $popover = $('<a href="#">@fat</a>')
Stefan Neculai's avatar
Stefan Neculai committed
158
      .appendTo('#qunit-fixture')
159
      .bootstrapPopover({
fat's avatar
fat committed
160
        html: true,
Stefan Neculai's avatar
Stefan Neculai committed
161
162
163
164
165
        content: function () {
          return $div
        }
      })

166
167
168
169
    function popoverInserted() {
      assert.notEqual($('.popover').length, 0, 'popover was inserted')
      assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted')
    }
Stefan Neculai's avatar
Stefan Neculai committed
170

171
172
173
    $popover
      .one('shown.bs.popover', function () {
        popoverInserted()
Stefan Neculai's avatar
Stefan Neculai committed
174

175
176
        $popover.one('hidden.bs.popover', function () {
          assert.strictEqual($('.popover').length, 0, 'popover was removed')
Stefan Neculai's avatar
Stefan Neculai committed
177

178
179
180
181
182
183
184
185
186
187
188
          $popover.one('shown.bs.popover', function () {
            popoverInserted()

            $popover.one('hidden.bs.popover', function () {
              assert.strictEqual($('.popover').length, 0, 'popover was removed')
              done()
            }).bootstrapPopover('hide')
          }).bootstrapPopover('show')
        }).bootstrapPopover('hide')
      })
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
189
190
  })

191
  QUnit.test('should get title and content from attributes', function (assert) {
192
    assert.expect(4)
193
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
194
    var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
XhmikosR's avatar
XhmikosR committed
195
      .appendTo('#qunit-fixture')
196
      .bootstrapPopover()
197
198
199
200
201
202
203
204
205
206
      .one('shown.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
        assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
        $popover.bootstrapPopover('hide')
      })
      .one('hidden.bs.popover', function () {
        assert.strictEqual($('.popover').length, 0, 'popover was removed')
        done()
      })
207
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
208
209
  })

210
  QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) {
211
    assert.expect(4)
212
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
213
    var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
XhmikosR's avatar
XhmikosR committed
214
      .appendTo('#qunit-fixture')
215
      .bootstrapPopover({
XhmikosR's avatar
XhmikosR committed
216
217
        title: 'ignored title option',
        content: 'ignored content option'
218
      })
219
220
221
222
223
224
225
226
227
228
      .one('shown.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
        assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
        $popover.bootstrapPopover('hide')
      })
      .one('hidden.bs.popover', function () {
        assert.strictEqual($('.popover').length, 0, 'popover was removed')
        done()
      })
229
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
230
231
  })

232
  QUnit.test('should respect custom template', function (assert) {
233
    assert.expect(3)
234
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
235
    var $popover = $('<a href="#">@fat</a>')
XhmikosR's avatar
XhmikosR committed
236
      .appendTo('#qunit-fixture')
237
      .bootstrapPopover({
XhmikosR's avatar
XhmikosR committed
238
239
        title: 'Test',
        content: 'Test',
fat's avatar
fat committed
240
        template: '<div class="popover foobar"><div class="arrow"></div><div class="inner"><h3 class="title"/><div class="content"><p/></div></div></div>'
241
      })
242
243
244
245
246
247
248
249
250
251
      .one('shown.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        assert.ok($('.popover').hasClass('foobar'), 'custom class is present')
        $popover.bootstrapPopover('hide')
      })
      .one('hidden.bs.popover', function () {
        assert.strictEqual($('.popover').length, 0, 'popover was removed')
        done()
      })
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
252
253
  })

254
  QUnit.test('should destroy popover', function (assert) {
255
    assert.expect(3)
fat's avatar
fat committed
256
    var $popover = $('<div/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
257
258
259
260
261
      .bootstrapPopover({
        trigger: 'hover'
      })
      .on('click.foo', $.noop)

262
    assert.ok(Data.getData($popover[0], 'bs.popover'), 'popover has data')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
263
264

    $popover.bootstrapPopover('show')
fat's avatar
fat committed
265
    $popover.bootstrapPopover('dispose')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
266

Starsam80's avatar
Starsam80 committed
267
    assert.ok(!$popover.hasClass('show'), 'popover is hidden')
268
    assert.ok(!$popover.data('popover'), 'popover does not have data')
XhmikosR's avatar
XhmikosR committed
269
  })
270

271
  QUnit.test('should render popover element using delegated selector', function (assert) {
272
    assert.expect(2)
273
    var done = assert.async()
XhmikosR's avatar
XhmikosR committed
274
    var $div = $('<div><a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a></div>')
275
276
277
278
279
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
        selector: 'a',
        trigger: 'click'
      })
280
281
282
283
284
285
286
287
      .one('shown.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        $div.find('a').trigger('click')
      })
      .one('hidden.bs.popover', function () {
        assert.strictEqual($('.popover').length, 0, 'popover was removed')
        done()
      })
288

289
    $div.find('a').trigger('click')
290
291
  })

292
  QUnit.test('should detach popover content rather than removing it so that event handlers are left intact', function (assert) {
293
    assert.expect(1)
Chris Rebert's avatar
Chris Rebert committed
294
    var $content = $('<div class="content-with-handler"><a class="btn btn-warning">Button with event handler</a></div>').appendTo('#qunit-fixture')
295

296
    var handlerCalled = false
297
    $('.content-with-handler .btn').on('click', function () {
Chris Rebert's avatar
Chris Rebert committed
298
      handlerCalled = true
299
    })
Chris Rebert's avatar
Chris Rebert committed
300
301

    var $div = $('<div><a href="#">Show popover</a></div>')
302
303
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
Chris Rebert's avatar
Chris Rebert committed
304
305
306
        html: true,
        trigger: 'manual',
        container: 'body',
307
        animation: false,
Chris Rebert's avatar
Chris Rebert committed
308
        content: function () {
309
          return $content
Chris Rebert's avatar
Chris Rebert committed
310
        }
311
312
      })

313
    var done = assert.async()
Chris Rebert's avatar
Chris Rebert committed
314
315
316
317
318
319
    $div
      .one('shown.bs.popover', function () {
        $div
          .one('hidden.bs.popover', function () {
            $div
              .one('shown.bs.popover', function () {
320
                $('.content-with-handler .btn').trigger('click')
321
                assert.ok(handlerCalled, 'content\'s event handler still present')
322
                $div.bootstrapPopover('dispose')
323
                done()
Chris Rebert's avatar
Chris Rebert committed
324
325
326
327
328
329
              })
              .bootstrapPopover('show')
          })
          .bootstrapPopover('hide')
      })
      .bootstrapPopover('show')
330
  })
331

332
333
334
335
336
337
338
339
340
  QUnit.test('should do nothing when an attempt is made to hide an uninitialized popover', function (assert) {
    assert.expect(1)

    var $popover = $('<span data-toggle="popover" data-title="some title" data-content="some content">some text</span>')
      .appendTo('#qunit-fixture')
      .on('hidden.bs.popover shown.bs.popover', function () {
        assert.ok(false, 'should not fire any popover events')
      })
      .bootstrapPopover('hide')
341
    assert.ok(Data.getData($popover[0], 'bs.popover') === null, 'should not initialize the popover')
342
343
  })

fat's avatar
fat committed
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  QUnit.test('should fire inserted event', function (assert) {
    assert.expect(2)
    var done = assert.async()

    $('<a href="#">@Johann-S</a>')
      .appendTo('#qunit-fixture')
      .on('inserted.bs.popover', function () {
        assert.notEqual($('.popover').length, 0, 'popover was inserted')
        assert.ok(true, 'inserted event fired')
        done()
      })
      .bootstrapPopover({
        title: 'Test',
        content: 'Test'
      })
      .bootstrapPopover('show')
  })

362
363
364
365
366
367
  QUnit.test('should throw an error when show is called on hidden elements', function (assert) {
    assert.expect(1)
    var done = assert.async()

    try {
      $('<div data-toggle="popover" data-title="some title" data-content="@Johann-S" style="display: none"/>').bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
368
    } catch (err) {
369
370
371
372
      assert.strictEqual(err.message, 'Please use show on visible elements')
      done()
    }
  })
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404

  QUnit.test('should hide popovers when their containing modal is closed', function (assert) {
    assert.expect(1)
    var done = assert.async()
    var templateHTML = '<div id="modal-test" class="modal">' +
                          '<div class="modal-dialog" role="document">' +
                            '<div class="modal-content">' +
                              '<div class="modal-body">' +
                                '<button id="popover-test" type="button" class="btn btn-secondary" data-toggle="popover" data-placement="top" data-content="Popover">' +
                                  'Popover on top' +
                                '</button>' +
                              '</div>' +
                            '</div>' +
                          '</div>' +
                        '</div>'

    $(templateHTML).appendTo('#qunit-fixture')
    $('#popover-test')
      .on('shown.bs.popover', function () {
        $('#modal-test').modal('hide')
      })
      .on('hide.bs.popover', function () {
        assert.ok(true, 'popover hide')
        done()
      })

    $('#modal-test')
      .on('shown.bs.modal', function () {
        $('#popover-test').bootstrapPopover('show')
      })
      .modal('show')
  })
405
406
407
408
409
410
411
412
413
414
415

  QUnit.test('should convert number to string without error for content and title', function (assert) {
    assert.expect(2)
    var done = assert.async()
    var $popover = $('<a href="#">@mdo</a>')
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
        title: 5,
        content: 7
      })
      .on('shown.bs.popover', function () {
Mark Otto's avatar
Mark Otto committed
416
417
        assert.strictEqual($('.popover .popover-header').text(), '5')
        assert.strictEqual($('.popover .popover-body').text(), '7')
418
419
420
421
422
        done()
      })

    $popover.bootstrapPopover('show')
  })
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

  QUnit.test('popover should be shown right away after the call of disable/enable', function (assert) {
    assert.expect(2)
    var done = assert.async()
    var $popover = $('<a href="#">@mdo</a>')
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
        title: 'Test popover',
        content: 'with disable/enable'
      })
      .on('shown.bs.popover', function () {
        assert.strictEqual($('.popover').hasClass('show'), true)
        done()
      })

    $popover.bootstrapPopover('disable')
439
    EventHandler.trigger($popover[0], 'click')
440
441
442
    setTimeout(function () {
      assert.strictEqual($('.popover').length === 0, true)
      $popover.bootstrapPopover('enable')
443
      EventHandler.trigger($popover[0], 'click')
444
445
    }, 200)
  })
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

  QUnit.test('popover should call content function only once', function (assert) {
    assert.expect(1)
    var done = assert.async()
    var nbCall = 0
    $('<div id="popover" style="display:none">content</div>').appendTo('#qunit-fixture')
    var $popover = $('<a href="#">@Johann-S</a>')
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
        content: function () {
          nbCall++
          return $('#popover').clone().show().get(0)
        }
      })
      .on('shown.bs.popover', function () {
        assert.strictEqual(nbCall, 1)
        done()
      })

Johann-S's avatar
Johann-S committed
465
    EventHandler.trigger($popover[0], 'click')
466
  })
467
})