1
- import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
1
+ import { describe , expect , it , vi } from 'vitest'
2
2
import { Button } from '@ant-design-vue/ui'
3
3
import { mount } from '@vue/test-utils'
4
4
@@ -7,4 +7,254 @@ describe('Button', () => {
7
7
const wrapper = mount ( Button )
8
8
expect ( wrapper . html ( ) ) . toMatchSnapshot ( )
9
9
} )
10
+
11
+ describe ( 'Props' , ( ) => {
12
+ it ( 'should render different variants' , ( ) => {
13
+ const variants = [ 'solid' , 'outlined' , 'text' , 'link' , 'dashed' , 'filled' ] as const
14
+
15
+ variants . forEach ( variant => {
16
+ const wrapper = mount ( Button , {
17
+ props : { variant } ,
18
+ } )
19
+ expect ( wrapper . classes ( ) ) . toContain ( `ant-btn-${ variant } ` )
20
+ } )
21
+ } )
22
+
23
+ it ( 'should render different sizes' , ( ) => {
24
+ const sizes = [ 'sm' , 'md' , 'lg' ] as const
25
+
26
+ sizes . forEach ( size => {
27
+ const wrapper = mount ( Button , {
28
+ props : { size } ,
29
+ } )
30
+ expect ( wrapper . classes ( ) ) . toContain ( `ant-btn-${ size } ` )
31
+ } )
32
+ } )
33
+
34
+ it ( 'should render loading state' , ( ) => {
35
+ const wrapper = mount ( Button , {
36
+ props : { loading : true } ,
37
+ } )
38
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-loading' )
39
+ expect ( wrapper . findComponent ( { name : 'LoadingOutlined' } ) . exists ( ) ) . toBe ( true )
40
+ } )
41
+
42
+ it ( 'should render disabled state' , ( ) => {
43
+ const wrapper = mount ( Button , {
44
+ props : { disabled : true } ,
45
+ } )
46
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-disabled' )
47
+ expect ( wrapper . attributes ( 'disabled' ) ) . toBeDefined ( )
48
+ } )
49
+
50
+ it ( 'should render danger state' , ( ) => {
51
+ const wrapper = mount ( Button , {
52
+ props : { danger : true } ,
53
+ } )
54
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-danger' )
55
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-custom-color' )
56
+ } )
57
+
58
+ it ( 'should render with custom color' , ( ) => {
59
+ const wrapper = mount ( Button , {
60
+ props : { color : '#ff0000' } ,
61
+ } )
62
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-custom-color' )
63
+ expect ( wrapper . attributes ( 'style' ) ) . toBeDefined ( )
64
+ } )
65
+
66
+ it ( 'should handle href and target props' , ( ) => {
67
+ const wrapper = mount ( Button , {
68
+ props : { href : 'https://example.com' , target : '_blank' } ,
69
+ } )
70
+
71
+ // Mock window.open
72
+ const mockOpen = vi . fn ( )
73
+ vi . stubGlobal ( 'open' , mockOpen )
74
+
75
+ wrapper . trigger ( 'click' )
76
+ expect ( mockOpen ) . toHaveBeenCalledWith ( 'https://example.com' , '_blank' )
77
+
78
+ vi . unstubAllGlobals ( )
79
+ } )
80
+ } )
81
+
82
+ describe ( 'Events' , ( ) => {
83
+ it ( 'should emit click event' , async ( ) => {
84
+ const wrapper = mount ( Button )
85
+
86
+ await wrapper . trigger ( 'click' )
87
+
88
+ expect ( wrapper . emitted ( 'click' ) ) . toBeTruthy ( )
89
+ expect ( wrapper . emitted ( 'click' ) ?. [ 0 ] ) . toHaveLength ( 1 )
90
+ expect ( wrapper . emitted ( 'click' ) ?. [ 0 ] [ 0 ] ) . toBeInstanceOf ( MouseEvent )
91
+ } )
92
+
93
+ it ( 'should not emit click when disabled' , async ( ) => {
94
+ const wrapper = mount ( Button , {
95
+ props : { disabled : true } ,
96
+ } )
97
+
98
+ await wrapper . trigger ( 'click' )
99
+
100
+ expect ( wrapper . emitted ( 'click' ) ) . toBeFalsy ( )
101
+ } )
102
+
103
+ it ( 'should open link when href is provided' , ( ) => {
104
+ const mockOpen = vi . fn ( )
105
+ vi . stubGlobal ( 'open' , mockOpen )
106
+
107
+ const wrapper = mount ( Button , {
108
+ props : { href : 'https://example.com' } ,
109
+ } )
110
+
111
+ wrapper . trigger ( 'click' )
112
+ expect ( mockOpen ) . toHaveBeenCalledWith ( 'https://example.com' , undefined )
113
+
114
+ vi . unstubAllGlobals ( )
115
+ } )
116
+ } )
117
+
118
+ describe ( 'Slots' , ( ) => {
119
+ it ( 'should render default slot content' , ( ) => {
120
+ const wrapper = mount ( Button , {
121
+ slots : {
122
+ default : 'Click Me' ,
123
+ } ,
124
+ } )
125
+
126
+ expect ( wrapper . text ( ) ) . toContain ( 'Click Me' )
127
+ } )
128
+
129
+ it ( 'should render icon slot' , ( ) => {
130
+ const wrapper = mount ( Button , {
131
+ slots : {
132
+ icon : '<i class="custom-icon"></i>' ,
133
+ } ,
134
+ } )
135
+
136
+ expect ( wrapper . find ( '.custom-icon' ) . exists ( ) ) . toBe ( true )
137
+ } )
138
+
139
+ it ( 'should render custom loading slot' , ( ) => {
140
+ const wrapper = mount ( Button , {
141
+ props : { loading : true } ,
142
+ slots : {
143
+ loading : '<span class="custom-loading">Loading...</span>' ,
144
+ } ,
145
+ } )
146
+
147
+ expect ( wrapper . find ( '.custom-loading' ) . exists ( ) ) . toBe ( true )
148
+ expect ( wrapper . text ( ) ) . toContain ( 'Loading...' )
149
+ } )
150
+ } )
151
+
152
+ describe ( 'Styles and Classes' , ( ) => {
153
+ it ( 'should apply base classes' , ( ) => {
154
+ const wrapper = mount ( Button )
155
+
156
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn' )
157
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-solid' ) // default variant
158
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-md' ) // default size
159
+ } )
160
+
161
+ it ( 'should apply multiple state classes' , ( ) => {
162
+ const wrapper = mount ( Button , {
163
+ props : {
164
+ loading : true ,
165
+ danger : true ,
166
+ disabled : true ,
167
+ } ,
168
+ } )
169
+
170
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-loading' )
171
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-danger' )
172
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-disabled' )
173
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-custom-color' )
174
+ } )
175
+
176
+ it ( 'should apply custom color CSS variables' , ( ) => {
177
+ const wrapper = mount ( Button , {
178
+ props : { color : '#1890ff' } ,
179
+ } )
180
+
181
+ const style = wrapper . attributes ( 'style' )
182
+ expect ( style ) . toBeDefined ( )
183
+ } )
184
+ } )
185
+
186
+ describe ( 'Edge Cases' , ( ) => {
187
+ it ( 'should handle empty href' , ( ) => {
188
+ const mockOpen = vi . fn ( )
189
+ vi . stubGlobal ( 'open' , mockOpen )
190
+
191
+ const wrapper = mount ( Button , {
192
+ props : { href : '' } ,
193
+ } )
194
+
195
+ wrapper . trigger ( 'click' )
196
+ expect ( mockOpen ) . toHaveBeenCalledWith ( '' , undefined )
197
+
198
+ vi . unstubAllGlobals ( )
199
+ } )
200
+
201
+ it ( 'should handle loading and disabled states together' , ( ) => {
202
+ const wrapper = mount ( Button , {
203
+ props : {
204
+ loading : true ,
205
+ disabled : true ,
206
+ } ,
207
+ } )
208
+
209
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-loading' )
210
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-disabled' )
211
+ expect ( wrapper . attributes ( 'disabled' ) ) . toBeDefined ( )
212
+ } )
213
+
214
+ it ( 'should render with all props combined' , ( ) => {
215
+ const wrapper = mount ( Button , {
216
+ props : {
217
+ variant : 'outlined' ,
218
+ size : 'lg' ,
219
+ loading : true ,
220
+ danger : true ,
221
+ color : '#ff4d4f' ,
222
+ href : 'https://example.com' ,
223
+ target : '_blank' ,
224
+ } ,
225
+ slots : {
226
+ default : 'Complex Button' ,
227
+ icon : '<i class="icon"></i>' ,
228
+ } ,
229
+ } )
230
+
231
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn' )
232
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-outlined' )
233
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-lg' )
234
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-loading' )
235
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-danger' )
236
+ expect ( wrapper . classes ( ) ) . toContain ( 'ant-btn-custom-color' )
237
+ expect ( wrapper . text ( ) ) . toContain ( 'Complex Button' )
238
+ expect ( wrapper . find ( '.icon' ) . exists ( ) ) . toBe ( true )
239
+ } )
240
+ } )
241
+
242
+ describe ( 'Accessibility' , ( ) => {
243
+ it ( 'should have correct button element' , ( ) => {
244
+ const wrapper = mount ( Button )
245
+ expect ( wrapper . element . tagName ) . toBe ( 'BUTTON' )
246
+ } )
247
+
248
+ it ( 'should handle disabled attribute correctly' , ( ) => {
249
+ const enabledWrapper = mount ( Button , {
250
+ props : { disabled : false } ,
251
+ } )
252
+ expect ( enabledWrapper . attributes ( 'disabled' ) ) . toBeUndefined ( )
253
+
254
+ const disabledWrapper = mount ( Button , {
255
+ props : { disabled : true } ,
256
+ } )
257
+ expect ( disabledWrapper . attributes ( 'disabled' ) ) . toBeDefined ( )
258
+ } )
259
+ } )
10
260
} )
0 commit comments