tooltip.js 29.5 KB
Newer Older
Jacob Thornton's avatar
Jacob Thornton committed
1
$(function () {
2
  'use strict'
Jacob Thornton's avatar
Jacob Thornton committed
3

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

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

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

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

fat's avatar
fat committed
48
49
  QUnit.test('should expose default settings', function (assert) {
    assert.expect(1)
50
    assert.ok($.fn.bootstrapTooltip.Constructor.Default, 'defaults is defined')
XhmikosR's avatar
XhmikosR committed
51
52
  })

fat's avatar
fat committed
53
54
  QUnit.test('should empty title attribute', function (assert) {
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
55
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
fat's avatar
fat committed
56
    assert.strictEqual($trigger.attr('title'), '', 'title attribute was emptied')
XhmikosR's avatar
XhmikosR committed
57
58
  })

fat's avatar
fat committed
59
60
  QUnit.test('should add data attribute for referencing original title', function (assert) {
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
61
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
fat's avatar
fat committed
62
    assert.strictEqual($trigger.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute')
XhmikosR's avatar
XhmikosR committed
63
64
  })

fat's avatar
fat committed
65
66
67
  QUnit.test('should add aria-describedby to the trigger on show', function (assert) {
    assert.expect(3)
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
68
      .bootstrapTooltip()
69
70
      .appendTo('#qunit-fixture')
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
71

72
73
    var id = $('.tooltip').attr('id')

fat's avatar
fat committed
74
75
76
    assert.strictEqual($('#' + id).length, 1, 'has a unique id')
    assert.strictEqual($('.tooltip').attr('aria-describedby'), $trigger.attr('id'), 'tooltip id and aria-describedby on trigger match')
    assert.ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
77
78
  })

fat's avatar
fat committed
79
80
81
  QUnit.test('should remove aria-describedby from trigger on hide', function (assert) {
    assert.expect(2)
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
82
      .bootstrapTooltip()
83
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
84
85

    $trigger.bootstrapTooltip('show')
fat's avatar
fat committed
86
    assert.ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
87
88

    $trigger.bootstrapTooltip('hide')
fat's avatar
fat committed
89
    assert.ok(!$trigger[0].hasAttribute('aria-describedby'), 'trigger does not have aria-describedby')
90
91
  })

fat's avatar
fat committed
92
93
94
  QUnit.test('should assign a unique id tooltip element', function (assert) {
    assert.expect(2)
    $('<a href="#" rel="tooltip" title="Another tooltip"/>')
95
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
96
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
97

XhmikosR's avatar
XhmikosR committed
98
    var id = $('.tooltip').attr('id')
99

fat's avatar
fat committed
100
101
    assert.strictEqual($('#' + id).length, 1, 'tooltip has unique id')
    assert.strictEqual(id.indexOf('tooltip'), 0, 'tooltip id has prefix')
102
103
  })

fat's avatar
fat committed
104
  QUnit.test('should place tooltips relative to placement option', function (assert) {
fat's avatar
fat committed
105
106
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
107
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
108
      .bootstrapTooltip({ placement: 'bottom' })
XhmikosR's avatar
XhmikosR committed
109

Heinrich Fenkart's avatar
Heinrich Fenkart committed
110
    $tooltip.bootstrapTooltip('show')
111
112
113

    assert
      .ok($('.tooltip')
Starsam80's avatar
Starsam80 committed
114
      .is('.fade.bs-tether-element-attached-top.bs-tether-element-attached-center.show'), 'has correct classes applied')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
115
116

    $tooltip.bootstrapTooltip('hide')
117
118

    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
119
120
  })

fat's avatar
fat committed
121
122
123
  QUnit.test('should allow html entities', function (assert) {
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip" title="&lt;b&gt;@fat&lt;/b&gt;"/>')
XhmikosR's avatar
XhmikosR committed
124
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
125
      .bootstrapTooltip({ html: true })
XhmikosR's avatar
XhmikosR committed
126

Heinrich Fenkart's avatar
Heinrich Fenkart committed
127
    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
128
    assert.notEqual($('.tooltip b').length, 0, 'b tag was inserted')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
129
130

    $tooltip.bootstrapTooltip('hide')
131
    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
132
133
  })

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  QUnit.test('should allow DOMElement title (html: false)', function (assert) {
    assert.expect(3)
    var title = document.createTextNode('<3 writing tests')
    var $tooltip = $('<a href="#" rel="tooltip"/>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({ title: title })

    $tooltip.bootstrapTooltip('show')

    assert.notEqual($('.tooltip').length, 0, 'tooltip inserted')
    assert.strictEqual($('.tooltip').text(), '<3 writing tests', 'title inserted')
    assert.ok(!$.contains($('.tooltip').get(0), title), 'title node copied, not moved')
  })

  QUnit.test('should allow DOMElement title (html: true)', function (assert) {
    assert.expect(3)
    var title = document.createTextNode('<3 writing tests')
    var $tooltip = $('<a href="#" rel="tooltip"/>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({ html: true, title: title })

    $tooltip.bootstrapTooltip('show')

    assert.notEqual($('.tooltip').length, 0, 'tooltip inserted')
    assert.strictEqual($('.tooltip').text(), '<3 writing tests', 'title inserted')
    assert.ok($.contains($('.tooltip').get(0), title), 'title node moved, not copied')
  })


fat's avatar
fat committed
163
164
165
  QUnit.test('should respect custom classes', function (assert) {
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
166
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
167
      .bootstrapTooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>' })
XhmikosR's avatar
XhmikosR committed
168

Heinrich Fenkart's avatar
Heinrich Fenkart committed
169
    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
170
    assert.ok($('.tooltip').hasClass('some-class'), 'custom class is present')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
171
172

    $tooltip.bootstrapTooltip('hide')
173
    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
174
175
  })

fat's avatar
fat committed
176
177
  QUnit.test('should fire show event', function (assert) {
    assert.expect(1)
178
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
179

fat's avatar
fat committed
180
    $('<div title="tooltip title"/>')
XhmikosR's avatar
XhmikosR committed
181
      .on('show.bs.tooltip', function () {
fat's avatar
fat committed
182
        assert.ok(true, 'show event fired')
183
        done()
XhmikosR's avatar
XhmikosR committed
184
      })
185
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
186
187
  })

188
189
190
191
192
193
194
195
196
197
198
199
200
  QUnit.test('should throw an error when show is called on hidden elements', function (assert) {
    assert.expect(1)
    var done = assert.async()

    try {
      $('<div title="tooltip title" style="display: none"/>').bootstrapTooltip('show')
    }
    catch (err) {
      assert.strictEqual(err.message, 'Please use show on visible elements')
      done()
    }
  })

fat's avatar
fat committed
201
202
  QUnit.test('should fire inserted event', function (assert) {
    assert.expect(2)
203
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
204

fat's avatar
fat committed
205
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
206
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
207
208
209
      .on('inserted.bs.tooltip', function () {
        assert.notEqual($('.tooltip').length, 0, 'tooltip was inserted')
        assert.ok(true, 'inserted event fired')
210
        done()
XhmikosR's avatar
XhmikosR committed
211
      })
212
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
213
214
  })

fat's avatar
fat committed
215
216
  QUnit.test('should fire shown event', function (assert) {
    assert.expect(1)
217
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
218

fat's avatar
fat committed
219
    $('<div title="tooltip title"></div>')
220
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
221
222
223
224
225
226
227
228
229
230
231
232
      .on('shown.bs.tooltip', function () {
        assert.ok(true, 'shown was called')
        done()
      })
      .bootstrapTooltip('show')
  })

  QUnit.test('should not fire shown event when show was prevented', function (assert) {
    assert.expect(1)
    var done = assert.async()

    $('<div title="tooltip title"/>')
XhmikosR's avatar
XhmikosR committed
233
234
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
fat's avatar
fat committed
235
        assert.ok(true, 'show event fired')
236
        done()
XhmikosR's avatar
XhmikosR committed
237
238
      })
      .on('shown.bs.tooltip', function () {
fat's avatar
fat committed
239
        assert.ok(false, 'shown event fired')
XhmikosR's avatar
XhmikosR committed
240
      })
241
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
242
243
  })

fat's avatar
fat committed
244
245
  QUnit.test('should fire hide event', function (assert) {
    assert.expect(1)
246
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
247

fat's avatar
fat committed
248
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
249
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
250
      .on('shown.bs.tooltip', function () {
251
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
252
253
      })
      .on('hide.bs.tooltip', function () {
fat's avatar
fat committed
254
        assert.ok(true, 'hide event fired')
255
        done()
XhmikosR's avatar
XhmikosR committed
256
      })
257
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
258
259
  })

fat's avatar
fat committed
260
261
  QUnit.test('should fire hidden event', function (assert) {
    assert.expect(1)
262
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
263

fat's avatar
fat committed
264
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
265
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
266
      .on('shown.bs.tooltip', function () {
267
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
268
269
      })
      .on('hidden.bs.tooltip', function () {
fat's avatar
fat committed
270
        assert.ok(true, 'hidden event fired')
271
        done()
XhmikosR's avatar
XhmikosR committed
272
      })
273
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
274
275
  })

fat's avatar
fat committed
276
277
  QUnit.test('should not fire hidden event when hide was prevented', function (assert) {
    assert.expect(1)
278
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
279

fat's avatar
fat committed
280
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
281
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
282
      .on('shown.bs.tooltip', function () {
283
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
284
285
286
      })
      .on('hide.bs.tooltip', function (e) {
        e.preventDefault()
fat's avatar
fat committed
287
        assert.ok(true, 'hide event fired')
288
        done()
XhmikosR's avatar
XhmikosR committed
289
290
      })
      .on('hidden.bs.tooltip', function () {
fat's avatar
fat committed
291
        assert.ok(false, 'hidden event fired')
XhmikosR's avatar
XhmikosR committed
292
      })
293
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
294
295
  })

fat's avatar
fat committed
296
297
298
  QUnit.test('should destroy tooltip', function (assert) {
    assert.expect(7)
    var $tooltip = $('<div/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
299
300
301
      .bootstrapTooltip()
      .on('click.foo', function () {})

fat's avatar
fat committed
302
303
304
    assert.ok($tooltip.data('bs.tooltip'), 'tooltip has data')
    assert.ok($._data($tooltip[0], 'events').mouseover && $._data($tooltip[0], 'events').mouseout, 'tooltip has hover events')
    assert.strictEqual($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip has extra click.foo event')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
305
306

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
307
    $tooltip.bootstrapTooltip('dispose')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
308

Starsam80's avatar
Starsam80 committed
309
    assert.ok(!$tooltip.hasClass('show'), 'tooltip is hidden')
fat's avatar
fat committed
310
311
312
    assert.ok(!$._data($tooltip[0], 'bs.tooltip'), 'tooltip does not have data')
    assert.strictEqual($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip still has click.foo')
    assert.ok(!$._data($tooltip[0], 'events').mouseover && !$._data($tooltip[0], 'events').mouseout, 'tooltip does not have hover events')
XhmikosR's avatar
XhmikosR committed
313
314
  })

315
316
317
318
319
320
321
322
  // QUnit.test('should show tooltip with delegate selector on click', function (assert) {
  //   assert.expect(2)
  //   var $div = $('<div><a href="#" rel="tooltip" title="Another tooltip"/></div>')
  //     .appendTo('#qunit-fixture')
  //     .bootstrapTooltip({
  //       selector: 'a[rel="tooltip"]',
  //       trigger: 'click'
  //     })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
323

324
325
  //   $div.find('a').trigger('click')
  //   assert.ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
326

327
328
329
  //   $div.find('a').trigger('click')
  //   assert.strictEqual($div.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
  // })
XhmikosR's avatar
XhmikosR committed
330

fat's avatar
fat committed
331
332
333
  QUnit.test('should show tooltip when toggle is called', function (assert) {
    assert.expect(1)
    $('<a href="#" rel="tooltip" title="tooltip on toggle"/>')
XhmikosR's avatar
XhmikosR committed
334
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
335
      .bootstrapTooltip({ trigger: 'manual' })
336
      .bootstrapTooltip('toggle')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
337

Starsam80's avatar
Starsam80 committed
338
    assert.ok($('.tooltip').is('.fade.show'), 'tooltip is faded active')
XhmikosR's avatar
XhmikosR committed
339
340
  })

fat's avatar
fat committed
341
342
  QUnit.test('should hide previously shown tooltip when toggle is called on tooltip', function (assert) {
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
343
    $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
344
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
345
      .bootstrapTooltip({ trigger: 'manual' })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
346
347
348
      .bootstrapTooltip('show')

    $('.tooltip').bootstrapTooltip('toggle')
Starsam80's avatar
Starsam80 committed
349
    assert.ok($('.tooltip').not('.fade.show'), 'tooltip was faded out')
350
351
  })

fat's avatar
fat committed
352
353
354
  QUnit.test('should place tooltips inside body when container is body', function (assert) {
    assert.expect(3)
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
355
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
356
      .bootstrapTooltip({ container: 'body' })
357
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
358

fat's avatar
fat committed
359
360
    assert.notEqual($('body > .tooltip').length, 0, 'tooltip is direct descendant of body')
    assert.strictEqual($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
361
362

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
363
    assert.strictEqual($('body > .tooltip').length, 0, 'tooltip was removed from dom')
XhmikosR's avatar
XhmikosR committed
364
365
  })

fat's avatar
fat committed
366
367
  QUnit.test('should add position class before positioning so that position-specific styles are taken into account', function (assert) {
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
368
    var styles = '<style>'
369
370
371
      + '.tooltip.right { white-space: nowrap; }'
      + '.tooltip.right .tooltip-inner { max-width: none; }'
      + '</style>'
372
    var $styles = $(styles).appendTo('head')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
373

fat's avatar
fat committed
374
    var $container = $('<div/>').appendTo('#qunit-fixture')
fat's avatar
fat committed
375
    var $target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
376
377
      .appendTo($container)
      .bootstrapTooltip({
378
        placement: 'right'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
379
380
      })
      .bootstrapTooltip('show')
381
382

    var $tooltip = $($target.data('bs.tooltip').tip)
XhmikosR's avatar
XhmikosR committed
383

384
    // this is some dumb hack stuff because sub pixels in firefox
385
    var top = Math.round($target.offset().top + $target[0].offsetHeight / 2 - $tooltip[0].offsetHeight / 2)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
386
    var top2 = Math.round($tooltip.offset().top)
XhmikosR's avatar
XhmikosR committed
387
    var topDiff = top - top2
fat's avatar
fat committed
388
    assert.ok(topDiff <= 1 && topDiff >= -1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
389
390
391
392
    $target.bootstrapTooltip('hide')

    $container.remove()
    $styles.remove()
XhmikosR's avatar
XhmikosR committed
393
394
  })

fat's avatar
fat committed
395
396
397
  QUnit.test('should use title attribute for tooltip text', function (assert) {
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
XhmikosR's avatar
XhmikosR committed
398
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
399
400
401
      .bootstrapTooltip()

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
402
    assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
403
404

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
405
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
406
407
  })

fat's avatar
fat committed
408
409
410
  QUnit.test('should prefer title attribute over title option', function (assert) {
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
XhmikosR's avatar
XhmikosR committed
411
      .appendTo('#qunit-fixture')
412
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
413
414
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
415
416

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
417
    assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while preferred over title option')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
418
419

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
420
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
421
422
  })

fat's avatar
fat committed
423
424
425
  QUnit.test('should use title option', function (assert) {
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip"/>')
XhmikosR's avatar
XhmikosR committed
426
      .appendTo('#qunit-fixture')
427
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
428
429
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
430
431

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
432
    assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
433
434

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
435
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
436
437
  })

438
  QUnit.test('should not error when trying to show an top-placed tooltip that has been removed from the dom', function (assert) {
fat's avatar
fat committed
439
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
440
    var passed = true
fat's avatar
fat committed
441
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
442
      .appendTo('#qunit-fixture')
Chris Rebert's avatar
Chris Rebert committed
443
      .one('show.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
444
        $(this).remove()
Chris Rebert's avatar
Chris Rebert committed
445
      })
fat's avatar
fat committed
446
      .bootstrapTooltip({ placement: 'top' })
Chris Rebert's avatar
Chris Rebert committed
447
448

    try {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
449
450
      $tooltip.bootstrapTooltip('show')
    } catch (err) {
Chris Rebert's avatar
Chris Rebert committed
451
452
453
454
      passed = false
      console.log(err)
    }

fat's avatar
fat committed
455
    assert.ok(passed, '.tooltip(\'show\') should not throw an error if element no longer is in dom')
Chris Rebert's avatar
Chris Rebert committed
456
  })
fat's avatar
fat committed
457

fat's avatar
fat committed
458
459
  QUnit.test('should place tooltip on top of element', function (assert) {
    assert.expect(1)
460
    var done = assert.async()
fat's avatar
fat committed
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

    var containerHTML = '<div>'
        + '<p style="margin-top: 200px">'
        + '<a href="#" title="very very very very very very very long tooltip">Hover me</a>'
        + '</p>'
        + '</div>'

    var $container = $(containerHTML)
      .css({
        position: 'absolute',
        bottom: 0,
        left: 0,
        textAlign: 'right',
        width: 300,
        height: 300
      })
      .appendTo('#qunit-fixture')

    var $trigger = $container
      .find('a')
      .css('margin-top', 200)
      .bootstrapTooltip({
fat's avatar
fat committed
483
        placement: 'top',
fat's avatar
fat committed
484
485
486
487
        animate: false
      })
      .bootstrapTooltip('show')

488
    var $tooltip = $($trigger.data('bs.tooltip').tip)
fat's avatar
fat committed
489
490

    setTimeout(function () {
fat's avatar
fat committed
491
      assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
492
      done()
fat's avatar
fat committed
493
494
495
    }, 0)
  })

fat's avatar
fat committed
496
497
  QUnit.test('should show tooltip if leave event hasn\'t occurred before delay expires', function (assert) {
    assert.expect(2)
498
    var done = assert.async()
fat's avatar
fat committed
499

fat's avatar
fat committed
500
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
501
      .appendTo('#qunit-fixture')
502
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
503
504

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
505
      assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip is not faded active')
506
    }, 100)
fat's avatar
fat committed
507
508

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
509
      assert.ok($('.tooltip').is('.fade.show'), '200ms: tooltip is faded active')
510
      done()
511
    }, 200)
fat's avatar
fat committed
512
513
514
515

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
516
517
  QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) {
    assert.expect(2)
518
    var done = assert.async()
fat's avatar
fat committed
519

fat's avatar
fat committed
520
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
521
      .appendTo('#qunit-fixture')
522
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
523
524

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
525
      assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip not faded active')
fat's avatar
fat committed
526
      $tooltip.trigger('mouseout')
527
    }, 100)
fat's avatar
fat committed
528
529

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
530
      assert.ok(!$('.tooltip').is('.fade.show'), '200ms: tooltip not faded active')
531
      done()
532
    }, 200)
fat's avatar
fat committed
533
534
535
536

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
537
538
  QUnit.test('should not hide tooltip if leave event occurs and enter event occurs within the hide delay', function (assert) {
    assert.expect(3)
539
    var done = assert.async()
fat's avatar
fat committed
540

fat's avatar
fat committed
541
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
542
      .appendTo('#qunit-fixture')
543
      .bootstrapTooltip({ delay: { show: 0, hide: 150 } })
fat's avatar
fat committed
544
545

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
546
      assert.ok($('.tooltip').is('.fade.show'), '1ms: tooltip faded active')
fat's avatar
fat committed
547
548
549
      $tooltip.trigger('mouseout')

      setTimeout(function () {
Starsam80's avatar
Starsam80 committed
550
        assert.ok($('.tooltip').is('.fade.show'), '100ms: tooltip still faded active')
fat's avatar
fat committed
551
        $tooltip.trigger('mouseenter')
552
      }, 100)
fat's avatar
fat committed
553
554

      setTimeout(function () {
Starsam80's avatar
Starsam80 committed
555
        assert.ok($('.tooltip').is('.fade.show'), '200ms: tooltip still faded active')
556
        done()
557
      }, 200)
fat's avatar
fat committed
558
559
560
561
562
    }, 0)

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
563
564
  QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) {
    assert.expect(2)
565
    var done = assert.async()
fat's avatar
fat committed
566

fat's avatar
fat committed
567
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
568
      .appendTo('#qunit-fixture')
569
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
570
571

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
572
      assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip not faded active')
fat's avatar
fat committed
573
      $tooltip.trigger('mouseout')
574
    }, 100)
