1+ import type { ComponentProps } from "vue-component-type-helpers" ;
12import { mount } from "@vue/test-utils" ;
23import { describe , expect , it } from "vitest" ;
34import ChevronDownIcon from "./icons/ChevronDownIcon.vue" ;
45import XMarkIcon from "./icons/XMarkIcon.vue" ;
56import Indicators from "./Indicators.vue" ;
7+ import Select from "./Select.vue" ;
68import Spinner from "./Spinner.vue" ;
79
8- const defaultProps = {
9- hasSelectedOption : false ,
10- isMenuOpen : false ,
10+ const options = [
11+ { label : "France" , value : "FR" } ,
12+ { label : "United Kingdom" , value : "GB" } ,
13+ { label : "United States" , value : "US" } ,
14+ { label : "Germany" , value : "DE" } ,
15+ ] ;
16+
17+ const defaultProps : ComponentProps < typeof Select > = {
18+ options,
19+ modelValue : null ,
1120 isClearable : true ,
1221 isLoading : false ,
1322 isDisabled : false ,
1423} ;
1524
25+ async function dispatchEvent ( wrapper : ReturnType < typeof mount > , event : Event ) {
26+ document . dispatchEvent ( event ) ;
27+ await wrapper . vm . $nextTick ( ) ;
28+ } ;
29+
1630describe ( "component setup and initialization" , ( ) => {
1731 it ( "should render with default imports" , ( ) => {
18- const wrapper = mount ( Indicators , {
19- props : defaultProps ,
20- } ) ;
32+ const wrapper = mount ( Select , { props : defaultProps } ) ;
2133
2234 expect ( wrapper . findComponent ( ChevronDownIcon ) . exists ( ) ) . toBe ( true ) ;
2335 expect ( wrapper . findComponent ( XMarkIcon ) . exists ( ) ) . toBe ( false ) ;
@@ -27,92 +39,56 @@ describe("component setup and initialization", () => {
2739
2840describe ( "dropdown button rendering" , ( ) => {
2941 it ( "should render dropdown button when not loading" , ( ) => {
30- const wrapper = mount ( Indicators , {
31- props : {
32- ...defaultProps ,
33- isLoading : false ,
34- } ,
35- } ) ;
42+ const wrapper = mount ( Select , { props : { ...defaultProps , isLoading : false } } ) ;
3643
3744 expect ( wrapper . find ( ".dropdown-icon" ) . exists ( ) ) . toBe ( true ) ;
3845 } ) ;
3946
4047 it ( "should not render dropdown button when loading" , ( ) => {
41- const wrapper = mount ( Indicators , {
42- props : {
43- ...defaultProps ,
44- isLoading : true ,
45- } ,
46- } ) ;
48+ const wrapper = mount ( Select , { props : { ...defaultProps , isLoading : true } } ) ;
4749
4850 expect ( wrapper . find ( ".dropdown-icon" ) . exists ( ) ) . toBe ( false ) ;
4951 } ) ;
5052
51- it ( "should add active class to dropdown button when menu is open" , ( ) => {
52- const wrapper = mount ( Indicators , {
53- props : {
54- ...defaultProps ,
55- isMenuOpen : true ,
56- } ,
57- } ) ;
53+ it ( "should add active class to dropdown button when menu is open" , async ( ) => {
54+ const wrapper = mount ( Select , { props : { ...defaultProps } } ) ;
5855
56+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
5957 expect ( wrapper . find ( ".dropdown-icon" ) . classes ( ) ) . toContain ( "active" ) ;
6058 } ) ;
6159
6260 it ( "should disable dropdown button when component is disabled" , ( ) => {
63- const wrapper = mount ( Indicators , {
64- props : {
65- ...defaultProps ,
66- isDisabled : true ,
67- } ,
68- } ) ;
61+ const wrapper = mount ( Select , { props : { ...defaultProps , isDisabled : true } } ) ;
6962
7063 expect ( wrapper . find ( ".dropdown-icon" ) . attributes ( "disabled" ) ) . toBe ( "" ) ;
7164 } ) ;
7265
7366 it ( "should emit toggle event when dropdown button is clicked" , async ( ) => {
74- const wrapper = mount ( Indicators , {
75- props : defaultProps ,
76- } ) ;
67+ const wrapper = mount ( Select , { props : defaultProps } ) ;
68+ const indicators = wrapper . findComponent ( Indicators ) ;
7769
7870 await wrapper . find ( ".dropdown-icon" ) . trigger ( "click" ) ;
79- expect ( wrapper . emitted ( "toggle" ) ) . toBeTruthy ( ) ;
80- expect ( wrapper . emitted ( "toggle" ) ! . length ) . toBe ( 1 ) ;
71+ expect ( indicators . emitted ( "toggle" ) ) . toStrictEqual ( [ [ ] ] ) ;
8172 } ) ;
8273} ) ;
8374
8475describe ( "loading state handling" , ( ) => {
8576 it ( "should render spinner when loading" , ( ) => {
86- const wrapper = mount ( Indicators , {
87- props : {
88- ...defaultProps ,
89- isLoading : true ,
90- } ,
91- } ) ;
77+ const wrapper = mount ( Select , { props : { ...defaultProps , isLoading : true } } ) ;
9278
9379 expect ( wrapper . findComponent ( Spinner ) . exists ( ) ) . toBe ( true ) ;
9480 } ) ;
9581
9682 it ( "should not render spinner when not loading" , ( ) => {
97- const wrapper = mount ( Indicators , {
98- props : {
99- ...defaultProps ,
100- isLoading : false ,
101- } ,
102- } ) ;
83+ const wrapper = mount ( Select , { props : { ...defaultProps , isLoading : false } } ) ;
10384
10485 expect ( wrapper . findComponent ( Spinner ) . exists ( ) ) . toBe ( false ) ;
10586 } ) ;
10687
10788 it ( "should use custom loading slot content when provided" , ( ) => {
108- const wrapper = mount ( Indicators , {
109- props : {
110- ...defaultProps ,
111- isLoading : true ,
112- } ,
113- slots : {
114- loading : "<div class=\"custom-loader\">Loading...</div>" ,
115- } ,
89+ const wrapper = mount ( Select , {
90+ props : { ...defaultProps , isLoading : true } ,
91+ slots : { loading : "<div class=\"custom-loader\">Loading...</div>" } ,
11692 } ) ;
11793
11894 expect ( wrapper . find ( ".custom-loader" ) . exists ( ) ) . toBe ( true ) ;
@@ -121,106 +97,85 @@ describe("loading state handling", () => {
12197} ) ;
12298
12399describe ( "clear button behavior" , ( ) => {
124- it ( "should render clear button when there is a selected option and isClearable is true" , ( ) => {
125- const wrapper = mount ( Indicators , {
126- props : {
127- ...defaultProps ,
128- hasSelectedOption : true ,
129- isClearable : true ,
130- } ,
131- } ) ;
100+ it ( "should render clear button when there is a selected option and isClearable is true" , async ( ) => {
101+ const wrapper = mount ( Select , { props : { ...defaultProps } } ) ;
102+
103+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
104+ await dispatchEvent ( wrapper , new KeyboardEvent ( "keydown" , { key : "Enter" } ) ) ;
132105
133106 expect ( wrapper . find ( ".clear-button" ) . exists ( ) ) . toBe ( true ) ;
134107 } ) ;
135108
136109 it ( "should not render clear button when there is no selected option" , ( ) => {
137- const wrapper = mount ( Indicators , {
138- props : {
139- ...defaultProps ,
140- hasSelectedOption : false ,
141- isClearable : true ,
142- } ,
110+ const wrapper = mount ( Select , {
111+ props : { ...defaultProps , isClearable : true } ,
143112 } ) ;
144113
145114 expect ( wrapper . find ( ".clear-button" ) . exists ( ) ) . toBe ( false ) ;
146115 } ) ;
147116
148- it ( "should not render clear button when isClearable is false" , ( ) => {
149- const wrapper = mount ( Indicators , {
150- props : {
151- ...defaultProps ,
152- hasSelectedOption : true ,
153- isClearable : false ,
154- } ,
117+ it ( "should not render clear button when isClearable is false" , async ( ) => {
118+ const wrapper = mount ( Select , {
119+ props : { ...defaultProps , isClearable : false } ,
155120 } ) ;
156121
122+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
123+ await dispatchEvent ( wrapper , new KeyboardEvent ( "keydown" , { key : "Enter" } ) ) ;
124+
157125 expect ( wrapper . find ( ".clear-button" ) . exists ( ) ) . toBe ( false ) ;
158126 } ) ;
159127
160- it ( "should not render clear button when loading" , ( ) => {
161- const wrapper = mount ( Indicators , {
162- props : {
163- ...defaultProps ,
164- hasSelectedOption : true ,
165- isClearable : true ,
166- isLoading : true ,
167- } ,
128+ it ( "should not render clear button when loading" , async ( ) => {
129+ const wrapper = mount ( Select , {
130+ props : { ...defaultProps , isClearable : true , isLoading : true } ,
168131 } ) ;
169132
133+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
134+ await dispatchEvent ( wrapper , new KeyboardEvent ( "keydown" , { key : "Enter" } ) ) ;
135+
170136 expect ( wrapper . find ( ".clear-button" ) . exists ( ) ) . toBe ( false ) ;
171137 } ) ;
172138
173139 it ( "should emit clear event when clear button is clicked" , async ( ) => {
174- const wrapper = mount ( Indicators , {
175- props : {
176- ...defaultProps ,
177- hasSelectedOption : true ,
178- } ,
179- } ) ;
140+ const wrapper = mount ( Select , { props : defaultProps } ) ;
141+ const indicators = wrapper . findComponent ( Indicators ) ;
180142
143+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
144+ await dispatchEvent ( wrapper , new KeyboardEvent ( "keydown" , { key : "Enter" } ) ) ;
181145 await wrapper . find ( ".clear-button" ) . trigger ( "click" ) ;
182- expect ( wrapper . emitted ( "clear" ) ) . toBeTruthy ( ) ;
183- expect ( wrapper . emitted ( "clear" ) ! . length ) . toBe ( 1 ) ;
184- } ) ;
185146
186- it ( "should not be clickable when disabled" , async ( ) => {
187- const wrapper = mount ( Indicators , {
188- props : {
189- ...defaultProps ,
190- hasSelectedOption : true ,
191- isDisabled : true ,
192- } ,
193- } ) ;
194-
195- const clearButton = wrapper . find ( ".clear-button" ) ;
196- expect ( clearButton . attributes ( "disabled" ) ) . toBe ( "" ) ;
147+ expect ( indicators . emitted ( "clear" ) ) . toBeTruthy ( ) ;
148+ expect ( indicators . emitted ( "clear" ) ! . length ) . toBe ( 1 ) ;
197149 } ) ;
198150} ) ;
199151
200152describe ( "custom slots" , ( ) => {
201- it ( "should use custom clear button slot content when provided" , ( ) => {
202- const wrapper = mount ( Indicators , {
203- props : {
204- ...defaultProps ,
205- hasSelectedOption : true ,
206- } ,
153+ it ( "should use custom clear button slot content when provided" , async ( ) => {
154+ const wrapper = mount ( Select , {
155+ props : { ...defaultProps } ,
207156 slots : {
208157 clear : "<span class=\"custom-clear\">✕</span>" ,
209158 } ,
210159 } ) ;
211160
161+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
162+ await dispatchEvent ( wrapper , new KeyboardEvent ( "keydown" , { key : "Enter" } ) ) ;
163+
212164 expect ( wrapper . find ( ".custom-clear" ) . exists ( ) ) . toBe ( true ) ;
213165 expect ( wrapper . findComponent ( XMarkIcon ) . exists ( ) ) . toBe ( false ) ;
214166 } ) ;
215167
216- it ( "should use custom dropdown slot content when provided" , ( ) => {
217- const wrapper = mount ( Indicators , {
168+ it ( "should use custom dropdown slot content when provided" , async ( ) => {
169+ const wrapper = mount ( Select , {
218170 props : defaultProps ,
219171 slots : {
220172 dropdown : "<span class=\"custom-dropdown\">▼</span>" ,
221173 } ,
222174 } ) ;
223175
176+ await wrapper . get ( "input" ) . trigger ( "mousedown" ) ;
177+ await dispatchEvent ( wrapper , new KeyboardEvent ( "keydown" , { key : "Enter" } ) ) ;
178+
224179 expect ( wrapper . find ( ".custom-dropdown" ) . exists ( ) ) . toBe ( true ) ;
225180 expect ( wrapper . findComponent ( ChevronDownIcon ) . exists ( ) ) . toBe ( false ) ;
226181 } ) ;
0 commit comments