import React from "react"; import type { ReactNode } from "react"; import { render, screen, userEvent } from "@testing-library/react-native"; import { SelectItem, SelectItemPrefix, SelectItemSuffix } from "./SelectItem"; import { SelectTrigger } from "./SelectTrigger"; import { SelectRoot } from "../SelectRoot"; import { SelectPrimitive } from "../../primitives/Select"; import { Icon } from "../../Icon"; import { Text } from "../../Text"; import { PortalHostWrapper } from "../../utils/test"; import { tokens } from "../../utils/design"; const user = userEvent.setup(); beforeAll(() => { const MockNativeMethods = require("react-native/jest/MockNativeMethods"); const mockedMethods = MockNativeMethods.default ?? MockNativeMethods; mockedMethods.measure.mockImplementation( ( callback: ( x: number, y: number, width: number, height: number, pageX: number, pageY: number, ) => void, ) => { callback(0, 0, 320, 48, 20, 100); }, ); }); function renderItems( items: ReactNode, defaultValue?: { value: string; label: string }, onValueChange?: (option?: { value: string; label: string }) => void, ) { return render( {items} , { wrapper: PortalHostWrapper }, ); } async function openSelect() { await user.press(screen.getByTestId("ATL-Select-Trigger")); } describe("Select.Item", () => { it("renders the option label from the label prop", async () => { renderItems(); await openSelect(); expect(screen.getByText("Toronto")).toBeDefined(); }); it("shows the default checkmark on the selected row only", async () => { renderItems( <> , { value: "tor", label: "Toronto" }, ); await openSelect(); // The indicator self-hides on unselected rows, so only the selected row's // checkmark is in the tree. expect(screen.getAllByTestId("checkmark")).toHaveLength(1); }); it("renders prefix and suffix slots around the label", async () => { renderItems( } suffix={ ON } />, ); await openSelect(); expect(screen.getByTestId("home")).toBeDefined(); expect(screen.getByText("ON")).toBeDefined(); expect(screen.getByText("Toronto")).toBeDefined(); }); it("shows the suffix alongside the checkmark on the selected row", async () => { renderItems( ON } />, { value: "tor", label: "Toronto" }, ); await openSelect(); // The suffix coexists with the selected-state marker (it doesn't replace it). expect(screen.getByText("ON")).toBeDefined(); expect(screen.getByTestId("checkmark")).toBeDefined(); }); it("overrides the default checkmark via the indicator prop", async () => { renderItems( } />, { value: "tor", label: "Toronto" }, ); await openSelect(); expect(screen.getByTestId("starFill")).toBeDefined(); expect(screen.queryByTestId("checkmark")).toBeNull(); }); it("selects an option on press (selection flows through the sugar)", async () => { const onValueChange = jest.fn(); renderItems( , undefined, onValueChange, ); await openSelect(); await user.press(screen.getByText("Toronto")); expect(onValueChange).toHaveBeenCalledWith({ value: "tor", label: "Toronto", }); }); it("greys a disabled option's label", async () => { renderItems(); await openSelect(); expect(screen.getByText("Vancouver")).toHaveStyle({ color: tokens["color-disabled"], }); }); });