From 88e9fc89409b2ee4c80c2f94289b08f468326a29 Mon Sep 17 00:00:00 2001 From: Aubrey Quinn Date: Mon, 21 Oct 2024 21:58:01 +0100 Subject: [PATCH 1/2] improved unit test coverage for has tool tip parent function --- lib/util/hasTooltipParent.js | 31 ------- lib/util/hasTooltipParent.ts | 39 ++++++++ .../lib/rules/utils/hasTooltipParent.test.ts | 89 +++++++++++++++++++ 3 files changed, 128 insertions(+), 31 deletions(-) delete mode 100644 lib/util/hasTooltipParent.js create mode 100644 lib/util/hasTooltipParent.ts create mode 100644 tests/lib/rules/utils/hasTooltipParent.test.ts diff --git a/lib/util/hasTooltipParent.js b/lib/util/hasTooltipParent.js deleted file mode 100644 index e73a704..0000000 --- a/lib/util/hasTooltipParent.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -var elementType = require("jsx-ast-utils").elementType; - -function hasToolTipParent(context) { - const ancestors = context.getAncestors(); - - if (ancestors == null || ancestors.length === 0) { - return false; - } - - var toolTip = false; - - ancestors.forEach(item => { - if ( - item.type === "JSXElement" && - item.openingElement != null && - item.openingElement.type === "JSXOpeningElement" && - elementType(item.openingElement) === "Tooltip" - ) { - toolTip = true; - } - }); - - return toolTip; -} - -module.exports = { - hasToolTipParent -}; diff --git a/lib/util/hasTooltipParent.ts b/lib/util/hasTooltipParent.ts new file mode 100644 index 0000000..462ac00 --- /dev/null +++ b/lib/util/hasTooltipParent.ts @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { elementType } from "jsx-ast-utils"; +import { TSESLint, TSESTree } from "@typescript-eslint/utils"; +import { JSXOpeningElement } from "estree-jsx"; + +// Type guard to check if a node is a JSXElement +const isJSXElement = (node: TSESTree.Node): node is TSESTree.JSXElement => { + return node.type === "JSXElement"; +}; + +const hasToolTipParent = (context: TSESLint.RuleContext): boolean => { + const ancestors = context.getAncestors(); + + if (!ancestors || ancestors.length === 0) { + return false; + } + + // Iterate through ancestors and return false if a non-JSXElement is found before a Tooltip + for (const item of ancestors) { + if (!isJSXElement(item)) { + return false; // Stop if a non-JSXElement is encountered + } + + const { openingElement } = item; + if ( + openingElement && + openingElement.type === "JSXOpeningElement" && + elementType(openingElement as unknown as JSXOpeningElement) === "Tooltip" + ) { + return true; // Return true if we find a Tooltip + } + } + + return false; +}; + +export { hasToolTipParent }; diff --git a/tests/lib/rules/utils/hasTooltipParent.test.ts b/tests/lib/rules/utils/hasTooltipParent.test.ts new file mode 100644 index 0000000..2125d24 --- /dev/null +++ b/tests/lib/rules/utils/hasTooltipParent.test.ts @@ -0,0 +1,89 @@ +import { hasToolTipParent } from "../../../../lib/util/hasTooltipParent"; +import { TSESLint } from "@typescript-eslint/utils"; + +// Mocking the elementType utility +jest.mock("jsx-ast-utils", () => ({ + elementType: (openingElement: any) => openingElement.name.name +})); + +describe("hasToolTipParent", () => { + let mockContext: TSESLint.RuleContext; + + beforeEach(() => { + mockContext = { + getAncestors: jest.fn() + } as unknown as TSESLint.RuleContext; + }); + + test("should return false when there are no ancestors", () => { + (mockContext.getAncestors as jest.Mock).mockReturnValue([]); + + const result = hasToolTipParent(mockContext); + expect(result).toBe(false); + }); + + test("should return false when no Tooltip ancestor exists", () => { + const mockAncestors = [ + { + type: "JSXElement", + openingElement: { + type: "JSXOpeningElement", + name: { name: "Button" } // Not a Tooltip + } + }, + { + type: "JSXElement", + openingElement: { + type: "JSXOpeningElement", + name: { name: "Div" } // Not a Tooltip + } + } + ]; + (mockContext.getAncestors as jest.Mock).mockReturnValue(mockAncestors); + + const result = hasToolTipParent(mockContext); + expect(result).toBe(false); + }); + + test("should return true when a Tooltip ancestor exists", () => { + const mockAncestors = [ + { + type: "JSXElement", + openingElement: { + type: "JSXOpeningElement", + name: { name: "Div" } // Not a Tooltip + } + }, + { + type: "JSXElement", + openingElement: { + type: "JSXOpeningElement", + name: { name: "Tooltip" } // This is a Tooltip + } + } + ]; + (mockContext.getAncestors as jest.Mock).mockReturnValue(mockAncestors); + + const result = hasToolTipParent(mockContext); + expect(result).toBe(true); + }); + + test("should return false when the ancestor is not a JSXElement", () => { + const mockAncestors = [ + { + type: "Literal" // Not a JSXElement + }, + { + type: "JSXElement", + openingElement: { + type: "JSXOpeningElement", + name: { name: "Tooltip" } // Tooltip exists but first ancestor is invalid + } + } + ]; + (mockContext.getAncestors as jest.Mock).mockReturnValue(mockAncestors); + + const result = hasToolTipParent(mockContext); + expect(result).toBe(false); + }); +}); From 9dd2aace75d4616bf30a9cbf45f86367c70497a8 Mon Sep 17 00:00:00 2001 From: Aubrey Quinn Date: Mon, 21 Oct 2024 22:00:36 +0100 Subject: [PATCH 2/2] fixed broken tests --- lib/util/hasTooltipParent.ts | 31 +++++-------------- .../lib/rules/utils/hasTooltipParent.test.ts | 19 ------------ 2 files changed, 8 insertions(+), 42 deletions(-) diff --git a/lib/util/hasTooltipParent.ts b/lib/util/hasTooltipParent.ts index 462ac00..e41abae 100644 --- a/lib/util/hasTooltipParent.ts +++ b/lib/util/hasTooltipParent.ts @@ -2,14 +2,9 @@ // Licensed under the MIT License. import { elementType } from "jsx-ast-utils"; -import { TSESLint, TSESTree } from "@typescript-eslint/utils"; +import { TSESLint } from "@typescript-eslint/utils"; // Assuming context comes from TSESLint import { JSXOpeningElement } from "estree-jsx"; -// Type guard to check if a node is a JSXElement -const isJSXElement = (node: TSESTree.Node): node is TSESTree.JSXElement => { - return node.type === "JSXElement"; -}; - const hasToolTipParent = (context: TSESLint.RuleContext): boolean => { const ancestors = context.getAncestors(); @@ -17,23 +12,13 @@ const hasToolTipParent = (context: TSESLint.RuleContext): boo return false; } - // Iterate through ancestors and return false if a non-JSXElement is found before a Tooltip - for (const item of ancestors) { - if (!isJSXElement(item)) { - return false; // Stop if a non-JSXElement is encountered - } - - const { openingElement } = item; - if ( - openingElement && - openingElement.type === "JSXOpeningElement" && - elementType(openingElement as unknown as JSXOpeningElement) === "Tooltip" - ) { - return true; // Return true if we find a Tooltip - } - } - - return false; + return ancestors.some( + item => + item.type === "JSXElement" && + item.openingElement && + item.openingElement.type === "JSXOpeningElement" && + elementType(item.openingElement as unknown as JSXOpeningElement) === "Tooltip" + ); }; export { hasToolTipParent }; diff --git a/tests/lib/rules/utils/hasTooltipParent.test.ts b/tests/lib/rules/utils/hasTooltipParent.test.ts index 2125d24..b048b33 100644 --- a/tests/lib/rules/utils/hasTooltipParent.test.ts +++ b/tests/lib/rules/utils/hasTooltipParent.test.ts @@ -67,23 +67,4 @@ describe("hasToolTipParent", () => { const result = hasToolTipParent(mockContext); expect(result).toBe(true); }); - - test("should return false when the ancestor is not a JSXElement", () => { - const mockAncestors = [ - { - type: "Literal" // Not a JSXElement - }, - { - type: "JSXElement", - openingElement: { - type: "JSXOpeningElement", - name: { name: "Tooltip" } // Tooltip exists but first ancestor is invalid - } - } - ]; - (mockContext.getAncestors as jest.Mock).mockReturnValue(mockAncestors); - - const result = hasToolTipParent(mockContext); - expect(result).toBe(false); - }); });