popover.js 15.3 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
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.popover, 'undefined', 'popover was set back to undefined (org value)')
26
27
  })

28
29
30
31
32
33
34
35
36
37
38
39
  QUnit.test('should throw explicit error on undefined method', function (assert) {
    assert.expect(1)
    var $el = $('<div/>')
    $el.bootstrapPopover()
    try {
      $el.bootstrapPopover('noMethod')
    }
    catch (err) {
      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($popover.data('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($('.popover').data('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)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
84
    var $popover = $('<a href="#">@fat</a>')
XhmikosR's avatar
XhmikosR committed
85
      .appendTo('#qunit-fixture')
86
      .bootstrapPopover({
XhmikosR's avatar
XhmikosR committed
87
88
89
90
91
92
        title: function () {
          return '@fat'
        },
        content: function () {
          return 'loves writing tests (╯°□°)╯︵ ┻━┻'
        }
93
94
      })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
95
    $popover.bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
96

97
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
Mark Otto's avatar
Mark Otto committed
98
99
    assert.strictEqual($('.popover .popover-header').text(), '@fat', 'title correctly inserted')
    assert.strictEqual($('.popover .popover-body').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
XhmikosR's avatar
XhmikosR committed
100

Heinrich Fenkart's avatar
Heinrich Fenkart committed
101
    $popover.bootstrapPopover('hide')
fat's avatar
fat committed
102

103
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
Stefan Neculai's avatar
Stefan Neculai committed
104
105
  })

106
107
108
109
110
111
112
113
114
115
116
  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')
      .bootstrapPopover({ html: true, title: title, content: content })

    $popover.bootstrapPopover('show')

    assert.notEqual($('.popover').length, 0, 'popover inserted')
Mark Otto's avatar
Mark Otto committed
117
    assert.strictEqual($('.popover .popover-header').text(), '@glebm <3 writing tests', 'title inserted')
118
119
    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
120
    assert.strictEqual($('.popover .popover-body').html().toLowerCase(), '<i>¯\\_(ツ)_/¯</i>', 'content inserted')
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    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')
      .bootstrapPopover({ title: title, content: content })

    $popover.bootstrapPopover('show')

    assert.notEqual($('.popover').length, 0, 'popover inserted')
Mark Otto's avatar
Mark Otto committed
135
    assert.strictEqual($('.popover .popover-header').text(), '@glebm <3 writing tests', 'title inserted')
136
    assert.ok(!$.contains($('.popover').get(0), title), 'title node copied, not moved')
Mark Otto's avatar
Mark Otto committed
137
    assert.strictEqual($('.popover .popover-body').html(), '¯\\_(ツ)_/¯', 'content inserted')
138
139
140
141
    assert.ok(!$.contains($('.popover').get(0), content), 'content node copied, not moved')
  })


142
  QUnit.test('should not duplicate HTML object', function (assert) {
143
    assert.expect(6)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
144
    var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
Stefan Neculai's avatar
Stefan Neculai committed
145

Heinrich Fenkart's avatar
Heinrich Fenkart committed
146
    var $popover = $('<a href="#">@fat</a>')
Stefan Neculai's avatar
Stefan Neculai committed
147
      .appendTo('#qunit-fixture')
148
      .bootstrapPopover({
fat's avatar
fat committed
149
        html: true,
Stefan Neculai's avatar
Stefan Neculai committed
150
151
152
153
154
        content: function () {
          return $div
        }
      })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
155
    $popover.bootstrapPopover('show')
156
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
Mark Otto's avatar
Mark Otto committed
157
    assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted')
Stefan Neculai's avatar
Stefan Neculai committed
158

Heinrich Fenkart's avatar
Heinrich Fenkart committed
159
    $popover.bootstrapPopover('hide')
160
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
Stefan Neculai's avatar
Stefan Neculai committed
161

Heinrich Fenkart's avatar
Heinrich Fenkart committed
162
    $popover.bootstrapPopover('show')
163
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
Mark Otto's avatar
Mark Otto committed
164
    assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted')
Stefan Neculai's avatar
Stefan Neculai committed
165

Heinrich Fenkart's avatar
Heinrich Fenkart committed
166
    $popover.bootstrapPopover('hide')
167
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
XhmikosR's avatar
XhmikosR committed
168
169
  })

170
  QUnit.test('should get title and content from attributes', function (assert) {
171
    assert.expect(4)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
172
    var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
XhmikosR's avatar
XhmikosR committed
173
      .appendTo('#qunit-fixture')
174
175
      .bootstrapPopover()
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
176

177
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
Mark Otto's avatar
Mark Otto committed
178
179
    assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
    assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
XhmikosR's avatar
XhmikosR committed
180

Heinrich Fenkart's avatar
Heinrich Fenkart committed
181
    $popover.bootstrapPopover('hide')
182
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
XhmikosR's avatar
XhmikosR committed
183
184
  })

185
  QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) {
186
    assert.expect(4)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
187
    var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
XhmikosR's avatar
XhmikosR committed
188
      .appendTo('#qunit-fixture')
189
      .bootstrapPopover({
XhmikosR's avatar
XhmikosR committed
190
191
        title: 'ignored title option',
        content: 'ignored content option'
192
      })
193
      .bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
194

195
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
Mark Otto's avatar
Mark Otto committed
196
197
    assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
    assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
XhmikosR's avatar
XhmikosR committed
198

Heinrich Fenkart's avatar
Heinrich Fenkart committed
199
    $popover.bootstrapPopover('hide')
200
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
XhmikosR's avatar
XhmikosR committed
201
202
  })

