From 6eda673aaf8d8bb31fbaeca83b0fdbb1b6519ce8 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Mon, 17 Mar 2025 17:45:18 -0700 Subject: [PATCH] test(pagination-nav): add unit tests --- tests/PaginationNav.test.svelte | 19 --- tests/PaginationNav/PaginationNav.test.svelte | 36 ++++ tests/PaginationNav/PaginationNav.test.ts | 159 ++++++++++++++++++ 3 files changed, 195 insertions(+), 19 deletions(-) delete mode 100644 tests/PaginationNav.test.svelte create mode 100644 tests/PaginationNav/PaginationNav.test.svelte create mode 100644 tests/PaginationNav/PaginationNav.test.ts diff --git a/tests/PaginationNav.test.svelte b/tests/PaginationNav.test.svelte deleted file mode 100644 index 872194a9..00000000 --- a/tests/PaginationNav.test.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - - - { - console.log(e.detail); // { page: number; } - }} - on:click:button--next={(e) => { - console.log(e.detail); // { page: number; } - }} - on:click:button--previous={(e) => { - console.log(e.detail); // { page: number; } - }} -/> diff --git a/tests/PaginationNav/PaginationNav.test.svelte b/tests/PaginationNav/PaginationNav.test.svelte new file mode 100644 index 00000000..42b4e28d --- /dev/null +++ b/tests/PaginationNav/PaginationNav.test.svelte @@ -0,0 +1,36 @@ + + + { + console.log("change", e.detail); + }} + on:click:button--previous={(e) => { + console.log("previous", e.detail); + }} + on:click:button--next={(e) => { + console.log("next", e.detail); + }} +/> diff --git a/tests/PaginationNav/PaginationNav.test.ts b/tests/PaginationNav/PaginationNav.test.ts new file mode 100644 index 00000000..7c4a5bd6 --- /dev/null +++ b/tests/PaginationNav/PaginationNav.test.ts @@ -0,0 +1,159 @@ +import { render, screen, within } from "@testing-library/svelte"; +import { user } from "../setup-tests"; +import PaginationNav from "./PaginationNav.test.svelte"; + +describe("PaginationNav", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("should render with default props", () => { + render(PaginationNav); + + const nav = screen.getByRole("navigation"); + expect(nav).toHaveClass("bx--pagination-nav"); + expect(nav).toHaveAttribute("aria-label", "pagination"); + + const list = screen.getByRole("list"); + expect(list).toHaveClass("bx--pagination-nav__list"); + + expect(screen.getByText("Previous page")).toBeInTheDocument(); + expect(screen.getByText("Next page")).toBeInTheDocument(); + + const pageItems = screen.getAllByRole("listitem"); + expect(pageItems.length).toBeGreaterThan(0); + }); + + it("should render correct number of pages", () => { + render(PaginationNav, { + props: { total: 5 }, + }); + + const pageItems = screen.getAllByRole("listitem"); + expect(pageItems.length).toBe(7); // 5 pages + 2 navigation buttons + }); + + it("should show correct active page", () => { + render(PaginationNav, { + props: { page: 3 }, + }); + + const listItems = screen.getAllByRole("listitem"); + expect(within(listItems[3]).getByRole("button")).toHaveAttribute( + "aria-current", + "page", + ); + }); + + it("should handle custom shown pages", () => { + render(PaginationNav, { + props: { total: 20, shown: 5 }, + }); + + const pageItems = screen.getAllByRole("listitem"); + // Should show 5 pages + 2 navigation buttons + expect(pageItems.length).toBe(7); + }); + + it("should disable previous button on first page", () => { + render(PaginationNav, { + props: { page: 1 }, + }); + + const prevButton = screen.getByRole("button", { name: "Previous page" }); + expect(prevButton).toBeDisabled(); + }); + + it("should disable next button on last page", () => { + render(PaginationNav, { + props: { page: 10, total: 10 }, + }); + + const nextButton = screen.getByRole("button", { name: "Next page" }); + expect(nextButton).toBeDisabled(); + }); + + it("should enable navigation buttons when looping", () => { + render(PaginationNav, { + props: { loop: true, page: 1, total: 10 }, + }); + + const prevButton = screen.getByRole("button", { name: "Previous page" }); + const nextButton = screen.getByRole("button", { name: "Next page" }); + + expect(prevButton).not.toBeDisabled(); + expect(nextButton).not.toBeDisabled(); + }); + + it("should support custom button text", () => { + render(PaginationNav, { + props: { + backwardText: "Previous", + forwardText: "Next", + }, + }); + + expect( + screen.getByRole("button", { name: "Previous" }), + ).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Next" })).toBeInTheDocument(); + }); + + test.each([ + ["top", ["bx--btn--icon-only--top", "bx--btn--icon-only--top"]], + ["right", ["bx--btn--icon-only--right", "bx--btn--icon-only--right"]], + ["bottom", ["bx--btn--icon-only--bottom", "bx--btn--icon-only--bottom"]], + ["left", ["bx--btn--icon-only--left", "bx--btn--icon-only--left"]], + ["outside", ["bx--btn--icon-only--left", "bx--btn--icon-only--right"]], + ["inside", ["bx--btn--icon-only--right", "bx--btn--icon-only--left"]], + ] as const)("should support %s position", (position, [prev, next]) => { + render(PaginationNav, { + props: { tooltipPosition: position }, + }); + + const prevButton = screen.getByRole("button", { name: "Previous page" }); + const nextButton = screen.getByRole("button", { name: "Next page" }); + + expect(prevButton).toHaveClass("bx--tooltip--align-center"); + expect(prevButton).toHaveClass(prev); + + expect(nextButton).toHaveClass("bx--tooltip--align-center"); + expect(nextButton).toHaveClass(next); + }); + + it("should emit change event when clicking a page", async () => { + const consoleLog = vi.spyOn(console, "log"); + render(PaginationNav); + + const pageButton = screen.getByRole("button", { name: /2/ }); + await user.click(pageButton); + expect(consoleLog).toHaveBeenCalledWith("change", { page: 2 }); + + const nextButton = screen.getByRole("button", { name: "Next page" }); + await user.click(nextButton); + expect(consoleLog).toHaveBeenCalledWith("change", { page: 3 }); + + const prevButton = screen.getByRole("button", { name: "Previous page" }); + await user.click(prevButton); + expect(consoleLog).toHaveBeenCalledWith("change", { page: 2 }); + }); + + it("should handle overflow selection", async () => { + const consoleLog = vi.spyOn(console, "log"); + render(PaginationNav, { + props: { total: 100, shown: 5 }, + }); + + const overflowIndicator = screen.getByLabelText("Select Page number"); + expect(overflowIndicator).toBeInTheDocument(); + + await user.selectOptions(overflowIndicator, "4"); + + expect(consoleLog).toHaveBeenCalledWith("change", { page: 4 }); + expect(consoleLog).toHaveBeenCalledTimes(1); + + await user.selectOptions(overflowIndicator, "50"); + expect(consoleLog).toHaveBeenCalledWith("change", { page: 50 }); + expect(consoleLog).toHaveBeenCalledTimes(2); + }); +});