fat's avatar
fat committed
575
576

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
577
      assert.ok(!$('.tooltip').is('.fade.show'), '200ms: tooltip not faded active')
578
      done()
579
    }, 200)
fat's avatar
fat committed
580
581
582
583

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
584
585
  QUnit.test('should not show tooltip if leave event occurs before delay expires, even if hide delay is 0', function (assert) {
    assert.expect(2)
586
    var done = assert.async()
fat's avatar
fat committed
587

fat's avatar
fat committed
588
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
589
      .appendTo('#qunit-fixture')
590
      .bootstrapTooltip({ delay: { show: 150, hide: 0 } })
fat's avatar
fat committed
591
592

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
593
      assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip not faded active')
fat's avatar
fat committed
594
      $tooltip.trigger('mouseout')
595
    }, 100)
fat's avatar
fat committed
596
597

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
598
      assert.ok(!$('.tooltip').is('.fade.show'), '250ms: tooltip not faded active')
599
      done()
600
    }, 250)
fat's avatar
fat committed
601
602
603
604

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
605
606
  QUnit.test('should wait 200ms before hiding the tooltip', function (assert) {
    assert.expect(3)
607
    var done = assert.async()
fat's avatar
fat committed
608

fat's avatar
fat committed
609
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
610
      .appendTo('#qunit-fixture')
611
      .bootstrapTooltip({ delay: { show: 0, hide: 150 } })
fat's avatar
fat committed
612
613

    setTimeout(function () {
Starsam80's avatar
Starsam80 committed
614
      assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.show'), '1ms: tooltip faded active')
fat's avatar
fat committed
615
616
617
618

      $tooltip.trigger('mouseout')

      setTimeout(function () {
Starsam80's avatar
Starsam80 committed
619
        assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.show'), '100ms: tooltip still faded active')
620
      }, 100)
fat's avatar
fat committed
621
622

      setTimeout(function () {
Starsam80's avatar
Starsam80 committed
623
        assert.ok(!$($tooltip.data('bs.tooltip').tip).is('.show'), '200ms: tooltip removed')
fat's avatar
fat committed
624
        done()
625
      }, 200)
fat's avatar
fat committed
626
627
628
629
630
631

    }, 0)

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
632
  QUnit.test('should correctly position tooltips on SVG elements', function (assert) {
633
634
    if (!window.SVGElement) {
      // Skip IE8 since it doesn't support SVG
fat's avatar
fat committed
635
      assert.expect(0)
636
637
      return
    }
fat's avatar
fat committed
638
    assert.expect(2)
639

640
    var done = assert.async()
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660

    var styles = '<style>'
        + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
        + '.tooltip { position: absolute; }'
        + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }'
        + '</style>'
    var $styles = $(styles).appendTo('head')

    $('#qunit-fixture').append(
        '<div style="position: fixed; top: 0; left: 0;">'
      + '  <svg width="200" height="200">'
      + '    <circle cx="100" cy="100" r="10" title="m" id="theCircle" />'
      + '  </svg>'
      + '</div>')
    var $circle = $('#theCircle')

    $circle
      .on('shown.bs.tooltip', function () {
        var offset = $('.tooltip').offset()
        $styles.remove()
fat's avatar
fat committed
661
        assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
662
        $circle.bootstrapTooltip('hide')
fat's avatar
fat committed
663
        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
664
        done()
665
      })
fat's avatar
fat committed
666
      .bootstrapTooltip({ placement: 'top', trigger: 'manual' })
667
668
669
670

    $circle.bootstrapTooltip('show')
  })

fat's avatar
fat committed
671
672
  QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) {
    assert.expect(1)
673
    var titleHtml = function () {
674
      var uid = Util.getUID('tooltip')
675
676
677
      return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
    }

fat's avatar
fat committed
678
    var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>')
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
      .appendTo('#qunit-fixture')

    $tooltip.bootstrapTooltip({
      html: true,
      animation: false,
      trigger: 'hover',
      delay: { show: 0, hide: 500 },
      container: $tooltip,
      title: titleHtml
    })

    $('#tt-outer').trigger('mouseenter')

    var currentUid = $('#tt-content').text()

    $('#tt-content').trigger('mouseenter')
fat's avatar
fat committed
695
    assert.strictEqual(currentUid, $('#tt-content').text())
696
697
  })

