]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
rewrite tab unit tests
authorJohann-S <johann.servoire@gmail.com>
Mon, 22 Jul 2019 13:24:17 +0000 (15:24 +0200)
committerJohann-S <johann.servoire@gmail.com>
Tue, 23 Jul 2019 12:23:50 +0000 (14:23 +0200)
build/build-plugins.js
js/index.esm.js
js/index.umd.js
js/src/tab/tab.js [moved from js/src/tab.js with 97% similarity]
js/src/tab/tab.spec.js [new file with mode: 0644]
js/tests/unit/.eslintrc.json [deleted file]
js/tests/unit/tab.js [deleted file]
js/tests/unit/tests-polyfills.js [deleted file]

index febe575c94d0013b67faf6638435f1a93d330b09..7aa2a4e5291a700f8cf0be2759f5eb955a75055a 100644 (file)
@@ -40,7 +40,7 @@ const bsPlugins = {
   Modal: path.resolve(__dirname, '../js/src/modal/modal.js'),
   Popover: path.resolve(__dirname, '../js/src/popover/popover.js'),
   ScrollSpy: path.resolve(__dirname, '../js/src/scrollspy/scrollspy.js'),
-  Tab: path.resolve(__dirname, '../js/src/tab.js'),
+  Tab: path.resolve(__dirname, '../js/src/tab/tab.js'),
   Toast: path.resolve(__dirname, '../js/src/toast/toast.js'),
   Tooltip: path.resolve(__dirname, '../js/src/tooltip/tooltip.js')
 }
index e8c9ab6391e8eaa2ffe2fc4d0a51e15be48b0849..18b12a454f3c10e9228d0f91e9bbcbdab210ac59 100644 (file)
@@ -13,7 +13,7 @@ import Dropdown from './src/dropdown/dropdown'
 import Modal from './src/modal/modal'
 import Popover from './src/popover/popover'
 import ScrollSpy from './src/scrollspy/scrollspy'
-import Tab from './src/tab'
+import Tab from './src/tab/tab'
 import Toast from './src/toast/toast'
 import Tooltip from './src/tooltip/tooltip'
 
index 207b952ca5dd5385df92473e4660b1a78a2305f6..17657f38f8ed6e3a3c670a67055ec21b718c41d3 100644 (file)
@@ -13,7 +13,7 @@ import Dropdown from './src/dropdown/dropdown'
 import Modal from './src/modal/modal'
 import Popover from './src/popover/popover'
 import ScrollSpy from './src/scrollspy/scrollspy'
-import Tab from './src/tab'
+import Tab from './src/tab/tab'
 import Toast from './src/toast/toast'
 import Tooltip from './src/tooltip/tooltip'
 
similarity index 97%
rename from js/src/tab.js
rename to js/src/tab/tab.js
index b9db64baa4135668f971f150616a056c671b6fa4..e882ff1d2aeb94ae455a5cbe159c34400351778a 100644 (file)
@@ -13,10 +13,10 @@ import {
   getTransitionDurationFromElement,
   makeArray,
   reflow
-} from './util/index'
-import Data from './dom/data'
-import EventHandler from './dom/event-handler'
-import SelectorEngine from './dom/selector-engine'
+} from '../util/index'
+import Data from '../dom/data'
+import EventHandler from '../dom/event-handler'
+import SelectorEngine from '../dom/selector-engine'
 
 /**
  * ------------------------------------------------------------------------
@@ -253,7 +253,7 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
  * ------------------------------------------------------------------------
  * add .tab to jQuery only if jQuery is present
  */
