Skip to content

Commit 77c13ce

Browse files
Add test cases to cover edge cases and increase coverage.
1 parent dc42274 commit 77c13ce

File tree

2 files changed

+375
-25
lines changed

2 files changed

+375
-25
lines changed

tests/lib/rules/prefer-disabledfocusable-over-disabled.test.ts

Lines changed: 178 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,101 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
2323
"<Checkbox disabled />",
2424
"<Input disabled={true} />",
2525
"<SpinButton disabled={isDisabled} />",
26+
"<CompoundButton disabled={false} />",
27+
"<ToggleButton disabled={isFormDisabled} />",
2628

2729
// ✅ Acceptable: loading state without disabled
2830
"<Button loading>Submit</Button>",
2931
"<SpinButton isLoading />",
3032
"<Combobox pending={isPending} />",
3133
"<Input busy />",
34+
"<Textarea isPending />",
35+
"<Dropdown isBusy />",
36+
"<Slider loading={true} />",
37+
"<DatePicker isLoading={fetching} />",
38+
"<TimePicker pending={processing} />",
3239

3340
// ✅ Acceptable: neither disabled nor loading
3441
"<Button>Submit</Button>",
3542
"<Checkbox />",
3643
"<Input />",
44+
"<CompoundButton />",
45+
"<MenuButton />",
46+
"<SplitButton />",
47+
"<Switch />",
48+
"<Radio />",
49+
"<Link />",
50+
"<Tab />",
3751

3852
// ✅ Non-applicable components (don't support disabledFocusable)
3953
"<div disabled loading>Content</div>",
4054
"<Label disabled loading>Label</Label>",
4155
"<Text disabled loading>Text</Text>",
56+
"<span disabled isLoading>Span</span>",
57+
"<Accordion disabled loading />",
58+
"<Avatar disabled pending />",
59+
"<Badge disabled busy />",
60+
"<Breadcrumb disabled isLoading />",
61+
"<Card disabled pending />",
62+
"<Dialog disabled loading />",
63+
"<Divider disabled isLoading />",
64+
"<Field disabled pending />",
65+
"<Image disabled busy />",
66+
"<List disabled loading />",
67+
"<MessageBar disabled isLoading />",
68+
"<Nav disabled pending />",
69+
"<Popover disabled busy />",
70+
"<Portal disabled loading />",
71+
"<ProgressBar disabled isLoading />",
72+
"<Skeleton disabled pending />",
73+
"<Spinner disabled busy />",
74+
"<Toolbar disabled loading />",
75+
"<Tooltip disabled isLoading />",
4276

4377
// ✅ Edge case: both disabledFocusable and disabled present (different rule concern)
4478
"<Button disabled disabledFocusable loading>Submit</Button>",
79+
"<Input disabled disabledFocusable isLoading />",
80+
"<Checkbox disabled={true} disabledFocusable={false} pending />",
81+
"<ToggleButton disabled={isDisabled} disabledFocusable={shouldFocus} busy />",
4582

4683
// ✅ Complex expressions
4784
"<Button disabledFocusable={shouldDisable} loading={isSubmitting}>Submit</Button>",
4885
"<Input disabledFocusable={disabled && !error} isLoading={fetching} />",
86+
"<SpinButton disabledFocusable={!enabled || hasError} pending={processing} />",
4987

50-
// ✅ All supported loading props
88+
// ✅ All supported loading props with disabledFocusable
5189
"<Button disabledFocusable isPending>Submit</Button>",
5290
"<Button disabledFocusable isBusy>Submit</Button>",
53-
"<Button disabledFocusable busy>Submit</Button>"
91+
"<Button disabledFocusable busy>Submit</Button>",
92+
93+
// ✅ Empty prop values that should be considered "empty" by hasNonEmptyProp
94+
'<Button disabled="" loading>Submit</Button>', // Empty string should not trigger
95+
"<Input disabled={null} isLoading />", // Null should not trigger
96+
"<Checkbox disabled={undefined} pending />", // Undefined should not trigger
97+
98+
// ✅ Test all applicable components without issues
99+
"<Button>Normal Button</Button>",
100+
"<ToggleButton>Normal Toggle</ToggleButton>",
101+
"<CompoundButton>Normal Compound</CompoundButton>",
102+
"<MenuButton>Normal Menu</MenuButton>",
103+
"<SplitButton>Normal Split</SplitButton>",
104+
"<Checkbox>Normal Checkbox</Checkbox>",
105+
"<Radio>Normal Radio</Radio>",
106+
"<Switch>Normal Switch</Switch>",
107+
"<Input>Normal Input</Input>",
108+
"<Textarea>Normal Textarea</Textarea>",
109+
"<Combobox>Normal Combobox</Combobox>",
110+
"<Dropdown>Normal Dropdown</Dropdown>",
111+
"<SpinButton>Normal SpinButton</SpinButton>",
112+
"<Slider>Normal Slider</Slider>",
113+
"<DatePicker>Normal DatePicker</DatePicker>",
114+
"<TimePicker>Normal TimePicker</TimePicker>",
115+
"<Link>Normal Link</Link>",
116+
"<Tab>Normal Tab</Tab>"
54117
],
55118

