tooltip.js 26.9 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
  })

fat's avatar
fat committed
28
29
  QUnit.test('should return jquery collection containing the element', function (assert) {
    assert.expect(2)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
30
31
    var $el = $('<div/>')
    var $tooltip = $el.bootstrapTooltip()
fat's avatar
fat committed
32
33
    assert.ok($tooltip instanceof $, 'returns jquery collection')
    assert.strictEqual($tooltip[0], $el[0], 'collection contains element')
XhmikosR's avatar
XhmikosR committed
34
35
  })

fat's avatar
fat committed
36
37
  QUnit.test('should expose default settings', function (assert) {
    assert.expect(1)
38
    assert.ok($.fn.bootstrapTooltip.Constructor.Default, 'defaults is defined')
XhmikosR's avatar
XhmikosR committed
39
40
  })

fat's avatar
fat committed
41
42
  QUnit.test('should empty title attribute', function (assert) {
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
43
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
fat's avatar
fat committed
44
    assert.strictEqual($trigger.attr('title'), '', 'title attribute was emptied')
XhmikosR's avatar
XhmikosR committed
45
46
  })

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

fat's avatar
fat committed
53
54
55
  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
56
      .bootstrapTooltip()
57
58
      .appendTo('#qunit-fixture')
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
59

60
61
    var id = $('.tooltip').attr('id')

fat's avatar
fat committed
62
63
64
    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')
65
66
  })

fat's avatar
fat committed
67
68
69
  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
70
      .bootstrapTooltip()
71
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
72
73

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

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

fat's avatar
fat committed
80
81
82
  QUnit.test('should assign a unique id tooltip element', function (assert) {
    assert.expect(2)
    $('<a href="#" rel="tooltip" title="Another tooltip"/>')
83
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
84
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
85

XhmikosR's avatar
XhmikosR committed
86
    var id = $('.tooltip').attr('id')
87

fat's avatar
fat committed
88
89
    assert.strictEqual($('#' + id).length, 1, 'tooltip has unique id')
    assert.strictEqual(id.indexOf('tooltip'), 0, 'tooltip id has prefix')
90
91
  })

fat's avatar
fat committed
92
  QUnit.test('should place tooltips relative to placement option', function (assert) {
fat's avatar
fat committed
93
94
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
95
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
96
      .bootstrapTooltip({ placement: 'bottom' })
XhmikosR's avatar
XhmikosR committed
97

Heinrich Fenkart's avatar
Heinrich Fenkart committed
98
    $tooltip.bootstrapTooltip('show')
99
100
101
102

    assert
      .ok($('.tooltip')
      .is('.fade.bs-tether-element-attached-top.bs-tether-element-attached-center.in'), 'has correct classes applied')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
103
104

    $tooltip.bootstrapTooltip('hide')
105
106

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

fat's avatar
fat committed
109
110
111
  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
112
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
113
      .bootstrapTooltip({ html: true })
XhmikosR's avatar
XhmikosR committed
114

Heinrich Fenkart's avatar
Heinrich Fenkart committed
115
    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
116
    assert.notEqual($('.tooltip b').length, 0, 'b tag was inserted')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
117
118

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

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  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
151
152
153
  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
154
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
155
      .bootstrapTooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>' })
XhmikosR's avatar
XhmikosR committed
156

Heinrich Fenkart's avatar
Heinrich Fenkart committed
157
    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
158
    assert.ok($('.tooltip').hasClass('some-class'), 'custom class is present')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
159
160

    $tooltip.bootstrapTooltip('hide')
161
    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
162
163
  })

fat's avatar
fat committed
164
165
  QUnit.test('should fire show event', function (assert) {
    assert.expect(1)
166
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
167

fat's avatar
fat committed
168
    $('<div title="tooltip title"/>')
XhmikosR's avatar
XhmikosR committed
169
      .on('show.bs.tooltip', function () {
fat's avatar
fat committed
170
        assert.ok(true, 'show event fired')
171
        done()
XhmikosR's avatar
XhmikosR committed
172
      })
173
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
174
175
  })

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

