Skip to content

Commit 972c452

Browse files
committed
fix(BDropdownItem): contains disabled on button
refactor(BDropdownItem): prop variant explicit test: dropdown-divider.spec.ts test: dropdown-form.spec.ts test: dropdown-header.spec.ts test: dropdown-item.spec.ts
1 parent 99ac9ab commit 972c452

File tree

5 files changed

+327
-2
lines changed

5 files changed

+327
-2
lines changed

packages/bootstrap-vue-3/src/components/BDropdown/BDropdownItem.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ const props = withDefaults(defineProps<BDropdownItemProps>(), {
3333
active: false,
3434
disabled: false,
3535
rel: undefined,
36-
variant: undefined,
3736
target: '_self',
3837
})
3938
@@ -51,14 +50,15 @@ const attrs = useAttrs()
5150
const classes = computed(() => ({
5251
active: activeBoolean.value,
5352
disabled: disabledBoolean.value,
54-
[`text-${props.variant}`]: !!props.variant,
53+
[`text-${props.variant}`]: props.variant !== undefined,
5554
}))
5655
5756
const tag = computed<'button' | 'a' | typeof BLink>(() =>
5857
props.href ? 'a' : attrs.to ? BLink : 'button'
5958
)
6059
6160
const componentAttrs = computed(() => ({
61+
'disabled': disabledBoolean.value,
6262
'aria-current': activeBoolean.value ? 'true' : null,
6363
'href': tag.value === 'a' ? props.href : null,
6464
'rel': props.rel,
@@ -67,6 +67,7 @@ const componentAttrs = computed(() => ({
6767
...(attrs.to ? {activeClass: 'active', ...attrs} : {}),
6868
}))
6969
70+
// Pretty sure this emits if tag is not button and is diabled
7071
const clicked = (e: MouseEvent): void => emit('click', e)
7172
</script>
7273

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {enableAutoUnmount, mount} from '@vue/test-utils'
2+
import {afterEach, describe, expect, it} from 'vitest'
3+
import BDropdownDivider from './BDropdownDivider.vue'
4+
5+
describe('dropdown-divider', () => {
6+
enableAutoUnmount(afterEach)
7+
8+
it('is tag li', () => {
9+
const wrapper = mount(BDropdownDivider)
10+
expect(wrapper.element.tagName).toBe('LI')
11+
})
12+
13+
it('has static attr role to be presentation', () => {
14+
const wrapper = mount(BDropdownDivider)
15+
expect(wrapper.attributes('role')).toBe('presentation')
16+
})
17+
18+
it('has child hr when not prop hr', () => {
19+
const wrapper = mount(BDropdownDivider)
20+
const $hr = wrapper.find('hr')
21+
expect($hr.exists()).toBe(true)
22+
})
23+
24+
it('has child hr is prop tag', () => {
25+
const wrapper = mount(BDropdownDivider, {
26+
props: {tag: 'h4'},
27+
})
28+
const $hr = wrapper.find('hr')
29+
const $h4 = wrapper.find('h4')
30+
expect($hr.exists()).toBe(false)
31+
expect($h4.exists()).toBe(true)
32+
})
33+
34+
it('child hr has static class dropdown-divider', () => {
35+
const wrapper = mount(BDropdownDivider)
36+
const $hr = wrapper.get('hr')
37+
expect($hr.classes()).toContain('dropdown-divider')
38+
})
39+
40+
it('child hr has static attr role to be separator', () => {
41+
const wrapper = mount(BDropdownDivider)
42+
const $hr = wrapper.get('hr')
43+
expect($hr.attributes('role')).toBe('separator')
44+
})
45+
46+
it('child hr has static attr aria-orientation to be horizontal', () => {
47+
const wrapper = mount(BDropdownDivider)
48+
const $hr = wrapper.get('hr')
49+
expect($hr.attributes('aria-orientation')).toBe('horizontal')
50+
})
51+
})
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {enableAutoUnmount, mount} from '@vue/test-utils'
2+
import {afterEach, describe, expect, it} from 'vitest'
3+
import BDropdownForm from './BDropdownForm.vue'
4+
5+
describe('dropdown-form', () => {
6+
enableAutoUnmount(afterEach)
7+
8+
it('tag is li', () => {
9+
const wrapper = mount(BDropdownForm)
10+
expect(wrapper.element.tagName).toBe('LI')
11+
})
12+
13+
it('has static role to be presentation', () => {
14+
const wrapper = mount(BDropdownForm)
15+
expect(wrapper.attributes('role')).toBe('presentation')
16+
})
17+
18+
it('has child form', () => {
19+
const wrapper = mount(BDropdownForm)
20+
const $form = wrapper.find('form')
21+
expect($form.exists()).toBe(true)
22+
})
23+
24+
it('child form has static class px-4', () => {
25+
const wrapper = mount(BDropdownForm)
26+
const $form = wrapper.get('form')
27+
expect($form.classes()).toContain('px-4')
28+
})
29+
30+
it('child form has static class py-3', () => {
31+
const wrapper = mount(BDropdownForm)
32+
const $form = wrapper.get('form')
33+
expect($form.classes()).toContain('py-3')
34+
})
35+
36+
it('child form renders default slot', () => {
37+
const wrapper = mount(BDropdownForm, {
38+
slots: {default: 'foobar'},
39+
})
40+
const $form = wrapper.get('form')
41+
expect($form.text()).toBe('foobar')
42+
})
43+
})
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {enableAutoUnmount, mount} from '@vue/test-utils'
2+
import {afterEach, describe, expect, it} from 'vitest'
3+
import BDropdownHeader from './BDropdownHeader.vue'
4+
5+
describe('dropdown-header', () => {
6+
enableAutoUnmount(afterEach)
7+
8+
it('tag is li', () => {
9+
const wrapper = mount(BDropdownHeader)
10+
expect(wrapper.element.tagName).toBe('LI')
11+
})
12+
13+
it('has child h6', () => {
14+
const wrapper = mount(BDropdownHeader)
15+
const $h6 = wrapper.find('h6')
16+
expect($h6.exists()).toBe(true)
17+
})
18+
19+
it('child h6 has static class dropdown-header', () => {
20+
const wrapper = mount(BDropdownHeader)
21+
const $h6 = wrapper.get('h6')
22+
expect($h6.classes()).toContain('dropdown-header')
23+
})
24+
25+
it('child h6 renders default slot', () => {
26+
const wrapper = mount(BDropdownHeader, {
27+
slots: {default: 'foobar'},
28+
})
29+
const $h6 = wrapper.get('h6')
30+
expect($h6.text()).toBe('foobar')
31+
})
32+
})
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import {enableAutoUnmount, mount} from '@vue/test-utils'
2+
import {afterEach, describe, expect, it} from 'vitest'
3+
import BDropdownItem from './BDropdownItem.vue'
4+
import BLink from '../BLink/BLink.vue'
5+
6+
describe('dropdown-item', () => {
7+
enableAutoUnmount(afterEach)
8+
9+
it('is tag li', () => {
10+
const wrapper = mount(BDropdownItem)
11+
expect(wrapper.element.tagName).toBe('LI')
12+
})
13+
14+
it('has static attr role to be presentation', () => {
15+
const wrapper = mount(BDropdownItem)
16+
expect(wrapper.attributes('role')).toBe('presentation')
17+
})
18+
19+
it('has child with dynamic tag of button by default', () => {
20+
const wrapper = mount(BDropdownItem)
21+
const $button = wrapper.find('button')
22+
expect($button.exists()).toBe(true)
23+
})
24+
25+
it('child is tag a when prop href', () => {
26+
const wrapper = mount(BDropdownItem, {
27+
props: {href: '/abc'},
28+
})
29+
const $button = wrapper.find('button')
30+
const $a = wrapper.find('a')
31+
expect($button.exists()).toBe(false)
32+
expect($a.exists()).toBe(true)
33+
})
34+
35+
it('child is tag BLink when prop to', () => {
36+
const wrapper = mount(BDropdownItem, {
37+
props: {to: '/abc'},
38+
})
39+
const $button = wrapper.find('button')
40+
const $blink = wrapper.findComponent(BLink)
41+
expect($button.exists()).toBe(false)
42+
expect($blink.exists()).toBe(true)
43+
})
44+
45+
it('child is tag prefers a over blink', () => {
46+
const wrapper = mount(BDropdownItem, {
47+
props: {href: '/abc', to: '/abc'},
48+
})
49+
const $a = wrapper.find('a')
50+
const $blink = wrapper.findComponent(BLink)
51+
expect($blink.exists()).toBe(false)
52+
expect($a.exists()).toBe(true)
53+
})
54+
55+
it('child is tag prefers Blink over button', () => {
56+
const wrapper = mount(BDropdownItem, {
57+
props: {to: '/abc'},
58+
})
59+
const $button = wrapper.find('button')
60+
const $blink = wrapper.findComponent(BLink)
61+
expect($blink.exists()).toBe(true)
62+
expect($button.exists()).toBe(false)
63+
})
64+
65+
it('button child contains static class dropdown-item', () => {
66+
const wrapper = mount(BDropdownItem)
67+
const $button = wrapper.get('button')
68+
expect($button.classes()).toContain('dropdown-item')
69+
})
70+
71+
it('button renders default slot', () => {
72+
const wrapper = mount(BDropdownItem, {
73+
slots: {default: 'foobar'},
74+
})
75+
const $button = wrapper.get('button')
76+
expect($button.text()).toBe('foobar')
77+
})
78+
79+
it('button contains prop link class as class', () => {
80+
const wrapper = mount(BDropdownItem, {
81+
props: {linkClass: ['foo']},
82+
})
83+
const $button = wrapper.get('button')
84+
expect($button.classes()).toContain('foo')
85+
})
86+
87+
it('button has class active when prop active', async () => {
88+
const wrapper = mount(BDropdownItem, {
89+
props: {active: true},
90+
})
91+
const $button = wrapper.get('button')
92+
expect($button.classes()).toContain('active')
93+
await wrapper.setProps({active: false})
94+
expect($button.classes()).not.toContain('active')
95+
})
96+
97+
it('button has class disabled when prop disabled', async () => {
98+
const wrapper = mount(BDropdownItem, {
99+
props: {disabled: true},
100+
})
101+
const $button = wrapper.get('button')
102+
expect($button.classes()).toContain('disabled')
103+
await wrapper.setProps({disabled: false})
104+
expect($button.classes()).not.toContain('disabled')
105+
})
106+
107+
it('button has class text-{type} when prop variant', async () => {
108+
const wrapper = mount(BDropdownItem, {
109+
props: {variant: 'danger'},
110+
})
111+
const $button = wrapper.get('button')
112+
expect($button.classes()).toContain('text-danger')
113+
await wrapper.setProps({variant: undefined})
114+
expect($button.classes()).not.toContain('text-danger')
115+
})
116+
117+
it('emits a click event when clicked', async () => {
118+
const wrapper = mount(BDropdownItem)
119+
const $button = wrapper.get('button')
120+
await $button.trigger('click')
121+
expect(wrapper.emitted()).toHaveProperty('click')
122+
})
123+
124+
it('click event passes value MouseEvent', async () => {
125+
const wrapper = mount(BDropdownItem)
126+
const $button = wrapper.get('button')
127+
await $button.trigger('click')
128+
const $emitted = wrapper.emitted('click') ?? []
129+
expect($emitted[0][0] instanceof MouseEvent).toBe(true)
130+
})
131+
132+
it('does not emit click when disabled', async () => {
133+
const wrapper = mount(BDropdownItem, {
134+
props: {disabled: true},
135+
})
136+
const $button = wrapper.get('button')
137+
await $button.trigger('click')
138+
expect(wrapper.emitted()).not.toHaveProperty('click')
139+
})
140+
141+
it('button has disabled attr when prop disabled', async () => {
142+
const wrapper = mount(BDropdownItem, {
143+
props: {disabled: true},
144+
})
145+
const $button = wrapper.get('button')
146+
expect($button.attributes('disabled')).toBe('')
147+
await wrapper.setProps({disabled: false})
148+
expect($button.attributes('disabled')).toBeUndefined()
149+
})
150+
151+
it('button has aria-current attr when prop active', async () => {
152+
const wrapper = mount(BDropdownItem, {
153+
props: {active: true},
154+
})
155+
const $button = wrapper.get('button')
156+
expect($button.attributes('aria-current')).toBe('true')
157+
await wrapper.setProps({active: false})
158+
expect($button.attributes('aria-current')).toBeUndefined()
159+
})
160+
161+
it('button has href attr when prop href', () => {
162+
const wrapper = mount(BDropdownItem, {
163+
props: {href: '/abc'},
164+
})
165+
const $a = wrapper.get('a')
166+
expect($a.attributes('href')).toBe('/abc')
167+
})
168+
169+
it('button has rel attr when prop rel', () => {
170+
const wrapper = mount(BDropdownItem, {
171+
props: {rel: 'foobar'},
172+
})
173+
const $button = wrapper.get('button')
174+
expect($button.attributes('rel')).toBe('foobar')
175+
})
176+
177+
it('button has target attr when prop target', () => {
178+
const wrapper = mount(BDropdownItem, {
179+
props: {target: '_parent'},
180+
})
181+
const $button = wrapper.get('button')
182+
expect($button.attributes('target')).toBe('_parent')
183+
})
184+
185+
it('button has type button when tag is button', () => {
186+
const wrapper = mount(BDropdownItem)
187+
const $button = wrapper.get('button')
188+
expect($button.attributes('type')).toBe('button')
189+
})
190+
191+
it('does not have type button when tag is not button', () => {
192+
const wrapper = mount(BDropdownItem, {
193+
props: {href: '/abc'},
194+
})
195+
const $a = wrapper.get('a')
196+
expect($a.attributes('type')).toBeUndefined()
197+
})
198+
})

0 commit comments

Comments
 (0)