mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-08 14:46:34 +02:00
rewrite toast unit tests
This commit is contained in:
committed by
Johann-S
parent
6a59c58480
commit
e916a9bc03
@@ -11,10 +11,10 @@ import {
|
||||
emulateTransitionEnd,
|
||||
getTransitionDurationFromElement,
|
||||
typeCheckConfig
|
||||
} from './util/index'
|
||||
import Data from './dom/data'
|
||||
import EventHandler from './dom/event-handler'
|
||||
import Manipulator from './dom/manipulator'
|
||||
} from '../util/index'
|
||||
import Data from '../dom/data'
|
||||
import EventHandler from '../dom/event-handler'
|
||||
import Manipulator from '../dom/manipulator'
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
@@ -226,7 +226,7 @@ class Toast {
|
||||
* ------------------------------------------------------------------------
|
||||
* add .toast to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (typeof $ !== 'undefined') {
|
||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
||||
$.fn[NAME] = Toast._jQueryInterface
|
374
js/src/toast/toast.spec.js
Normal file
374
js/src/toast/toast.spec.js
Normal file
@@ -0,0 +1,374 @@
|
||||
import Toast from './toast'
|
||||
|
||||
/** Test helpers */
|
||||
import { getFixture, clearFixture, jQueryMock } from '../../tests/helpers/fixture'
|
||||
|
||||
describe('Toast', () => {
|
||||
let fixtureEl
|
||||
|
||||
beforeAll(() => {
|
||||
fixtureEl = getFixture()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
clearFixture()
|
||||
})
|
||||
|
||||
describe('VERSION', () => {
|
||||
it('should return plugin version', () => {
|
||||
expect(Toast.VERSION).toEqual(jasmine.any(String))
|
||||
})
|
||||
})
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should allow to config in js', done => {
|
||||
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
|
||||
})
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(true)
|
||||
done()
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
|
||||
it('should close toast when close element with data-dismiss attribute is set', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="1" data-autohide="false" data-animation="false">',
|
||||
' <button type="button" class="ml-2 mb-1 close" data-dismiss="toast">',
|
||||
' close',
|
||||
' </button>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(true)
|
||||
|
||||
const button = toastEl.querySelector('.close')
|
||||
|
||||
button.click()
|
||||
})
|
||||
|
||||
toastEl.addEventListener('hidden.bs.toast', () => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(false)
|
||||
done()
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Default', () => {
|
||||
it('should expose default setting to allow to override them', () => {
|
||||
const defaultDelay = 1000
|
||||
|
||||
Toast.Default.delay = defaultDelay
|
||||
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-autohide="false" data-animation="false">',
|
||||
' <button type="button" class="ml-2 mb-1 close" data-dismiss="toast">',
|
||||
' close',
|
||||
' </button>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
expect(toast._config.delay).toEqual(defaultDelay)
|
||||
})
|
||||
})
|
||||
|
||||
describe('DefaultType', () => {
|
||||
it('should expose default setting types for read', () => {
|
||||
expect(Toast.DefaultType).toEqual(jasmine.any(Object))
|
||||
})
|
||||
})
|
||||
|
||||
describe('show', () => {
|
||||
it('should auto hide', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="1">',
|
||||
' <div class="toast-body">',
|
||||
' a simple toast',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('.toast')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
toastEl.addEventListener('hidden.bs.toast', () => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(false)
|
||||
done()
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
|
||||
it('should not add fade class', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="1" data-animation="false">',
|
||||
' <div class="toast-body">',
|
||||
' a simple toast',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('.toast')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
expect(toastEl.classList.contains('fade')).toEqual(false)
|
||||
done()
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
|
||||
it('should not trigger shown if show is prevented', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="1" data-animation="false">',
|
||||
' <div class="toast-body">',
|
||||
' a simple toast',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('.toast')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
const assertDone = () => {
|
||||
setTimeout(() => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(false)
|
||||
done()
|
||||
}, 20)
|
||||
}
|
||||
|
||||
toastEl.addEventListener('show.bs.toast', event => {
|
||||
event.preventDefault()
|
||||
assertDone()
|
||||
})
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
throw new Error('shown event should not be triggered if show is prevented')
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
})
|
||||
|
||||
describe('hide', () => {
|
||||
it('should allow to hide toast manually', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="1" data-autohide="false">',
|
||||
' <div class="toast-body">',
|
||||
' a simple toast',
|
||||
' </div>',
|
||||
' </div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('.toast')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
toast.hide()
|
||||
})
|
||||
|
||||
toastEl.addEventListener('hidden.bs.toast', () => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(false)
|
||||
done()
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
|
||||
it('should do nothing when we call hide on a non shown toast', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const toastEl = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
spyOn(toastEl.classList, 'contains')
|
||||
|
||||
toast.hide()
|
||||
|
||||
expect(toastEl.classList.contains).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not trigger hidden if hide is prevented', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="1" data-animation="false">',
|
||||
' <div class="toast-body">',
|
||||
' a simple toast',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('.toast')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
const assertDone = () => {
|
||||
setTimeout(() => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(true)
|
||||
done()
|
||||
}, 20)
|
||||
}
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
toast.hide()
|
||||
})
|
||||
|
||||
toastEl.addEventListener('hide.bs.toast', event => {
|
||||
event.preventDefault()
|
||||
assertDone()
|
||||
})
|
||||
|
||||
toastEl.addEventListener('hidden.bs.toast', () => {
|
||||
throw new Error('hidden event should not be triggered if hide is prevented')
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
})
|
||||
|
||||
describe('dispose', () => {
|
||||
it('should allow to destroy toast', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const toastEl = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(toastEl)
|
||||
|
||||
expect(Toast._getInstance(toastEl)).toBeDefined()
|
||||
|
||||
toast.dispose()
|
||||
|
||||
expect(Toast._getInstance(toastEl)).toBeNull()
|
||||
})
|
||||
|
||||
it('should allow to destroy toast and hide it before that', done => {
|
||||
fixtureEl.innerHTML = [
|
||||
'<div class="toast" data-delay="0" data-autohide="false">',
|
||||
' <div class="toast-body">',
|
||||
' a simple toast',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
|
||||
const toastEl = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(toastEl)
|
||||
const expected = () => {
|
||||
expect(toastEl.classList.contains('show')).toEqual(true)
|
||||
expect(Toast._getInstance(toastEl)).toBeDefined()
|
||||
|
||||
toast.dispose()
|
||||
|
||||
expect(Toast._getInstance(toastEl)).toBeNull()
|
||||
expect(toastEl.classList.contains('show')).toEqual(false)
|
||||
|
||||
done()
|
||||
}
|
||||
|
||||
toastEl.addEventListener('shown.bs.toast', () => {
|
||||
setTimeout(expected, 1)
|
||||
})
|
||||
|
||||
toast.show()
|
||||
})
|
||||
})
|
||||
|
||||
describe('_jQueryInterface', () => {
|
||||
it('should create a toast', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
jQueryMock.fn.toast = Toast._jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.toast.call(jQueryMock)
|
||||
|
||||
expect(Toast._getInstance(div)).toBeDefined()
|
||||
})
|
||||
|
||||
it('should not re create a toast', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(div)
|
||||
|
||||
jQueryMock.fn.toast = Toast._jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.toast.call(jQueryMock)
|
||||
|
||||
expect(Toast._getInstance(div)).toEqual(toast)
|
||||
})
|
||||
|
||||
it('should call a toast method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(div)
|
||||
|
||||
spyOn(toast, 'show')
|
||||
|
||||
jQueryMock.fn.toast = Toast._jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
jQueryMock.fn.toast.call(jQueryMock, 'show')
|
||||
|
||||
expect(Toast._getInstance(div)).toEqual(toast)
|
||||
expect(toast.show).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should throw error on undefined method', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const action = 'undefinedMethod'
|
||||
|
||||
jQueryMock.fn.toast = Toast._jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
jQueryMock.fn.toast.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('_getInstance', () => {
|
||||
it('should return collapse instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
const toast = new Toast(div)
|
||||
|
||||
expect(Toast._getInstance(div)).toEqual(toast)
|
||||
})
|
||||
|
||||
it('should return null when there is no collapse instance', () => {
|
||||
fixtureEl.innerHTML = '<div></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
expect(Toast._getInstance(div)).toEqual(null)
|
||||
})
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user