fat's avatar
fat committed
180
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
181
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
182
183
184
      .on('inserted.bs.tooltip', function () {
        assert.notEqual($('.tooltip').length, 0, 'tooltip was inserted')
        assert.ok(true, 'inserted event fired')
185
        done()
XhmikosR's avatar
XhmikosR committed
186
      })
187
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
188
189
  })

fat's avatar
fat committed
190
191
  QUnit.test('should fire shown event', function (assert) {
    assert.expect(1)
192
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
193

fat's avatar
fat committed
194
    $('<div title="tooltip title"></div>')
195
      .appendTo('#qunit-fixture')
fat's avatar
fat committed
196
197
198
199
200
201
202
203
204
205
206
207
      .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
208
209
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
fat's avatar
fat committed
210
        assert.ok(true, 'show event fired')
211
        done()
XhmikosR's avatar
XhmikosR committed
212
213
      })
      .on('shown.bs.tooltip', function () {
fat's avatar
fat committed
214
        assert.ok(false, 'shown event fired')
XhmikosR's avatar
XhmikosR committed
215
      })
216
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
217
218
  })

fat's avatar
fat committed
219
220
  QUnit.test('should fire hide event', function (assert) {
    assert.expect(1)
221
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
222

fat's avatar
fat committed
223
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
224
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
225
      .on('shown.bs.tooltip', function () {
226
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
227
228
      })
      .on('hide.bs.tooltip', function () {
fat's avatar
fat committed
229
        assert.ok(true, 'hide event fired')
230
        done()
XhmikosR's avatar
XhmikosR committed
231
      })
232
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
233
234
  })

fat's avatar
fat committed
235
236
  QUnit.test('should fire hidden event', function (assert) {
    assert.expect(1)
237
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
238

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

fat's avatar
fat committed
251
252
  QUnit.test('should not fire hidden event when hide was prevented', function (assert) {
    assert.expect(1)
253
    var done = assert.async()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
254

fat's avatar
fat committed
255
    $('<div title="tooltip title"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
256
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
257
      .on('shown.bs.tooltip', function () {
258
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
259
260
261
      })
      .on('hide.bs.tooltip', function (e) {
        e.preventDefault()
fat's avatar
fat committed
262
        assert.ok(true, 'hide event fired')
263
        done()
XhmikosR's avatar
XhmikosR committed
264
265
      })
      .on('hidden.bs.tooltip', function () {
fat's avatar
fat committed
266
        assert.ok(false, 'hidden event fired')
XhmikosR's avatar
XhmikosR committed
267
      })
268
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
269
270
  })

fat's avatar
fat committed
271
272
273
  QUnit.test('should destroy tooltip', function (assert) {
    assert.expect(7)
    var $tooltip = $('<div/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
274
275
276
      .bootstrapTooltip()
      .on('click.foo', function () {})

fat's avatar
fat committed
277
278
279
    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
280
281

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
282
    $tooltip.bootstrapTooltip('dispose')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
283

fat's avatar
fat committed
284
285
286
287
    assert.ok(!$tooltip.hasClass('in'), 'tooltip is hidden')
    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
288
289
  })

290
291
292
293
294
295
296
297
  // 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
298

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

302
303
304
  //   $div.find('a').trigger('click')
  //   assert.strictEqual($div.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
  // })
XhmikosR's avatar
XhmikosR committed
305

fat's avatar
fat committed
306
307
308
  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
309
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
310
      .bootstrapTooltip({ trigger: 'manual' })
311
      .bootstrapTooltip('toggle')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
312

fat's avatar
fat committed
313
    assert.ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
XhmikosR's avatar
XhmikosR committed
314
315
  })

fat's avatar
fat committed
316
317
  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
318
    $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
319
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
320
      .bootstrapTooltip({ trigger: 'manual' })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
321
322
323
      .bootstrapTooltip('show')

    $('.tooltip').bootstrapTooltip('toggle')
fat's avatar
fat committed
324
    assert.ok($('.tooltip').not('.fade.in'), 'tooltip was faded out')
325
326
  })

