Skip to content

Commit bbedacb

Browse files
Add additional edge cases.
1 parent 7350b25 commit bbedacb

File tree

1 file changed

+129
-10
lines changed

1 file changed

+129
-10
lines changed

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

Lines changed: 129 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
8080
"<Checkbox disabled={true} disabledFocusable={false} pending />",
8181
"<ToggleButton disabled={isDisabled} disabledFocusable={shouldFocus} busy />",
8282

83-
// ✅ Complex expressions
83+
// ✅ Complex expressions with disabledFocusable
8484
"<Button disabledFocusable={shouldDisable} loading={isSubmitting}>Submit</Button>",
8585
"<Input disabledFocusable={disabled && !error} isLoading={fetching} />",
8686
"<SpinButton disabledFocusable={!enabled || hasError} pending={processing} />",
@@ -113,7 +113,31 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
113113
"<DatePicker>Normal DatePicker</DatePicker>",
114114
"<TimePicker>Normal TimePicker</TimePicker>",
115115
"<Link>Normal Link</Link>",
116-
"<Tab>Normal Tab</Tab>"
116+
"<Tab>Normal Tab</Tab>",
117+
118+
// ✅ Test components with different casing variations
119+
"<button disabled loading>Submit</button>", // lowercase (should not trigger - not a FluentUI component)
120+
"<BUTTON disabled loading>Submit</BUTTON>", // uppercase (should not trigger - not a FluentUI component)
121+
122+
// ✅ Cases where loading props are truly empty (null, undefined, empty string)
123+
'<Input disabled={true} isLoading="">Submit</Input>', // loading is empty string
124+
"<Checkbox disabled={true} pending={null} />", // loading is null
125+
"<SpinButton disabled={true} busy={undefined} />", // loading is undefined
126+
127+
// ✅ Cases where only one prop exists (no combination to trigger rule)
128+
"<Button disabled={(() => false)()}>Submit</Button>", // only disabled, no loading
129+
"<Input isLoading={status === 'loading'} />", // only loading, no disabled
130+
"<Checkbox loading={(() => true)()} />", // only loading, no disabled
131+
"<ToggleButton disabled={isDisabled ? false : true} />", // only disabled, no loading
132+
133+
// ✅ JSXSpreadAttribute cases without both props
134+
"<Button {...props} disabled={false}>Submit</Button>", // only disabled, no loading
135+
"<Input {...buttonProps} isLoading={1} />", // only loading, no disabled
136+
137+
// ✅ Cases where disabled has truly empty values
138+
'<Button disabled="" loading={false}>Submit</Button>', // disabled is empty string (should not trigger because disabled is empty)
139+
"<Input disabled={null} loading={true} />", // disabled is null (should not trigger because disabled is empty)
140+
"<Checkbox disabled={undefined} pending={true} />" // disabled is undefined (should not trigger because disabled is empty)
117141
],
118142

119143
invalid: [
@@ -134,26 +158,55 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
134158
output: "<Checkbox disabledFocusable pending />"
135159
},
136160

137-
// ❌ Test case where getLoadingStateProp returns null (should use preferDisabledFocusableGeneric)
138-
// This shouldn't happen in practice but tests the fallback
161+
// ❌ Boolean prop values (ALL boolean values are considered "non-empty" by hasNonEmptyProp)
139162
{
140-
code: "<Button disabled loading>Submit</Button>",
163+
code: "<Button disabled={true} loading={true}>Submit</Button>",
141164
errors: [{ messageId: "preferDisabledFocusable" }],
142-
output: "<Button disabledFocusable loading>Submit</Button>"
165+
output: "<Button disabledFocusable={true} loading={true}>Submit</Button>"
143166
},
144-
145-
// ❌ Boolean prop values
146167
{
147-
code: "<Button disabled={true} loading={true}>Submit</Button>",
168+
code: "<Button disabled={true} loading={false}>Submit</Button>", // MOVED FROM VALID - false is still non-empty!
148169
errors: [{ messageId: "preferDisabledFocusable" }],
149-
output: "<Button disabledFocusable={true} loading={true}>Submit</Button>"
170+
output: "<Button disabledFocusable={true} loading={false}>Submit</Button>"
150171
},
151172
{
152173
code: "<Input disabled={false} isLoading={processing} />",
153174
errors: [{ messageId: "preferDisabledFocusable" }],
154175
output: "<Input disabledFocusable={false} isLoading={processing} />"
155176
},
156177

