1- import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
1+ import { describe , expect , it , vi } from 'vitest'
22import { Button } from '@ant-design-vue/ui'
33import { mount } from '@vue/test-utils'
44
@@ -7,4 +7,254 @@ describe('Button', () => {
77 const wrapper = mount ( Button )
88 expect ( wrapper . html ( ) ) . toMatchSnapshot ( )
99 } )
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+ } )
10260} )
0 commit comments