fat's avatar
fat committed
327
328
329
  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
330
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
331
      .bootstrapTooltip({ container: 'body' })
332
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
333

fat's avatar
fat committed
334
335
    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
336
337

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

fat's avatar
fat committed
341
342
  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
343
    var styles = '<style>'
344
345
346
      + '.tooltip.right { white-space: nowrap; }'
      + '.tooltip.right .tooltip-inner { max-width: none; }'
      + '</style>'
347
    var $styles = $(styles).appendTo('head')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
348

fat's avatar
fat committed
349
    var $container = $('<div/>').appendTo('#qunit-fixture')
fat's avatar
fat committed
350
    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
351
352
      .appendTo($container)
      .bootstrapTooltip({
353
        placement: 'right'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
354
355
      })
      .bootstrapTooltip('show')
356
357

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

    // this is some dumb hack shit because sub pixels in firefox
Heinrich Fenkart's avatar
Heinrich Fenkart committed
360
361
    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
362
    var topDiff = top - top2
fat's avatar
fat committed
363
    assert.ok(topDiff <= 1 && topDiff >= -1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
364
365
366
367
    $target.bootstrapTooltip('hide')

    $container.remove()
    $styles.remove()
XhmikosR's avatar
XhmikosR committed
368
369
  })

fat's avatar
fat committed
370
371
372
  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
373
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
374
375
376
      .bootstrapTooltip()

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

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
380
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
381
382
  })

fat's avatar
fat committed
383
384
385
  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
386
      .appendTo('#qunit-fixture')
387
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
388
389
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
390
391

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
392
    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
393
394

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
395
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
396
397
  })

fat's avatar
fat committed
398
399
400
  QUnit.test('should use title option', function (assert) {
    assert.expect(2)
    var $tooltip = $('<a href="#" rel="tooltip"/>')
XhmikosR's avatar
XhmikosR committed
401
      .appendTo('#qunit-fixture')
402
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
403
404
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
405
406

    $tooltip.bootstrapTooltip('show')
fat's avatar
fat committed
407
    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
408
409

    $tooltip.bootstrapTooltip('hide')
fat's avatar
fat committed
410
    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
411
412
  })

413
  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
414
    assert.expect(1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
415
    var passed = true
fat's avatar
fat committed
416
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
417
      .appendTo('#qunit-fixture')
Chris Rebert's avatar
Chris Rebert committed
418
      .one('show.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
419
        $(this).remove()
Chris Rebert's avatar
Chris Rebert committed
420
      })
fat's avatar
fat committed
421
      .bootstrapTooltip({ placement: 'top' })
Chris Rebert's avatar
Chris Rebert committed
422
423

    try {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
424
425
      $tooltip.bootstrapTooltip('show')
    } catch (err) {
Chris Rebert's avatar
Chris Rebert committed
426
427
428
429
      passed = false
      console.log(err)
    }

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

fat's avatar
fat committed
433
434
  QUnit.test('should place tooltip on top of element', function (assert) {
    assert.expect(1)
435
    var done = assert.async()
fat's avatar
fat committed
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

    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
458
        placement: 'top',
fat's avatar
fat committed
459
460
461
462
        animate: false
      })
      .bootstrapTooltip('show')

463
    var $tooltip = $($trigger.data('bs.tooltip').tip)
fat's avatar
fat committed
464
465

    setTimeout(function () {
fat's avatar
fat committed
466
      assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
467
      done()
fat's avatar
fat committed
468
469
470
    }, 0)
  })

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

