]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Use transitionEnd in QUnit since we moved away from PhantomJS
authorJohann-S <johann.servoire@gmail.com>
Tue, 20 Mar 2018 10:07:58 +0000 (11:07 +0100)
committerJohann-S <johann.servoire@gmail.com>
Tue, 20 Mar 2018 14:56:51 +0000 (15:56 +0100)
12 files changed:
js/src/alert.js
js/src/carousel.js
js/src/collapse.js
js/src/modal.js
js/src/tab.js
js/src/tooltip.js
js/src/util.js
js/tests/unit/alert.js
js/tests/unit/collapse.js
js/tests/unit/popover.js
js/tests/unit/tooltip.js
js/tests/unit/util.js

index a072b2e4eb77d7692affdb57c0cee7a389871449..7719c57bfb5acb1005795a463b637a9550929aae 100644 (file)
@@ -102,8 +102,7 @@ const Alert = (($) => {
     _removeElement(element) {
       $(element).removeClass(ClassName.SHOW)
 
-      if (!Util.supportsTransitionEnd() ||
-          !$(element).hasClass(ClassName.FADE)) {
+      if (!$(element).hasClass(ClassName.FADE)) {
         this._destroyElement(element)
         return
       }
index 54bb0791c94a3597c322661c8660cd4304d4afe4..0c192cd7d1ee21fb11e6648506315bfeba1fe296 100644 (file)
@@ -142,8 +142,7 @@ const Carousel = (($) => {
         this._isPaused = true
       }
 
-      if ($(this._element).find(Selector.NEXT_PREV)[0] &&
-        Util.supportsTransitionEnd()) {
+      if ($(this._element).find(Selector.NEXT_PREV)[0]) {
         Util.triggerTransitionEnd(this._element)
         this.cycle(true)
       }
@@ -376,8 +375,7 @@ const Carousel = (($) => {
         to: nextElementIndex
       })
 
-      if (Util.supportsTransitionEnd() &&
-        $(this._element).hasClass(ClassName.SLIDE)) {
+      if ($(this._element).hasClass(ClassName.SLIDE)) {
         $(nextElement).addClass(orderClassName)
 
         Util.reflow(nextElement)
index ee357e37a622df164a46a1a350826f3914a30b80..58033566b3131d9e585b34189a4fdf1dbb45ff11 100644 (file)
@@ -182,11 +182,6 @@ const Collapse = (($) => {
         $(this._element).trigger(Event.SHOWN)
       }
 
-      if (!Util.supportsTransitionEnd()) {
-        complete()
-        return
-      }
-
       const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
       const scrollSize = `scroll${capitalizedDimension}`
       const transitionDuration = Util.getTransitionDurationFromElement(this._element)
@@ -246,12 +241,6 @@ const Collapse = (($) => {
       }
 
       this._element.style[dimension] = ''
-
-      if (!Util.supportsTransitionEnd()) {
-        complete()
-        return
-      }
-
       const transitionDuration = Util.getTransitionDurationFromElement(this._element)
 
       $(this._element)
index 414359e97a41a50ac660b3e99740a4fe5281c747..efe2f0d4a41c7fcdf41af2bfa77d76fafb4fdc83 100644 (file)
@@ -107,7 +107,7 @@ const Modal = (($) => {
         return
       }
 
-      if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
+      if ($(this._element).hasClass(ClassName.FADE)) {
         this._isTransitioning = true
       }
 
@@ -168,8 +168,7 @@ const Modal = (($) => {
       }
 
       this._isShown = false
-
-      const transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)
+      const transition = $(this._element).hasClass(ClassName.FADE)
 
       if (transition) {
         this._isTransitioning = true
@@ -228,8 +227,7 @@ const Modal = (($) => {
     }
 
     _showElement(relatedTarget) {
-      const transition = Util.supportsTransitionEnd() &&
-        $(this._element).hasClass(ClassName.FADE)
+      const transition = $(this._element).hasClass(ClassName.FADE)
 
       if (!this._element.parentNode ||
          this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
@@ -331,8 +329,6 @@ const Modal = (($) => {
         ? ClassName.FADE : ''
 
       if (this._isShown && this._config.backdrop) {
-        const doAnimate = Util.supportsTransitionEnd() && animate
-
         this._backdrop = document.createElement('div')
         this._backdrop.className = ClassName.BACKDROP
 
@@ -357,7 +353,7 @@ const Modal = (($) => {
           }
         })
 
-        if (doAnimate) {
+        if (animate) {
           Util.reflow(this._backdrop)
         }
 
@@ -367,7 +363,7 @@ const Modal = (($) => {
           return
         }
 
-        if (!doAnimate) {
+        if (!animate) {
           callback()
           return
         }
@@ -387,8 +383,7 @@ const Modal = (($) => {
           }
         }
 
-        if (Util.supportsTransitionEnd() &&
-           $(this._element).hasClass(ClassName.FADE)) {
+        if ($(this._element).hasClass(ClassName.FADE)) {
           const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
 
           $(this._backdrop)
index ebf28d76c792eef232c78aebf1f086138925ec1a..fb40a7402b72ba3efb1b04fbc74a479b3245e059 100644 (file)
@@ -151,7 +151,6 @@ const Tab = (($) => {
 
       const active = activeElements[0]
       const isTransitioning = callback &&
-        Util.supportsTransitionEnd() &&
         (active && $(active).hasClass(ClassName.FADE))
 
       const complete = () => this._transitionComplete(
index 19a020d43d742933319aac7b0ae731b6d64b92f3..64508fcab133f9024c7287eaca3c731479f23c54 100644 (file)
@@ -333,7 +333,7 @@ const Tooltip = (($) => {
           }
         }
 
-        if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
+        if ($(this.tip).hasClass(ClassName.FADE)) {
           const transitionDuration = Util.getTransitionDurationFromElement(this.tip)
 
           $(this.tip)
@@ -383,8 +383,7 @@ const Tooltip = (($) => {
       this._activeTrigger[Trigger.FOCUS] = false
       this._activeTrigger[Trigger.HOVER] = false
 
-      if (Util.supportsTransitionEnd() &&
-          $(this.tip).hasClass(ClassName.FADE)) {
+      if ($(this.tip).hasClass(ClassName.FADE)) {
         const transitionDuration = Util.getTransitionDurationFromElement(tip)
 
         $(tip)
index 1b1f13beaefc8eae9f64251670ad02145ebb0e29..f7a968de3dcc85f3580693c72dad785891f9fce6 100644 (file)
@@ -14,8 +14,7 @@ const Util = (($) => {
    * ------------------------------------------------------------------------
    */
 
-  let transition = false
-
+  const TRANSITION_END = 'transitionend'
   const MAX_UID = 1000000
   const MILLISECONDS_MULTIPLIER = 1000
 
@@ -26,8 +25,8 @@ const Util = (($) => {
 
   function getSpecialTransitionEndEvent() {
     return {
-      bindType: transition.end,
-      delegateType: transition.end,
+      bindType: TRANSITION_END,
+      delegateType: TRANSITION_END,
       handle(event) {
         if ($(event.target).is(this)) {
           return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
@@ -37,16 +36,6 @@ const Util = (($) => {
     }
   }
 
-  function transitionEndTest() {
-    if (typeof window !== 'undefined' && window.QUnit) {
-      return false
-    }
-
-    return {
-      end: 'transitionend'
-    }
-  }
-
   function transitionEndEmulator(duration) {
     let called = false
 
@@ -64,13 +53,8 @@ const Util = (($) => {
   }
 
   function setTransitionEndSupport() {
-    transition = transitionEndTest()
-
     $.fn.emulateTransitionEnd = transitionEndEmulator
-
-    if (Util.supportsTransitionEnd()) {
-      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
-    }
+    $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
   }
 
   /**
@@ -130,11 +114,12 @@ const Util = (($) => {
     },
 
     triggerTransitionEnd(element) {
-      $(element).trigger(transition.end)
+      $(element).trigger(TRANSITION_END)
     },
 
+    // TODO: Remove in v5
     supportsTransitionEnd() {
-      return Boolean(transition)
+      return Boolean(TRANSITION_END)
     },
 
     isElement(obj) {
index 2dcaeb6d007b0fb8bba35dd9f652889527d71ae8..165c91f1e14fcd30fd801f0a4df585a9511d3e25 100644 (file)
@@ -48,6 +48,7 @@ $(function () {
 
   QUnit.test('should remove element when clicking .close', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var alertHTML = '<div class="alert alert-danger fade show">' +
         '<a class="close" href="#" data-dismiss="alert">×</a>' +
         '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' +
@@ -56,9 +57,13 @@ $(function () {
 
     assert.notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom')
 
-    $alert.find('.close').trigger('click')
-
-    assert.strictEqual($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom')
+    $alert
+      .one('closed.bs.alert', function () {
+        assert.strictEqual($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom')
+        done()
+      })
+      .find('.close')
+      .trigger('click')
   })
 
   QUnit.test('should not fire closed when close is prevented', function (assert) {
index b9e3c4757cff41a4c8d0c86d7b719e212c1215c4..4a99f16325dad82d878e0e59a3b6e714a2ee6aae 100644 (file)
@@ -45,10 +45,14 @@ $(function () {
 
   QUnit.test('should show a collapsed element', function (assert) {
     assert.expect(2)
-    var $el = $('<div class="collapse"/>').bootstrapCollapse('show')
+    var done = assert.async()
+    var $el = $('<div class="collapse"/>')
 
-    assert.ok($el.hasClass('show'), 'has class "show"')
-    assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
+    $el.one('shown.bs.collapse', function () {
+      assert.ok($el.hasClass('show'), 'has class "show"')
+      assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
+      done()
+    }).bootstrapCollapse('show')
   })
 
   QUnit.test('should show multiple collapsed elements', function (assert) {
index b75837811fd5bb9933b5dacb8fb126227dc0cc5e..3eef811d609aa06d2eb71910182968e17ecf78db 100644 (file)
@@ -80,6 +80,7 @@ $(function () {
 
   QUnit.test('should get title and content from options', function (assert) {
     assert.expect(4)
+    var done = assert.async()
     var $popover = $('<a href="#">@fat</a>')
       .appendTo('#qunit-fixture')
       .bootstrapPopover({
@@ -91,15 +92,18 @@ $(function () {
         }
       })
 
-    $popover.bootstrapPopover('show')
-
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.strictEqual($('.popover .popover-header').text(), '@fat', 'title correctly inserted')
-    assert.strictEqual($('.popover .popover-body').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
-
-    $popover.bootstrapPopover('hide')
-
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
+    $popover
+      .one('shown.bs.popover', function () {
+        assert.notEqual($('.popover').length, 0, 'popover was inserted')
+        assert.strictEqual($('.popover .popover-header').text(), '@fat', 'title correctly inserted')
+        assert.strictEqual($('.popover .popover-body').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted')
+        $popover.bootstrapPopover('hide')
+      })
+      .one('hidden.bs.popover', function () {
+        assert.strictEqual($('.popover').length, 0, 'popover was removed')
+        done()
+      })
+      .bootstrapPopover('show')
   })
 
   QUnit.test('should allow DOMElement title and content (html: true)', function (assert) {
@@ -146,6 +150,7 @@ $(function () {
 
   QUnit.test('should not duplicate HTML object', function (assert) {
     assert.expect(6)
+    var done = assert.async()
     var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
 
     var $popover = $('<a href="#">@fat</a>')
@@ -157,56 +162,75 @@ $(function () {
         }
       })
 
-    $popover.bootstrapPopover('show')
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted')
+    function popoverInserted() {
+      assert.notEqual($('.popover').length, 0, 'popover was inserted')
+      assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted')
+    }
 
-    $popover.bootstrapPopover('hide')
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
+    $popover
+      .one('shown.bs.popover', function () {
+        popoverInserted()
 
-    $popover.bootstrapPopover('show')
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.equal($('.popover .popover-body').html(), $div[0].outerHTML, 'content correctly inserted')
+        $popover.one('hidden.bs.popover', function () {
+          assert.strictEqual($('.popover').length, 0, 'popover was removed')
 
-    $popover.bootstrapPopover('hide')
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
+          $popover.one('shown.bs.popover', function () {
+            popoverInserted()
+
+            $popover.one('hidden.bs.popover', function () {
+              assert.strictEqual($('.popover').length, 0, 'popover was removed')
+              done()
+            }).bootstrapPopover('hide')
+          }).bootstrapPopover('show')
+        }).bootstrapPopover('hide')
+      })
+      .bootstrapPopover('show')
   })
 
   QUnit.test('should get title and content from attributes', function (assert) {
     assert.expect(4)
+    var done = assert.async()
     var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
       .appendTo('#qunit-fixture')
       .bootstrapPopover()
+      .one('shown.bs.popover', function () {
+        assert.notEqual($('.popover').length, 0, 'popover was inserted')
+        assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
+        assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
+        $popover.bootstrapPopover('hide')
+      })
+      .one('hidden.bs.popover', function () {
+        assert.strictEqual($('.popover').length, 0, 'popover was removed')
+        done()
+      })
       .bootstrapPopover('show')
-
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
-    assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
-
-    $popover.bootstrapPopover('hide')
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
   })
 
   QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) {
     assert.expect(4)
+    var done = assert.async()
     var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
       .appendTo('#qunit-fixture')
       .bootstrapPopover({
         title: 'ignored title option',
         content: 'ignored content option'
       })
+      .one('shown.bs.popover', function () {
+        assert.notEqual($('.popover').length, 0, 'popover was inserted')
+        assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
+        assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
+        $popover.bootstrapPopover('hide')
+      })
+      .one('hidden.bs.popover', function () {
+        assert.strictEqual($('.popover').length, 0, 'popover was removed')
+        done()
+      })
       .bootstrapPopover('show')
-
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.strictEqual($('.popover .popover-header').text(), '@mdo', 'title correctly inserted')
-    assert.strictEqual($('.popover .popover-body').text(), 'loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻', 'content correctly inserted')
-
-    $popover.bootstrapPopover('hide')
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
   })
 
   QUnit.test('should respect custom template', function (assert) {
     assert.expect(3)
+    var done = assert.async()
     var $popover = $('<a href="#">@fat</a>')
       .appendTo('#qunit-fixture')
       .bootstrapPopover({
@@ -214,14 +238,16 @@ $(function () {
         content: 'Test',
         template: '<div class="popover foobar"><div class="arrow"></div><div class="inner"><h3 class="title"/><div class="content"><p/></div></div></div>'
       })
-
-    $popover.bootstrapPopover('show')
-
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-    assert.ok($('.popover').hasClass('foobar'), 'custom class is present')
-
-    $popover.bootstrapPopover('hide')
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
+      .one('shown.bs.popover', function () {
+        assert.notEqual($('.popover').length, 0, 'popover was inserted')
+        assert.ok($('.popover').hasClass('foobar'), 'custom class is present')
+        $popover.bootstrapPopover('hide')
+      })
+      .one('hidden.bs.popover', function () {
+        assert.strictEqual($('.popover').length, 0, 'popover was removed')
+        done()
+      })
+      .bootstrapPopover('show')
   })
 
   QUnit.test('should destroy popover', function (assert) {
@@ -247,18 +273,23 @@ $(function () {
 
   QUnit.test('should render popover element using delegated selector', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $div = $('<div><a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a></div>')
       .appendTo('#qunit-fixture')
       .bootstrapPopover({
         selector: 'a',
         trigger: 'click'
       })
+      .one('shown.bs.popover', function () {
+        assert.notEqual($('.popover').length, 0, 'popover was inserted')
+        $div.find('a').trigger('click')
+      })
+      .one('hidden.bs.popover', function () {
+        assert.strictEqual($('.popover').length, 0, 'popover was removed')
+        done()
+      })
 
     $div.find('a').trigger('click')
-    assert.notEqual($('.popover').length, 0, 'popover was inserted')
-
-    $div.find('a').trigger('click')
-    assert.strictEqual($('.popover').length, 0, 'popover was removed')
   })
 
   QUnit.test('should detach popover content rather than removing it so that event handlers are left intact', function (assert) {
@@ -276,6 +307,7 @@ $(function () {
         html: true,
         trigger: 'manual',
         container: 'body',
+        animation: false,
         content: function () {
           return $content
         }
@@ -289,8 +321,8 @@ $(function () {
             $div
               .one('shown.bs.popover', function () {
                 $('.content-with-handler .btn').trigger('click')
-                $div.bootstrapPopover('dispose')
                 assert.ok(handlerCalled, 'content\'s event handler still present')
+                $div.bootstrapPopover('dispose')
                 done()
               })
               .bootstrapPopover('show')
index bdccd3a38d60626300868608734f420a88594924..20d022c5dcd2e258f65f78c22658d8b078135459 100644 (file)
@@ -77,15 +77,21 @@ $(function () {
 
   QUnit.test('should remove aria-describedby from trigger on hide', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
       .bootstrapTooltip()
       .appendTo('#qunit-fixture')
 
-    $trigger.bootstrapTooltip('show')
-    assert.ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
-
-    $trigger.bootstrapTooltip('hide')
-    assert.ok(!$trigger[0].hasAttribute('aria-describedby'), 'trigger does not have aria-describedby')
+    $trigger
+      .one('shown.bs.tooltip', function () {
+        assert.ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
+        $trigger.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.ok(!$trigger[0].hasAttribute('aria-describedby'), 'trigger does not have aria-describedby')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should assign a unique id tooltip element', function (assert) {
@@ -102,40 +108,51 @@ $(function () {
 
   QUnit.test('should place tooltips relative to placement option', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({
         placement: 'bottom'
       })
 
-    $tooltip.bootstrapTooltip('show')
-
-    assert
-      .ok($('.tooltip')
-        .is('.fade.bs-tooltip-bottom.show'), 'has correct classes applied')
-
-    $tooltip.bootstrapTooltip('hide')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.ok($('.tooltip')
+          .is('.fade.bs-tooltip-bottom.show'), 'has correct classes applied')
 
-    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should allow html entities', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip" title="&lt;b&gt;@fat&lt;/b&gt;"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({
         html: true
       })
 
-    $tooltip.bootstrapTooltip('show')
-    assert.notEqual($('.tooltip b').length, 0, 'b tag was inserted')
-
-    $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.notEqual($('.tooltip b').length, 0, 'b tag was inserted')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should allow DOMElement title (html: false)', function (assert) {
     assert.expect(3)
+    var done = assert.async()
     var title = document.createTextNode('<3 writing tests')
     var $tooltip = $('<a href="#" rel="tooltip"/>')
       .appendTo('#qunit-fixture')
@@ -143,15 +160,19 @@ $(function () {
         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')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        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')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should allow DOMElement title (html: true)', function (assert) {
     assert.expect(3)
+    var done = assert.async()
     var title = document.createTextNode('<3 writing tests')
     var $tooltip = $('<a href="#" rel="tooltip"/>')
       .appendTo('#qunit-fixture')
@@ -160,26 +181,35 @@ $(function () {
         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')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        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')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should respect custom classes', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({
         template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>'
       })
 
-    $tooltip.bootstrapTooltip('show')
-    assert.ok($('.tooltip').hasClass('some-class'), 'custom class is present')
-
-    $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.ok($('.tooltip').hasClass('some-class'), 'custom class is present')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should fire show event', function (assert) {
@@ -363,18 +393,24 @@ $(function () {
 
   QUnit.test('should place tooltips inside body when container is body', function (assert) {
     assert.expect(3)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({
         container: 'body'
       })
-      .bootstrapTooltip('show')
-
-    assert.notEqual($('body > .tooltip').length, 0, 'tooltip is direct descendant of body')
-    assert.strictEqual($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')
 
-    $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('body > .tooltip').length, 0, 'tooltip was removed from dom')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.notEqual($('body > .tooltip').length, 0, 'tooltip is direct descendant of body')
+        assert.strictEqual($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($('body > .tooltip').length, 0, 'tooltip was removed from dom')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should add position class before positioning so that position-specific styles are taken into account', function (assert) {
@@ -405,45 +441,63 @@ $(function () {
 
   QUnit.test('should use title attribute for tooltip text', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip()
 
-    $tooltip.bootstrapTooltip('show')
-    assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
-
-    $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should prefer title attribute over title option', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({
         title: 'This is a tooltip with some content'
       })
 
-    $tooltip.bootstrapTooltip('show')
-    assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while preferred over title option')
-
-    $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while preferred over title option')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should use title option', function (assert) {
     assert.expect(2)
+    var done = assert.async()
     var $tooltip = $('<a href="#" rel="tooltip"/>')
       .appendTo('#qunit-fixture')
       .bootstrapTooltip({
         title: 'This is a tooltip with some content'
       })
 
-    $tooltip.bootstrapTooltip('show')
-    assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
-
-    $tooltip.bootstrapTooltip('hide')
-    assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
+    $tooltip
+      .one('shown.bs.tooltip', function () {
+        assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
+        $tooltip.bootstrapTooltip('hide')
+      })
+      .one('hidden.bs.tooltip', function () {
+        assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
+        done()
+      })
+      .bootstrapTooltip('show')
   })
 
   QUnit.test('should not error when trying to show an top-placed tooltip that has been removed from the dom', function (assert) {
@@ -869,7 +923,6 @@ $(function () {
     var done = assert.async()
     var $el = $('<a href="#" rel="tooltip" title="7"/>')
       .appendTo('#qunit-fixture')
-      .bootstrapTooltip('show')
       .on('shown.bs.tooltip', function () {
         var tooltip = $el.data('bs.tooltip')
         var $tooltip = $(tooltip.getTipElement())
index c4f9459f993e2783beec6bc48d8b043c4a5d746d..9a25a528619de81786d594eb6deae6490518bdc2 100644 (file)
@@ -90,4 +90,9 @@ $(function () {
     id2 = Util.getUID('test')
     assert.ok(id !== id2, id + ' !== ' + id2)
   })
+
+  QUnit.test('Util.supportsTransitionEnd should return true', function (assert) {
+    assert.expect(1)
+    assert.ok(Util.supportsTransitionEnd())
+  })
 })