178+
// ❌ Cases that were incorrectly in valid section (hasNonEmptyProp treats these as non-empty)
179+
{
180+
code: "<Button disabled={(() => false)()} loading={(() => true)()}>Submit</Button>",
181+
errors: [{ messageId: "preferDisabledFocusable" }],
182+
output: "<Button disabledFocusable={(() => false)()} loading={(() => true)()}>Submit</Button>"
183+
},
184+
{
185+
code: "<Input disabled={isDisabled ? false : true} isLoading={status === 'loading'} />",
186+
errors: [{ messageId: "preferDisabledFocusable" }],
187+
output: "<Input disabledFocusable={isDisabled ? false : true} isLoading={status === 'loading'} />"
188+
},
189+
{
190+
code: "<Button {...props} disabled={false} loading>Submit</Button>",
191+
errors: [{ messageId: "preferDisabledFocusable" }],
192+
output: "<Button {...props} disabledFocusable={false} loading>Submit</Button>"
193+
},
194+
{
195+
code: "<Input {...buttonProps} disabled loading={false} />",
196+
errors: [{ messageId: "preferDisabledFocusable" }],
197+
output: "<Input {...buttonProps} disabledFocusable loading={false} />"
198+
},
199+
{
200+
code: "<Button disabled={0} loading>Submit</Button>", // 0 is considered non-empty
201+
errors: [{ messageId: "preferDisabledFocusable" }],
202+
output: "<Button disabledFocusable={0} loading>Submit</Button>"
203+
},
204+
{
205+
code: "<Input disabled={false} isLoading={1} />",
206+
errors: [{ messageId: "preferDisabledFocusable" }],
207+
output: "<Input disabledFocusable={false} isLoading={1} />"
208+
},
209+
157210
// ❌ Expression prop values
158211
{
159212
code: "<SpinButton disabled={isDisabled} loading={isSubmitting} />",
@@ -317,6 +370,72 @@ ruleTester.run("prefer-disabledfocusable-over-disabled", rule as unknown as Rule
317370
code: "<Checkbox disabled={shouldDisable || isReadonly} busy={processing} />",
318371
errors: [{ messageId: "preferDisabledFocusable" }],
319372
output: "<Checkbox disabledFocusable={shouldDisable || isReadonly} busy={processing} />"
373+
},
374+
375+
// ❌ Test more complex expression scenarios
376+
{
377+
code: "<Button disabled={isSubmitting || hasError} loading={status === 'pending'}>Submit</Button>",
378+
errors: [{ messageId: "preferDisabledFocusable" }],
379+
output: "<Button disabledFocusable={isSubmitting || hasError} loading={status === 'pending'}>Submit</Button>"
380+
},
381+
382+
// ❌ Additional test cases to ensure full coverage
383+
{
384+
code: "<Button disabled={true} loading>Submit</Button>",
385+
errors: [{ messageId: "preferDisabledFocusable" }],
386+
output: "<Button disabledFocusable={true} loading>Submit</Button>"
387+
},
388+
389+
// ❌ Test edge cases for fix function coverage
390+
{
391+
code: "<Button disabled={1} loading={true}>Submit</Button>", // truthy number
392+
errors: [{ messageId: "preferDisabledFocusable" }],
393+
output: "<Button disabledFocusable={1} loading={true}>Submit</Button>"
394+
},
395+
{
396+
code: "<Input disabled={'true'} isLoading={'false'} />", // string values
397+
errors: [{ messageId: "preferDisabledFocusable" }],
398+
output: "<Input disabledFocusable={'true'} isLoading={'false'} />"
399+
},
400+
401+
// ❌ Test JSXSpreadAttribute with invalid cases
402+
{
403+
code: "<Button {...props} disabled loading>Submit</Button>",
404+
errors: [{ messageId: "preferDisabledFocusable" }],
405+
output: "<Button {...props} disabledFocusable loading>Submit</Button>"
406+
},
407+
{
408+
code: "<Input disabled {...inputProps} isLoading />",
409+
errors: [{ messageId: "preferDisabledFocusable" }],
410+
output: "<Input disabledFocusable {...inputProps} isLoading />"
411+
},
412+
413+
// ❌ Test cases where fix function edge cases might be triggered
414+
{
415+
code: "<Button disabled={variable} pending={anotherVariable}>Submit</Button>",
416+
errors: [{ messageId: "preferDisabledFocusable" }],
417+
output: "<Button disabledFocusable={variable} pending={anotherVariable}>Submit</Button>"
418+
},
419+
420+
// ❌ Test more combinations to increase coverage
421+
{
422+
code: "<Combobox disabled={true} loading={true} pending={false} />", // Multiple loading props
423+
errors: [{ messageId: "preferDisabledFocusable" }],
424+
output: "<Combobox disabledFocusable={true} loading={true} pending={false} />"
425+
},
426+
427+
// ❌ Edge case: Test with numeric and other literal values
428+
{
429+
code: "<Button disabled={42} loading={-1}>Submit</Button>", // Numeric values
430+
errors: [{ messageId: "preferDisabledFocusable" }],
431+
output: "<Button disabledFocusable={42} loading={-1}>Submit</Button>"
432+
},
433+
434+
// ❌ Test string prop values that are non-empty
435+
{
436+
code: '<Button disabled="true" loading="false">Submit</Button>',
437+
errors: [{ messageId: "preferDisabledFocusable" }],
438+
output: '<Button disabledFocusable="true" loading="false">Submit</Button>'
320439
}
321440
]
322441
});

0 commit comments

Comments
 (0)