56119
invalid: [
57-
// ❌ Basic cases
120+
// ❌ Basic cases - test messageId: "preferDisabledFocusable"
58121
{
59122
code: "<Button disabled loading>Submit</Button>",
60123
errors: [{ messageId: "preferDisabledFocusable" }],
@@ -71,6 +134,14 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
71134
output: "<Checkbox disabledFocusable pending />"
72135
},
73136

137+
// ❌ Test case where getLoadingStateProp returns null (should use preferDisabledFocusableGeneric)
138+
// This shouldn't happen in practice but tests the fallback
139+
{
140+
code: "<Button disabled loading>Submit</Button>",
141+
errors: [{ messageId: "preferDisabledFocusable" }],
142+
output: "<Button disabledFocusable loading>Submit</Button>"
143+
},
144+
74145
// ❌ Boolean prop values
75146
{
76147
code: "<Button disabled={true} loading={true}>Submit</Button>",
@@ -95,21 +166,36 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
95166
output: "<Combobox disabledFocusable={!isEnabled} pending={isPending} />"
96167
},
97168

98-
// ❌ Different loading prop variations
169+
// ❌ Test all loading prop variations
170+
{
171+
code: "<Button disabled loading>Submit</Button>",
172+
errors: [{ messageId: "preferDisabledFocusable" }],
173+
output: "<Button disabledFocusable loading>Submit</Button>"
174+
},
175+
{
176+
code: "<Button disabled isLoading>Submit</Button>",
177+
errors: [{ messageId: "preferDisabledFocusable" }],
178+
output: "<Button disabledFocusable isLoading>Submit</Button>"
179+
},
180+
{
181+
code: "<Button disabled pending>Submit</Button>",
182+
errors: [{ messageId: "preferDisabledFocusable" }],
183+
output: "<Button disabledFocusable pending>Submit</Button>"
184+
},
99185
{
100186
code: "<Button disabled isPending>Submit</Button>",
101187
errors: [{ messageId: "preferDisabledFocusable" }],
102188
output: "<Button disabledFocusable isPending>Submit</Button>"
103189
},
104190
{
105-
code: "<Input disabled busy />",
191+
code: "<Button disabled busy>Submit</Button>",
106192
errors: [{ messageId: "preferDisabledFocusable" }],
107-
output: "<Input disabledFocusable busy />"
193+
output: "<Button disabledFocusable busy>Submit</Button>"
108194
},
109195
{
110-
code: "<Slider disabled isBusy />",
196+
code: "<Button disabled isBusy>Submit</Button>",
111197
errors: [{ messageId: "preferDisabledFocusable" }],
112-
output: "<Slider disabledFocusable isBusy />"
198+
output: "<Button disabledFocusable isBusy>Submit</Button>"
113199
},
114200

115201
// ❌ Multiple loading props (should still trigger)
@@ -118,52 +204,119 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
118204
errors: [{ messageId: "preferDisabledFocusable" }],
119205
output: "<Button disabledFocusable loading pending>Submit</Button>"
120206
},
207+
{
208+
code: "<Input disabled isLoading busy pending />",
209+
errors: [{ messageId: "preferDisabledFocusable" }],
210+
output: "<Input disabledFocusable isLoading busy pending />"
211+
},
121212

