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([]);
});
});