Skip to content

Commit 9c88311

Browse files
committed
increased unit test coverage
1 parent 4d7b5f3 commit 9c88311

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
5+
import { TSESLint } from "@typescript-eslint/utils";
6+
import { hasLabeledChild } from "../../../../lib/util/hasLabeledChild";
7+
8+
// helper for loc/range
9+
const mockLocRange = () => ({
10+
loc: {
11+
start: { line: 0, column: 0 },
12+
end: { line: 0, column: 0 }
13+
},
14+
range: [0, 0] as [number, number]
15+
});
16+
17+
// minimal JSXOpeningElement: <img />
18+
const openingEl: TSESTree.JSXOpeningElement = {
19+
type: AST_NODE_TYPES.JSXOpeningElement,
20+
name: {
21+
type: AST_NODE_TYPES.JSXIdentifier,
22+
name: "img",
23+
...mockLocRange()
24+
},
25+
attributes: [], // no props
26+
selfClosing: true, // <img />
27+
...mockLocRange()
28+
};
29+
30+
// minimal RuleContext mock
31+
const mockContext = {
32+
report: jest.fn(),
33+
getSourceCode: jest.fn()
34+
} as unknown as TSESLint.RuleContext<string, unknown[]>;
35+
36+
describe("hasLabeledChild", () => {
37+
it("returns false for a self-closing <img /> with no labeled children", () => {
38+
expect(hasLabeledChild(openingEl, mockContext)).toBe(false);
39+
});
40+
});

tests/lib/rules/utils/ruleFactory.test.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jest.mock("../../../../lib/util/hasFieldParent", () => ({
1818
jest.mock("../../../../lib/util/hasLabeledChild", () => ({
1919
hasLabeledChild: jest.fn()
2020
}));
21+
jest.mock("../../../../lib/util/hasTooltipParent", () => ({
22+
hasToolTipParent: jest.fn()
23+
}));
2124

2225
import { hasNonEmptyProp } from "../../../../lib/util/hasNonEmptyProp";
2326
import {
@@ -33,6 +36,7 @@ import { hasAccessibleLabel, LabeledControlConfig, makeLabeledControlRule } from
3336
import type { TSESTree } from "@typescript-eslint/utils";
3437
import { Rule, RuleTester } from "eslint";
3538
import { hasLabeledChild } from "../../../../lib/util/hasLabeledChild";
39+
import { hasToolTipParent } from "../../../../lib/util/hasTooltipParent";
3640

3741
// Helper: reset all mocks to a default "false" stance
3842
const 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

4853
beforeEach(() => {
@@ -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

Comments
 (0)