-
+/* istanbul ignore if */
 if (typeof $ !== 'undefined') {
   const JQUERY_NO_CONFLICT = $.fn[NAME]
   $.fn[NAME] = Tab._jQueryInterface
diff --git a/js/src/tab/tab.spec.js b/js/src/tab/tab.spec.js
new file mode 100644 (file)
index 0000000..3fae366
--- /dev/null
@@ -0,0 +1,593 @@
+import Tab from './tab'
+
+/** Test helpers */
+import { getFixture, clearFixture, jQueryMock } from '../../tests/helpers/fixture'
+
+describe('Tab', () => {
+  let fixtureEl
+
+  beforeAll(() => {
+    fixtureEl = getFixture()
+  })
+
+  afterEach(() => {
+    clearFixture()
+  })
+
+  describe('VERSION', () => {
+    it('should return plugin version', () => {
+      expect(Tab.VERSION).toEqual(jasmine.any(String))
+    })
+  })
+
+  describe('show', () => {
+    it('should activate element by tab id', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav">',
+        '  <li><a href="#home" role="tab">Home</a></li>',
+        '  <li><a id="triggerProfile" role="tab" href="#profile">Profile</a></li>',
+        '</ul>',
+        '<ul><li id="home"/><li id="profile"/></ul>'
+      ].join('')
+
+      const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')
+      const tab = new Tab(profileTriggerEl)
+
+      profileTriggerEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelector('#profile').classList.contains('active')).toEqual(true)
+        expect(profileTriggerEl.getAttribute('aria-selected')).toEqual('true')
+        done()
+      })
+
+      tab.show()
+    })
+
+    it('should activate element by tab id in ordered list', done => {
+      fixtureEl.innerHTML = [
+        '<ol class="nav nav-pills">',
+        '  <li><a href="#home">Home</a></li>',
+        '  <li><a id="triggerProfile" href="#profile">Profile</a></li>',
+        '</ol>',
+        '<ol><li id="home"/><li id="profile"/></ol>'
+      ].join('')
+
+      const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')
+      const tab = new Tab(profileTriggerEl)
+
+      profileTriggerEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelector('#profile').classList.contains('active')).toEqual(true)
+        done()
+      })
+
+      tab.show()
+    })
+
+    it('should activate element by tab id in nav list', done => {
+      fixtureEl.innerHTML = [
+        '<nav class="nav">',
+        '  <a href="#home">Home</a>',
+        '  <a id="triggerProfile" href="#profile">Profile</a>',
+        '</nav>',
+        '<nav><div id="home"></div><div id="profile"></div></nav>'
+      ].join('')
+
+      const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')
+      const tab = new Tab(profileTriggerEl)
+
+      profileTriggerEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelector('#profile').classList.contains('active')).toEqual(true)
+        done()
+      })
+
+      tab.show()
+    })
+
+    it('should activate element by tab id in list group', done => {
+      fixtureEl.innerHTML = [
+        '<div class="list-group">',
+        '  <a href="#home">Home</a>',
+        '  <a id="triggerProfile" href="#profile">Profile</a>',
+        '</div>',
+        '<nav><div id="home"></div><div id="profile"></div></nav>'
+      ].join('')
+
+      const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')
+      const tab = new Tab(profileTriggerEl)
+
+      profileTriggerEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelector('#profile').classList.contains('active')).toEqual(true)
+        done()
+      })
+
+      tab.show()
+    })
+
+    it('should not fire shown when show is prevented', done => {
+      fixtureEl.innerHTML = '<div class="nav"></div>'
+
+      const navEl = fixtureEl.querySelector('div')
+      const tab = new Tab(navEl)
+      const expectDone = () => {
+        setTimeout(() => {
+          expect().nothing()
+          done()
+        }, 30)
+      }
+
+      navEl.addEventListener('show.bs.tab', ev => {
+        ev.preventDefault()
+        expectDone()
+      })
+
+      navEl.addEventListener('shown.bs.tab', () => {
+        throw new Error('should not trigger shown event')
+      })
+
+      tab.show()
+    })
+
+    it('should not fire shown when tab is already active', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
+        '  <li class="nav-item"><a href="#profile" class="nav-link" role="tab">Profile</a></li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div class="tab-pane active" id="home" role="tabpanel"></div>',
+        '  <div class="tab-pane" id="profile" role="tabpanel"></div>',
+        '</div>'
+      ].join('')
+
+      const triggerActive = fixtureEl.querySelector('a.active')
+      const tab = new Tab(triggerActive)
+
+      triggerActive.addEventListener('shown.bs.tab', () => {
+        throw new Error('should not trigger shown event')
+      })
+
+      tab.show()
+      setTimeout(() => {
+        expect().nothing()
+        done()
+      }, 30)
+    })
+
+    it('should not fire shown when tab is disabled', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
+        '  <li class="nav-item"><a href="#profile" class="nav-link disabled" role="tab">Profile</a></li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div class="tab-pane active" id="home" role="tabpanel"></div>',
+        '  <div class="tab-pane" id="profile" role="tabpanel"></div>',
+        '</div>'
+      ].join('')
+
+      const triggerDisabled = fixtureEl.querySelector('a.disabled')
+      const tab = new Tab(triggerDisabled)
+
+      triggerDisabled.addEventListener('shown.bs.tab', () => {
+        throw new Error('should not trigger shown event')
+      })
+
+      tab.show()
+      setTimeout(() => {
+        expect().nothing()
+        done()
+      }, 30)
+    })
+
+    it('show and shown events should reference correct relatedTarget', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
+        '  <li class="nav-item"><a id="triggerProfile" href="#profile" class="nav-link" role="tab">Profile</a></li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div class="tab-pane active" id="home" role="tabpanel"></div>',
+        '  <div class="tab-pane" id="profile" role="tabpanel"></div>',
+        '</div>'
+      ].join('')
+
+      const secondTabTrigger = fixtureEl.querySelector('#triggerProfile')
+      const secondTab = new Tab(secondTabTrigger)
+
+      secondTabTrigger.addEventListener('show.bs.tab', ev => {
+        expect(ev.relatedTarget.hash).toEqual('#home')
+      })
+
+      secondTabTrigger.addEventListener('shown.bs.tab', ev => {
+        expect(ev.relatedTarget.hash).toEqual('#home')
+        expect(secondTabTrigger.getAttribute('aria-selected')).toEqual('true')
+        expect(fixtureEl.querySelector('a:not(.active)').getAttribute('aria-selected')).toEqual('false')
+        done()
+      })
+
+      secondTab.show()
+    })
+
+    it('should fire hide and hidden events', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav">',
+        '  <li><a href="#home">Home</a></li>',
+        '  <li><a href="#profile">Profile</a></li>',
+        '</ul>'
+      ].join('')
+
+      const triggerList = fixtureEl.querySelectorAll('a')
+      const firstTab = new Tab(triggerList[0])
+      const secondTab = new Tab(triggerList[1])
+
+      let hideCalled = false
+      triggerList[0].addEventListener('shown.bs.tab', () => {
+        secondTab.show()
+      })
+
+      triggerList[0].addEventListener('hide.bs.tab', ev => {
+        hideCalled = true
+        expect(ev.relatedTarget.hash).toEqual('#profile')
+      })
+
+      triggerList[0].addEventListener('hidden.bs.tab', ev => {
+        expect(hideCalled).toEqual(true)
+        expect(ev.relatedTarget.hash).toEqual('#profile')
+        done()
+      })
+
+      firstTab.show()
+    })
+
+    it('should not fire hidden when hide is prevented', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav">',
+        '  <li><a href="#home">Home</a></li>',
+        '  <li><a href="#profile">Profile</a></li>',
+        '</ul>'
+      ].join('')
+
+      const triggerList = fixtureEl.querySelectorAll('a')
+      const firstTab = new Tab(triggerList[0])
+      const secondTab = new Tab(triggerList[1])
+      const expectDone = () => {
+        setTimeout(() => {
+          expect().nothing()
+          done()
+        }, 30)
+      }
+
+      triggerList[0].addEventListener('shown.bs.tab', () => {
+        secondTab.show()
+      })
+
+      triggerList[0].addEventListener('hide.bs.tab', ev => {
+        ev.preventDefault()
+        expectDone()
+      })
+
+      triggerList[0].addEventListener('hidden.bs.tab', () => {
+        throw new Error('should not trigger hidden')
+      })
+
+      firstTab.show()
+    })
+
+    it('should handle removed tabs', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item">',
+        '    <a class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">',
+        '      <button class="close"><span aria-hidden="true">&times;</span></button>',
+        '    </a>',
+        '  </li>',
+        '  <li class="nav-item">',
+        '    <a id="secondNav" class="nav-link nav-tab" href="#buzz" role="tab" data-toggle="tab">',
+        '      <button class="close"><span aria-hidden="true">&times;</span></button>',
+        '    </a>',
+        '  </li>',
+        '  <li class="nav-item">',
+        '    <a class="nav-link nav-tab" href="#references" role="tab" data-toggle="tab">',
+        '      <button id="btnClose" class="close"><span aria-hidden="true">&times;</span></button>',
+        '    </a>',
+        '  </li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div role="tabpanel" class="tab-pane fade show active" id="profile">test 1</div>',
+        '  <div role="tabpanel" class="tab-pane fade" id="buzz">test 2</div>',
+        '  <div role="tabpanel" class="tab-pane fade" id="references">test 3</div>',
+        '</div>'
+      ].join('')
+
+      const secondNavEl = fixtureEl.querySelector('#secondNav')
+      const btnCloseEl = fixtureEl.querySelector('#btnClose')
+      const secondNavTab = new Tab(secondNavEl)
+
+      secondNavEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelectorAll('.nav-tab').length).toEqual(2)
+        done()
+      })
+
+      btnCloseEl.addEventListener('click', () => {
+        const linkEl = btnCloseEl.parentNode
+        const liEl = linkEl.parentNode
+        const tabId = linkEl.getAttribute('href')
+        const tabIdEl = fixtureEl.querySelector(tabId)
+
+        liEl.parentNode.removeChild(liEl)
+        tabIdEl.parentNode.removeChild(tabIdEl)
+        secondNavTab.show()
+      })
+
+      btnCloseEl.click()
+    })
+  })
+
+  describe('dispose', () => {
+    it('should dispose a tab', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const el = fixtureEl.querySelector('div')
+      const tab = new Tab(fixtureEl.querySelector('div'))
+
+      expect(Tab._getInstance(el)).not.toBeNull()
+
+      tab.dispose()
+
+      expect(Tab._getInstance(el)).toBeNull()
+    })
+  })
+
+  describe('_jQueryInterface', () => {
+    it('should create a tab', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+
+      jQueryMock.fn.tab = Tab._jQueryInterface
+      jQueryMock.elements = [div]
+
+      jQueryMock.fn.tab.call(jQueryMock)
+
+      expect(Tab._getInstance(div)).toBeDefined()
+    })
+
+    it('should not re create a tab', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const tab = new Tab(div)
+
+      jQueryMock.fn.tab = Tab._jQueryInterface
+      jQueryMock.elements = [div]
+
+      jQueryMock.fn.tab.call(jQueryMock)
+
+      expect(Tab._getInstance(div)).toEqual(tab)
+    })
+
+    it('should call a tab method', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const tab = new Tab(div)
+
+      spyOn(tab, 'show')
+
+      jQueryMock.fn.tab = Tab._jQueryInterface
+      jQueryMock.elements = [div]
+
+      jQueryMock.fn.tab.call(jQueryMock, 'show')
+
+      expect(Tab._getInstance(div)).toEqual(tab)
+      expect(tab.show).toHaveBeenCalled()
+    })
+
+    it('should throw error on undefined method', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const div = fixtureEl.querySelector('div')
+      const action = 'undefinedMethod'
+
+      jQueryMock.fn.tab = Tab._jQueryInterface
+      jQueryMock.elements = [div]
+
+      try {
+        jQueryMock.fn.tab.call(jQueryMock, action)
+      } catch (error) {
+        expect(error.message).toEqual(`No method named "${action}"`)
+      }
+    })
+  })
+
+  describe('_getInstance', () => {
+    it('should return null if there is no instance', () => {
+      expect(Tab._getInstance(fixtureEl)).toEqual(null)
+    })
+
+    it('should return this instance', () => {
+      fixtureEl.innerHTML = '<div></div>'
+
+      const divEl = fixtureEl.querySelector('div')
+      const tab = new Tab(divEl)
+
+      expect(Tab._getInstance(divEl)).toEqual(tab)
+    })
+  })
+
+  describe('data-api', () => {
+    it('should create dynamicaly a tab', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
+        '  <li class="nav-item"><a id="triggerProfile" data-toggle="tab" href="#profile" class="nav-link" role="tab">Profile</a></li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div class="tab-pane active" id="home" role="tabpanel"></div>',
+        '  <div class="tab-pane" id="profile" role="tabpanel"></div>',
+        '</div>'
+      ].join('')
+
+      const secondTabTrigger = fixtureEl.querySelector('#triggerProfile')
+
+      secondTabTrigger.addEventListener('shown.bs.tab', () => {
+        expect(secondTabTrigger.classList.contains('active')).toEqual(true)
+        expect(fixtureEl.querySelector('#profile').classList.contains('active')).toEqual(true)
+        done()
+      })
+
+      secondTabTrigger.click()
+    })
+
+    it('selected tab should deactivate previous selected link in dropdown', () => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs">',
+        '  <li class="nav-item"><a class="nav-link" href="#home" data-toggle="tab">Home</a></li>',
+        '  <li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>',
+        '  <li class="nav-item dropdown">',
+        '    <a class="nav-link dropdown-toggle active" data-toggle="dropdown" href="#">Dropdown</>',
+        '    <div class="dropdown-menu">',
+        '      <a class="dropdown-item active" href="#dropdown1" id="dropdown1-tab" data-toggle="tab">@fat</a>',
+        '      <a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-toggle="tab">@mdo</a>',
+        '    </div>',
+        '  </li>',
+        '</ul>'
+      ].join('')
+
+      const firstLiLinkEl = fixtureEl.querySelector('li:first-child a')
+
+      firstLiLinkEl.click()
+      expect(firstLiLinkEl.classList.contains('active')).toEqual(true)
+      expect(fixtureEl.querySelector('li:last-child a').classList.contains('active')).toEqual(false)
+      expect(fixtureEl.querySelector('li:last-child .dropdown-menu a:first-child').classList.contains('active')).toEqual(false)
+    })
+
+    it('should handle nested tabs', done => {
+      fixtureEl.innerHTML = [
+        '<nav class="nav nav-tabs" role="tablist">',
+        '  <a id="tab1" href="#x-tab1" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab1">Tab 1</a>',
+        '  <a href="#x-tab2" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-selected="true">Tab 2</a>',
+        '  <a href="#x-tab3" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab3">Tab 3</a>',
+        '</nav>',
+        '<div class="tab-content">',
+        '  <div class="tab-pane" id="x-tab1" role="tabpanel">',
+        '    <nav class="nav nav-tabs" role="tablist">',
+        '      <a href="#nested-tab1" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-selected="true">Nested Tab 1</a>',
+        '      <a id="tabNested2" href="#nested-tab2" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-profile">Nested Tab2</a>',
+        '    </nav>',
+        '    <div class="tab-content">',
+        '      <div class="tab-pane active" id="nested-tab1" role="tabpanel">Nested Tab1 Content</div>',
+        '      <div class="tab-pane" id="nested-tab2" role="tabpanel">Nested Tab2 Content</div>',
+        '    </div>',
+        '  </div>',
+        '  <div class="tab-pane active" id="x-tab2" role="tabpanel">Tab2 Content</div>',
+        '  <div class="tab-pane" id="x-tab3" role="tabpanel">Tab3 Content</div>',
+        '</div>'
+      ].join('')
+
+      const tab1El = fixtureEl.querySelector('#tab1')
+      const tabNested2El = fixtureEl.querySelector('#tabNested2')
+      const xTab1El = fixtureEl.querySelector('#x-tab1')
+
+      tabNested2El.addEventListener('shown.bs.tab', () => {
+        expect(xTab1El.classList.contains('active')).toEqual(true)
+        done()
+      })
+
+      tab1El.addEventListener('shown.bs.tab', () => {
+        expect(xTab1El.classList.contains('active')).toEqual(true)
+        tabNested2El.click()
+      })
+
+      tab1El.click()
+    })
+
+    it('should not remove fade class if no active pane is present', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item"><a id="tab-home" href="#home" class="nav-link" data-toggle="tab" role="tab">Home</a></li>',
+        '  <li class="nav-item"><a id="tab-profile" href="#profile" class="nav-link" data-toggle="tab" role="tab">Profile</a></li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div class="tab-pane fade" id="home" role="tabpanel"></div>',
+        '  <div class="tab-pane fade" id="profile" role="tabpanel"></div>',
+        '</div>'
+      ].join('')
+
+      const triggerTabProfileEl = fixtureEl.querySelector('#tab-profile')
+      const triggerTabHomeEl = fixtureEl.querySelector('#tab-home')
+      const tabProfileEl = fixtureEl.querySelector('#profile')
+      const tabHomeEl = fixtureEl.querySelector('#home')
+
+      triggerTabProfileEl.addEventListener('shown.bs.tab', () => {
+        expect(tabProfileEl.classList.contains('fade')).toEqual(true)
+        expect(tabProfileEl.classList.contains('show')).toEqual(true)
+
+        triggerTabHomeEl.addEventListener('shown.bs.tab', () => {
+          expect(tabProfileEl.classList.contains('fade')).toEqual(true)
+          expect(tabProfileEl.classList.contains('show')).toEqual(false)
+
+          expect(tabHomeEl.classList.contains('fade')).toEqual(true)
+          expect(tabHomeEl.classList.contains('show')).toEqual(true)
+
+          done()
+        })
+
+        triggerTabHomeEl.click()
+      })
+
+      triggerTabProfileEl.click()
+    })
+
+    it('should not add show class to tab panes if there is no `.fade` class', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item">',
+        '    <a class="nav-link nav-tab" href="#home" role="tab" data-toggle="tab">Home</a>',
+        '  </li>',
+        '  <li class="nav-item">',
+        '    <a id="secondNav" class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">Profile</a>',
+        '  </li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div role="tabpanel" class="tab-pane" id="home">test 1</div>',
+        '  <div role="tabpanel" class="tab-pane" id="profile">test 2</div>',
+        '</div>'
+      ].join('')
+
+      const secondNavEl = fixtureEl.querySelector('#secondNav')
+
+      secondNavEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelectorAll('.show').length).toEqual(0)
+        done()
+      })
+
+      secondNavEl.click()
+    })
+
+    it('should add show class to tab panes if there is a `.fade` class', done => {
+      fixtureEl.innerHTML = [
+        '<ul class="nav nav-tabs" role="tablist">',
+        '  <li class="nav-item">',
+        '    <a class="nav-link nav-tab" href="#home" role="tab" data-toggle="tab">Home</a>',
+        '  </li>',
+        '  <li class="nav-item">',
+        '    <a id="secondNav" class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">Profile</a>',
+        '  </li>',
+        '</ul>',
+        '<div class="tab-content">',
+        '  <div role="tabpanel" class="tab-pane fade" id="home">test 1</div>',
+        '  <div role="tabpanel" class="tab-pane fade" id="profile">test 2</div>',
+        '</div>'
+      ].join('')
+
+      const secondNavEl = fixtureEl.querySelector('#secondNav')
+
+      secondNavEl.addEventListener('shown.bs.tab', () => {
+        expect(fixtureEl.querySelectorAll('.show').length).toEqual(1)
+        done()
+      })
+
+      secondNavEl.click()
+    })
+  })
+})
diff --git a/js/tests/unit/.eslintrc.json b/js/tests/unit/.eslintrc.json
deleted file mode 100644 (file)
index b4b9ac7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-{
-  "root": true,
-  "env": {
-    "jquery": true,
-    "qunit": true
-  },
-  "globals": {
-    "bootstrap": false,
-    "sinon": false,
-    "Util": false,
-    "Sanitizer": false,
-    "Data": false,
-    "Alert": false,
-    "Button": false,
-    "Carousel": false,
-    "Simulator": false,
-    "Toast": false,
-    "EventHandler": false,
-    "Manipulator": false,
-    "SelectorEngine": false
-  },
-  "parserOptions": {
-    "ecmaVersion": 5,
-    "sourceType": "script"
-  },
-  "extends": [
-    "plugin:unicorn/recommended",
-    "xo",
-    "xo/browser"
-  ],
-  "rules": {
-    "capitalized-comments": "off",
-    "indent": [
-      "error",
-      2,
-      {
-        "MemberExpression": "off",
-        "SwitchCase": 1
-      }
-    ],
-    "multiline-ternary": [
-      "error",
-      "always-multiline"
-    ],
-    "new-cap": "off",
-    "object-curly-spacing": [
-      "error",
-      "always"
-    ],
-    "semi": [
-      "error",
-      "never"
-    ],
-    "strict": "error",
-    "unicorn/no-unused-properties": "error",
-    "unicorn/prefer-includes": "off",
-    "unicorn/prefer-node-append": "off",
-    "unicorn/prefer-node-remove": "off",
-    "unicorn/prefer-query-selector": "off",
-    "unicorn/prevent-abbreviations": "off"
-  }
-}
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
deleted file mode 100644 (file)
index 827fb70..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-$(function () {
-  'use strict'
-
-  var Tab = typeof window.bootstrap === 'undefined' ? window.Tab : window.bootstrap.Tab
-
-  QUnit.module('tabs plugin')
-
-  QUnit.test('should be defined on jquery object', function (assert) {
-    assert.expect(1)
-    assert.ok($(document.body).tab, 'tabs method is defined')
-  })
-
-  QUnit.module('tabs', {
-    beforeEach: function () {
-      // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
-      $.fn.bootstrapTab = $.fn.tab.noConflict()
-    },
-    afterEach: function () {
-      $.fn.tab = $.fn.bootstrapTab
-      delete $.fn.bootstrapTab
-      $('#qunit-fixture').html('')
-    }
-  })
-
-  QUnit.test('should provide no conflict', function (assert) {
-    assert.expect(1)
-    assert.strictEqual(typeof $.fn.tab, 'undefined', 'tab was set back to undefined (org value)')
-  })
-
-  QUnit.test('should throw explicit error on undefined method', function (assert) {
-    assert.expect(1)
-    var $el = $('<div/>')
-    $el.bootstrapTab()
-    try {
-      $el.bootstrapTab('noMethod')
-    } catch (error) {
-      assert.strictEqual(error.message, 'No method named "noMethod"')
-    }
-  })
-
-  QUnit.test('should return jquery collection containing the element', function (assert) {
-    assert.expect(2)
-    var $el = $('<div/>')
-    var $tab = $el.bootstrapTab()
-    assert.ok($tab instanceof $, 'returns jquery collection')
-    assert.strictEqual($tab[0], $el[0], 'collection contains element')
-  })
-
-  QUnit.test('should activate element by tab id', function (assert) {
-    assert.expect(2)
-    var tabsHTML = '<ul class="nav">' +
-        '<li><a href="#home">Home</a></li>' +
-        '<li><a href="#profile">Profile</a></li>' +
-        '</ul>'
-
-    $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
-
-    $(tabsHTML).find('li:last-child a').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
-
-    $(tabsHTML).find('li:first-child a').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
-  })
-
-  QUnit.test('should activate element by tab id', function (assert) {
-    assert.expect(2)
-    var pillsHTML = '<ul class="nav nav-pills">' +
-        '<li><a href="#home">Home</a></li>' +
-        '<li><a href="#profile">Profile</a></li>' +
-        '</ul>'
-
-    $('<ul><li id="home"/><li id="profile"/></ul>').appendTo('#qunit-fixture')
-
-    $(pillsHTML).find('li:last-child a').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
-
-    $(pillsHTML).find('li:first-child a').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
-  })
-
-  QUnit.test('should activate element by tab id in ordered list', function (assert) {
-    assert.expect(2)
-    var pillsHTML = '<ol class="nav nav-pills">' +
-        '<li><a href="#home">Home</a></li>' +
-        '<li><a href="#profile">Profile</a></li>' +
-        '</ol>'
-
-    $('<ol><li id="home"/><li id="profile"/></ol>').appendTo('#qunit-fixture')
-
-    $(pillsHTML).find('li:last-child a').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
-
-    $(pillsHTML).find('li:first-child a').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
-  })
-
-  QUnit.test('should activate element by tab id in nav list', function (assert) {
-    assert.expect(2)
-    var tabsHTML = '<nav class="nav">' +
-                      '<a href="#home">Home</a>' +
-                      '<a href="#profile">Profile</a>' +
-                    '</nav>'
-
-    $('<nav><div id="home"></div><div id="profile"></div></nav>').appendTo('#qunit-fixture')
-
-    $(tabsHTML).find('a:last-child').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
-
-    $(tabsHTML).find('a:first-child').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
-  })
-
-  QUnit.test('should activate element by tab id in list group', function (assert) {
-    assert.expect(2)
-    var tabsHTML = '<div class="list-group">' +
-                      '<a href="#home">Home</a>' +
-                      '<a href="#profile">Profile</a>' +
-                    '</div>'
-
-    $('<nav><div id="home"></div><div id="profile"></div></nav>').appendTo('#qunit-fixture')
-
-    $(tabsHTML).find('a:last-child').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
-
-    $(tabsHTML).find('a:first-child').bootstrapTab('show')
-    assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
-  })
-
-  QUnit.test('should not fire shown when show is prevented', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    $('<div class="nav"/>')
-      .on('show.bs.tab', function (e) {
-        e.preventDefault()
-        assert.ok(true, 'show event fired')
-        done()
-      })
-      .on('shown.bs.tab', function () {
-        assert.ok(false, 'shown event fired')
-      })
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('should not fire shown when tab is already active', function (assert) {
-    assert.expect(0)
-    var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
-      '<li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>' +
-      '<li class="nav-item"><a href="#profile" class="nav-link" role="tab">Profile</a></li>' +
-      '</ul>' +
-      '<div class="tab-content">' +
-      '<div class="tab-pane active" id="home" role="tabpanel"></div>' +
-      '<div class="tab-pane" id="profile" role="tabpanel"></div>' +
-      '</div>'
-
-    $(tabsHTML)
-      .find('a.active')
-      .on('shown.bs.tab', function () {
-        assert.ok(true, 'shown event fired')
-      })
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('should not fire shown when tab is disabled', function (assert) {
-    assert.expect(0)
-    var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
-      '<li class="nav-item"><a href="#home" class="nav-link active" role="tab">Home</a></li>' +
-      '<li class="nav-item"><a href="#profile" class="nav-link disabled" role="tab">Profile</a></li>' +
-      '</ul>' +
-      '<div class="tab-content">' +
-      '<div class="tab-pane active" id="home" role="tabpanel"></div>' +
-      '<div class="tab-pane" id="profile" role="tabpanel"></div>' +
-      '</div>'
-
-    $(tabsHTML)
-      .find('a.disabled')
-      .on('shown.bs.tab', function () {
-        assert.ok(true, 'shown event fired')
-      })
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('show and shown events should reference correct relatedTarget', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-
-    var dropHTML =
-        '<ul class="drop nav">' +
-        '  <li class="dropdown"><a data-toggle="dropdown" href="#">1</a>' +
-        '    <ul class="dropdown-menu nav">' +
-        '      <li><a href="#a1-1" data-toggle="tab">1-1</a></li>' +
-        '      <li><a href="#a1-2" data-toggle="tab">1-2</a></li>' +
-        '    </ul>' +
-        '  </li>' +
-        '</ul>'
-
-    $(dropHTML)
-      .find('ul > li:first-child a')
-      .bootstrapTab('show')
-      .end()
-      .find('ul > li:last-child a')
-      .on('show.bs.tab', function (e) {
-        assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
-      })
-      .on('shown.bs.tab', function (e) {
-        assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
-        done()
-      })
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('should fire hide and hidden events', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-
-    var tabsHTML = '<ul class="nav">' +
-        '<li><a href="#home">Home</a></li>' +
-        '<li><a href="#profile">Profile</a></li>' +
-        '</ul>'
-
-    $(tabsHTML)
-      .find('li:first-child a')
-      .on('hide.bs.tab', function () {
-        assert.ok(true, 'hide event fired')
-      })
-      .bootstrapTab('show')
-      .end()
-      .find('li:last-child a')
-      .bootstrapTab('show')
-
-    $(tabsHTML)
-      .find('li:first-child a')
-      .on('hidden.bs.tab', function () {
-        assert.ok(true, 'hidden event fired')
-        done()
-      })
-      .bootstrapTab('show')
-      .end()
-      .find('li:last-child a')
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('should not fire hidden when hide is prevented', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    var tabsHTML = '<ul class="nav">' +
-        '<li><a href="#home">Home</a></li>' +
-        '<li><a href="#profile">Profile</a></li>' +
-        '</ul>'
-
-    $(tabsHTML)
-      .find('li:first-child a')
-      .on('hide.bs.tab', function (e) {
-        e.preventDefault()
-        assert.ok(true, 'hide event fired')
-        done()
-      })
-      .on('hidden.bs.tab', function () {
-        assert.ok(false, 'hidden event fired')
-      })
-      .bootstrapTab('show')
-      .end()
-      .find('li:last-child a')
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('hide and hidden events contain correct relatedTarget', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-
-    var tabsHTML = '<ul class="nav">' +
-        '<li><a href="#home">Home</a></li>' +
-        '<li><a href="#profile">Profile</a></li>' +
-        '</ul>'
-
-    $(tabsHTML)
-      .find('li:first-child a')
-      .on('hide.bs.tab', function (e) {
-        assert.strictEqual(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
-      })
-      .on('hidden.bs.tab', function (e) {
-        assert.strictEqual(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
-        done()
-      })
-      .bootstrapTab('show')
-      .end()
-      .find('li:last-child a')
-      .bootstrapTab('show')
-  })
-
-  QUnit.test('selected tab should have aria-selected', function (assert) {
-    assert.expect(8)
-    var tabsHTML = '<ul class="nav nav-tabs">' +
-        '<li><a class="nav-item active" href="#home" toggle="tab" aria-selected="true">Home</a></li>' +
-        '<li><a class="nav-item" href="#profile" toggle="tab" aria-selected="false">Profile</a></li>' +
-        '</ul>'
-    var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
-
-    $tabs.find('li:first-child a').bootstrapTab('show')
-    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'shown tab has aria-selected = true')
-    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'hidden tab has aria-selected = false')
-
-    $tabs.find('li:last-child a').trigger('click')
-    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'after click, shown tab has aria-selected = true')
-    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'after click, hidden tab has aria-selected = false')
-
-    $tabs.find('li:first-child a').bootstrapTab('show')
-    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'shown tab has aria-selected = true')
-    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'hidden tab has aria-selected = false')
-
-    $tabs.find('li:first-child a').trigger('click')
-    assert.strictEqual($tabs.find('.active').attr('aria-selected'), 'true', 'after second show event, shown tab still has aria-selected = true')
-    assert.strictEqual($tabs.find('a:not(.active)').attr('aria-selected'), 'false', 'after second show event, hidden tab has aria-selected = false')
-  })
-
-  QUnit.test('selected tab should deactivate previous selected tab', function (assert) {
-    assert.expect(2)
-    var tabsHTML = '<ul class="nav nav-tabs">' +
-        '<li class="nav-item"><a class="nav-link active" href="#home" data-toggle="tab">Home</a></li>' +
-        '<li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>' +
-        '</ul>'
-    var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
-
-    $tabs.find('li:last-child a')[0].click()
-    assert.notOk($tabs.find('li:first-child a').hasClass('active'))
-    assert.ok($tabs.find('li:last-child a').hasClass('active'))
-  })
-
-  QUnit.test('selected tab should deactivate previous selected link in dropdown', function (assert) {
-    assert.expect(3)
-    var tabsHTML = '<ul class="nav nav-tabs">' +
-        '<li class="nav-item"><a class="nav-link" href="#home" data-toggle="tab">Home</a></li>' +
-        '<li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>' +
-        '<li class="nav-item dropdown"><a class="nav-link dropdown-toggle active" data-toggle="dropdown" href="#">Dropdown</a>' +
-        '<div class="dropdown-menu">' +
-        '<a class="dropdown-item active" href="#dropdown1" id="dropdown1-tab" data-toggle="tab">@fat</a>' +
-        '<a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-toggle="tab">@mdo</a>' +
-        '</div>' +
-        '</li>' +
-        '</ul>'
-    var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
-
-    $tabs.find('li:first-child a')[0].click()
-    assert.ok($tabs.find('li:first-child a').hasClass('active'))
-    assert.notOk($tabs.find('li:last-child a').hasClass('active'))
-    assert.notOk($tabs.find('li:last-child .dropdown-menu a:first-child').hasClass('active'))
-  })
-
-  QUnit.test('Nested tabs', function (assert) {
-    assert.expect(2)
-    var done = assert.async()
-    var tabsHTML =
-        '<nav class="nav nav-tabs" role="tablist">' +
-        '  <a id="tab1" href="#x-tab1" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab1">Tab 1</a>' +
-        '  <a href="#x-tab2" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-selected="true">Tab 2</a>' +
-        '  <a href="#x-tab3" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-tab3">Tab 3</a>' +
-        '</nav>' +
-        '<div class="tab-content">' +
-        '  <div class="tab-pane" id="x-tab1" role="tabpanel">' +
-        '    <nav class="nav nav-tabs" role="tablist">' +
-        '      <a href="#nested-tab1" class="nav-item nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-selected="true">Nested Tab 1</a>' +
-        '      <a id="tabNested2" href="#nested-tab2" class="nav-item nav-link" data-toggle="tab" role="tab" aria-controls="x-profile">Nested Tab2</a>' +
-        '    </nav>' +
-        '    <div class="tab-content">' +
-        '      <div class="tab-pane active" id="nested-tab1" role="tabpanel">Nested Tab1 Content</div>' +
-        '      <div class="tab-pane" id="nested-tab2" role="tabpanel">Nested Tab2 Content</div>' +
-        '    </div>' +
-        '  </div>' +
-        '  <div class="tab-pane active" id="x-tab2" role="tabpanel">Tab2 Content</div>' +
-        '  <div class="tab-pane" id="x-tab3" role="tabpanel">Tab3 Content</div>' +
-        '</div>'
-
-    $(tabsHTML).appendTo('#qunit-fixture')
-
-    $('#tabNested2').on('shown.bs.tab', function () {
-      assert.ok($('#x-tab1').hasClass('active'))
-      done()
-    })
-
-    $('#tab1').on('shown.bs.tab', function () {
-      assert.ok($('#x-tab1').hasClass('active'))
-      $('#tabNested2')[0].click()
-    })
-
-    $('#tab1')[0].click()
-  })
-
-  QUnit.test('should not remove fade class if no active pane is present', function (assert) {
-    assert.expect(6)
-    var done = assert.async()
-    var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
-      '<li class="nav-item"><a id="tab-home" href="#home" class="nav-link" data-toggle="tab" role="tab">Home</a></li>' +
-      '<li class="nav-item"><a id="tab-profile" href="#profile" class="nav-link" data-toggle="tab" role="tab">Profile</a></li>' +
-      '</ul>' +
-      '<div class="tab-content">' +
-      '<div class="tab-pane fade" id="home" role="tabpanel"></div>' +
-      '<div class="tab-pane fade" id="profile" role="tabpanel"></div>' +
-      '</div>'
-
-    $(tabsHTML).appendTo('#qunit-fixture')
-    $('#tab-profile')
-      .on('shown.bs.tab', function () {
-        assert.ok($('#profile').hasClass('fade'))
-        assert.ok($('#profile').hasClass('show'))
-
-        $('#tab-home')
-          .on('shown.bs.tab', function () {
-            assert.ok($('#profile').hasClass('fade'))
-            assert.notOk($('#profile').hasClass('show'))
-            assert.ok($('#home').hasClass('fade'))
-            assert.ok($('#home').hasClass('show'))
-
-            done()
-          })
-
-        $('#tab-home')[0].click()
-      })
-
-    $('#tab-profile')[0].click()
-  })
-
-  QUnit.test('should handle removed tabs', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    var html = [
-      '<ul class="nav nav-tabs" role="tablist">',
-      '  <li class="nav-item">',
-      '    <a class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">',
-      '      <button class="close"><span aria-hidden="true">&times;</span></button>',
-      '    </a>',
-      '  </li>',
-      '  <li class="nav-item">',
-      '    <a id="secondNav" class="nav-link nav-tab" href="#buzz" role="tab" data-toggle="tab">',
-      '      <button class="close"><span aria-hidden="true">&times;</span></button>',
-      '    </a>',
-      '  </li>',
-      '  <li class="nav-item">',
-      '    <a class="nav-link nav-tab" href="#references" role="tab" data-toggle="tab">',
-      '      <button id="btnClose" class="close"><span aria-hidden="true">&times;</span></button>',
-      '    </a>',
-      '  </li>',
-      '</ul>',
-      '<div class="tab-content">',
-      '  <div role="tabpanel" class="tab-pane fade show active" id="profile">test 1</div>',
-      '  <div role="tabpanel" class="tab-pane fade" id="buzz">test 2</div>',
-      '  <div role="tabpanel" class="tab-pane fade" id="references">test 3</div>',
-      '</div>'
-    ].join('')
-
-    $(html).appendTo('#qunit-fixture')
-
-    $('#secondNav').on('shown.bs.tab', function () {
-      assert.strictEqual($('.nav-tab').length, 2)
-      done()
-    })
-
-    $('#btnClose').one('click', function () {
-      var tabId = $(this).parents('a').attr('href')
-      $(this).parents('li').remove()
-      $(tabId).remove()
-      $('.nav-tabs a:last').bootstrapTab('show')
-    })
-      .trigger($.Event('click'))
-  })
-
-  QUnit.test('should not add show class to tab panes if there is no `.fade` class', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    var html = [
-      '<ul class="nav nav-tabs" role="tablist">',
-      '  <li class="nav-item">',
-      '    <a class="nav-link nav-tab" href="#home" role="tab" data-toggle="tab">Home</a>',
-      '  </li>',
-      '  <li class="nav-item">',
-      '    <a id="secondNav" class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">Profile</a>',
-      '  </li>',
-      '</ul>',
-      '<div class="tab-content">',
-      '  <div role="tabpanel" class="tab-pane" id="home">test 1</div>',
-      '  <div role="tabpanel" class="tab-pane" id="profile">test 2</div>',
-      '</div>'
-    ].join('')
-
-    $(html).appendTo('#qunit-fixture')
-
-    $('#secondNav').on('shown.bs.tab', function () {
-      assert.strictEqual($('.show').length, 0)
-      done()
-    })
-
-    $('#secondNav')[0].click()
-  })
-
-  QUnit.test('should add show class to tab panes if there is a `.fade` class', function (assert) {
-    assert.expect(1)
-    var done = assert.async()
-
-    var html = [
-      '<ul class="nav nav-tabs" role="tablist">',
-      '  <li class="nav-item">',
-      '    <a class="nav-link nav-tab" href="#home" role="tab" data-toggle="tab">Home</a>',
-      '  </li>',
-      '  <li class="nav-item">',
-      '    <a id="secondNav" class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">Profile</a>',
-      '  </li>',
-      '</ul>',
-      '<div class="tab-content">',
-      '  <div role="tabpanel" class="tab-pane fade" id="home">test 1</div>',
-      '  <div role="tabpanel" class="tab-pane fade" id="profile">test 2</div>',
-      '</div>'
-    ].join('')
-
-    $(html).appendTo('#qunit-fixture')
-
-    $('#secondNav').on('shown.bs.tab', function () {
-      assert.strictEqual($('.show').length, 1)
-      done()
-    })
-
-    $('#secondNav')[0].click()
-  })
-
-  QUnit.test('should return the version', function (assert) {
-    assert.expect(1)
-    assert.strictEqual(typeof Tab.VERSION, 'string')
-  })
-})
diff --git a/js/tests/unit/tests-polyfills.js b/js/tests/unit/tests-polyfills.js
deleted file mode 100644 (file)
index 4f2583e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Polyfills for our unit tests
-(function () {
-  'use strict'
-
-  // Event constructor shim
-  if (!window.Event || typeof window.Event !== 'function') {
-    var origEvent = window.Event
-    window.Event = function (inType, params) {
-      params = params || {}
-      var e = document.createEvent('Event')
-      e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable))
-      return e
-    }
-
-    window.Event.prototype = origEvent.prototype
-  }
-
-  if (typeof window.CustomEvent !== 'function') {
-    window.CustomEvent = function (event, params) {
-      params = params || { bubbles: false, cancelable: false, detail: null }
-      var evt = document.createEvent('CustomEvent')
-      evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
-      return evt
-    }
-
-    CustomEvent.prototype = window.Event.prototype
-  }
-})()