tooltip.js 27.3 KB
Newer Older
Jacob Thornton's avatar
Jacob Thornton committed
1
$(function () {
XhmikosR's avatar
XhmikosR committed
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')
114
      .is('.fade.bs-tether-element-attached-top.bs-tether-element-attached-center.active'), '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
  })

fat's avatar
fat committed
188
189
  QUnit.test('should fire inserted event', function (assert) {
    assert.expect(2)
190
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
191

fat's avatar
fat committed
192
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
193
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
194
195
196
      .on('inserted.bs.tooltip', function () {
        assert.notEqual($('.tooltip').length, 0, 'tooltip was inserted')
        assert.ok(true, 'inserted event fired')
197
        done()
XhmikosR's avatar
XhmikosR committed
198
      })
199
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
200
201
  })

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

fat's avatar
fat committed
206
    $('<div title="tooltip title"></div>')
207
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
208
209
210
211
212
213
214
215
216
217
218
219
      .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
220
221
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
fat's avatar
fat committed
222
        assert.ok(true, 'show event fired')
223
        done()
XhmikosR's avatar
XhmikosR committed
224
225
      })
      .on('shown.bs.tooltip', function () {
fat's avatar
fat committed
226
        assert.ok(false, 'shown event fired')
XhmikosR's avatar
XhmikosR committed
227
      })
228
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
229
230
  })

fat's avatar
fat committed
231
232
  QUnit.test('should fire hide event', function (assert) {
    assert.expect(1)
233
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
234

fat's avatar
fat committed
235
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
236
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
237
      .on('shown.bs.tooltip', function () {
238
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
239
240
      })
      .on('hide.bs.tooltip', function () {
fat's avatar
fat committed
241
        assert.ok(true, 'hide event fired')
242
        done()
XhmikosR's avatar
XhmikosR committed
243
      })
244
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
245
246
  })

fat's avatar
fat committed
247
248
  QUnit.test('should fire hidden event', function (assert) {
    assert.expect(1)
249
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
250

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

fat's avatar
fat committed
263
264
  QUnit.test('should not fire hidden event when hide was prevented', function (assert) {
    assert.expect(1)
265
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
266

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

fat's avatar
fat committed
283
284
285
  QUnit.test('should destroy tooltip', function (assert) {
    assert.expect(7)
    var $tooltip = $('<div/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
286
287
288
      .bootstrapTooltip()
      .on('click.foo', function () {})

fat's avatar
fat committed
289
290
291
    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
292
293

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
294
    $tooltip.bootstrapTooltip('dispose')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
295

296
    assert.ok(!$tooltip.hasClass('active'), 'tooltip is hidden')
fat's avatar
fat committed
297
298
299
    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
300
301
  })

302
303
304
305
306
307
308
309
  // 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
310

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

314
315
316
  //   $div.find('a').trigger('click')
  //   assert.strictEqual($div.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
  // })
XhmikosR's avatar
XhmikosR committed
317

fat's avatar
fat committed
318
319
320
  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
321
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
322
      .bootstrapTooltip({ trigger: 'manual' })
323
      .bootstrapTooltip('toggle')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
324

325
    assert.ok($('.tooltip').is('.fade.active'), 'tooltip is faded active')
XhmikosR's avatar
XhmikosR committed
326
327
  })

fat's avatar
fat committed
328
329
  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
330
    $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
331
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
332
      .bootstrapTooltip({ trigger: 'manual' })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
333
334
335
      .bootstrapTooltip('show')

    $('.tooltip').bootstrapTooltip('toggle')
336
    assert.ok($('.tooltip').not('.fade.active'), 'tooltip was faded out')
337
338
  })

fat's avatar
fat committed
339
340
341
  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
342
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
343
      .bootstrapTooltip({ container: 'body' })
344
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
345

fat's avatar
fat committed
346
347
    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
348
349

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

fat's avatar
fat committed
353
354
  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
355
    var styles = '<style>'
356
357
358
      + '.tooltip.right { white-space: nowrap; }'
      + '.tooltip.right .tooltip-inner { max-width: none; }'
      + '</style>'
359
    var $styles = $(styles).appendTo('head')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
360

fat's avatar
fat committed
361
    var $container = $('<div/>').appendTo('#qunit-fixture')
fat's avatar
fat committed
362
    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
363
364
      .appendTo($container)
      .bootstrapTooltip({
365
        placement: 'right'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
366
367
      })
      .bootstrapTooltip('show')
368
369

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

371
    // this is some dumb hack stuff because sub pixels in firefox
Heinrich Fenkart's avatar
Heinrich Fenkart committed
372
373
    var top = Math.round($target.offset().top + ($target[0].offsetHeight / 2) - ($tooltip[0].offsetHeight / 2))
    var top2 = Math.round($tooltip.offset().top)
XhmikosR's avatar
XhmikosR committed
374
    var topDiff = top - top2
fat's avatar
fat committed
375
    assert.ok(topDiff <= 1 && topDiff >= -1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
376
377
378
379
    $target.bootstrapTooltip('hide')

    $container.remove()
    $styles.remove()
XhmikosR's avatar
XhmikosR committed
380
381
  })