fat's avatar
fat committed
698
699
  QUnit.test('should not reload the tooltip if the mouse leaves and re-enters before hiding', function (assert) {
    assert.expect(4)
700

701
    var titleHtml = function () {
702
      var uid = Util.getUID('tooltip')
703
704
705
      return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
    }

fat's avatar
fat committed
706
    var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>')
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
      .appendTo('#qunit-fixture')

    $tooltip.bootstrapTooltip({
      html: true,
      animation: false,
      trigger: 'hover',
      delay: { show: 0, hide: 500 },
      title: titleHtml
    })

    var obj = $tooltip.data('bs.tooltip')

    $('#tt-outer').trigger('mouseenter')

    var currentUid = $('#tt-content').text()

    $('#tt-outer').trigger('mouseleave')
fat's avatar
fat committed
724
    assert.strictEqual(currentUid, $('#tt-content').text())
fat's avatar
fat committed
725

726
    assert.ok(obj._hoverState === 'out', 'the tooltip hoverState should be set to "out"')
727

728
    $('#tt-outer').trigger('mouseenter')
Starsam80's avatar
Starsam80 committed
729
    assert.ok(obj._hoverState === 'show', 'the tooltip hoverState should be set to "show"')
730

fat's avatar
fat committed
731
    assert.strictEqual(currentUid, $('#tt-content').text())
732
733
  })