fat's avatar
fat committed
475
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
476
      .appendTo('#qunit-fixture')
477
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
478
479

    setTimeout(function () {
fat's avatar
fat committed
480
      assert.ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip is not faded in')
481
    }, 100)
fat's avatar
fat committed
482
483

    setTimeout(function () {
fat's avatar
fat committed
484
      assert.ok($('.tooltip').is('.fade.in'), '200ms: tooltip is faded in')
485
      done()
486
    }, 200)
fat's avatar
fat committed
487
488
489
490

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
491
492
  QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) {
    assert.expect(2)
493
    var done = assert.async()
fat's avatar
fat committed
494

fat's avatar
fat committed
495
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
496
      .appendTo('#qunit-fixture')
497
      .bootstrapTooltip({ delay: 150 })
fat's avatar
fat committed
498
499

    setTimeout(function () {
fat's avatar
fat committed
500
      assert.ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip not faded in')
fat's avatar
fat committed
501
      $tooltip.trigger('mouseout')
502
    }, 100)
fat's avatar
fat committed
503
504

    setTimeout(function () {
fat's avatar
fat committed
505
      assert.ok(!$('.tooltip').is('.fade.in'), '200ms: tooltip not faded in')
506
      done()
507
    }, 200)
fat's avatar
fat committed
508
509
510
511

    $tooltip.trigger('mouseenter')
  })

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

fat's avatar
fat committed
516
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
517
      .appendTo('#qunit-fixture')
518
      .bootstrapTooltip({ delay: { show: 0, hide: 150 }})
fat's avatar
fat committed
519
520

    setTimeout(function () {
fat's avatar
fat committed
521
      assert.ok($('.tooltip').is('.fade.in'), '1ms: tooltip faded in')
fat's avatar
fat committed
522
523
524
      $tooltip.trigger('mouseout')

      setTimeout(function () {
fat's avatar
fat committed
525
        assert.ok($('.tooltip').is('.fade.in'), '100ms: tooltip still faded in')
fat's avatar
fat committed
526
        $tooltip.trigger('mouseenter')
527
      }, 100)
fat's avatar
fat committed
528
529

      setTimeout(function () {
fat's avatar
fat committed
530
        assert.ok($('.tooltip').is('.fade.in'), '200ms: tooltip still faded in')
531
        done()
532
      }, 200)
fat's avatar
fat committed
533
534
535
536
537
    }, 0)

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
538
539
  QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) {
    assert.expect(2)
540
    var done = assert.async()
fat's avatar
fat committed
541

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

    setTimeout(function () {
fat's avatar
fat committed
547
      assert.ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip not faded in')
fat's avatar
fat committed
548
      $tooltip.trigger('mouseout')
549
    }, 100)
fat's avatar
fat committed
550
551

    setTimeout(function () {
fat's avatar
fat committed
552
      assert.ok(!$('.tooltip').is('.fade.in'), '200ms: tooltip not faded in')
553
      done()
554
    }, 200)
fat's avatar
fat committed
555
556
557
558

    $tooltip.trigger('mouseenter')
  })

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

fat's avatar
fat committed
563
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
fat's avatar
fat committed
564
      .appendTo('#qunit-fixture')
565
      .bootstrapTooltip({ delay: { show: 150, hide: 0 }})
fat's avatar
fat committed
566
567

    setTimeout(function () {
fat's avatar
fat committed
568
      assert.ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip not faded in')
fat's avatar
fat committed
569
      $tooltip.trigger('mouseout')
570
    }, 100)
fat's avatar
fat committed
571
572

    setTimeout(function () {
fat's avatar
fat committed
573
      assert.ok(!$('.tooltip').is('.fade.in'), '250ms: tooltip not faded in')
574
      done()
575
    }, 250)
