UNPKG

vueless

Version:

Vue Styleless UI Component Library, powered by Tailwind CSS.

332 lines (272 loc) • 8.52 kB
import { mount } from "@vue/test-utils"; import { describe, it, expect, vi } from "vitest"; import UAlert from "../UAlert.vue"; import UIcon from "../../ui.image-icon/UIcon.vue"; import UButton from "../../ui.button/UButton.vue"; import UText from "../../ui.text-block/UText.vue"; import type { Props } from "../types.ts"; describe("UAlert.vue", () => { // Props tests describe("Props", () => { // Variant prop it("applies the correct variant class", async () => { const variants = { solid: "text-inverted bg-primary", outlined: "text-primary border-primary", subtle: "text-primary bg-primary/10 border-primary/15", soft: "text-primary bg-primary/10", }; Object.entries(variants).forEach(([variant, classes]) => { const component = mount(UAlert, { props: { variant: variant as Props["variant"], color: "primary", }, }); expect(component.attributes("class")).toContain(classes); }); }); // Size prop it("applies the correct size class", async () => { const size = { xs: "text-tiny", sm: "text-small", md: "text-medium", lg: "text-large", }; Object.entries(size).forEach(([size, classes]) => { const component = mount(UAlert, { props: { size: size as Props["size"], }, }); expect(component.attributes("class")).toContain(classes); expect(component.findComponent(UText).props("size")).toBe(size); }); }); // Color prop it("applies the correct color class", async () => { const colors = [ "primary", "secondary", "error", "warning", "success", "info", "notice", "neutral", "grayscale", ]; colors.forEach((color) => { const component = mount(UAlert, { props: { color: color as Props["color"], }, }); expect(component.attributes("class")).toContain(color); }); }); // Title prop it("renders the correct title text", () => { const title = "Alert Title"; const component = mount(UAlert, { props: { title, }, }); expect(component.text()).toContain(title); }); // Description prop it("renders the correct description text", () => { const description = "Alert Description"; const component = mount(UAlert, { props: { description, }, }); expect(component.text()).toContain(description); }); // Icon prop it("renders icon when icon prop is provided", () => { const icon = "info"; const component = mount(UAlert, { props: { icon, }, }); const nestedUIconComponents = component.findAllComponents(UIcon); // At least one icon should be the alert icon const alertIcon = nestedUIconComponents.find((icon) => icon.props("name") === "info"); expect(alertIcon).toBeDefined(); }); // Closable prop it("renders close button when closable prop is true", () => { const closable = true; const component = mount(UAlert, { props: { closable, }, }); const closeButton = component.findComponent(UButton); expect(closeButton.exists()).toBe(true); }); // Timeout prop it("auto-closes after timeout", async () => { vi.useFakeTimers(); const timeout = 1000; const component = mount(UAlert, { props: { timeout, }, }); expect(component.isVisible()).toBe(true); vi.advanceTimersByTime(timeout); await component.vm.$nextTick(); expect(component.emitted("hide")).toBeTruthy(); expect(component.isVisible()).toBe(false); vi.useRealTimers(); }); // DataTest prop it("applies the correct data-test attribute", () => { const dataTest = "test-alert"; const component = mount(UAlert, { props: { dataTest, }, }); expect(component.attributes("data-test")).toBe(dataTest); }); }); // Slots tests describe("Slots", () => { // Default slot it("renders content from default slot", () => { const slotContent = "Custom Content"; const component = mount(UAlert, { slots: { default: slotContent, }, }); expect(component.text()).toContain(slotContent); }); // Title slot it("renders content from title slot", () => { const title = "Alert Title"; const slotText = "Custom Title"; const slotClass = "title-content"; const component = mount(UAlert, { props: { title, }, slots: { title: `<span class='${slotClass}'>${slotText}</span>`, }, }); expect(component.text()).not.toContain(title); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.find(`.${slotClass}`).text()).toBe(slotText); }); // Description slot it("renders content from description slot", () => { const description = "Alert Description"; const slotText = "Custom Description"; const slotClass = "description-content"; const component = mount(UAlert, { props: { description, }, slots: { description: `<span class='${slotClass}'>${slotText}</span>`, }, }); expect(component.text()).not.toContain(description); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.find(`.${slotClass}`).text()).toBe(slotText); }); // Left slot it("renders content from left slot", () => { const slotText = "Left"; const slotClass = "left-content"; const component = mount(UAlert, { slots: { left: `<span class='${slotClass}'>${slotText}</span>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.find(`.${slotClass}`).text()).toBe(slotText); }); // Close slot it("renders content from close slot", () => { const slotText = "Close"; const slotClass = "close-content"; const component = mount(UAlert, { props: { closable: true, }, slots: { close: `<span class='${slotClass}'>${slotText}</span>`, }, }); expect(component.find(`.${slotClass}`).exists()).toBe(true); expect(component.find(`.${slotClass}`).text()).toBe(slotText); }); // Slot bindings it("provides correct bindings to slots", () => { const title = "Alert Title"; const description = "Alert Description"; const icon = "info"; // classes const titleClass = "alert-title"; const descriptionClass = "alert-description"; const iconClass = "alert-icon"; const component = mount(UAlert, { props: { title, description, icon, }, slots: { title: ` <template #title="{ title }"> <span class="${titleClass}">{{ title }}</span> </template> `, description: ` <template #description="{ description }"> <span class="${descriptionClass}">{{ description }}</span> </template> `, left: ` <template #left="{ iconName }"> <span class="${iconClass}">{{ iconName }}</span> </template> `, }, }); expect(component.find(`.${titleClass}`).text()).toBe(title); expect(component.find(`.${descriptionClass}`).text()).toBe(description); expect(component.find(`.${iconClass}`).text()).toBe(icon); }); }); // Events tests describe("Events", () => { // Hidden event it("emits hidden event when close button is clicked", async () => { const component = mount(UAlert, { props: { closable: true, }, }); await component.findComponent(UButton).trigger("click"); expect(component.emitted("hide")).toBeTruthy(); }); }); // Exposed refs tests describe("Exposed refs", () => { // wrapperRef it("exposes wrapperRef", () => { const component = mount(UAlert, {}); expect(component.vm.wrapperRef).toBeDefined(); }); }); });