Skip to content

Commit e859558

Browse files
authored
chore(toast): create unit tests for toasts (bootstrap-vue#3236)
1 parent 4073e04 commit e859558

File tree

7 files changed

+573
-12
lines changed

7 files changed

+573
-12
lines changed

src/components/modal/modal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ export default Vue.extend({
929929
Portal,
930930
{
931931
props: {
932-
name: this._uid,
932+
name: `b-modal-${this._uid}`,
933933
to: modalManager.modalTargetName,
934934
slim: true,
935935
disabled: this.static

src/components/toast/helpers/bv-toast.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
* Plugin for adding `$bvToast` property to all Vue instances
33
*/
44

5-
/* istanbul ignore file: not ready for testing yet as things are still changing */
6-
75
import Vue from '../../../utils/vue'
86
import { getComponentConfig } from '../../../utils/config'
97
import { requestAF } from '../../../utils/dom'
@@ -82,6 +80,7 @@ const BToastPop = Vue.extend({
8280
this.$once('hidden', handleDestroy)
8381
// Self destruct when toaster is destroyed
8482
this.listenOnRoot('bv::toaster::destroyed', toaster => {
83+
/* istanbul ignore next: hard to test */
8584
if (toaster === self.toaster) {
8685
handleDestroy()
8786
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { mount, createWrapper, createLocalVue as CreateLocalVue } from '@vue/test-utils'
2+
import { waitNT, waitRAF } from '../../../../tests/utils'
3+
import toastPlugin from '../index'
4+
5+
describe('$bvToast', () => {
6+
const localVue = new CreateLocalVue()
7+
8+
beforeAll(() => {
9+
// Prevent multiple Vue warnings in tests
10+
jest.spyOn(console, 'warn').mockImplementation(() => {})
11+
// Install plugin after we have trapped console.warn
12+
localVue.use(toastPlugin)
13+
})
14+
15+
afterAll(() => {
16+
console.warn.mockClear()
17+
})
18+
19+
it('$bvToast.show() and $bvToast.hide() works', async () => {
20+
const App = localVue.extend({
21+
render(h) {
22+
return h(
23+
'b-toast',
24+
{
25+
props: {
26+
id: 'test1',
27+
static: true,
28+
visible: false,
29+
noAutoHide: true
30+
}
31+
},
32+
'content'
33+
)
34+
}
35+
})
36+
const wrapper = mount(App, {
37+
attachToDocument: true,
38+
localVue: localVue
39+
})
40+
41+
expect(wrapper.isVueInstance()).toBe(true)
42+
43+
await waitNT(wrapper.vm)
44+
await waitRAF()
45+
46+
expect(wrapper.vm.$bvToast).toBeDefined()
47+
expect(wrapper.vm.$bvToast.show).toBeDefined()
48+
expect(typeof wrapper.vm.$bvToast.show).toEqual('function')
49+
expect(wrapper.vm.$bvToast.hide).toBeDefined()
50+
expect(typeof wrapper.vm.$bvToast.hide).toEqual('function')
51+
52+
expect(wrapper.find('.toast').exists()).toBe(false)
53+
54+
wrapper.vm.$bvToast.show('test1')
55+
56+
await waitNT(wrapper.vm)
57+
await waitRAF()
58+
await waitNT(wrapper.vm)
59+
await waitRAF()
60+
61+
expect(wrapper.find('.toast').exists()).toBe(true)
62+
63+
wrapper.vm.$bvToast.hide('test1')
64+
65+
await waitNT(wrapper.vm)
66+
await waitRAF()
67+
await waitNT(wrapper.vm)
68+
await waitRAF()
69+
70+
expect(wrapper.find('.toast').exists()).toBe(false)
71+
72+
wrapper.destroy()
73+
})
74+
75+
it('$bvModal.toast() works', async () => {
76+
const App = localVue.extend({
77+
render(h) {
78+
return h('div', {}, 'app')
79+
}
80+
})
81+
const wrapper = mount(App, {
82+
attachToDocument: true,
83+
localVue: localVue
84+
})
85+
86+
expect(wrapper.isVueInstance()).toBe(true)
87+
88+
// `$bvModal.toast`
89+
expect(wrapper.vm.$bvToast).toBeDefined()
90+
const bvToast = wrapper.vm.$bvToast
91+
expect(bvToast.toast).toBeDefined()
92+
expect(typeof bvToast.toast).toEqual('function')
93+
94+
// Trigger a toast
95+
bvToast.toast('message', {
96+
id: 'test2',
97+
title: 'title',
98+
noAutoHide: true
99+
})
100+
101+
await waitNT(wrapper.vm)
102+
await waitRAF()
103+
await waitNT(wrapper.vm)
104+
await waitRAF()
105+
await waitNT(wrapper.vm)
106+
await waitRAF()
107+
108+
// Find the toast
109+
const toast = document.querySelector('#test2')
110+
expect(toast).toBeDefined()
111+
expect(toast).not.toEqual(null)
112+
const $toast = createWrapper(toast)
113+
expect($toast.is('div')).toBe(true)
114+
115+
// Find header
116+
expect($toast.find('.toast-header').exists()).toBe(true)
117+
expect($toast.find('.toast-header').text()).toContain('title')
118+
119+
// Find body
120+
expect($toast.find('.toast-body').exists()).toBe(true)
121+
expect($toast.find('.toast-body').text()).toContain('message')
122+
123+
// Find the Close button and click it
124+
expect($toast.findAll('button').length).toBe(1)
125+
const $button = $toast.find('button')
126+
expect($button.classes()).toContain('close')
127+
$button.trigger('click')
128+
129+
await waitNT(wrapper.vm)
130+
await waitRAF()
131+
await waitNT(wrapper.vm)
132+
await waitRAF()
133+
await waitNT(wrapper.vm)
134+
await waitRAF()
135+
136+
// Toast should be gone from DOM
137+
expect(document.querySelector('#test2')).toBe(null)
138+
})
139+
})

src/components/toast/toast.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import BButtonClose from '../button/button-close'
99
import BToaster from './toaster'
1010
import BLink from '../link/link'
1111

12-
/* istanbul ignore file: for now until ready for testing */
13-
1412
// --- Constants ---
1513

1614
const NAME = 'BToast'
@@ -180,11 +178,11 @@ export default Vue.extend({
180178
this.$emit('change', newVal)
181179
}
182180
},
183-
toaster(newVal) {
181+
toaster(newVal) /* istanbul ignore next */ {
184182
// If toaster target changed, make sure toaster exists
185183
this.$nextTick(() => this.ensureToaster)
186184
},
187-
static(newVal) {
185+
static(newVal) /* istanbul ignore next */ {
188186
// If static changes to true, and the toast is showing,
189187
// ensure the toaster target exists
190188
if (newVal && this.localShow) {
@@ -214,6 +212,7 @@ export default Vue.extend({
214212
}
215213
})
216214
// Make sure we hide when toaster is destroyed
215+
/* istanbul ignore next: difficult to test */
217216
this.listenOnRoot('bv::toaster::destroyed', toaster => {
218217
if (toaster === this.computedToaster) {
219218
this.hide()

0 commit comments

Comments
 (0)