import { defineComponent, nextTick, shallowRef, toRef, type PropType } from "vue"; import { describe, test, expect } from "vite-plus/test"; import { render } from "@vue-tui/testing"; import { Text, useInput, usePaste } from "@vue-tui/runtime"; describe("usePaste", () => { test("receives pasted text from bracketed paste", async () => { const pasted = shallowRef(""); const App = defineComponent(() => { usePaste((text) => { pasted.value = text; }); return () => {pasted.value || "waiting"}; }); const { stdin } = await render(App); await stdin.write("\x1b[200~hello world\x1b[201~"); expect(pasted.value).toBe("hello world"); }); test("paste falls through to useInput when no paste listeners", async () => { const received = shallowRef(""); const App = defineComponent(() => { useInput((input) => { received.value += input; }); return () => {received.value || "waiting"}; }); const { stdin } = await render(App); // Without usePaste, paste events fall through as regular input await stdin.write("\x1b[200~pasted\x1b[201~"); expect(received.value).toBe("pasted"); }); test("respects isActive option", async () => { const pasted = shallowRef(""); const active = shallowRef(false); const App = defineComponent(() => { usePaste( (text) => { pasted.value = text; }, { isActive: active }, ); return () => {pasted.value || "waiting"}; }); const { stdin } = await render(App); await stdin.write("\x1b[200~ignored\x1b[201~"); expect(pasted.value).toBe(""); active.value = true; await stdin.write("\x1b[200~captured\x1b[201~"); expect(pasted.value).toBe("captured"); }); test("accepts a handler ref and calls the latest function", async () => { const calls: string[] = []; const firstHandler = (text: string) => calls.push(`first:${text}`); const secondHandler = (text: string) => calls.push(`second:${text}`); const currentHandler = shallowRef(firstHandler); const Child = defineComponent({ props: { onPaste: { type: Function as PropType<(text: string) => void>, required: true, }, }, setup(props) { usePaste(toRef(props, "onPaste")); return () => child; }, }); const App = defineComponent(() => { return () => ; }); const { stdin } = await render(App); await stdin.write("\x1b[200~alpha\x1b[201~"); expect(calls).toEqual(["first:alpha"]); currentHandler.value = secondHandler; await nextTick(); await stdin.write("\x1b[200~beta\x1b[201~"); expect(calls).toEqual(["first:alpha", "second:beta"]); }); test("usePaste intercepts paste so useInput does not receive it", async () => { const inputReceived: string[] = []; const pasteReceived: string[] = []; const App = defineComponent(() => { useInput((input) => { inputReceived.push(input); }); usePaste((text) => { pasteReceived.push(text); }); return () => listening; }); const { stdin } = await render(App); await stdin.write("\x1b[200~pasted text\x1b[201~"); expect(pasteReceived).toEqual(["pasted text"]); expect(inputReceived).toEqual([]); }); });