fat's avatar
fat committed
734
  QUnit.test('should correctly position tooltips on transformed elements', function (assert) {
735
736
    var styleProps = document.documentElement.style
    if (!('transform' in styleProps) && !('webkitTransform' in styleProps) && !('msTransform' in styleProps)) {
fat's avatar
fat committed
737
      assert.expect(0)
738
739
      return
    }
fat's avatar
fat committed
740
    assert.expect(2)
741

742
    var done = assert.async()
743
744
745
746
747
748
749
750
751
752

    var styles = '<style>'
        + '#qunit-fixture { top: 0; left: 0; }'
        + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
        + '.tooltip { position: absolute; }'
        + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }'
        + '#target { position: absolute; top: 100px; left: 50px; width: 100px; height: 200px; -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); }'
        + '</style>'
    var $styles = $(styles).appendTo('head')

fat's avatar
fat committed
753
    var $element = $('<div id="target" title="1"/>').appendTo('#qunit-fixture')
754
755
756
757
758

    $element
      .on('shown.bs.tooltip', function () {
        var offset = $('.tooltip').offset()
        $styles.remove()
fat's avatar
fat committed
759
760
        assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
        assert.ok(Math.abs(offset.top - 126) <= 1, 'tooltip has correct vertical location')
761
        $element.bootstrapTooltip('hide')
762
        done()
763
764
765
766
767
768
769
770
      })
      .bootstrapTooltip({
        trigger: 'manual'
      })

    $element.bootstrapTooltip('show')
  })

