UNPKG

vueless

Version:

Vue Styleless UI Component Library, powered by Tailwind CSS.

312 lines (250 loc) 9.19 kB
import { mount } from "@vue/test-utils"; import { describe, it, expect } from "vitest"; import { createRouter, createWebHistory } from "vue-router"; import UPage from "../UPage.vue"; import type { Props } from "../types"; import type { UnknownObject } from "../../types"; // Create a mock router for testing router-link functionality const router = createRouter({ history: createWebHistory(), routes: [ { path: "/", name: "home", component: { template: "<div>Home</div>" } }, { path: "/back", name: "back", component: { template: "<div>Back</div>" } }, ], }); // Helper function to mount component with router const mountWithRouter = (component: unknown, options: UnknownObject) => { return mount(component, { ...options, global: { plugins: [router], ...(options.global || {}), }, }); }; describe("UPage.vue", () => { describe("Props", () => { it("Variant – applies correct variant classes", () => { const variants = { solid: "bg-default border-transparent", outlined: "bg-default border-muted", subtle: "bg-muted border-default/50", soft: "bg-muted border-transparent", inverted: "bg-inverted border-transparent", }; Object.entries(variants).forEach(([variant, classes]) => { const component = mount(UPage, { props: { variant: variant as Props["variant"], }, }); // Check that the page element has the expected classes expect(component.find("[vl-key='page']").attributes("class")).toContain(classes); }); }); it("Size – applies correct size classes", () => { const sizeClasses = { xs: "md:w-[25rem]", sm: "md:w-[31.25rem]", md: "md:w-[37.5rem]", lg: "md:w-[43.75rem]", xl: "md:w-[50rem]", "2xl": "md:w-[56.25rem]", "3xl": "md:w-[62.5rem]", "4xl": "md:w-[68.75rem]", "5xl": "md:w-[75rem]", wide: "md:w-full", }; Object.entries(sizeClasses).forEach(([size, classes]) => { const component = mount(UPage, { props: { size: size as Props["size"], }, }); expect(component.attributes("class")).toContain(classes); }); }); it("Title Size – applies correct titleSize to the header", () => { const titleSizes = ["xs", "sm", "md", "lg", "xl", "2xl"]; const title = "Test Title"; titleSizes.forEach((size) => { const component = mount(UPage, { props: { title, titleSize: size as Props["titleSize"], }, }); const header = component.findComponent({ name: "UHeader" }); expect(header.exists()).toBe(true); expect(header.props("size")).toBe(size); }); }); it("Rounding – applies correct rounding classes", () => { const variants = { true: "border-r-0", false: "rounded-large", }; Object.entries(variants).forEach(([variant, classes]) => { const component = mount(UPage, { props: { rounding: variant === "true", }, }); // Get the page element by vl-key const pageElement = component.find("[vl-key='page']"); // Check that the page element has the expected classes expect(pageElement.attributes("class")).toContain(classes); }); }); it("Title – renders the title correctly", () => { const title = "Test Title"; const component = mount(UPage, { props: { title, }, }); const header = component.findComponent({ name: "UHeader" }); expect(header.exists()).toBe(true); expect(header.props("label")).toBe(title); }); it("Description – renders the description correctly", () => { const description = "Test Description"; const component = mount(UPage, { props: { title: "Test Title", // Need a title to make isExistHeader true description, }, }); const descriptionElement = component.find("[vl-key='description']"); expect(descriptionElement.exists()).toBe(true); expect(descriptionElement.text()).toBe(description); }); it("Back To – renders back link correctly", () => { // Need to provide a valid RouteLocationRaw object const backTo = { path: "/back" }; const backLabel = "Back"; const component = mountWithRouter(UPage, { props: { title: "Test Title", // Need a title to make isExistHeader true backTo, backLabel, }, }); const backLink = component.findComponent({ name: "ULink" }); expect(backLink.exists()).toBe(true); expect(backLink.props("to")).toEqual(backTo); expect(backLink.props("label")).toBe(backLabel); }); it("Data Test – applies the correct data-test attribute", () => { const dataTest = "page-test"; const component = mount(UPage, { props: { dataTest, }, }); expect(component.attributes("data-test")).toBe(dataTest); }); }); describe("Slots", () => { it("Default – renders content in default slot", () => { const slotContent = "Default Content"; const slotClass = "default-content"; const component = mount(UPage, { slots: { default: `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); it("Before-title – renders content in before-title slot", () => { const slotContent = "Before Title Content"; const slotClass = "before-title-content"; const component = mount(UPage, { slots: { "before-title": `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); it("Title – renders content in title slot", () => { const slotContent = "Title Content"; const slotClass = "title-content"; const component = mount(UPage, { slots: { title: `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); it("After-title – renders content in after-title slot", () => { const slotContent = "After Title Content"; const slotClass = "after-title-content"; const component = mount(UPage, { slots: { "after-title": `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); it("Actions – renders content in actions slot", () => { const slotContent = "Actions Content"; const slotClass = "actions-content"; const component = mount(UPage, { slots: { actions: `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); it("Footer-left – renders content in footer-left slot", () => { const slotContent = "Footer Left Content"; const slotClass = "footer-left-content"; const component = mount(UPage, { slots: { "footer-left": `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); it("Footer-right – renders content in footer-right slot", () => { const slotContent = "Footer Right Content"; const slotClass = "footer-right-content"; const component = mount(UPage, { slots: { "footer-right": `<div class="${slotClass}">${slotContent}</div>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.text()).toContain(slotContent); }); }); describe("Events", () => { it("Back – emits back event when back link is clicked", async () => { const component = mountWithRouter(UPage, { props: { title: "Test Title", // Need a title to make isExistHeader true backTo: { path: "/back" }, backLabel: "Back", }, }); const backLink = component.findComponent({ name: "ULink" }); expect(backLink.exists()).toBe(true); await backLink.trigger("click"); expect(component.emitted()).toHaveProperty("back"); expect(component.emitted().back).toHaveLength(1); }); }); describe("Exposed refs", () => { it("wrapperRef – exposes wrapperRef", () => { const component = mount(UPage); expect(component.vm.wrapperRef).toBeDefined(); expect(component.vm.wrapperRef instanceof HTMLDivElement).toBe(true); }); }); });