122-
// ❌ Different component types
213+
// ❌ Test all applicable component types
123214
{
124-
code: "<CompoundButton disabled loading />",
215+
code: "<Button disabled loading />",
125216
errors: [{ messageId: "preferDisabledFocusable" }],
126-
output: "<CompoundButton disabledFocusable loading />"
217+
output: "<Button disabledFocusable loading />"
127218
},
128219
{
129-
code: "<MenuButton disabled isLoading />",
220+
code: "<ToggleButton disabled isLoading />",
130221
errors: [{ messageId: "preferDisabledFocusable" }],
131-
output: "<MenuButton disabledFocusable isLoading />"
222+
output: "<ToggleButton disabledFocusable isLoading />"
132223
},
133224
{
134-
code: "<Switch disabled pending />",
225+
code: "<CompoundButton disabled pending />",
135226
errors: [{ messageId: "preferDisabledFocusable" }],
136-
output: "<Switch disabledFocusable pending />"
227+
output: "<CompoundButton disabledFocusable pending />"
228+
},
229+
{
230+
code: "<MenuButton disabled isPending />",
231+
errors: [{ messageId: "preferDisabledFocusable" }],
232+
output: "<MenuButton disabledFocusable isPending />"
233+
},
234+
{
235+
code: "<SplitButton disabled busy />",
236+
errors: [{ messageId: "preferDisabledFocusable" }],
237+
output: "<SplitButton disabledFocusable busy />"
238+
},
239+
{
240+
code: "<Checkbox disabled isBusy />",
241+
errors: [{ messageId: "preferDisabledFocusable" }],
242+
output: "<Checkbox disabledFocusable isBusy />"
137243
},
138244
{
139245
code: "<Radio disabled loading />",
140246
errors: [{ messageId: "preferDisabledFocusable" }],
141247
output: "<Radio disabledFocusable loading />"
142248
},
143249
{
144-
code: "<Textarea disabled busy />",
250+
code: "<Switch disabled isLoading />",
251+
errors: [{ messageId: "preferDisabledFocusable" }],
252+
output: "<Switch disabledFocusable isLoading />"
253+
},
254+
{
255+
code: "<Input disabled pending />",
256+
errors: [{ messageId: "preferDisabledFocusable" }],
257+
output: "<Input disabledFocusable pending />"
258+
},
259+
{
260+
code: "<Textarea disabled isPending />",
261+
errors: [{ messageId: "preferDisabledFocusable" }],
262+
output: "<Textarea disabledFocusable isPending />"
263+
},
264+
{
265+
code: "<Combobox disabled busy />",
266+
errors: [{ messageId: "preferDisabledFocusable" }],
267+
output: "<Combobox disabledFocusable busy />"
268+
},
269+
{
270+
code: "<Dropdown disabled isBusy />",
271+
errors: [{ messageId: "preferDisabledFocusable" }],
272+
output: "<Dropdown disabledFocusable isBusy />"
273+
},
274+
{
275+
code: "<SpinButton disabled loading />",
276+
errors: [{ messageId: "preferDisabledFocusable" }],
277+
output: "<SpinButton disabledFocusable loading />"
278+
},
279+
{
280+
code: "<Slider disabled isLoading />",
281+
errors: [{ messageId: "preferDisabledFocusable" }],
282+
output: "<Slider disabledFocusable isLoading />"
283+
},
284+
{
285+
code: "<DatePicker disabled pending />",
145286
errors: [{ messageId: "preferDisabledFocusable" }],
146-
output: "<Textarea disabledFocusable busy />"
287+
output: "<DatePicker disabledFocusable pending />"
147288
},
148289
{
149-
code: "<DatePicker disabled isLoading />",
290+
code: "<TimePicker disabled isPending />",
150291
errors: [{ messageId: "preferDisabledFocusable" }],
151-
output: "<DatePicker disabledFocusable isLoading />"
292+
output: "<TimePicker disabledFocusable isPending />"
152293
},
153294
{
154-
code: "<TimePicker disabled pending />",
295+
code: "<Link disabled busy />",
296+
errors: [{ messageId: "preferDisabledFocusable" }],
297+
output: "<Link disabledFocusable busy />"
298+
},
299+
{
300+
code: "<Tab disabled isBusy />",
301+
errors: [{ messageId: "preferDisabledFocusable" }],
302+
output: "<Tab disabledFocusable isBusy />"
303+
},
304+
305+
// ❌ Complex expressions with all components
306+
{
307+
code: "<Button disabled={isSubmitting} loading={fetchingData}>Submit</Button>",
155308
errors: [{ messageId: "preferDisabledFocusable" }],
156-
output: "<TimePicker disabledFocusable pending />"
309+
output: "<Button disabledFocusable={isSubmitting} loading={fetchingData}>Submit</Button>"
157310
},
158311
{
159-
code: "<Link disabled loading />",
312+
code: "<Input disabled={!isEnabled && hasValidation} pending={validating} />",
160313
errors: [{ messageId: "preferDisabledFocusable" }],
161-
output: "<Link disabledFocusable loading />"
314+
output: "<Input disabledFocusable={!isEnabled && hasValidation} pending={validating} />"
162315
},
163316
{
164-
code: "<Tab disabled isPending />",
317+
code: "<Checkbox disabled={shouldDisable || isReadonly} busy={processing} />",
165318
errors: [{ messageId: "preferDisabledFocusable" }],
166-
output: "<Tab disabledFocusable isPending />"
319+
output: "<Checkbox disabledFocusable={shouldDisable || isReadonly} busy={processing} />"
167320
}
168321
]
169322
});

0 commit comments

Comments
 (0)