mirror of
https://github.com/twbs/bootstrap.git
synced 2024-11-29 11:24:18 +01:00
rewrite tab unit tests
This commit is contained in:
parent
e1b5d8471a
commit
233f3fb1ce
@ -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')
|
||||
}
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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
|
593
js/src/tab/tab.spec.js
Normal file
593
js/src/tab/tab.spec.js
Normal file
@ -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">×</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">×</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">×</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()
|
||||
})
|
||||
})
|
||||
})
|
@ -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"
|
||||
}
|
||||
}
|
@ -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">×</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">×</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">×</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')
|
||||
})
|
||||
})
|
@ -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
|
||||
}
|
||||
})()
|
Loading…
Reference in New Issue
Block a user