@@ -18,6 +18,9 @@ jest.mock("../../../../lib/util/hasFieldParent", () => ({
1818jest . mock ( "../../../../lib/util/hasLabeledChild" , ( ) => ( {
1919 hasLabeledChild : jest . fn ( )
2020} ) ) ;
21+ jest . mock ( "../../../../lib/util/hasTooltipParent" , ( ) => ( {
22+ hasToolTipParent : jest . fn ( )
23+ } ) ) ;
2124
2225import { hasNonEmptyProp } from "../../../../lib/util/hasNonEmptyProp" ;
2326import {
@@ -33,6 +36,7 @@ import { hasAccessibleLabel, LabeledControlConfig, makeLabeledControlRule } from
3336import type { TSESTree } from "@typescript-eslint/utils" ;
3437import { Rule , RuleTester } from "eslint" ;
3538import { hasLabeledChild } from "../../../../lib/util/hasLabeledChild" ;
39+ import { hasToolTipParent } from "../../../../lib/util/hasTooltipParent" ;
3640
3741// Helper: reset all mocks to a default "false" stance
3842const resetAllMocksToFalse = ( ) => {
@@ -43,6 +47,7 @@ const resetAllMocksToFalse = () => {
4347 ( hasAssociatedLabelViaHtmlFor as jest . Mock ) . mockReset ( ) . mockReturnValue ( false ) ;
4448 ( hasFieldParent as jest . Mock ) . mockReset ( ) . mockReturnValue ( false ) ;
4549 ( hasLabeledChild as jest . Mock ) . mockReset ( ) . mockReturnValue ( false ) ;
50+ ( hasToolTipParent as jest . Mock ) . mockReset ( ) . mockReturnValue ( false ) ;
4651} ;
4752
4853beforeEach ( ( ) => {
@@ -74,7 +79,7 @@ describe("hasAccessibleLabel (unit)", () => {
7479 allowHtmlFor : true ,
7580 allowLabelledBy : true ,
7681 allowWrappingLabel : true ,
77- allowTooltipParent : false ,
82+ allowTooltipParent : true ,
7883 allowDescribedBy : true ,
7984 messageId : "errorMsg" ,
8085 description : "anything" ,
@@ -93,6 +98,12 @@ describe("hasAccessibleLabel (unit)", () => {
9398 expect ( hasAccessibleLabel ( node , { } , cfg ) ) . toBe ( true ) ;
9499 } ) ;
95100
101+ test ( "true when allowTooltipParent and hasTooltipParent(ctx) === true" , ( ) => {
102+ ( hasToolTipParent as jest . Mock ) . mockReturnValue ( true ) ;
103+ const node = makeOpeningElement ( "RadioGroup" ) ;
104+ expect ( hasAccessibleLabel ( node , { } , cfg ) ) . toBe ( true ) ;
105+ } ) ;
106+
96107 test ( "true when a label prop is non-empty via hasNonEmptyProp" , ( ) => {
97108 ( hasNonEmptyProp as jest . Mock ) . mockImplementation ( ( attrs , name ) => ( name === "label" ? true : false ) ) ;
98109 const node = makeOpeningElement ( "RadioGroup" , [
@@ -143,7 +154,7 @@ describe("makeLabeledControlRule (RuleTester integration)", () => {
143154 allowHtmlFor : true ,
144155 allowLabelledBy : true ,
145156 allowWrappingLabel : true ,
146- allowTooltipParent : false ,
157+ allowTooltipParent : true ,
147158 allowDescribedBy : true ,
148159 messageId : "noUnlabeledRadioGroup" ,
149160 description : "Accessibility: RadioGroup must have a programmatic and visual label." ,
@@ -296,4 +307,29 @@ describe("makeLabeledControlRule (RuleTester integration)", () => {
296307 invalid : [ { code : `<RadioGroup />` , errors : [ { messageId : baseCfg . messageId } ] } ]
297308 } ) ;
298309 } ) ;
310+
311+ // 9) tool tip parent
312+ describe ( "accepts when parent Tooltip provides label" , ( ) => {
313+ beforeEach ( ( ) => {
314+ resetAllMocksToFalse ( ) ;
315+ ( hasToolTipParent as jest . Mock ) . mockReturnValue ( true ) ;
316+ } ) ;
317+
318+ const rule = makeLabeledControlRule ( baseCfg ) ;
319+
320+ ruleTester . run ( "no-unlabeled-radio-group (Tooltip parent)" , rule as unknown as Rule . RuleModule , {
321+ valid : [
322+ {
323+ code : `
324+ <>
325+ <Tooltip label="Account type">
326+ <RadioGroup />
327+ </Tooltip>
328+ </>
329+ `
330+ }
331+ ] ,
332+ invalid : [ ]
333+ } ) ;
334+ } ) ;
299335} ) ;
0 commit comments