From 53684d6fbb0b378bfe29ae8fc4c347c9306bea6e Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Sat, 29 Aug 2020 00:25:37 -0400 Subject: [PATCH] Add test spec for components/ui/autocomplete.vue --- components/ui/__tests__/autocomplete.spec.js | 305 +++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 components/ui/__tests__/autocomplete.spec.js diff --git a/components/ui/__tests__/autocomplete.spec.js b/components/ui/__tests__/autocomplete.spec.js new file mode 100644 index 000000000..2754a4b5f --- /dev/null +++ b/components/ui/__tests__/autocomplete.spec.js @@ -0,0 +1,305 @@ +import autocomplete from "../autocomplete" +import { mount } from "@vue/test-utils" + +const props = { + placeholder: "", + value: "", + spellcheck: false, + source: ["app", "apple", "appliance", "brian", "bob", "alice"], +} + +const factory = (props) => + mount(autocomplete, { + propsData: props, + }) + +describe("autocomplete", () => { + test("mounts properly", () => { + const wrapper = factory(props) + + expect(wrapper).toBeTruthy() + }) + + test("emits input event on text update [v-model compat]", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("testval") + + await wrapper.vm.$nextTick() + + expect(wrapper.emitted("input")).toBeTruthy() + expect(wrapper.emitted("input").length).toEqual(1) + }) + + test("shows matching suggestions", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + const suggestions = wrapper.findAll("li").wrappers.map((el) => el.text()) + + expect(suggestions).toContain("pp") + expect(suggestions).toContain("pple") + expect(suggestions).toContain("ppliance") + expect(suggestions).toContain("lice") + }) + + test("doesnt show non-matching suggestions", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("b") + await wrapper.vm.$nextTick() + + const suggestions = wrapper.findAll("li").wrappers.map((el) => el.text()) + + expect(suggestions).not.toContain("pp") + expect(suggestions).not.toContain("pple") + expect(suggestions).not.toContain("ppliance") + expect(suggestions).not.toContain("lice") + }) + + test("updates suggestions on input", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("b") + await wrapper.vm.$nextTick() + + const suggestions = wrapper.findAll("li").wrappers.map((el) => el.text()) + + expect(suggestions).not.toContain("pp") + expect(suggestions).not.toContain("pple") + expect(suggestions).not.toContain("ppliance") + expect(suggestions).not.toContain("lice") + }) + + test("applies suggestion on clicking", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("b") + await wrapper.vm.$nextTick() + + const selectedSuggestion = wrapper.findAll("li").at(0) + const selectedText = selectedSuggestion.text() + + await selectedSuggestion.trigger("click") + await wrapper.vm.$nextTick() + + expect(input.element.value).toEqual("b" + selectedText) + }) + + test("hide selection on pressing ESC", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("b") + await wrapper.vm.$nextTick() + + await input.trigger("keyup", { code: "Escape" }) + await wrapper.vm.$nextTick() + + expect(wrapper.find("ul").exists()).toEqual(false) + }) + + test("pressing up when nothing is selected selects the first in the list", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowUp", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(0).element.classList.contains("active")).toEqual(true) + }) + + test("pressing down arrow when nothing is selected selects the first in the list", async () => { + const wrapper = factory(props) + + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(0).element.classList.contains("active")).toEqual(true) + }) + + test("pressing down arrow moves down the selection list", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(1).element.classList.contains("active")).toEqual(true) + }) + + test("pressing up arrow moves up the selection list", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowUp", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(0).element.classList.contains("active")).toEqual(true) + }) + + test("pressing down arrow at the end of the list doesn't update the selection", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("b") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(1).element.classList.contains("active")).toEqual(true) + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(1).element.classList.contains("active")).toEqual(true) + }) + + test("pressing up arrow at the top of the list doesn't update the selection", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("b") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowUp", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(0).element.classList.contains("active")).toEqual(true) + + await input.trigger("keydown", { + code: "ArrowUp", + }) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll("li").at(0).element.classList.contains("active")).toEqual(true) + }) + + test("pressing tab performs the current completion", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + const selectedSuggestion = wrapper.find("li.active").text() + + await input.trigger("keydown", { + code: "Tab", + }) + await wrapper.vm.$nextTick() + + expect(input.element.value).toEqual("a" + selectedSuggestion) + }) + + test("pressing tab when nothing is selected selects the first suggestion", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + const firstSuggestionText = wrapper.findAll("li").at(0).text() + + await input.trigger("keydown", { + code: "Tab", + }) + await wrapper.vm.$nextTick() + + expect(input.element.value).toEqual("a" + firstSuggestionText) + }) + + test("pressing any non-special key doesn't do anything", async () => { + const wrapper = factory(props) + const input = wrapper.find("input") + + await input.setValue("a") + await wrapper.vm.$nextTick() + + await input.trigger("keydown", { + code: "ArrowDown", + }) + await wrapper.vm.$nextTick() + + const selectedSuggestion = wrapper.find("li.active").text() + + await input.trigger("keydown", { + code: "Tab", + }) + await wrapper.vm.$nextTick() + + expect(input.element.value).toEqual("a" + selectedSuggestion) + }) +})