203
  QUnit.test('should respect custom template', function (assert) {
204
    assert.expect(3)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
205
    var $popover = $('<a href="#">@fat</a>')
XhmikosR's avatar
XhmikosR committed
206
      .appendTo('#qunit-fixture')
207
      .bootstrapPopover({
XhmikosR's avatar
XhmikosR committed
208
209
        title: 'Test',
        content: 'Test',
fat's avatar
fat committed
210
        template: '<div class="popover foobar"><div class="arrow"></div><div class="inner"><h3 class="title"/><div class="content"><p/></div></div></div>'
211
212
      })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
213
    $popover.bootstrapPopover('show')
XhmikosR's avatar
XhmikosR committed
214

215
216
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
    assert.ok($('.popover').hasClass('foobar'), 'custom class is present')
XhmikosR's avatar
XhmikosR committed
217

Heinrich Fenkart's avatar
Heinrich Fenkart committed
218
    $popover.bootstrapPopover('hide')
219
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
XhmikosR's avatar
XhmikosR committed
220
221
  })

222
  QUnit.test('should destroy popover', function (assert) {
223
    assert.expect(7)
fat's avatar
fat committed
224
    var $popover = $('<div/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
225
226
227
228
229
      .bootstrapPopover({
        trigger: 'hover'
      })
      .on('click.foo', $.noop)

230
231
    assert.ok($popover.data('bs.popover'), 'popover has data')
    assert.ok($._data($popover[0], 'events').mouseover && $._data($popover[0], 'events').mouseout, 'popover has hover event')
232
    assert.strictEqual($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover has extra click.foo event')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
233
234

    $popover.bootstrapPopover('show')
fat's avatar
fat committed
235
    $popover.bootstrapPopover('dispose')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
236

Starsam80's avatar
Starsam80 committed
237
    assert.ok(!$popover.hasClass('show'), 'popover is hidden')
238
    assert.ok(!$popover.data('popover'), 'popover does not have data')
239
    assert.strictEqual($._data($popover[0], 'events').click[0].namespace, 'foo', 'popover still has click.foo')
240
    assert.ok(!$._data($popover[0], 'events').mouseover && !$._data($popover[0], 'events').mouseout, 'popover does not have any events')
XhmikosR's avatar
XhmikosR committed
241
  })
242

243
  QUnit.test('should render popover element using delegated selector', function (assert) {
244
    assert.expect(2)
XhmikosR's avatar
XhmikosR committed
245
    var $div = $('<div><a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a></div>')
246
247
248
249
250
251
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
        selector: 'a',
        trigger: 'click'
      })

252
    $div.find('a').trigger('click')
253
    assert.notEqual($('.popover').length, 0, 'popover was inserted')
254

255
    $div.find('a').trigger('click')
256
    assert.strictEqual($('.popover').length, 0, 'popover was removed')
257
258
  })

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

263
    var handlerCalled = false
264
    $('.content-with-handler .btn').on('click', function () {
Chris Rebert's avatar
Chris Rebert committed
265
      handlerCalled = true
266
    })
Chris Rebert's avatar
Chris Rebert committed
267
268

    var $div = $('<div><a href="#">Show popover</a></div>')
269
270
      .appendTo('#qunit-fixture')
      .bootstrapPopover({
Chris Rebert's avatar
Chris Rebert committed
271
272
273
274
        html: true,
        trigger: 'manual',
        container: 'body',
        content: function () {
275
          return $content
Chris Rebert's avatar
Chris Rebert committed
276
        }
277
278
      })

279
    var done = assert.async()
Chris Rebert's avatar
Chris Rebert committed
280
281
282
283
284
285
    $div
      .one('shown.bs.popover', function () {
        $div
          .one('hidden.bs.popover', function () {
            $div
              .one('shown.bs.popover', function () {
286
                $('.content-with-handler .btn').trigger('click')
fat's avatar
fat committed
287
                $div.bootstrapPopover('dispose')
288
                assert.ok(handlerCalled, 'content\'s event handler still present')
289
                done()
Chris Rebert's avatar
Chris Rebert committed
290
291
292
293
294
295
              })
              .bootstrapPopover('show')
          })
          .bootstrapPopover('hide')
      })
      .bootstrapPopover('show')
296
  })
297

298
299
300
301
302
303
304
305
306
  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')
XhmikosR's avatar
XhmikosR committed
307
    assert.strictEqual(typeof $popover.data('bs.popover'), 'undefined', 'should not initialize the popover')
308
309
  })

fat's avatar
fat committed
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  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')
  })

328
329
330
331
332
333
334
335
336
337
338
339
  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')
    }
    catch (err) {
      assert.strictEqual(err.message, 'Please use show on visible elements')
      done()
    }
  })
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

  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')
  })
372
373
374
375
376
377
378
379
380
381
382

  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
383
384
        assert.strictEqual($('.popover .popover-header').text(), '5')
        assert.strictEqual($('.popover .popover-body').text(), '7')
385
386
387
388
389
        done()
      })

    $popover.bootstrapPopover('show')
  })
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

  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')
    $popover.trigger($.Event('click'))
    setTimeout(function () {
      assert.strictEqual($('.popover').length === 0, true)
      $popover.bootstrapPopover('enable')
      $popover.trigger($.Event('click'))
    }, 200)
  })
413
})