Unify workspace lint, format, and type-check quality gates (#2732)

This commit is contained in:
Paweł Kuna
2026-07-30 19:36:41 +02:00
committed by GitHub
parent c527135aae
commit 6db32ea2c2
114 changed files with 2021 additions and 2696 deletions
+8 -24
View File
@@ -36,11 +36,7 @@ describe('Alert', () => {
describe('data-api', () => {
it('should close an alert without instantiating manually', () => {
fixtureEl.innerHTML = [
'<div class="alert">',
' <button type="button" data-bs-dismiss="alert">x</button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="alert">', ' <button type="button" data-bs-dismiss="alert">x</button>', '</div>'].join('')
const button = document.querySelector('button')!
button.click()
@@ -48,11 +44,7 @@ describe('Alert', () => {
})
it('should close an alert with parent selector', () => {
fixtureEl.innerHTML = [
'<div class="alert">',
' <button type="button" data-bs-target=".alert" data-bs-dismiss="alert">x</button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="alert">', ' <button type="button" data-bs-target=".alert" data-bs-dismiss="alert">x</button>', '</div>'].join('')
const button = document.querySelector('button')!
button.click()
@@ -60,11 +52,7 @@ describe('Alert', () => {
})
it('should close an alert via data-tblr-dismiss', () => {
fixtureEl.innerHTML = [
'<div class="alert">',
' <button type="button" data-tblr-dismiss="alert">x</button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="alert">', ' <button type="button" data-tblr-dismiss="alert">x</button>', '</div>'].join('')
const button = document.querySelector('button')!
button.click()
@@ -72,11 +60,7 @@ describe('Alert', () => {
})
it('should close an alert via data-tblr-dismiss with data-tblr-target', () => {
fixtureEl.innerHTML = [
'<div class="alert">',
' <button type="button" data-tblr-target=".alert" data-tblr-dismiss="alert">x</button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="alert">', ' <button type="button" data-tblr-target=".alert" data-tblr-dismiss="alert">x</button>', '</div>'].join('')
const button = document.querySelector('button')!
button.click()
@@ -86,7 +70,7 @@ describe('Alert', () => {
describe('close', () => {
it('should close an alert', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div class="alert"></div>'
const alertEl = document.querySelector('.alert')!
@@ -102,7 +86,7 @@ describe('Alert', () => {
})
it('should close alert with fade class', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div class="alert fade"></div>'
const alertEl = document.querySelector('.alert')!
@@ -118,13 +102,13 @@ describe('Alert', () => {
})
it('should not remove alert if close event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div class="alert"></div>'
const alertEl = document.querySelector('.alert')!
const alert = new Alert(alertEl)
alertEl.addEventListener('close.bs.alert', event => {
alertEl.addEventListener('close.bs.alert', (event) => {
event.preventDefault()
setTimeout(() => {
expect(document.querySelector('.alert')).not.toBeNull()
+1 -4
View File
@@ -37,10 +37,7 @@ describe('Button', () => {
describe('data-api', () => {
it('should toggle active class on click', () => {
fixtureEl.innerHTML = [
'<button class="btn" data-bs-toggle="button">btn</button>',
'<button class="btn testParent" data-bs-toggle="button"><div class="test"></div></button>'
].join('')
fixtureEl.innerHTML = ['<button class="btn" data-bs-toggle="button">btn</button>', '<button class="btn testParent" data-bs-toggle="button"><div class="test"></div></button>'].join('')
const btn = fixtureEl.querySelector('.btn') as HTMLElement
const divTest = fixtureEl.querySelector('.test') as HTMLElement
+26 -119
View File
@@ -61,16 +61,8 @@ describe('Carousel', () => {
})
it('should go to next item on right arrow key', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' <div id="item2" class="carousel-item">item 2</div>', ' <div class="carousel-item">item 3</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl, { keyboard: true })
@@ -87,16 +79,8 @@ describe('Carousel', () => {
})
it('should go to previous item on left arrow key', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div id="item1" class="carousel-item">item 1</div>',
' <div class="carousel-item active">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div id="item1" class="carousel-item">item 1</div>', ' <div class="carousel-item active">item 2</div>', ' <div class="carousel-item">item 3</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl, { keyboard: true })
@@ -113,14 +97,7 @@ describe('Carousel', () => {
})
it('should not prevent keydown for non-arrow keys', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' <div class="carousel-item">item 2</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
new Carousel(carouselEl, { keyboard: true })
@@ -133,14 +110,7 @@ describe('Carousel', () => {
})
it('should ignore keyboard in input/textarea', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active"><input type="text"></div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active"><input type="text"></div>', ' <div class="carousel-item">item 2</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl, { keyboard: true })
@@ -172,15 +142,8 @@ describe('Carousel', () => {
describe('next', () => {
it('should slide to next item', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' <div id="item2" class="carousel-item">item 2</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -199,14 +162,7 @@ describe('Carousel', () => {
describe('prev', () => {
it('should stay at start when wrap is false', () => {
return new Promise<void>((resolve, reject) => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div id="one" class="carousel-item active"></div>',
' <div id="two" class="carousel-item"></div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div id="one" class="carousel-item active"></div>', ' <div id="two" class="carousel-item"></div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl, { wrap: false })
@@ -255,16 +211,8 @@ describe('Carousel', () => {
describe('to', () => {
it('should go to specific index', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
' <div id="item3" class="carousel-item">item 3</div>',
' </div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' <div id="item2" class="carousel-item">item 2</div>', ' <div id="item3" class="carousel-item">item 3</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -280,14 +228,7 @@ describe('Carousel', () => {
})
it('should ignore invalid index', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' <div class="carousel-item">item 2</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -352,14 +293,7 @@ describe('Carousel', () => {
describe('_updateInterval', () => {
it('should use data-bs-interval from active element', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active" data-bs-interval="2000">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active" data-bs-interval="2000">item 1</div>', ' <div class="carousel-item">item 2</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -369,14 +303,7 @@ describe('Carousel', () => {
})
it('should use data-tblr-interval from active element', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active" data-tblr-interval="3000">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active" data-tblr-interval="3000">item 1</div>', ' <div class="carousel-item">item 2</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -386,13 +313,7 @@ describe('Carousel', () => {
})
it('should fall back to defaultInterval if no data-interval', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -414,7 +335,7 @@ describe('Carousel', () => {
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
'</div>',
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
@@ -439,7 +360,7 @@ describe('Carousel', () => {
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item">item 2</div>',
' </div>',
'</div>'
'</div>',
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
@@ -453,13 +374,7 @@ describe('Carousel', () => {
})
it('should skip if no indicators element', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div class="carousel-item active">item 1</div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl)
@@ -493,16 +408,8 @@ describe('Carousel', () => {
describe('wrap', () => {
it('should wrap from end to start', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div id="one" class="carousel-item active"></div>',
' <div id="two" class="carousel-item"></div>',
' <div id="three" class="carousel-item"></div>',
' </div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div id="myCarousel" class="carousel slide">', ' <div class="carousel-inner">', ' <div id="one" class="carousel-item active"></div>', ' <div id="two" class="carousel-item"></div>', ' <div id="three" class="carousel-item"></div>', ' </div>', '</div>'].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
const carousel = new Carousel(carouselEl, { wrap: true })
@@ -562,7 +469,7 @@ describe('Carousel', () => {
})
it('should navigate via data-tblr-slide="next"', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
@@ -570,7 +477,7 @@ describe('Carousel', () => {
' <div id="item2" class="carousel-item">item 2</div>',
' </div>',
' <button data-tblr-slide="next" data-bs-target="#myCarousel">Next</button>',
'</div>'
'</div>',
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
@@ -586,7 +493,7 @@ describe('Carousel', () => {
})
it('should navigate via data-tblr-slide="prev"', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
@@ -594,7 +501,7 @@ describe('Carousel', () => {
' <div class="carousel-item active">item 2</div>',
' </div>',
' <button data-tblr-slide="prev" data-bs-target="#myCarousel">Prev</button>',
'</div>'
'</div>',
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
@@ -610,7 +517,7 @@ describe('Carousel', () => {
})
it('should handle data-tblr-slide-to in indicators', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-indicators">',
@@ -621,7 +528,7 @@ describe('Carousel', () => {
' <div class="carousel-item active">item 1</div>',
' <div id="item2" class="carousel-item">item 2</div>',
' </div>',
'</div>'
'</div>',
].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel')!
+44 -110
View File
@@ -46,14 +46,7 @@ describe('Collapse', () => {
})
it('should allow DOM element in parent config', () => {
fixtureEl.innerHTML = [
'<div class="my-collapse">',
' <div class="item">',
' <a data-bs-toggle="collapse" href="#">Toggle</a>',
' <div class="collapse">Lorem ipsum</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="my-collapse">', ' <div class="item">', ' <a data-bs-toggle="collapse" href="#">Toggle</a>', ' <div class="collapse">Lorem ipsum</div>', ' </div>', '</div>'].join('')
const collapseEl = fixtureEl.querySelector('div.collapse')!
const myCollapseEl = fixtureEl.querySelector('.my-collapse')!
@@ -63,14 +56,7 @@ describe('Collapse', () => {
})
it('should allow string selector in parent config', () => {
fixtureEl.innerHTML = [
'<div class="my-collapse">',
' <div class="item">',
' <a data-bs-toggle="collapse" href="#">Toggle</a>',
' <div class="collapse">Lorem ipsum</div>',
' </div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="my-collapse">', ' <div class="item">', ' <a data-bs-toggle="collapse" href="#">Toggle</a>', ' <div class="collapse">Lorem ipsum</div>', ' </div>', '</div>'].join('')
const collapseEl = fixtureEl.querySelector('div.collapse')!
const myCollapseEl = fixtureEl.querySelector('.my-collapse')!
@@ -104,7 +90,7 @@ describe('Collapse', () => {
})
it('should collapse children with parent', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div class="my-collapse">',
' <div class="item">',
@@ -115,15 +101,14 @@ describe('Collapse', () => {
' <a data-bs-toggle="collapse" href="#">Toggle 2</a>',
' <div id="collapse2" class="collapse">Lorem ipsum 2</div>',
' </div>',
'</div>'
'</div>',
].join('')
const parent = fixtureEl.querySelector('.my-collapse')!
const collapseEl1 = fixtureEl.querySelector('#collapse1')!
const collapseEl2 = fixtureEl.querySelector('#collapse2')!
const collapseList = Array.from(fixtureEl.querySelectorAll('.collapse'))
.map(el => new Collapse(el, { parent, toggle: false }))
const collapseList = Array.from(fixtureEl.querySelectorAll('.collapse')).map((el) => new Collapse(el, { parent, toggle: false }))
collapseEl2.addEventListener('shown.bs.collapse', () => {
expect(collapseEl2.classList.contains('show')).toBe(true)
@@ -162,7 +147,7 @@ describe('Collapse', () => {
})
it('should show a collapsed element', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div class="collapse" style="height: 0px;"></div>'
const collapseEl = fixtureEl.querySelector('div')!
@@ -183,7 +168,7 @@ describe('Collapse', () => {
})
it('should show a collapsed element on width', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div class="collapse collapse-horizontal" style="width: 0px;"></div>'
const collapseEl = fixtureEl.querySelector('div')!
@@ -204,15 +189,8 @@ describe('Collapse', () => {
})
it('should collapse only the first collapse', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="card" id="accordion1">',
' <div id="collapse1" class="collapse"></div>',
'</div>',
'<div class="card" id="accordion2">',
' <div id="collapse2" class="collapse show"></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="card" id="accordion1">', ' <div id="collapse1" class="collapse"></div>', '</div>', '<div class="card" id="accordion2">', ' <div id="collapse2" class="collapse show"></div>', '</div>'].join('')
const el1 = fixtureEl.querySelector('#collapse1')!
const el2 = fixtureEl.querySelector('#collapse2')!
@@ -229,7 +207,7 @@ describe('Collapse', () => {
})
it('should handle toggling children siblings in accordion', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="parentGroup" class="accordion">',
' <div class="accordion-header">',
@@ -249,7 +227,7 @@ describe('Collapse', () => {
' </div>',
' </div>',
' </div>',
'</div>'
'</div>',
].join('')
const el = (s: string) => fixtureEl.querySelector(s) as HTMLElement
@@ -282,12 +260,7 @@ describe('Collapse', () => {
})
it('should not show if active children are transitioning', () => {
fixtureEl.innerHTML = [
'<div id="accordion">',
' <div id="collapse1" class="collapse show" data-bs-parent="#accordion"></div>',
' <div id="collapse2" class="collapse" data-bs-parent="#accordion"></div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="accordion">', ' <div id="collapse1" class="collapse show" data-bs-parent="#accordion"></div>', ' <div id="collapse2" class="collapse" data-bs-parent="#accordion"></div>', '</div>'].join('')
const el1 = fixtureEl.querySelector('#collapse1')!
const el2 = fixtureEl.querySelector('#collapse2')!
@@ -310,7 +283,7 @@ describe('Collapse', () => {
const collapseEl = fixtureEl.querySelector('div')!
const collapse = new Collapse(collapseEl, { toggle: false })
collapseEl.addEventListener('show.bs.collapse', event => {
collapseEl.addEventListener('show.bs.collapse', (event) => {
event.preventDefault()
setTimeout(() => {
resolve()
@@ -352,7 +325,7 @@ describe('Collapse', () => {
})
it('should hide a collapse element', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div class="collapse show"></div>'
const collapseEl = fixtureEl.querySelector('div')!
@@ -375,7 +348,7 @@ describe('Collapse', () => {
const collapseEl = fixtureEl.querySelector('div')!
const collapse = new Collapse(collapseEl, { toggle: false })
collapseEl.addEventListener('hide.bs.collapse', event => {
collapseEl.addEventListener('hide.bs.collapse', (event) => {
event.preventDefault()
setTimeout(resolve, 10)
})
@@ -406,20 +379,15 @@ describe('Collapse', () => {
describe('data-api', () => {
it('should prevent url change on nested elements', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" class="collapsed" href="#collapse">',
' <span id="nested"></span>',
'</a>',
'<div id="collapse" class="collapse"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a role="button" data-bs-toggle="collapse" class="collapsed" href="#collapse">', ' <span id="nested"></span>', '</a>', '<div id="collapse" class="collapse"></div>'].join('')
const triggerEl = fixtureEl.querySelector('a')!
const nestedTriggerEl = fixtureEl.querySelector('#nested')!
const spy = vi.spyOn(Event.prototype, 'preventDefault')
triggerEl.addEventListener('click', event => {
triggerEl.addEventListener('click', (event) => {
expect((event.target as Element).isEqualNode(nestedTriggerEl)).toBe(true)
expect(spy).toHaveBeenCalled()
resolve()
@@ -430,12 +398,8 @@ describe('Collapse', () => {
})
it('should show multiple collapsed elements', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" class="collapsed" href=".multi"></a>',
'<div id="collapse1" class="collapse multi"></div>',
'<div id="collapse2" class="collapse multi"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a role="button" data-bs-toggle="collapse" class="collapsed" href=".multi"></a>', '<div id="collapse1" class="collapse multi"></div>', '<div id="collapse2" class="collapse multi"></div>'].join('')
const trigger = fixtureEl.querySelector('a')!
const collapse1 = fixtureEl.querySelector('#collapse1')!
@@ -454,12 +418,8 @@ describe('Collapse', () => {
})
it('should hide multiple collapsed elements', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" href=".multi"></a>',
'<div id="collapse1" class="collapse multi show"></div>',
'<div id="collapse2" class="collapse multi show"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a role="button" data-bs-toggle="collapse" href=".multi"></a>', '<div id="collapse1" class="collapse multi show"></div>', '<div id="collapse2" class="collapse multi show"></div>'].join('')
const trigger = fixtureEl.querySelector('a')!
const collapse1 = fixtureEl.querySelector('#collapse1')!
@@ -478,11 +438,8 @@ describe('Collapse', () => {
})
it('should show collapse via data-tblr-target', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" class="collapsed" data-tblr-target="#test1"></a>',
'<div id="test1" class="collapse"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a role="button" data-bs-toggle="collapse" class="collapsed" data-tblr-target="#test1"></a>', '<div id="test1" class="collapse"></div>'].join('')
const trigger = fixtureEl.querySelector('a') as HTMLElement
const collapseEl = fixtureEl.querySelector('#test1')!
@@ -499,11 +456,8 @@ describe('Collapse', () => {
})
it('should hide collapse via data-tblr-target', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" data-tblr-target="#test1"></a>',
'<div id="test1" class="collapse show"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a role="button" data-bs-toggle="collapse" data-tblr-target="#test1"></a>', '<div id="test1" class="collapse show"></div>'].join('')
const trigger = fixtureEl.querySelector('a') as HTMLElement
const collapseEl = fixtureEl.querySelector('#test1')!
@@ -520,12 +474,8 @@ describe('Collapse', () => {
})
it('should remove collapsed class from trigger on show', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a id="link1" role="button" data-bs-toggle="collapse" class="collapsed" href="#" data-bs-target="#test1"></a>',
'<a id="link2" role="button" data-bs-toggle="collapse" class="collapsed" href="#" data-bs-target="#test1"></a>',
'<div id="test1"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a id="link1" role="button" data-bs-toggle="collapse" class="collapsed" href="#" data-bs-target="#test1"></a>', '<a id="link2" role="button" data-bs-toggle="collapse" class="collapsed" href="#" data-bs-target="#test1"></a>', '<div id="test1"></div>'].join('')
const link1 = fixtureEl.querySelector('#link1')!
const link2 = fixtureEl.querySelector('#link2')!
@@ -544,12 +494,8 @@ describe('Collapse', () => {
})
it('should add collapsed class to trigger on hide', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<a id="link1" role="button" data-bs-toggle="collapse" href="#" data-bs-target="#test1"></a>',
'<a id="link2" role="button" data-bs-toggle="collapse" href="#" data-bs-target="#test1"></a>',
'<div id="test1" class="show"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<a id="link1" role="button" data-bs-toggle="collapse" href="#" data-bs-target="#test1"></a>', '<a id="link2" role="button" data-bs-toggle="collapse" href="#" data-bs-target="#test1"></a>', '<div id="test1" class="show"></div>'].join('')
const link1 = fixtureEl.querySelector('#link1')!
const link2 = fixtureEl.querySelector('#link2')!
@@ -568,7 +514,7 @@ describe('Collapse', () => {
})
it('should allow accordion with non-card children', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="accordion">',
' <div class="item">',
@@ -579,7 +525,7 @@ describe('Collapse', () => {
' <a id="linkTriggerTwo" data-bs-toggle="collapse" href="#collapseTwo"></a>',
' <div id="collapseTwo" class="collapse show" data-bs-parent="#accordion"></div>',
' </div>',
'</div>'
'</div>',
].join('')
const trigger = fixtureEl.querySelector('#linkTrigger') as HTMLElement
@@ -605,11 +551,8 @@ describe('Collapse', () => {
})
it('should not prevent event for input', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<input type="checkbox" data-bs-toggle="collapse" data-bs-target="#collapsediv1">',
'<div id="collapsediv1"></div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<input type="checkbox" data-bs-toggle="collapse" data-bs-target="#collapsediv1">', '<div id="collapsediv1"></div>'].join('')
const target = fixtureEl.querySelector('input') as HTMLInputElement
const collapseEl = fixtureEl.querySelector('#collapsediv1')!
@@ -625,7 +568,7 @@ describe('Collapse', () => {
})
it('should allow accordion with nested elements', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="accordion">',
' <div class="row">',
@@ -642,7 +585,7 @@ describe('Collapse', () => {
' </div>',
' </div>',
' </div>',
'</div>'
'</div>',
].join('')
const triggerEl = fixtureEl.querySelector('#linkTrigger') as HTMLElement
@@ -678,7 +621,7 @@ describe('Collapse', () => {
})
it('should collapse accordion children but not nested accordion', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div id="accordion">',
' <div class="item">',
@@ -696,7 +639,7 @@ describe('Collapse', () => {
' <a id="linkTriggerTwo" data-bs-toggle="collapse" href="#collapseTwo"></a>',
' <div id="collapseTwo" data-bs-parent="#accordion" class="collapse show"></div>',
' </div>',
'</div>'
'</div>',
].join('')
const trigger = fixtureEl.querySelector('#linkTrigger') as HTMLElement
@@ -798,11 +741,8 @@ describe('Collapse', () => {
describe('data-tblr-toggle', () => {
it('should show collapse via data-tblr-toggle="collapse"', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="collapse" data-bs-target="#test1">Toggle</button>',
'<div id="test1" class="collapse">Content</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="collapse" data-bs-target="#test1">Toggle</button>', '<div id="test1" class="collapse">Content</div>'].join('')
const target = fixtureEl.querySelector('#test1')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="collapse"]') as HTMLElement
@@ -817,11 +757,8 @@ describe('Collapse', () => {
})
it('should hide collapse via data-tblr-toggle="collapse"', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="collapse" data-bs-target="#test1">Toggle</button>',
'<div id="test1" class="collapse show">Content</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="collapse" data-bs-target="#test1">Toggle</button>', '<div id="test1" class="collapse show">Content</div>'].join('')
const target = fixtureEl.querySelector('#test1')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="collapse"]') as HTMLElement
@@ -836,11 +773,8 @@ describe('Collapse', () => {
})
it('should show collapse via data-tblr-toggle with data-tblr-target', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="collapse" data-tblr-target="#test1">Toggle</button>',
'<div id="test1" class="collapse">Content</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="collapse" data-tblr-target="#test1">Toggle</button>', '<div id="test1" class="collapse">Content</div>'].join('')
const target = fixtureEl.querySelector('#test1')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="collapse"]') as HTMLElement
+1 -3
View File
@@ -95,9 +95,7 @@ describe('Data', () => {
Data.set(div, TEST_KEY, { ...TEST_DATA })
Data.set(div, UNKNOWN_KEY, { ...TEST_DATA })
expect(spy).toHaveBeenCalledWith(
expect.stringContaining(TEST_KEY)
)
expect(spy).toHaveBeenCalledWith(expect.stringContaining(TEST_KEY))
spy.mockRestore()
})
+4 -4
View File
@@ -222,7 +222,7 @@ describe('EventHandler', () => {
it('should allow preventing the default action', () => {
EventHandler.on(div, 'show.bs.test', (event: unknown) => {
(event as Event).preventDefault()
;(event as Event).preventDefault()
})
const evt = EventHandler.trigger(div, 'show.bs.test')
@@ -351,7 +351,7 @@ describe('EventHandler', () => {
const mouseoverEvent = new MouseEvent('mouseover', {
bubbles: true,
relatedTarget: document.body
relatedTarget: document.body,
})
div.dispatchEvent(mouseoverEvent)
@@ -368,7 +368,7 @@ describe('EventHandler', () => {
const mouseoverEvent = new MouseEvent('mouseover', {
bubbles: true,
relatedTarget: btn
relatedTarget: btn,
})
div.dispatchEvent(mouseoverEvent)
@@ -384,7 +384,7 @@ describe('EventHandler', () => {
const mouseoverEvent = new MouseEvent('mouseover', {
bubbles: true,
relatedTarget: null
relatedTarget: null,
})
div.dispatchEvent(mouseoverEvent)
@@ -6,7 +6,7 @@ vi.mock('../../../src/bootstrap/util/index', async (importOriginal) => {
const actual = await importOriginal<typeof import('../../../src/bootstrap/util/index')>()
return {
...actual,
isVisible: () => true
isVisible: () => true,
}
})
@@ -72,7 +72,7 @@ describe('SelectorEngine', () => {
const result = SelectorEngine.children(parent, 'span')
expect(result).toHaveLength(2)
result.forEach(el => expect(el.tagName).toBe('SPAN'))
result.forEach((el) => expect(el.tagName).toBe('SPAN'))
})
it('should return an empty array when no children match', () => {
@@ -167,7 +167,7 @@ describe('SelectorEngine', () => {
const result = SelectorEngine.focusableChildren(parent)
expect(result.length).toBeGreaterThanOrEqual(1)
const tags = result.map(el => el.tagName)
const tags = result.map((el) => el.tagName)
expect(tags).toContain('BUTTON')
expect(tags).toContain('INPUT')
expect(tags).not.toContain('SPAN')
@@ -178,7 +178,7 @@ describe('SelectorEngine', () => {
const parent = fixtureEl.querySelector('div')!
const result = SelectorEngine.focusableChildren(parent)
const texts = result.map(el => el.textContent)
const texts = result.map((el) => el.textContent)
expect(texts).toContain('Yes')
expect(texts).not.toContain('No')
@@ -189,7 +189,7 @@ describe('SelectorEngine', () => {
const parent = fixtureEl.querySelector('div')!
const result = SelectorEngine.focusableChildren(parent)
const texts = result.map(el => el.textContent)
const texts = result.map((el) => el.textContent)
expect(texts).toContain('Visible')
expect(texts).not.toContain('Hidden')
File diff suppressed because it is too large Load Diff
+43 -60
View File
@@ -18,19 +18,20 @@ describe('Modal', () => {
}
})
const createModalHTML = () => [
'<div class="modal" tabindex="-1">',
' <div class="modal-dialog">',
' <div class="modal-content">',
' <div class="modal-header">',
' <h5 class="modal-title">Modal</h5>',
' <button type="button" class="btn-close" data-bs-dismiss="modal"></button>',
' </div>',
' <div class="modal-body"><p>Content</p></div>',
' </div>',
' </div>',
'</div>'
].join('')
const createModalHTML = () =>
[
'<div class="modal" tabindex="-1">',
' <div class="modal-dialog">',
' <div class="modal-content">',
' <div class="modal-header">',
' <h5 class="modal-title">Modal</h5>',
' <button type="button" class="btn-close" data-bs-dismiss="modal"></button>',
' </div>',
' <div class="modal-body"><p>Content</p></div>',
' </div>',
' </div>',
'</div>',
].join('')
describe('VERSION', () => {
it('should return plugin version', () => {
@@ -81,7 +82,7 @@ describe('Modal', () => {
describe('toggle', () => {
it('should show when hidden', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -96,7 +97,7 @@ describe('Modal', () => {
})
it('should hide when shown', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -117,7 +118,7 @@ describe('Modal', () => {
describe('show', () => {
it('should show modal', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -136,7 +137,7 @@ describe('Modal', () => {
})
it('should not show if already shown', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -154,12 +155,12 @@ describe('Modal', () => {
})
it('should not show if show event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
modalEl.addEventListener('show.bs.modal', event => {
modalEl.addEventListener('show.bs.modal', (event) => {
event.preventDefault()
setTimeout(() => {
expect(modal._isShown).toBe(false)
@@ -172,7 +173,7 @@ describe('Modal', () => {
})
it('should pass relatedTarget in show event', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML() + '<button id="trigger">Open</button>'
const modalEl = fixtureEl.querySelector('.modal')!
const trigger = fixtureEl.querySelector('#trigger') as HTMLElement
@@ -190,7 +191,7 @@ describe('Modal', () => {
describe('hide', () => {
it('should hide modal', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -220,13 +221,13 @@ describe('Modal', () => {
})
it('should not hide if hide event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
modalEl.addEventListener('shown.bs.modal', () => {
modalEl.addEventListener('hide.bs.modal', event => {
modalEl.addEventListener('hide.bs.modal', (event) => {
event.preventDefault()
setTimeout(() => {
expect(modal._isShown).toBe(true)
@@ -285,7 +286,7 @@ describe('Modal', () => {
describe('keyboard', () => {
it('should close on Escape when keyboard is true', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { keyboard: true })
@@ -304,7 +305,7 @@ describe('Modal', () => {
})
it('should not close on Escape when keyboard is false', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { keyboard: false })
@@ -323,7 +324,7 @@ describe('Modal', () => {
})
it('should ignore non-Escape keys', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -376,7 +377,7 @@ describe('Modal', () => {
describe('_triggerBackdropTransition', () => {
it('should add and remove modal-static class', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { keyboard: false })
@@ -396,13 +397,13 @@ describe('Modal', () => {
})
it('should not transition if hidePrevented is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { keyboard: false })
modalEl.addEventListener('shown.bs.modal', () => {
modalEl.addEventListener('hidePrevented.bs.modal', event => {
modalEl.addEventListener('hidePrevented.bs.modal', (event) => {
event.preventDefault()
setTimeout(() => {
expect(modal._isShown).toBe(true)
@@ -418,7 +419,7 @@ describe('Modal', () => {
})
it('should early return if overflowY is hidden', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { keyboard: false })
@@ -441,7 +442,7 @@ describe('Modal', () => {
})
it('should early return if already has modal-static class', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { keyboard: false })
@@ -466,7 +467,7 @@ describe('Modal', () => {
describe('backdrop click', () => {
it('should hide when clicking outside dialog with backdrop true', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { backdrop: true })
@@ -486,7 +487,7 @@ describe('Modal', () => {
})
it('should not hide when click starts inside dialog', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const dialog = modalEl.querySelector('.modal-dialog')!
@@ -510,7 +511,7 @@ describe('Modal', () => {
})
it('should trigger backdrop transition with static backdrop', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl, { backdrop: 'static' })
@@ -539,7 +540,7 @@ describe('Modal', () => {
const modal = new Modal(modalEl)
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
modalEl.addEventListener('shown.bs.modal', () => {
expect(document.body.contains(modalEl)).toBe(true)
modal.dispose()
@@ -552,7 +553,7 @@ describe('Modal', () => {
})
it('should scroll modal body to top', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createModalHTML()
const modalEl = fixtureEl.querySelector('.modal')!
const modal = new Modal(modalEl)
@@ -569,13 +570,8 @@ describe('Modal', () => {
describe('data-tblr-toggle', () => {
it('should open modal via data-tblr-toggle="modal"', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="modal" data-bs-target="#testModal">Open</button>',
'<div class="modal" id="testModal" tabindex="-1">',
' <div class="modal-dialog"><div class="modal-content"></div></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="modal" data-bs-target="#testModal">Open</button>', '<div class="modal" id="testModal" tabindex="-1">', ' <div class="modal-dialog"><div class="modal-content"></div></div>', '</div>'].join('')
const modalEl = fixtureEl.querySelector('#testModal')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="modal"]') as HTMLElement
@@ -591,13 +587,8 @@ describe('Modal', () => {
})
it('should open modal via data-tblr-toggle with data-tblr-target', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="modal" data-tblr-target="#testModal">Open</button>',
'<div class="modal" id="testModal" tabindex="-1">',
' <div class="modal-dialog"><div class="modal-content"></div></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="modal" data-tblr-target="#testModal">Open</button>', '<div class="modal" id="testModal" tabindex="-1">', ' <div class="modal-dialog"><div class="modal-content"></div></div>', '</div>'].join('')
const modalEl = fixtureEl.querySelector('#testModal')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="modal"]') as HTMLElement
@@ -615,16 +606,8 @@ describe('Modal', () => {
describe('data-tblr-dismiss', () => {
it('should close modal via data-tblr-dismiss="modal"', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="modal" tabindex="-1">',
' <div class="modal-dialog">',
' <div class="modal-content">',
' <button type="button" class="btn-close" data-tblr-dismiss="modal"></button>',
' </div>',
' </div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="modal" tabindex="-1">', ' <div class="modal-dialog">', ' <div class="modal-content">', ' <button type="button" class="btn-close" data-tblr-dismiss="modal"></button>', ' </div>', ' </div>', '</div>'].join('')
const modalEl = fixtureEl.querySelector('.modal')!
const dismissBtn = fixtureEl.querySelector('[data-tblr-dismiss="modal"]') as HTMLElement
+23 -47
View File
@@ -17,15 +17,8 @@ describe('Offcanvas', () => {
}
})
const createOffcanvasHTML = () => [
'<div class="offcanvas offcanvas-start" tabindex="-1">',
' <div class="offcanvas-header">',
' <h5 class="offcanvas-title">Offcanvas</h5>',
' <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>',
' </div>',
' <div class="offcanvas-body">Content</div>',
'</div>'
].join('')
const createOffcanvasHTML = () =>
['<div class="offcanvas offcanvas-start" tabindex="-1">', ' <div class="offcanvas-header">', ' <h5 class="offcanvas-title">Offcanvas</h5>', ' <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>', ' </div>', ' <div class="offcanvas-body">Content</div>', '</div>'].join('')
describe('VERSION', () => {
it('should return plugin version', () => {
@@ -68,7 +61,7 @@ describe('Offcanvas', () => {
describe('toggle', () => {
it('should show when hidden', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
@@ -83,7 +76,7 @@ describe('Offcanvas', () => {
})
it('should hide when shown', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
@@ -104,7 +97,7 @@ describe('Offcanvas', () => {
describe('show', () => {
it('should show offcanvas', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
@@ -122,7 +115,7 @@ describe('Offcanvas', () => {
})
it('should not show if already shown', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
@@ -145,12 +138,12 @@ describe('Offcanvas', () => {
})
it('should not show if show event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
el.addEventListener('show.bs.offcanvas', event => {
el.addEventListener('show.bs.offcanvas', (event) => {
event.preventDefault()
setTimeout(() => {
expect(instance._isShown).toBe(false)
@@ -163,7 +156,7 @@ describe('Offcanvas', () => {
})
it('should pass relatedTarget in show event', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML() + '<button id="trigger">Open</button>'
const el = fixtureEl.querySelector('.offcanvas')!
const trigger = fixtureEl.querySelector('#trigger') as HTMLElement
@@ -181,7 +174,7 @@ describe('Offcanvas', () => {
describe('hide', () => {
it('should hide offcanvas', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
@@ -215,13 +208,13 @@ describe('Offcanvas', () => {
})
it('should not hide if hide event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
el.addEventListener('shown.bs.offcanvas', () => {
el.addEventListener('hide.bs.offcanvas', event => {
el.addEventListener('hide.bs.offcanvas', (event) => {
event.preventDefault()
setTimeout(() => {
expect(instance._isShown).toBe(true)
@@ -250,7 +243,7 @@ describe('Offcanvas', () => {
describe('keyboard', () => {
it('should close on Escape when keyboard is true', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el, { keyboard: true })
@@ -269,7 +262,7 @@ describe('Offcanvas', () => {
})
it('should fire hidePrevented when keyboard is false and Escape pressed', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
new Offcanvas(el, { keyboard: false })
@@ -287,7 +280,7 @@ describe('Offcanvas', () => {
})
it('should ignore non-Escape keys', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el)
@@ -340,7 +333,7 @@ describe('Offcanvas', () => {
describe('scroll option', () => {
it('should not hide scrollbar when scroll is true', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el, { scroll: true })
@@ -357,7 +350,7 @@ describe('Offcanvas', () => {
describe('backdrop option', () => {
it('should work with backdrop set to false', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = createOffcanvasHTML()
const el = fixtureEl.querySelector('.offcanvas')!
const instance = new Offcanvas(el, { backdrop: false })
@@ -382,13 +375,8 @@ describe('Offcanvas', () => {
describe('data-tblr-toggle', () => {
it('should open offcanvas via data-tblr-toggle="offcanvas"', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="offcanvas" data-bs-target="#testOffcanvas">Open</button>',
'<div class="offcanvas offcanvas-start" id="testOffcanvas" tabindex="-1">',
' <div class="offcanvas-body">Content</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="offcanvas" data-bs-target="#testOffcanvas">Open</button>', '<div class="offcanvas offcanvas-start" id="testOffcanvas" tabindex="-1">', ' <div class="offcanvas-body">Content</div>', '</div>'].join('')
const offcanvasEl = fixtureEl.querySelector('#testOffcanvas')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="offcanvas"]') as HTMLElement
@@ -404,13 +392,8 @@ describe('Offcanvas', () => {
})
it('should open offcanvas via data-tblr-toggle with data-tblr-target', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button data-tblr-toggle="offcanvas" data-tblr-target="#testOffcanvas">Open</button>',
'<div class="offcanvas offcanvas-start" id="testOffcanvas" tabindex="-1">',
' <div class="offcanvas-body">Content</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="offcanvas" data-tblr-target="#testOffcanvas">Open</button>', '<div class="offcanvas offcanvas-start" id="testOffcanvas" tabindex="-1">', ' <div class="offcanvas-body">Content</div>', '</div>'].join('')
const offcanvasEl = fixtureEl.querySelector('#testOffcanvas')!
const btn = fixtureEl.querySelector('[data-tblr-toggle="offcanvas"]') as HTMLElement
@@ -428,15 +411,8 @@ describe('Offcanvas', () => {
describe('data-tblr-dismiss', () => {
it('should close offcanvas via data-tblr-dismiss="offcanvas"', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="offcanvas offcanvas-start" tabindex="-1">',
' <div class="offcanvas-header">',
' <button type="button" class="btn-close" data-tblr-dismiss="offcanvas"></button>',
' </div>',
' <div class="offcanvas-body">Content</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="offcanvas offcanvas-start" tabindex="-1">', ' <div class="offcanvas-header">', ' <button type="button" class="btn-close" data-tblr-dismiss="offcanvas"></button>', ' </div>', ' <div class="offcanvas-body">Content</div>', '</div>'].join('')
const el = fixtureEl.querySelector('.offcanvas')!
const dismissBtn = fixtureEl.querySelector('[data-tblr-dismiss="offcanvas"]') as HTMLElement
+6 -6
View File
@@ -7,8 +7,8 @@ vi.mock('@popperjs/core', () => ({
createPopper: vi.fn(() => ({
destroy: vi.fn(),
update: vi.fn(),
setOptions: vi.fn()
}))
setOptions: vi.fn(),
})),
}))
describe('Popover', () => {
@@ -77,7 +77,7 @@ describe('Popover', () => {
describe('show', () => {
it('should show popover', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Popover title" data-bs-content="Content">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const popover = new Popover(el, { animation: false })
@@ -93,7 +93,7 @@ describe('Popover', () => {
})
it('should show popover with only content', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const popover = new Popover(el, { content: 'Only content', animation: false })
@@ -108,7 +108,7 @@ describe('Popover', () => {
})
it('should show popover with only title', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Only title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const popover = new Popover(el, { animation: false })
@@ -125,7 +125,7 @@ describe('Popover', () => {
describe('hide', () => {
it('should hide popover', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="Content">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const popover = new Popover(el, { animation: false })
+28 -82
View File
@@ -12,7 +12,7 @@ class MockIntersectionObserver implements IntersectionObserver {
constructor(callback: IntersectionObserverCallback, options?: IntersectionObserverInit) {
this.callback = callback
this.options = options
this.root = options?.root as Element | null ?? null
this.root = (options?.root as Element | null) ?? null
this.rootMargin = options?.rootMargin ?? ''
this.thresholds = Array.isArray(options?.threshold) ? options!.threshold : [options?.threshold ?? 0]
}
@@ -23,16 +23,8 @@ class MockIntersectionObserver implements IntersectionObserver {
takeRecords = vi.fn().mockReturnValue([])
}
const getDummyFixture = () => [
'<nav id="navBar" class="navbar">',
' <ul class="nav">',
' <li class="nav-item"><a id="li-jsm-1" class="nav-link" href="#div-jsm-1">div 1</a></li>',
' </ul>',
'</nav>',
'<div class="content" data-bs-target="#navBar" style="overflow-y: auto">',
' <div id="div-jsm-1">div 1</div>',
'</div>'
].join('')
const getDummyFixture = () =>
['<nav id="navBar" class="navbar">', ' <ul class="nav">', ' <li class="nav-item"><a id="li-jsm-1" class="nav-link" href="#div-jsm-1">div 1</a></li>', ' </ul>', '</nav>', '<div class="content" data-bs-target="#navBar" style="overflow-y: auto">', ' <div id="div-jsm-1">div 1</div>', '</div>'].join('')
describe('ScrollSpy', () => {
let fixtureEl: HTMLElement
@@ -82,16 +74,7 @@ describe('ScrollSpy', () => {
})
it('should set _rootElement to null if overflowY is visible', () => {
fixtureEl.innerHTML = [
'<nav id="navigation" class="navbar">',
' <ul class="navbar-nav">',
' <li class="nav-item"><a class="nav-link" href="#one">One</a></li>',
' </ul>',
'</nav>',
'<div id="content" style="overflow-y: visible;">',
' <div id="one" style="height: 300px;">test</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<nav id="navigation" class="navbar">', ' <ul class="navbar-nav">', ' <li class="nav-item"><a class="nav-link" href="#one">One</a></li>', ' </ul>', '</nav>', '<div id="content" style="overflow-y: visible;">', ' <div id="one" style="height: 300px;">test</div>', '</div>'].join('')
const contentEl = fixtureEl.querySelector('#content')!
const originalGetComputedStyle = window.getComputedStyle
@@ -102,7 +85,7 @@ describe('ScrollSpy', () => {
get(target, prop) {
if (prop === 'overflowY') return 'visible'
return (target as any)[prop]
}
},
}) as CSSStyleDeclaration
}
@@ -110,42 +93,28 @@ describe('ScrollSpy', () => {
})
const scrollSpy = new ScrollSpy(contentEl, {
target: '#navigation'
target: '#navigation',
})
expect(scrollSpy._rootElement).toBeNull()
})
it('should respect threshold option', () => {
fixtureEl.innerHTML = [
'<ul id="navigation" class="navbar">',
' <a class="nav-link" href="#one">One</a>',
'</ul>',
'<div id="content">',
' <div id="one">test</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<ul id="navigation" class="navbar">', ' <a class="nav-link" href="#one">One</a>', '</ul>', '<div id="content">', ' <div id="one">test</div>', '</div>'].join('')
const scrollSpy = new ScrollSpy('#content', {
target: '#navigation',
threshold: [1]
threshold: [1],
})
expect(scrollSpy._observer!.thresholds).toEqual([1])
})
it('should parse string threshold from data attribute', () => {
fixtureEl.innerHTML = [
'<ul id="navigation" class="navbar">',
' <a class="nav-link" href="#one">One</a>',
'</ul>',
'<div id="content" data-bs-threshold="0,0.2,1">',
' <div id="one">test</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<ul id="navigation" class="navbar">', ' <a class="nav-link" href="#one">One</a>', '</ul>', '<div id="content" data-bs-threshold="0,0.2,1">', ' <div id="one">test</div>', '</div>'].join('')
const scrollSpy = new ScrollSpy('#content', {
target: '#navigation'
target: '#navigation',
})
expect(scrollSpy._observer!.thresholds).toEqual([0, 0.2, 1])
@@ -161,11 +130,11 @@ describe('ScrollSpy', () => {
'</nav>',
'<div id="content" style="height: 200px; overflow-y: auto;">',
' <div id="two" style="height: 300px;">test</div>',
'</div>'
'</div>',
].join('')
const scrollSpy = new ScrollSpy(fixtureEl.querySelector('#content')!, {
target: '#navigation'
target: '#navigation',
})
// jsdom elements are not "visible" (getClientRects returns empty), so maps are empty
@@ -267,10 +236,7 @@ describe('ScrollSpy', () => {
describe('event handler', () => {
it('should create scrollspy on window load event', () => {
fixtureEl.innerHTML = [
'<div id="nav"></div>',
'<div id="wrapper" data-bs-spy="scroll" data-bs-target="#nav" style="overflow-y: auto"></div>'
].join('')
fixtureEl.innerHTML = ['<div id="nav"></div>', '<div id="wrapper" data-bs-spy="scroll" data-bs-target="#nav" style="overflow-y: auto"></div>'].join('')
const scrollSpyEl = fixtureEl.querySelector('#wrapper')!
@@ -297,7 +263,7 @@ describe('ScrollSpy', () => {
const entry = {
isIntersecting: true,
target: section,
intersectionRatio: 1
intersectionRatio: 1,
} as unknown as IntersectionObserverEntry
Object.defineProperty(section, 'offsetTop', { value: 100, configurable: true })
@@ -322,7 +288,7 @@ describe('ScrollSpy', () => {
const entry = {
isIntersecting: false,
target: section
target: section,
} as unknown as IntersectionObserverEntry
scrollSpy._observerCallback([entry])
@@ -350,7 +316,7 @@ describe('ScrollSpy', () => {
const entry = {
isIntersecting: true,
target: section,
intersectionRatio: 1
intersectionRatio: 1,
} as unknown as IntersectionObserverEntry
scrollSpy._observerCallback([entry])
@@ -378,7 +344,7 @@ describe('ScrollSpy', () => {
const entry = {
isIntersecting: true,
target: section,
intersectionRatio: 1
intersectionRatio: 1,
} as unknown as IntersectionObserverEntry
scrollSpy._observerCallback([entry])
@@ -406,7 +372,7 @@ describe('ScrollSpy', () => {
const entry = {
isIntersecting: true,
target: section,
intersectionRatio: 1
intersectionRatio: 1,
} as unknown as IntersectionObserverEntry
const spy = vi.fn()
@@ -451,7 +417,7 @@ describe('ScrollSpy', () => {
'</nav>',
'<div class="content" style="overflow-y: auto">',
' <div id="one">one</div>',
'</div>'
'</div>',
].join('')
const div = fixtureEl.querySelector('.content')!
@@ -465,16 +431,7 @@ describe('ScrollSpy', () => {
})
it('should activate nav parents for nav-link target', () => {
fixtureEl.innerHTML = [
'<nav class="navbar">',
' <nav class="nav">',
' <a class="nav-link" id="a1" href="#one">One</a>',
' </nav>',
'</nav>',
'<div class="content" style="overflow-y: auto">',
' <div id="one">one</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<nav class="navbar">', ' <nav class="nav">', ' <a class="nav-link" id="a1" href="#one">One</a>', ' </nav>', '</nav>', '<div class="content" style="overflow-y: auto">', ' <div id="one">one</div>', '</div>'].join('')
const div = fixtureEl.querySelector('.content')!
const scrollSpy = new ScrollSpy(div)
@@ -489,15 +446,7 @@ describe('ScrollSpy', () => {
describe('_clearActiveClass', () => {
it('should remove active class from parent and children', () => {
fixtureEl.innerHTML = [
'<nav class="navbar active">',
' <a class="nav-link active" href="#one">One</a>',
' <a class="nav-link active" href="#two">Two</a>',
'</nav>',
'<div class="content" style="overflow-y: auto">',
' <div id="one">one</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<nav class="navbar active">', ' <a class="nav-link active" href="#one">One</a>', ' <a class="nav-link active" href="#two">Two</a>', '</nav>', '<div class="content" style="overflow-y: auto">', ' <div id="one">one</div>', '</div>'].join('')
const div = fixtureEl.querySelector('.content')!
const scrollSpy = new ScrollSpy(div)
@@ -521,7 +470,7 @@ describe('ScrollSpy', () => {
Object.defineProperty(section, 'getClientRects', {
value: () => [{ width: 100, height: 100 }],
configurable: true
configurable: true,
})
scrollSpy._initializeTargetsAndObservables()
@@ -541,7 +490,7 @@ describe('ScrollSpy', () => {
'<div class="content" style="overflow-y: auto">',
' <div id="div1">div 1</div>',
' <div id="div2">div 2</div>',
'</div>'
'</div>',
].join('')
const div = fixtureEl.querySelector('.content')!
@@ -563,7 +512,7 @@ describe('ScrollSpy', () => {
'<div class="content" style="overflow-y: auto">',
' <div id="one">one</div>',
' <div id="two">two</div>',
'</div>'
'</div>',
].join('')
const div = fixtureEl.querySelector('.content')!
@@ -600,7 +549,7 @@ describe('ScrollSpy', () => {
const section = fixtureEl.querySelector('#div-jsm-1') as HTMLElement
Object.defineProperty(section, 'getClientRects', {
value: () => [{ width: 100, height: 100 }],
configurable: true
configurable: true,
})
const scrollSpy = new ScrollSpy(div, { offset: 1, smoothScroll: true })
@@ -619,7 +568,7 @@ describe('ScrollSpy', () => {
const section = fixtureEl.querySelector('#div-jsm-1') as HTMLElement
Object.defineProperty(section, 'getClientRects', {
value: () => [{ width: 100, height: 100 }],
configurable: true
configurable: true,
})
// Manually set _rootElement to a plain object without scrollTo
@@ -650,7 +599,7 @@ describe('ScrollSpy', () => {
'</nav>',
'<div class="content" data-bs-target="#navBar" style="overflow-y: auto">',
' <div id="div-jsm-1">div 1</div>',
'</div>'
'</div>',
].join('')
const div = fixtureEl.querySelector('.content') as HTMLElement
@@ -666,10 +615,7 @@ describe('ScrollSpy', () => {
describe('data-tblr-spy', () => {
it('should create scrollspy on window load with data-tblr-spy="scroll"', () => {
fixtureEl.innerHTML = [
'<div id="nav"></div>',
'<div id="wrapper" data-tblr-spy="scroll" data-bs-target="#nav" style="overflow-y: auto"></div>'
].join('')
fixtureEl.innerHTML = ['<div id="nav"></div>', '<div id="wrapper" data-tblr-spy="scroll" data-bs-target="#nav" style="overflow-y: auto"></div>'].join('')
const scrollSpyEl = fixtureEl.querySelector('#wrapper')!
+45 -119
View File
@@ -22,14 +22,7 @@ describe('Tab', () => {
describe('constructor', () => {
it('should accept element as CSS selector or DOM element', () => {
fixtureEl.innerHTML = [
'<ul class="nav">',
' <li><a href="#home" role="tab">Home</a></li>',
'</ul>',
'<ul>',
' <li id="home"></li>',
'</ul>'
].join('')
fixtureEl.innerHTML = ['<ul class="nav">', ' <li><a href="#home" role="tab">Home</a></li>', '</ul>', '<ul>', ' <li id="home"></li>', '</ul>'].join('')
const tabEl = fixtureEl.querySelector('[href="#home"]')!
const tabBySelector = new Tab('[href="#home"]')
@@ -51,7 +44,7 @@ describe('Tab', () => {
describe('show', () => {
it('should activate element by tab id using buttons', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><button type="button" data-bs-target="#home" role="tab">Home</button></li>',
@@ -60,7 +53,7 @@ describe('Tab', () => {
'<ul>',
' <li id="home" role="tabpanel"></li>',
' <li id="profile" role="tabpanel"></li>',
'</ul>'
'</ul>',
].join('')
const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')!
@@ -77,17 +70,8 @@ describe('Tab', () => {
})
it('should activate element by tab id using links', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><a href="#home" role="tab">Home</a></li>',
' <li><a id="triggerProfile" href="#profile" role="tab">Profile</a></li>',
'</ul>',
'<ul>',
' <li id="home" role="tabpanel"></li>',
' <li id="profile" role="tabpanel"></li>',
'</ul>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<ul class="nav" role="tablist">', ' <li><a href="#home" role="tab">Home</a></li>', ' <li><a id="triggerProfile" href="#profile" role="tab">Profile</a></li>', '</ul>', '<ul>', ' <li id="home" role="tabpanel"></li>', ' <li id="profile" role="tabpanel"></li>', '</ul>'].join('')
const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')!
const tab = new Tab(profileTriggerEl)
@@ -103,7 +87,7 @@ describe('Tab', () => {
})
it('should activate element in list group', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div class="list-group" role="tablist">',
' <button type="button" data-bs-target="#home" role="tab">Home</button>',
@@ -112,7 +96,7 @@ describe('Tab', () => {
'<div>',
' <div id="home" role="tabpanel"></div>',
' <div id="profile" role="tabpanel"></div>',
'</div>'
'</div>',
].join('')
const profileTriggerEl = fixtureEl.querySelector('#triggerProfile')!
@@ -134,7 +118,7 @@ describe('Tab', () => {
const navEl = fixtureEl.querySelector('.nav > div')!
const tab = new Tab(navEl)
navEl.addEventListener('show.bs.tab', ev => {
navEl.addEventListener('show.bs.tab', (ev) => {
ev.preventDefault()
setTimeout(resolve, 30)
})
@@ -157,7 +141,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
' <div class="tab-pane" id="profile" role="tabpanel"></div>',
'</div>'
'</div>',
].join('')
const triggerActive = fixtureEl.querySelector('button.active')!
@@ -173,7 +157,7 @@ describe('Tab', () => {
})
it('show and shown events should reference correct relatedTarget', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab" aria-selected="true">Home</button></li>',
@@ -182,7 +166,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
' <div class="tab-pane" id="profile" role="tabpanel"></div>',
'</div>'
'</div>',
].join('')
const secondTabTrigger = fixtureEl.querySelector('#triggerProfile')!
@@ -203,13 +187,8 @@ describe('Tab', () => {
})
it('should fire hide and hidden events', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><button type="button" data-bs-target="#home" role="tab">Home</button></li>',
' <li><button type="button" data-bs-target="#profile" role="tab">Profile</button></li>',
'</ul>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<ul class="nav" role="tablist">', ' <li><button type="button" data-bs-target="#home" role="tab">Home</button></li>', ' <li><button type="button" data-bs-target="#profile" role="tab">Profile</button></li>', '</ul>'].join('')
const triggerList = fixtureEl.querySelectorAll('button')
const firstTab = new Tab(triggerList[0])
@@ -237,12 +216,7 @@ describe('Tab', () => {
it('should not fire hidden when hide is prevented', () => {
return new Promise<void>((resolve, reject) => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><button type="button" data-bs-target="#home" role="tab">Home</button></li>',
' <li><button type="button" data-bs-target="#profile" role="tab">Profile</button></li>',
'</ul>'
].join('')
fixtureEl.innerHTML = ['<ul class="nav" role="tablist">', ' <li><button type="button" data-bs-target="#home" role="tab">Home</button></li>', ' <li><button type="button" data-bs-target="#profile" role="tab">Profile</button></li>', '</ul>'].join('')
const triggerList = fixtureEl.querySelectorAll('button')
const firstTab = new Tab(triggerList[0])
@@ -252,7 +226,7 @@ describe('Tab', () => {
secondTab.show()
})
triggerList[0].addEventListener('hide.bs.tab', ev => {
triggerList[0].addEventListener('hide.bs.tab', (ev) => {
ev.preventDefault()
setTimeout(resolve, 30)
})
@@ -283,11 +257,7 @@ describe('Tab', () => {
describe('_activate', () => {
it('should not be called if element is null', () => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li class="nav-link"></li>',
'</ul>'
].join('')
fixtureEl.innerHTML = ['<ul class="nav" role="tablist">', ' <li class="nav-link"></li>', '</ul>'].join('')
const tabEl = fixtureEl.querySelector('.nav-link')!
const tab = new Tab(tabEl)
@@ -300,14 +270,7 @@ describe('Tab', () => {
describe('_setInitialAttributes', () => {
it('should set aria attributes', () => {
fixtureEl.innerHTML = [
'<ul class="nav">',
' <li class="nav-link" id="foo" data-bs-target="#panel"></li>',
' <li class="nav-link" data-bs-target="#panel2"></li>',
'</ul>',
'<div id="panel"></div>',
'<div id="panel2"></div>'
].join('')
fixtureEl.innerHTML = ['<ul class="nav">', ' <li class="nav-link" id="foo" data-bs-target="#panel"></li>', ' <li class="nav-link" data-bs-target="#panel2"></li>', '</ul>', '<div id="panel"></div>', '<div id="panel2"></div>'].join('')
const tabEl = fixtureEl.querySelector('.nav-link')!
const parent = fixtureEl.querySelector('.nav') as HTMLElement
@@ -331,11 +294,7 @@ describe('Tab', () => {
describe('_keydown', () => {
it('should ignore non-arrow keys', () => {
fixtureEl.innerHTML = [
'<ul class="nav">',
' <li class="nav-link" data-bs-toggle="tab"></li>',
'</ul>'
].join('')
fixtureEl.innerHTML = ['<ul class="nav">', ' <li class="nav-link" data-bs-toggle="tab"></li>', '</ul>'].join('')
const tabEl = fixtureEl.querySelector('.nav-link')!
const tab = new Tab(tabEl)
@@ -352,13 +311,7 @@ describe('Tab', () => {
})
it('should handle right/down arrow', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="nav">', ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>', '</div>'].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')!
const tabEl2 = fixtureEl.querySelector('#tab2')!
@@ -377,12 +330,7 @@ describe('Tab', () => {
})
it('should handle left/up arrow', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="nav">', ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>', '</div>'].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')!
const tabEl2 = fixtureEl.querySelector('#tab2')!
@@ -398,13 +346,7 @@ describe('Tab', () => {
})
it('should handle Home key', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="nav">', ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>', '</div>'].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')!
const tabEl3 = fixtureEl.querySelector('#tab3')!
@@ -420,13 +362,7 @@ describe('Tab', () => {
})
it('should handle End key', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="nav">', ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>', ' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>', '</div>'].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')!
const tabEl3 = fixtureEl.querySelector('#tab3')!
@@ -448,7 +384,7 @@ describe('Tab', () => {
' <span id="tab2" class="nav-link" data-bs-toggle="tab" disabled></span>',
' <span id="tab3" class="nav-link disabled" data-bs-toggle="tab"></span>',
' <span id="tab4" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
'</div>',
].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')!
@@ -504,7 +440,7 @@ describe('Tab', () => {
describe('data-api', () => {
it('should create dynamically a tab', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab" aria-selected="true">Home</button></li>',
@@ -513,7 +449,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
' <div class="tab-pane" id="profile" role="tabpanel"></div>',
'</div>'
'</div>',
].join('')
const secondTabTrigger = fixtureEl.querySelector('#triggerProfile')!
@@ -529,13 +465,8 @@ describe('Tab', () => {
})
it('should prevent default when trigger is <a>', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><a type="button" href="#test" class="active" role="tab" data-bs-toggle="tab">Home</a></li>',
' <li><a type="button" href="#test2" role="tab" data-bs-toggle="tab">Profile</a></li>',
'</ul>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<ul class="nav" role="tablist">', ' <li><a type="button" href="#test" class="active" role="tab" data-bs-toggle="tab">Home</a></li>', ' <li><a type="button" href="#test2" role="tab" data-bs-toggle="tab">Profile</a></li>', '</ul>'].join('')
const tabEl = fixtureEl.querySelector('[href="#test2"]') as HTMLElement
const spy = vi.spyOn(Event.prototype, 'preventDefault')
@@ -556,7 +487,7 @@ describe('Tab', () => {
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab">Home</button></li>',
' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#profile" class="nav-link" disabled role="tab" data-bs-toggle="tab">Profile</button></li>',
'</ul>'
'</ul>',
].join('')
const triggerDisabled = fixtureEl.querySelector('button[disabled]')!
@@ -575,7 +506,7 @@ describe('Tab', () => {
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab" data-bs-toggle="tab">Home</a></li>',
' <li class="nav-item" role="presentation"><a href="#profile" class="nav-link disabled" role="tab" data-bs-toggle="tab">Profile</a></li>',
'</ul>'
'</ul>',
].join('')
const triggerDisabled = fixtureEl.querySelector('a.disabled')!
@@ -589,7 +520,7 @@ describe('Tab', () => {
})
it('should handle nested tabs', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<nav class="nav nav-tabs" role="tablist">',
' <button type="button" id="tab1" data-bs-target="#x-tab1" class="nav-link" data-bs-toggle="tab" role="tab">Tab 1</button>',
@@ -607,7 +538,7 @@ describe('Tab', () => {
' </div>',
' </div>',
' <div class="tab-pane active" id="x-tab2" role="tabpanel">Tab2</div>',
'</div>'
'</div>',
].join('')
const tab1El = fixtureEl.querySelector('#tab1') as HTMLElement
@@ -640,7 +571,7 @@ describe('Tab', () => {
' <a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-bs-toggle="tab">@mdo</a>',
' </div>',
' </li>',
'</ul>'
'</ul>',
].join('')
const firstLiLinkEl = fixtureEl.querySelector('li:first-child a') as HTMLElement
@@ -670,7 +601,7 @@ describe('Tab', () => {
' <a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-bs-toggle="tab">@fat</a>',
' </div>',
' </li>',
'</ul>'
'</ul>',
].join('')
const firstDropItem = fixtureEl.querySelector('#nav1 .dropdown-item') as HTMLElement
@@ -693,7 +624,7 @@ describe('Tab', () => {
' <li><a class="dropdown-item" href="#dropdown2" data-bs-toggle="tab">@mdo</a></li>',
' </ul>',
' </li>',
'</ul>'
'</ul>',
].join('')
const dropItems = fixtureEl.querySelectorAll('.dropdown-item')
@@ -705,7 +636,7 @@ describe('Tab', () => {
})
it('should add show class to pane without fade', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation">',
@@ -718,7 +649,7 @@ describe('Tab', () => {
'<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>'
'</div>',
].join('')
const secondNavEl = fixtureEl.querySelector('#secondNav') as HTMLElement
@@ -735,7 +666,7 @@ describe('Tab', () => {
describe('data-tblr-toggle', () => {
it('should create tab via data-tblr-toggle="tab"', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab" aria-selected="true">Home</button></li>',
@@ -744,7 +675,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
' <div class="tab-pane" id="profile" role="tabpanel"></div>',
'</div>'
'</div>',
].join('')
const trigger = fixtureEl.querySelector('#triggerProfile') as HTMLElement
@@ -760,7 +691,7 @@ describe('Tab', () => {
})
it('should create tab via data-tblr-toggle="pill"', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav nav-pills" role="tablist">',
' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab" aria-selected="true">Home</button></li>',
@@ -769,7 +700,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
' <div class="tab-pane" id="profile" role="tabpanel"></div>',
'</div>'
'</div>',
].join('')
const trigger = fixtureEl.querySelector('#triggerProfile') as HTMLElement
@@ -784,12 +715,7 @@ describe('Tab', () => {
})
it('should initialize active tabs with data-tblr-toggle on load', () => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><button class="nav-link active" data-tblr-toggle="tab" data-bs-target="#home" role="tab">Home</button></li>',
'</ul>',
'<div id="home" role="tabpanel"></div>'
].join('')
fixtureEl.innerHTML = ['<ul class="nav" role="tablist">', ' <li><button class="nav-link active" data-tblr-toggle="tab" data-bs-target="#home" role="tab">Home</button></li>', '</ul>', '<div id="home" role="tabpanel"></div>'].join('')
const trigger = fixtureEl.querySelector('button') as HTMLElement
@@ -799,7 +725,7 @@ describe('Tab', () => {
})
it('should create tab via data-tblr-toggle="list"', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<div class="list-group" role="tablist">',
' <a class="list-group-item list-group-item-action active" data-tblr-toggle="list" href="#home" role="tab">Home</a>',
@@ -808,7 +734,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel">Home</div>',
' <div class="tab-pane" id="profile" role="tabpanel">Profile</div>',
'</div>'
'</div>',
].join('')
const trigger = fixtureEl.querySelector('#triggerProfile') as HTMLElement
@@ -823,7 +749,7 @@ describe('Tab', () => {
})
it('should switch tabs via data-tblr-toggle with data-tblr-target', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = [
'<ul class="nav" role="tablist">',
' <li><button class="nav-link active" data-tblr-toggle="tab" data-tblr-target="#home" role="tab">Home</button></li>',
@@ -832,7 +758,7 @@ describe('Tab', () => {
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel">Home</div>',
' <div class="tab-pane" id="profile" role="tabpanel">Profile</div>',
'</div>'
'</div>',
].join('')
const trigger = fixtureEl.querySelector('#triggerProfile') as HTMLElement
+34 -107
View File
@@ -38,12 +38,8 @@ describe('Toast', () => {
})
it('should allow config in js', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('div')!
const toast = new Toast(toastEl, { delay: 1 })
@@ -58,12 +54,8 @@ describe('Toast', () => {
})
it('should close toast when dismiss button is clicked', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1" data-bs-autohide="false" data-bs-animation="false">',
' <button type="button" class="btn-close" data-bs-dismiss="toast"></button>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1" data-bs-autohide="false" data-bs-animation="false">', ' <button type="button" class="btn-close" data-bs-dismiss="toast"></button>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('div')!
const toast = new Toast(toastEl)
@@ -84,12 +76,8 @@ describe('Toast', () => {
})
it('should close toast via data-tblr-dismiss', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1" data-bs-autohide="false" data-bs-animation="false">',
' <button type="button" class="btn-close" data-tblr-dismiss="toast"></button>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1" data-bs-autohide="false" data-bs-animation="false">', ' <button type="button" class="btn-close" data-tblr-dismiss="toast"></button>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('div')!
const toast = new Toast(toastEl)
@@ -117,11 +105,7 @@ describe('Toast', () => {
Toast.Default.delay = defaultDelay
fixtureEl.innerHTML = [
'<div class="toast" data-bs-autohide="false" data-bs-animation="false">',
' <button type="button" class="btn-close" data-bs-dismiss="toast"></button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="toast" data-bs-autohide="false" data-bs-animation="false">', ' <button type="button" class="btn-close" data-bs-dismiss="toast"></button>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('div')!
const toast = new Toast(toastEl)
@@ -140,12 +124,8 @@ describe('Toast', () => {
describe('show', () => {
it('should auto hide', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -160,12 +140,8 @@ describe('Toast', () => {
})
it('should not add fade class when animation is false', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1" data-bs-animation="false">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1" data-bs-animation="false">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -181,16 +157,12 @@ describe('Toast', () => {
it('should not trigger shown if show is prevented', () => {
return new Promise<void>((resolve, reject) => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1" data-bs-animation="false">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1" data-bs-animation="false">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
toastEl.addEventListener('show.bs.toast', event => {
toastEl.addEventListener('show.bs.toast', (event) => {
event.preventDefault()
setTimeout(() => {
expect(toastEl.classList.contains('show')).toBe(false)
@@ -207,12 +179,8 @@ describe('Toast', () => {
})
it('should clear timeout on mouse interaction', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -234,13 +202,8 @@ describe('Toast', () => {
})
it('should clear timeout on keyboard interaction', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button id="outside">outside</button>',
'<div class="toast">',
' <div class="toast-body">a simple toast <button>inside</button></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button id="outside">outside</button>', '<div class="toast">', ' <div class="toast-body">a simple toast <button>inside</button></div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -263,13 +226,8 @@ describe('Toast', () => {
})
it('should still auto hide after mouse and keyboard leave', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button id="outside-focusable">outside</button>',
'<div class="toast">',
' <div class="toast-body">a simple toast <button>inside</button></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button id="outside-focusable">outside</button>', '<div class="toast">', ' <div class="toast-body">a simple toast <button>inside</button></div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -297,13 +255,8 @@ describe('Toast', () => {
})
it('should not auto hide if focus leaves but mouse remains inside', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button id="outside-focusable">outside</button>',
'<div class="toast">',
' <div class="toast-body">a simple toast <button>inside</button></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button id="outside-focusable">outside</button>', '<div class="toast">', ' <div class="toast-body">a simple toast <button>inside</button></div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -328,13 +281,8 @@ describe('Toast', () => {
})
it('should not auto hide if mouse leaves but focus remains inside', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button id="outside-focusable">outside</button>',
'<div class="toast">',
' <div class="toast-body">a simple toast <button>inside</button></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button id="outside-focusable">outside</button>', '<div class="toast">', ' <div class="toast-body">a simple toast <button>inside</button></div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -359,12 +307,8 @@ describe('Toast', () => {
})
it('should handle _onInteraction with unknown event type', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -385,13 +329,8 @@ describe('Toast', () => {
})
it('should not schedule hide when relatedTarget is within the toast', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<button id="outside-focusable">outside</button>',
'<div class="toast">',
' <div class="toast-body">a simple toast <button id="inside-btn">inside</button></div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<button id="outside-focusable">outside</button>', '<div class="toast">', ' <div class="toast-body">a simple toast <button id="inside-btn">inside</button></div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const insideBtn = toastEl.querySelector('#inside-btn')!
@@ -402,7 +341,7 @@ describe('Toast', () => {
const focusOutEvent = new FocusEvent('focusout', {
bubbles: true,
relatedTarget: insideBtn
relatedTarget: insideBtn,
})
toast._onInteraction(focusOutEvent, false)
@@ -417,12 +356,8 @@ describe('Toast', () => {
describe('hide', () => {
it('should allow to hide toast manually', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1" data-bs-autohide="false">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1" data-bs-autohide="false">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -454,11 +389,7 @@ describe('Toast', () => {
it('should not trigger hidden if hide is prevented', () => {
return new Promise<void>((resolve, reject) => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="1" data-bs-animation="false">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="1" data-bs-animation="false">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('.toast')!
const toast = new Toast(toastEl)
@@ -467,7 +398,7 @@ describe('Toast', () => {
toast.hide()
})
toastEl.addEventListener('hide.bs.toast', event => {
toastEl.addEventListener('hide.bs.toast', (event) => {
event.preventDefault()
setTimeout(() => {
expect(toastEl.classList.contains('show')).toBe(true)
@@ -499,12 +430,8 @@ describe('Toast', () => {
})
it('should destroy and hide shown toast', () => {
return new Promise<void>(resolve => {
fixtureEl.innerHTML = [
'<div class="toast" data-bs-delay="0" data-bs-autohide="false">',
' <div class="toast-body">a simple toast</div>',
'</div>'
].join('')
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = ['<div class="toast" data-bs-delay="0" data-bs-autohide="false">', ' <div class="toast-body">a simple toast</div>', '</div>'].join('')
const toastEl = fixtureEl.querySelector('div')!
const toast = new Toast(toastEl)
+14 -14
View File
@@ -6,8 +6,8 @@ vi.mock('@popperjs/core', () => ({
createPopper: vi.fn(() => ({
destroy: vi.fn(),
update: vi.fn(),
setOptions: vi.fn()
}))
setOptions: vi.fn(),
})),
}))
describe('Tooltip', () => {
@@ -145,7 +145,7 @@ describe('Tooltip', () => {
})
it('should toggle tooltip visibility', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -167,7 +167,7 @@ describe('Tooltip', () => {
describe('show', () => {
it('should show tooltip', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -192,12 +192,12 @@ describe('Tooltip', () => {
})
it('should not show if show event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
el.addEventListener('show.bs.tooltip', event => {
el.addEventListener('show.bs.tooltip', (event) => {
event.preventDefault()
setTimeout(() => {
expect(tooltip._isShown()).toBe(false)
@@ -219,7 +219,7 @@ describe('Tooltip', () => {
})
it('should fire inserted event', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -235,7 +235,7 @@ describe('Tooltip', () => {
describe('hide', () => {
it('should hide tooltip', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -263,13 +263,13 @@ describe('Tooltip', () => {
})
it('should not hide if hide event is prevented', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
el.addEventListener('shown.bs.tooltip', () => {
el.addEventListener('hide.bs.tooltip', event => {
el.addEventListener('hide.bs.tooltip', (event) => {
event.preventDefault()
setTimeout(() => {
expect(tooltip._isShown()).toBe(true)
@@ -287,7 +287,7 @@ describe('Tooltip', () => {
describe('update', () => {
it('should call popper update', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -332,7 +332,7 @@ describe('Tooltip', () => {
})
it('should destroy popper on dispose', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -360,7 +360,7 @@ describe('Tooltip', () => {
})
it('should update shown tooltip', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
@@ -527,7 +527,7 @@ describe('Tooltip', () => {
describe('_disposePopper', () => {
it('should destroy popper and remove tip', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<a href="#" title="Tooltip title">Trigger</a>'
const el = fixtureEl.querySelector('a')!
const tooltip = new Tooltip(el, { animation: false })
+15 -13
View File
@@ -22,7 +22,7 @@ describe('Backdrop', () => {
describe('show', () => {
it('should append the backdrop and include the "show" class', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, isAnimated: false })
const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
@@ -41,7 +41,7 @@ describe('Backdrop', () => {
})
it('should not append the backdrop if not visible', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: false, isAnimated: true })
const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
@@ -54,7 +54,7 @@ describe('Backdrop', () => {
})
it('should include the "fade" class if animated', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, isAnimated: true })
const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
@@ -73,7 +73,7 @@ describe('Backdrop', () => {
describe('hide', () => {
it('should remove the backdrop html', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, isAnimated: true })
const getElements = () => document.body.querySelectorAll(CLASS_BACKDROP)
@@ -89,7 +89,7 @@ describe('Backdrop', () => {
})
it('should remove the "show" class', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, isAnimated: true })
const elem = instance._getElement()
@@ -102,7 +102,7 @@ describe('Backdrop', () => {
})
it('should not try to remove if not visible', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: false, isAnimated: true })
const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
@@ -121,12 +121,14 @@ describe('Backdrop', () => {
describe('click callback', () => {
it('should execute callback on click', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
let called = false
const instance = new Backdrop({
isVisible: true,
isAnimated: false,
clickCallback: () => { called = true }
clickCallback: () => {
called = true
},
})
instance.show(() => {
@@ -143,7 +145,7 @@ describe('Backdrop', () => {
describe('Config', () => {
it('should be appended on document.body by default', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true })
instance.show(() => {
expect(document.querySelector(CLASS_BACKDROP)!.parentElement).toBe(document.body)
@@ -153,7 +155,7 @@ describe('Backdrop', () => {
})
it('should find rootElement if passed as a string', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, rootElement: 'body' })
instance.show(() => {
expect(document.querySelector(CLASS_BACKDROP)!.parentElement).toBe(document.body)
@@ -163,7 +165,7 @@ describe('Backdrop', () => {
})
it('should be appended on custom rootElement', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
fixtureEl.innerHTML = '<div id="wrapper"></div>'
const wrapper = fixtureEl.querySelector('#wrapper')!
@@ -176,7 +178,7 @@ describe('Backdrop', () => {
})
it('should allow configuring className', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, className: 'foo' })
instance.show(() => {
expect(document.querySelector('.foo')).toBe(instance._getElement())
@@ -196,7 +198,7 @@ describe('Backdrop', () => {
})
it('should remove element and reset _isAppended after show', () => {
return new Promise<void>(resolve => {
return new Promise<void>((resolve) => {
const instance = new Backdrop({ isVisible: true, isAnimated: false })
instance.show(() => {
expect(instance._isAppended).toBe(true)
@@ -30,11 +30,7 @@ describe('Component Functions', () => {
describe('data-bs-dismiss', () => {
it('should get plugin and execute given method on click', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
' <button type="button" data-bs-dismiss="test" data-bs-target="#foo"></button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="foo" class="test">', ' <button type="button" data-bs-dismiss="test" data-bs-target="#foo"></button>', '</div>'].join('')
const spyGet = vi.spyOn(DummyClass, 'getOrCreateInstance')
const spyTest = vi.spyOn(DummyClass.prototype, 'testMethod')
@@ -49,11 +45,7 @@ describe('Component Functions', () => {
})
it('should use closest class when no data-bs-target', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
' <button type="button" data-bs-dismiss="test"></button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="foo" class="test">', ' <button type="button" data-bs-dismiss="test"></button>', '</div>'].join('')
const spyGet = vi.spyOn(DummyClass, 'getOrCreateInstance')
const spyHide = vi.spyOn(DummyClass.prototype, 'hide')
@@ -68,11 +60,7 @@ describe('Component Functions', () => {
})
it('should not trigger if disabled', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
' <button type="button" disabled data-bs-dismiss="test"></button>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="foo" class="test">', ' <button type="button" disabled data-bs-dismiss="test"></button>', '</div>'].join('')
const spy = vi.spyOn(DummyClass, 'getOrCreateInstance')
@@ -85,11 +73,7 @@ describe('Component Functions', () => {
})
it('should preventDefault for <a> elements', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
' <a type="button" data-bs-dismiss="test"></a>',
'</div>'
].join('')
fixtureEl.innerHTML = ['<div id="foo" class="test">', ' <a type="button" data-bs-dismiss="test"></a>', '</div>'].join('')
enableDismissTrigger(DummyClass)
const preventSpy = vi.spyOn(Event.prototype, 'preventDefault')
+13 -10
View File
@@ -45,7 +45,7 @@ describe('Config', () => {
testBool: true,
testString: 'foo',
testString1: 'foo',
testInt: 7
testInt: 7,
})
const instance = new DummyConfigClass()
@@ -66,14 +66,17 @@ describe('Config', () => {
testBool: true,
testString: 'foo',
testString1: 'foo',
testInt: 7
testInt: 7,
})
const instance = new DummyConfigClass()
const result = instance._mergeConfigObj({
testString1: 'test',
testInt: 3
}, fixtureEl.querySelector('#test')!)
const result = instance._mergeConfigObj(
{
testString1: 'test',
testInt: 3,
},
fixtureEl.querySelector('#test')!,
)
expect(result.testBool).toBe(false)
expect(result.testString).toBe('foo')
@@ -88,7 +91,7 @@ describe('Config', () => {
vi.spyOn(DummyConfigClass, 'Default', 'get').mockReturnValue({
testInt: 7,
testInt2: 79
testInt2: 79,
})
const instance = new DummyConfigClass()
@@ -105,7 +108,7 @@ describe('Config', () => {
it('should throw TypeError for wrong config types', () => {
vi.spyOn(DummyConfigClass, 'DefaultType', 'get').mockReturnValue({
toggle: 'boolean',
parent: '(string|element)'
parent: '(string|element)',
})
const obj = new DummyConfigClass()
@@ -119,7 +122,7 @@ describe('Config', () => {
it('should accept null when type includes null', () => {
vi.spyOn(DummyConfigClass, 'DefaultType', 'get').mockReturnValue({
toggle: 'boolean',
parent: '(null|element)'
parent: '(null|element)',
})
const obj = new DummyConfigClass()
@@ -133,7 +136,7 @@ describe('Config', () => {
it('should accept undefined when type includes undefined', () => {
vi.spyOn(DummyConfigClass, 'DefaultType', 'get').mockReturnValue({
toggle: 'boolean',
parent: '(undefined|element)'
parent: '(undefined|element)',
})
const obj = new DummyConfigClass()
+4 -9
View File
@@ -6,7 +6,7 @@ vi.mock('../../../src/bootstrap/util/index', async (importOriginal) => {
const actual = await importOriginal<typeof import('../../../src/bootstrap/util/index')>()
return {
...actual,
isVisible: () => true
isVisible: () => true,
}
})
@@ -19,12 +19,7 @@ describe('FocusTrap', () => {
})
beforeEach(() => {
fixtureEl.innerHTML =
'<div id="trap" tabindex="-1">' +
'<button id="btn1">First</button>' +
'<button id="btn2">Second</button>' +
'</div>' +
'<button id="outside">Outside</button>'
fixtureEl.innerHTML = '<div id="trap" tabindex="-1">' + '<button id="btn1">First</button>' + '<button id="btn2">Second</button>' + '</div>' + '<button id="outside">Outside</button>'
trapEl = fixtureEl.querySelector('#trap')!
})
@@ -40,14 +35,14 @@ describe('FocusTrap', () => {
it('Default should have correct values', () => {
expect(FocusTrap.Default).toEqual({
autofocus: true,
trapElement: null
trapElement: null,
})
})
it('DefaultType should have correct values', () => {
expect(FocusTrap.DefaultType).toEqual({
autofocus: 'boolean',
trapElement: 'element'
trapElement: 'element',
})
})
})
+4 -21
View File
@@ -1,22 +1,5 @@
import { describe, it, expect, beforeAll, beforeEach, afterEach, vi } from 'vitest'
import {
execute,
executeAfterTransition,
findShadowRoot,
getElement,
getNextActiveElement,
getTransitionDurationFromElement,
getUID,
isDisabled,
isElement,
isRTL,
isVisible,
noop,
parseSelector,
reflow,
toType,
triggerTransitionEnd
} from '../../../src/bootstrap/util/index'
import { execute, executeAfterTransition, findShadowRoot, getElement, getNextActiveElement, getTransitionDurationFromElement, getUID, isDisabled, isElement, isRTL, isVisible, noop, parseSelector, reflow, toType, triggerTransitionEnd } from '../../../src/bootstrap/util/index'
import { clearFixture, getFixture } from '../../helpers/fixture'
describe('util/index', () => {
@@ -44,7 +27,7 @@ describe('util/index', () => {
const original = window.CSS
Object.defineProperty(window, 'CSS', {
value: { escape: vi.fn((s: string) => s) },
configurable: true
configurable: true,
})
parseSelector('#test-id')
expect(window.CSS.escape).toHaveBeenCalledWith('test-id')
@@ -119,7 +102,7 @@ describe('util/index', () => {
const div = fixtureEl.querySelector('div')!
vi.spyOn(window, 'getComputedStyle').mockReturnValue({
transitionDuration: '0.3s',
transitionDelay: '0.1s'
transitionDelay: '0.1s',
} as CSSStyleDeclaration)
expect(getTransitionDurationFromElement(div)).toBe(400)
vi.restoreAllMocks()
@@ -130,7 +113,7 @@ describe('util/index', () => {
const div = fixtureEl.querySelector('div')!
vi.spyOn(window, 'getComputedStyle').mockReturnValue({
transitionDuration: '0.5s, 0.2s',
transitionDelay: '0.1s, 0s'
transitionDelay: '0.1s, 0s',
} as CSSStyleDeclaration)
expect(getTransitionDurationFromElement(div)).toBe(600)
vi.restoreAllMocks()
+1 -1
View File
@@ -5,7 +5,7 @@ describe('sanitizer', () => {
describe('DefaultAllowlist', () => {
it('should have a wildcard entry with common attributes', () => {
expect(DefaultAllowlist['*']).toBeDefined()
const wildcardStrings = DefaultAllowlist['*'].filter(a => typeof a === 'string')
const wildcardStrings = DefaultAllowlist['*'].filter((a) => typeof a === 'string')
expect(wildcardStrings).toContain('class')
expect(wildcardStrings).toContain('id')
expect(wildcardStrings).toContain('role')
+34 -26
View File
@@ -5,7 +5,7 @@ import { clearFixture, getFixture } from '../../helpers/fixture'
function mockTouchSupport() {
Object.defineProperty(document.documentElement, 'ontouchstart', {
value: () => {},
configurable: true
configurable: true,
})
}
@@ -26,7 +26,7 @@ function createTouchEvent(type: string, touches: Array<{ clientX: number }>, tar
radiusX: 0,
radiusY: 0,
rotationAngle: 0,
force: 0
force: 0,
})) as unknown as Touch[]
const event = new Event(type, { bubbles: true, cancelable: true }) as TouchEvent
@@ -40,8 +40,8 @@ function createPointerEvent(type: string, opts: Partial<PointerEvent> = {}): Poi
bubbles: true,
cancelable: true,
clientX: opts.clientX ?? 0,
pointerType: (opts as Record<string, unknown>).pointerType as string ?? 'touch',
...opts
pointerType: ((opts as Record<string, unknown>).pointerType as string) ?? 'touch',
...opts,
})
}
@@ -162,16 +162,20 @@ describe('Swipe', () => {
const leftCallback = vi.fn()
const swipe = new Swipe(div, { leftCallback })
div.dispatchEvent(new PointerEvent('pointerdown', {
bubbles: true,
clientX: 300,
pointerType: 'mouse'
}))
div.dispatchEvent(new PointerEvent('pointerup', {
bubbles: true,
clientX: 100,
pointerType: 'mouse'
}))
div.dispatchEvent(
new PointerEvent('pointerdown', {
bubbles: true,
clientX: 300,
pointerType: 'mouse',
}),
)
div.dispatchEvent(
new PointerEvent('pointerup', {
bubbles: true,
clientX: 100,
pointerType: 'mouse',
}),
)
expect(leftCallback).not.toHaveBeenCalled()
swipe.dispose()
@@ -181,16 +185,20 @@ describe('Swipe', () => {
const leftCallback = vi.fn()
const swipe = new Swipe(div, { leftCallback })
div.dispatchEvent(new PointerEvent('pointerdown', {
bubbles: true,
clientX: 300,
pointerType: 'pen'
}))
div.dispatchEvent(new PointerEvent('pointerup', {
bubbles: true,
clientX: 100,
pointerType: 'pen'
}))
div.dispatchEvent(
new PointerEvent('pointerdown', {
bubbles: true,
clientX: 300,
pointerType: 'pen',
}),
)
div.dispatchEvent(
new PointerEvent('pointerup', {
bubbles: true,
clientX: 100,
pointerType: 'pen',
}),
)
expect(leftCallback).toHaveBeenCalledOnce()
swipe.dispose()
@@ -296,7 +304,7 @@ describe('Swipe', () => {
expect(Swipe.Default).toEqual({
endCallback: null,
leftCallback: null,
rightCallback: null
rightCallback: null,
})
})
@@ -304,7 +312,7 @@ describe('Swipe', () => {
expect(Swipe.DefaultType).toEqual({
endCallback: '(function|null)',
leftCallback: '(function|null)',
rightCallback: '(function|null)'
rightCallback: '(function|null)',
})
})
})
@@ -30,7 +30,7 @@ describe('TemplateFactory', () => {
it('should sanitize template by default', () => {
const factory = new TemplateFactory({
sanitize: true,
template: '<div><a href="javascript:alert(7)">Click me</a></div>'
template: '<div><a href="javascript:alert(7)">Click me</a></div>',
})
expect(factory.toHtml().innerHTML).not.toContain('href="javascript:alert(7)')
})
@@ -38,7 +38,7 @@ describe('TemplateFactory', () => {
it('should not sanitize template if disabled', () => {
const factory = new TemplateFactory({
sanitize: false,
template: '<div><a href="javascript:alert(7)">Click me</a></div>'
template: '<div><a href="javascript:alert(7)">Click me</a></div>',
})
expect(factory.toHtml().innerHTML).toContain('href="javascript:alert(7)')
})
@@ -48,7 +48,7 @@ describe('TemplateFactory', () => {
sanitize: true,
html: true,
template: '<div id="foo"></div>',
content: { '#foo': '<a href="javascript:alert(7)">Click me</a>' }
content: { '#foo': '<a href="javascript:alert(7)">Click me</a>' },
})
expect(factory.toHtml().innerHTML).not.toContain('href="javascript:alert(7)')
})
@@ -58,7 +58,7 @@ describe('TemplateFactory', () => {
sanitize: false,
html: true,
template: '<div id="foo"></div>',
content: { '#foo': '<a href="javascript:alert(7)">Click me</a>' }
content: { '#foo': '<a href="javascript:alert(7)">Click me</a>' },
})
expect(factory.toHtml().innerHTML).toContain('href="javascript:alert(7)')
})
@@ -81,7 +81,7 @@ describe('TemplateFactory', () => {
const factory = new TemplateFactory({
extraClass() {
return 'testClass'
}
},
})
expect(factory.toHtml().classList.contains('testClass')).toBe(true)
})
@@ -93,7 +93,7 @@ describe('TemplateFactory', () => {
const template = '<div><div class="foo"></div><div class="foo2"></div></div>'
const factory = new TemplateFactory({
template,
content: { '.foo': 'bar', '.foo2': 'bar2' }
content: { '.foo': 'bar', '.foo2': 'bar2' },
})
const html = factory.toHtml()
@@ -106,7 +106,7 @@ describe('TemplateFactory', () => {
sanitize: true,
html: true,
template: '<div id="foo"></div>',
content: { '#bar': 'test' }
content: { '#bar': 'test' },
})
expect(factory.toHtml().outerHTML).toBe('<div id="foo"></div>')
})
@@ -116,7 +116,7 @@ describe('TemplateFactory', () => {
sanitize: true,
html: true,
template: '<div><div id="foo"></div></div>',
content: { '#foo': null }
content: { '#foo': null },
})
expect(factory.toHtml().outerHTML).toBe('<div></div>')
})
@@ -126,7 +126,7 @@ describe('TemplateFactory', () => {
sanitize: true,
html: true,
template: '<div><div id="foo"></div></div>',
content: { '#foo': () => null }
content: { '#foo': () => null },
})
expect(factory.toHtml().outerHTML).toBe('<div></div>')
})
@@ -138,7 +138,7 @@ describe('TemplateFactory', () => {
const factory = new TemplateFactory({
html: false,
template: '<div><div id="foo"></div></div>',
content: { '#foo': contentElement }
content: { '#foo': contentElement },
})
const fooEl = factory.toHtml().querySelector('#foo')!
@@ -154,7 +154,7 @@ describe('TemplateFactory', () => {
const factory = new TemplateFactory({
html: true,
template: '<div><div id="foo"></div></div>',
content: { '#foo': contentElement }
content: { '#foo': contentElement },
})
const fooEl = factory.toHtml().querySelector('#foo')!
@@ -165,7 +165,7 @@ describe('TemplateFactory', () => {
describe('getContent', () => {
it('should get content as array', () => {
const factory = new TemplateFactory({
content: { '.foo': 'bar', '.foo2': 'bar2' }
content: { '.foo': 'bar', '.foo2': 'bar2' },
})
expect(factory.getContent()).toEqual(['bar', 'bar2'])
})
@@ -177,8 +177,8 @@ describe('TemplateFactory', () => {
'.foo2': '',
'.foo3': null,
'.foo4': () => 2,
'.foo5': () => null
}
'.foo5': () => null,
},
})
expect(factory.getContent()).toEqual(['bar', 2])
})
@@ -187,14 +187,14 @@ describe('TemplateFactory', () => {
describe('hasContent', () => {
it('should return true if it has content', () => {
const factory = new TemplateFactory({
content: { '.foo': 'bar', '.foo2': 'bar2', '.foo3': '' }
content: { '.foo': 'bar', '.foo2': 'bar2', '.foo3': '' },
})
expect(factory.hasContent()).toBe(true)
})
it('should return false if all content is empty', () => {
const factory = new TemplateFactory({
content: { '.foo2': '', '.foo3': null, '.foo4': () => null }
content: { '.foo2': '', '.foo3': null, '.foo4': () => null },
})
expect(factory.hasContent()).toBe(false)
})
@@ -205,7 +205,7 @@ describe('TemplateFactory', () => {
const template = '<div><div class="foo"></div><div class="foo2"></div></div>'
const factory = new TemplateFactory({
template,
content: { '.foo': 'bar', '.foo2': 'bar2' }
content: { '.foo': 'bar', '.foo2': 'bar2' },
})
const text = (sel: string) => factory.toHtml().querySelector(sel)!.textContent
@@ -221,7 +221,7 @@ describe('TemplateFactory', () => {
const template = '<div><div class="foo"></div><div class="foo2"></div></div>'
const factory = new TemplateFactory({
template,
content: { '.foo': 'bar', '.foo2': 'bar2' }
content: { '.foo': 'bar', '.foo2': 'bar2' },
})
const text = (sel: string) => factory.toHtml().querySelector(sel)!.textContent