fat's avatar
fat committed
382
383
384
  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
385
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
386
387
388
      .bootstrapTooltip()

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

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
392
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
393
394
  })

fat's avatar
fat committed
395
396
397
  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
398
      .appendTo('#qunit-fixture')
399
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
400
401
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
402
403

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
404
    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
405
406

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

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

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
419
    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
420
421

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
422
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
423
424
  })

425
  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
426
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
427
    var passed = true
fat's avatar
fat committed
428
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
429
      .appendTo('#qunit-fixture')
Chris Rebert's avatar
Chris Rebert committed
430
      .one('show.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
431
        $(this).remove()
Chris Rebert's avatar
Chris Rebert committed
432
      })
fat's avatar
fat committed
433
      .bootstrapTooltip({ placement: 'top' })
Chris Rebert's avatar
Chris Rebert committed
434
435

    try {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
436
437
      $tooltip.bootstrapTooltip('show')
    } catch (err) {
Chris Rebert's avatar
Chris Rebert committed
438
439
440
441
      passed = false
      console.log(err)
    }

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

fat's avatar
fat committed
445
446
  QUnit.test('should place tooltip on top of element', function (assert) {
    assert.expect(1)
447
    var done = assert.async()
fat's avatar
fat committed
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

    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
470
        placement: 'top',
fat's avatar
fat committed
471
472
473
474
        animate: false
      })
      .bootstrapTooltip('show')

475
    var $tooltip = $($trigger.data('bs.tooltip').tip)
fat's avatar
fat committed
476
477

    setTimeout(function () {
fat's avatar
fat committed
478
      assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
479
      done()
fat's avatar
fat committed
480
481
482
    }, 0)
  })

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

fat's avatar
fat committed
487
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
488
      .appendTo('#qunit-fixture')
489
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
490
491

    setTimeout(function () {
492
      assert.ok(!$('.tooltip').is('.fade.active'), '100ms: tooltip is not faded active')
493
    }, 100)
fat's avatar
fat committed
494
495

    setTimeout(function () {
496
      assert.ok($('.tooltip').is('.fade.active'), '200ms: tooltip is faded active')
497
      done()
498
    }, 200)
fat's avatar
fat committed
499
500
501
502

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
503
504
  QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) {
    assert.expect(2)
505
    var done = assert.async()
fat's avatar
fat committed
506

fat's avatar
fat committed
507
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
508
      .appendTo('#qunit-fixture')
509
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
510
511

    setTimeout(function () {
512
      assert.ok(!$('.tooltip').is('.fade.active'), '100ms: tooltip not faded active')
fat's avatar
fat committed
513
      $tooltip.trigger('mouseout')
514
    }, 100)
fat's avatar
fat committed
515
516

    setTimeout(function () {
517
      assert.ok(!$('.tooltip').is('.fade.active'), '200ms: tooltip not faded active')
518
      done()
519
    }, 200)
fat's avatar
fat committed
520
521
522
523

    $tooltip.trigger('mouseenter')
  })

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

fat's avatar
fat committed
528
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
529
      .appendTo('#qunit-fixture')
530
      .bootstrapTooltip({ delay: { show: 0, hide: 150 }})
fat's avatar
fat committed
531
532

    setTimeout(function () {
533
      assert.ok($('.tooltip').is('.fade.active'), '1ms: tooltip faded active')
fat's avatar
fat committed
534
535
536
      $tooltip.trigger('mouseout')

      setTimeout(function () {
537
        assert.ok($('.tooltip').is('.fade.active'), '100ms: tooltip still faded active')
fat's avatar
fat committed
538
        $tooltip.trigger('mouseenter')
539
      }, 100)
fat's avatar
fat committed
540
541

      setTimeout(function () {
542
        assert.ok($('.tooltip').is('.fade.active'), '200ms: tooltip still faded active')
543
        done()
544
      }, 200)
fat's avatar
fat committed
545
546
547
548
549
    }, 0)

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
550
551
  QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) {
    assert.expect(2)
552
    var done = assert.async()
fat's avatar
fat committed
553

fat's avatar
fat committed
554
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
555
      .appendTo('#qunit-fixture')
556
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
557
558

    setTimeout(function () {
559
      assert.ok(!$('.tooltip').is('.fade.active'), '100ms: tooltip not faded active')
fat's avatar
fat committed
560
      $tooltip.trigger('mouseout')
561
    }, 100)
fat's avatar
fat committed
562
563

    setTimeout(function () {
564
      assert.ok(!$('.tooltip').is('.fade.active'), '200ms: tooltip not faded active')
565
      done()
566
    }, 200)
fat's avatar
fat committed
567
568
569
570

    $tooltip.trigger('mouseenter')
  })

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