fat's avatar
fat committed
771
  QUnit.test('should do nothing when an attempt is made to hide an uninitialized tooltip', function (assert) {
772
773
    assert.expect(1)

fat's avatar
fat committed
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
    var $tooltip = $('<span data-toggle="tooltip" title="some tip">some text</span>')
      .appendTo('#qunit-fixture')
      .on('hidden.bs.tooltip shown.bs.tooltip', function () {
        assert.ok(false, 'should not fire any tooltip events')
      })
      .bootstrapTooltip('hide')
    assert.strictEqual($tooltip.data('bs.tooltip'), undefined, 'should not initialize the tooltip')
  })

  QUnit.test('should not remove tooltip if multiple triggers are set and one is still active', function (assert) {
    assert.expect(41)
    var $el = $('<button>Trigger</button>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({ trigger: 'click hover focus', animation: false })
    var tooltip = $el.data('bs.tooltip')
789
    var $tooltip = $(tooltip.getTipElement())
fat's avatar
fat committed
790

Starsam80's avatar
Starsam80 committed
791
    function showingTooltip() { return $tooltip.hasClass('show') || tooltip._hoverState === 'show' }
fat's avatar
fat committed
792
793
794

    var tests = [
        ['mouseenter', 'mouseleave'],
795

fat's avatar
fat committed
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
        ['focusin', 'focusout'],

        ['click', 'click'],

        ['mouseenter', 'focusin', 'focusout', 'mouseleave'],
        ['mouseenter', 'focusin', 'mouseleave', 'focusout'],

        ['focusin', 'mouseenter', 'mouseleave', 'focusout'],
        ['focusin', 'mouseenter', 'focusout', 'mouseleave'],

        ['click', 'focusin', 'mouseenter', 'focusout', 'mouseleave', 'click'],
        ['mouseenter', 'click', 'focusin', 'focusout', 'mouseleave', 'click'],
        ['mouseenter', 'focusin', 'click', 'click', 'mouseleave', 'focusout']
    ]

    assert.ok(!showingTooltip())

    $.each(tests, function (idx, triggers) {
      for (var i = 0, len = triggers.length; i < len; i++) {
815
816
        $el.trigger(triggers[i])
        assert.equal(i < len - 1, showingTooltip())
fat's avatar
fat committed
817
818
      }
    })
819
820
  })

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
  QUnit.test('should show on first trigger after hide', function (assert) {
    assert.expect(3)
    var $el = $('<a href="#" rel="tooltip" title="Test tooltip"/>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({ trigger: 'click hover focus', animation: false })

    var tooltip = $el.data('bs.tooltip')
    var $tooltip = $(tooltip.getTipElement())

    function showingTooltip() { return $tooltip.hasClass('show') || tooltip._hoverState === 'show' }

    $el.trigger('click')
    assert.ok(showingTooltip(), 'tooltip is faded in')

    $el.bootstrapTooltip('hide')
    assert.ok(!showingTooltip(), 'tooltip was faded out')

    $el.trigger('click')
    assert.ok(showingTooltip(), 'tooltip is faded in again')
  })

842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
  QUnit.test('should hide tooltip 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">' +
                                '<a id="tooltipTest" href="#" data-toggle="tooltip" title="Some tooltip text!">Tooltip</a>' +
                              '</div>' +
                            '</div>' +
                          '</div>' +
                        '</div>'

    $(templateHTML).appendTo('#qunit-fixture')
    $('#tooltipTest')
      .bootstrapTooltip({ trigger: 'manuel' })
      .on('shown.bs.tooltip', function () {
        $('#modal-test').modal('hide')
      })
      .on('hide.bs.tooltip', function () {
        assert.ok(true, 'tooltip hide')
        done()
      })

    $('#modal-test')
      .on('shown.bs.modal', function () {
        $('#tooltipTest').bootstrapTooltip('show')
      })
      .modal('show')
  })
872
})