UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

266 lines (209 loc) 8.99 kB
import { beforeEach, afterEach, describe, expect, test, vi } from "vitest"; import { shallowMount, mount, enableAutoUnmount } from "@vue/test-utils"; import { nextTick } from "vue"; import OInput from "@/components/input/Input.vue"; describe("OInput", () => { enableAutoUnmount(afterEach); beforeEach(() => { vi.useFakeTimers(); }); afterEach(() => { vi.useRealTimers(); }); test("render correctly", () => { const wrapper = mount(OInput); expect(!!wrapper.vm).toBeTruthy(); expect(wrapper.exists()).toBeTruthy(); expect(wrapper.attributes("data-oruga")).toBe("input"); expect(wrapper.html()).toMatchSnapshot(); expect(wrapper.classes("o-input")).toBeTruthy(); }); test("test basic", async () => { const wrapper = mount(OInput, { props: { icon: "placeholder", iconClickable: true }, }); const input = wrapper.find("input"); expect(input.exists()).toBeTruthy(); expect(input.classes()).toContain("o-input__input"); expect(input.element.tagName).toBe("INPUT"); const value = "some value"; await input.setValue(value); await vi.runAllTimers(); // await debounce timer expect(wrapper.emitted("input")).toHaveLength(1); expect(wrapper.emitted("update:modelValue")).toHaveLength(1); expect(wrapper.vm.value).toEqual(value); }); test("render textarea element when type is textarea", () => { const wrapper = mount(OInput, { props: { type: "textarea" } }); expect(wrapper.classes()).toContain("o-input--textarea"); const input = wrapper.find("textarea"); expect(input.exists()).toBeTruthy(); expect(input.classes()).toContain("o-input__input"); expect(input.attributes("style")).toBeFalsy(); expect(input.element.tagName).toBe("TEXTAREA"); }); test("add inline style and call resize for textarea when autosize is true", async () => { const wrapper = mount(OInput, { props: { type: "textarea", autosize: true }, }); const target = wrapper.find("textarea"); const style = target.attributes("style"); expect(!!style).toBeTruthy(); await target.setValue("test2"); expect(target.attributes("style") == style).toBeFalsy(); expect(target.element.style.height).toContain("px"); }); test("render field password when the type property is password", () => { const wrapper = shallowMount(OInput, { props: { type: "password", passwordReveal: true }, }); const target = wrapper.find("input"); expect(target.exists()).toBeTruthy(); expect(target.attributes("type")).toBe("password"); const icon = wrapper.find("o-icon-stub"); expect(icon.exists()).toBeTruthy(); expect(icon.classes("o-input__icon-right")).toBeTruthy(); }); test("toggles the visibility of the password to true when the togglePasswordVisibility method is called", async () => { const wrapper = mount(OInput, { props: { modelValue: "foo", type: "password", passwordReveal: true, iconRightClickable: true, }, }); const target = wrapper.find("input"); expect(target).toBeTruthy(); await target.setValue("bar"); expect(target.element.type).toBe("password"); const icon = wrapper.find("[data-oruga='icon']"); expect(icon.exists()).toBeTruthy(); expect(icon.classes("o-icon--clickable")).toBeTruthy(); expect(icon.find(".mdi-eye").exists()).toBeTruthy(); await icon.trigger("click"); expect(wrapper.emitted("icon-right-click")).toHaveLength(1); expect(target.element.type).toBe("text"); expect(target.attributes().type).toBe("text"); expect(icon.find(".mdi-eye-off").exists()).toBeTruthy(); }); test("icon clickable", async () => { const wrapper = mount(OInput, { props: { icon: "foo", iconClickable: true }, }); const icon = wrapper.find("[data-oruga='icon']"); expect(icon.exists()).toBeTruthy(); expect(icon.classes("o-icon--clickable")).toBeTruthy(); expect(icon.find(".mdi-foo").exists()).toBeTruthy(); await icon.trigger("click"); expect(wrapper.emitted("icon-click")).toHaveLength(1); }); test("render the placeholder and readonly attribute when passed", () => { const wrapper = shallowMount(OInput, { props: { placeholder: "Awesome!", readonly: true }, }); const input = wrapper.find("input"); expect(input.element.getAttribute("placeholder")).toBe("Awesome!"); expect(input.attributes("readonly")).toBe(""); }); test("expands input when expanded property is passed", async () => { const wrapper = mount(OInput, { props: { expanded: true } }); expect(wrapper.classes()).toContain("o-input--expanded"); }); test("render accordingly when has size prop", () => { const wrapper = mount(OInput, { props: { size: "large" }, }); expect(wrapper.classes("o-input--large")).toBeTruthy(); }); test("render accordingly when has variant prop", () => { const wrapper = mount(OInput, { props: { variant: "danger" }, }); expect(wrapper.classes("o-input--danger")).toBeTruthy(); }); test("render accordingly when is disabled", () => { const wrapper = mount(OInput, { props: { disabled: true }, }); expect(wrapper.classes("o-input--disabled")).toBeTruthy(); const input = wrapper.find("input"); expect(input.exists()).toBeTruthy(); expect(input.attributes("disabled")).not.toBeUndefined(); }); test("keep its value on blur", async () => { const wrapper = mount(OInput, { props: { modelValue: "foo", "onUpdate:modelValue": (modelValue) => wrapper.setProps({ modelValue }), }, }); const input = wrapper.find("input"); expect(input.element.value).toBe("foo"); await input.setValue("bar"); await input.trigger("blur"); await vi.runAllTimers(); // await debounce timer const emits = wrapper.emitted("input"); expect(emits).toHaveLength(1); expect(emits![0][0]).toBe("bar"); expect(wrapper.emitted("blur")).toHaveLength(1); expect(wrapper.emitted("update:modelValue")).toHaveLength(1); expect(wrapper.emitted("update:modelValue")![0][0]).toBe("bar"); expect(wrapper.props("modelValue")).toBe("bar"); }); test("manage the click on icon", async () => { const wrapper = mount(OInput, { props: { icon: "magnify", iconClickable: true }, }); expect(wrapper.find("input").exists()).toBeTruthy(); const visibilityIcon = wrapper.find(".o-icon--clickable"); expect(visibilityIcon.exists()).toBeTruthy(); await visibilityIcon.trigger("click"); expect(wrapper.emitted("icon-click")).toHaveLength(1); }); test("check type number ", async () => { const wrapper = shallowMount(OInput, { props: { type: "number", min: 0, max: 1000, modelValue: 10, number: true, }, }); const input = wrapper.find("input"); expect(input.exists()).toBeTruthy(); expect(input.element.value).toBe("10"); await input.setValue(11); expect(input.element.value).toBe("11"); await input.setValue(12); expect(input.element.value).toBe("12"); await input.setValue(13); expect(input.element.value).toBe("13"); await input.setValue(12); expect(input.element.value).toBe("12"); await input.setValue(11); expect(input.element.value).toBe("11"); const emitted = wrapper.emitted("update:modelValue"); expect(emitted).toEqual([[11], [12], [13], [12], [11]]); }); test("check is empty when null", async () => { const wrapper = mount(OInput, { // @ts-expect-error special check for null instead of undefined props: { modelValue: null }, }); const input = wrapper.find("input"); expect(input.exists()).toBeTruthy(); expect(input.element.value).toEqual(""); }); test("react accordingly when method focus() is called", async () => { const wrapper = mount(OInput); const input = wrapper.find("input"); input.element.focus = vi.fn(); wrapper.vm.focus(); await nextTick(() => { expect(input.element.focus).toHaveBeenCalled(); }); }); });