fat's avatar
fat committed
575
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
576
      .appendTo('#qunit-fixture')
577
      .bootstrapTooltip({ delay: { show: 150, hide: 0 }})
fat's avatar
fat committed
578
579

    setTimeout(function () {
580
      assert.ok(!$('.tooltip').is('.fade.active'), '100ms: tooltip not faded active')
fat's avatar
fat committed
581
      $tooltip.trigger('mouseout')
582
    }, 100)
fat's avatar
fat committed
583
584

    setTimeout(function () {
585
      assert.ok(!$('.tooltip').is('.fade.active'), '250ms: tooltip not faded active')
586
      done()
587
    }, 250)
fat's avatar
fat committed
588
589
590
591

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
592
593
  QUnit.test('should wait 200ms before hiding the tooltip', function (assert) {
    assert.expect(3)
594
    var done = assert.async()
fat's avatar
fat committed
595

fat's avatar
fat committed
596
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
597
      .appendTo('#qunit-fixture')
598
      .bootstrapTooltip({ delay: { show: 0, hide: 150 }})
fat's avatar
fat committed
599
600

    setTimeout(function () {
601
      assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.active'), '1ms: tooltip faded active')
fat's avatar
fat committed
602
603
604
605

      $tooltip.trigger('mouseout')

      setTimeout(function () {
606
        assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.active'), '100ms: tooltip still faded active')
607
      }, 100)
fat's avatar
fat committed
608
609

      setTimeout(function () {
610
        assert.ok(!$($tooltip.data('bs.tooltip').tip).is('.active'), '200ms: tooltip removed')
fat's avatar
fat committed
611
        done()
612
      }, 200)
fat's avatar
fat committed
613
614
615
616
617
618

    }, 0)

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
619
  QUnit.test('should correctly position tooltips on SVG elements', function (assert) {
620
621
    if (!window.SVGElement) {
      // Skip IE8 since it doesn't support SVG
fat's avatar
fat committed
622
      assert.expect(0)
623
624
      return
    }
fat's avatar
fat committed
625
    assert.expect(2)
626

627
    var done = assert.async()
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

    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
648
        assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
649
        $circle.bootstrapTooltip('hide')
fat's avatar
fat committed
650
        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
651
        done()
652
      })
fat's avatar
fat committed
653
      .bootstrapTooltip({ placement: 'top', trigger: 'manual' })
654
655
656
657

    $circle.bootstrapTooltip('show')
  })

fat's avatar
fat committed
658
659
  QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) {
    assert.expect(1)
660
    var titleHtml = function () {
661
      var uid = Util.getUID('tooltip')
662
663
664
      return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
    }

fat's avatar
fat committed
665
    var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>')
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
      .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
682
    assert.strictEqual(currentUid, $('#tt-content').text())
683
684
  })

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

688
    var titleHtml = function () {
689
      var uid = Util.getUID('tooltip')
690
691
692
      return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
    }

fat's avatar
fat committed
693
    var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>')
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
      .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
711
    assert.strictEqual(currentUid, $('#tt-content').text())
fat's avatar
fat committed
712

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

715
    $('#tt-outer').trigger('mouseenter')
716
    assert.ok(obj._hoverState == 'active', 'the tooltip hoverState should be set to "active"')
717

fat's avatar
fat committed
718
    assert.strictEqual(currentUid, $('#tt-content').text())
719
720
  })

fat's avatar
fat committed
721
  QUnit.test('should correctly position tooltips on transformed elements', function (assert) {
722
723
    var styleProps = document.documentElement.style
    if (!('transform' in styleProps) && !('webkitTransform' in styleProps) && !('msTransform' in styleProps)) {
fat's avatar
fat committed
724
      assert.expect(0)
725
726
      return
    }
fat's avatar
fat committed
727
    assert.expect(2)
728

729
    var done = assert.async()
730
731
732
733
734
735
736
737
738
739

    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
740
    var $element = $('<div id="target" title="1"/>').appendTo('#qunit-fixture')
741
742
743
744
745

    $element
      .on('shown.bs.tooltip', function () {
        var offset = $('.tooltip').offset()
        $styles.remove()
fat's avatar
fat committed
746
747
        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')
748
        $element.bootstrapTooltip('hide')
749
        done()
750
751
752
753
754
755
756
757
      })
      .bootstrapTooltip({
        trigger: 'manual'
      })

    $element.bootstrapTooltip('show')
  })

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

fat's avatar
fat committed
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
    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')
776
    var $tooltip = $(tooltip.getTipElement())
fat's avatar
fat committed
777

778
    function showingTooltip() { return $tooltip.hasClass('active') || tooltip._hoverState == 'active' }
fat's avatar
fat committed
779
780
781

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

fat's avatar
fat committed
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
        ['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++) {
        $el.trigger(triggers[i]);
        assert.equal(i < (len - 1), showingTooltip())
      }
    })
806
807
  })

808
})