fat's avatar
fat committed
576
577
578
579

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
580
581
  QUnit.test('should wait 200ms before hiding the tooltip', function (assert) {
    assert.expect(3)
582
    var done = assert.async()
fat's avatar
fat committed
583

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

    setTimeout(function () {
589
      assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.in'), '1ms: tooltip faded in')
fat's avatar
fat committed
590
591
592
593

      $tooltip.trigger('mouseout')

      setTimeout(function () {
594
        assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.in'), '100ms: tooltip still faded in')
595
      }, 100)
fat's avatar
fat committed
596
597

      setTimeout(function () {
598
        assert.ok(!$($tooltip.data('bs.tooltip').tip).is('.in'), '200ms: tooltip removed')
fat's avatar
fat committed
599
        done()
600
      }, 200)
fat's avatar
fat committed
601
602
603
604
605
606

    }, 0)

    $tooltip.trigger('mouseenter')
  })

fat's avatar
fat committed
607
  QUnit.test('should correctly position tooltips on SVG elements', function (assert) {
608
609
    if (!window.SVGElement) {
      // Skip IE8 since it doesn't support SVG
fat's avatar
fat committed
610
      assert.expect(0)
611
612
      return
    }
fat's avatar
fat committed
613
    assert.expect(2)
614

615
    var done = assert.async()
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

    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
636
        assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
637
        $circle.bootstrapTooltip('hide')
fat's avatar
fat committed
638
        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
639
        done()
640
      })
fat's avatar
fat committed
641
      .bootstrapTooltip({ placement: 'top', trigger: 'manual' })
642
643
644
645

    $circle.bootstrapTooltip('show')
  })

fat's avatar
fat committed
646
647
  QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) {
    assert.expect(1)
648
    var titleHtml = function () {
649
      var uid = Util.getUID('tooltip')
650
651
652
      return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
    }

fat's avatar
fat committed
653
    var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>')
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
      .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
670
    assert.strictEqual(currentUid, $('#tt-content').text())
671
672
  })

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

676
    var titleHtml = function () {
677
      var uid = Util.getUID('tooltip')
678
679
680
      return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
    }

fat's avatar
fat committed
681
    var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>')
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
      .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
699
    assert.strictEqual(currentUid, $('#tt-content').text())
fat's avatar
fat committed
700

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

703
704
    $('#tt-outer').trigger('mouseenter')
    assert.ok(obj._hoverState == 'in', 'the tooltip hoverState should be set to "in"')
705

fat's avatar
fat committed
706
    assert.strictEqual(currentUid, $('#tt-content').text())
707
708
  })

fat's avatar
fat committed
709
  QUnit.test('should correctly position tooltips on transformed elements', function (assert) {
710
711
    var styleProps = document.documentElement.style
    if (!('transform' in styleProps) && !('webkitTransform' in styleProps) && !('msTransform' in styleProps)) {
fat's avatar
fat committed
712
      assert.expect(0)
713
714
      return
    }
fat's avatar
fat committed
715
    assert.expect(2)
716

717
    var done = assert.async()
718
719
720
721
722
723
724
725
726
727

    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
728
    var $element = $('<div id="target" title="1"/>').appendTo('#qunit-fixture')
729
730
731
732
733

    $element
      .on('shown.bs.tooltip', function () {
        var offset = $('.tooltip').offset()
        $styles.remove()
fat's avatar
fat committed
734
735
        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')
736
        $element.bootstrapTooltip('hide')
737
        done()
738
739
740
741
742
743
744
745
      })
      .bootstrapTooltip({
        trigger: 'manual'
      })

    $element.bootstrapTooltip('show')
  })

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

fat's avatar
fat committed
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
    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')
764
    var $tooltip = $(tooltip.getTipElement())
fat's avatar
fat committed
765

766
    function showingTooltip() { return $tooltip.hasClass('in') || tooltip._hoverState == 'in' }
fat's avatar
fat committed
767
768
769

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

fat's avatar
fat committed
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
        ['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())
      }
    })
794
795
  })

796
})