feat(ui): support custom answers in preview questions
This commit is contained in:
@@ -89,6 +89,31 @@ test("ask tool returns pending questions in non-interactive mode", async () => {
|
||||
assert.match(result.content[0].text, CUSTOM_OPTION_RE);
|
||||
});
|
||||
|
||||
test("ask tool includes custom answer fallback for preview questions", async () => {
|
||||
const tool = registerMockTool();
|
||||
|
||||
const result = await tool.execute(
|
||||
"call-1",
|
||||
{
|
||||
title: "Clarify",
|
||||
questions: [
|
||||
{
|
||||
id: "layout",
|
||||
label: "Layout",
|
||||
prompt: "Which layout?",
|
||||
type: "preview",
|
||||
options: [{ value: "compact", label: "Compact", preview: "A" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
undefined,
|
||||
noop,
|
||||
makeCtx(false)
|
||||
);
|
||||
|
||||
assert.match(result.content[0].text, CUSTOM_OPTION_RE);
|
||||
});
|
||||
|
||||
test("ask tool rejects invalid payloads before UI opens with structured issues", async () => {
|
||||
const tool = registerMockTool();
|
||||
|
||||
|
||||
@@ -154,3 +154,61 @@ test("selected multiline custom option renders full editor block", () => {
|
||||
assert(lines.some((line) => line.includes("second line")));
|
||||
assert(!lines.some((line) => line.includes("first line second line")));
|
||||
});
|
||||
|
||||
test("preview questions also show the custom answer option", () => {
|
||||
const state = createInitialState({
|
||||
questions: [
|
||||
{
|
||||
id: "q1",
|
||||
prompt: "Pick one",
|
||||
type: "preview",
|
||||
options: [{ value: "a", label: "A", preview: "Preview A" }],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const lines: string[] = [];
|
||||
renderQuestionScreen({
|
||||
editor: mockEditor(),
|
||||
lines,
|
||||
options: getRenderableOptions(state.questions[0]),
|
||||
question: state.questions[0],
|
||||
state,
|
||||
theme: mockTheme(),
|
||||
width: 80,
|
||||
});
|
||||
|
||||
assert(lines.some((line) => line.includes("Type your own")));
|
||||
});
|
||||
|
||||
test("preview custom option reuses the normal inline editor", () => {
|
||||
let state = createInitialState({
|
||||
questions: [
|
||||
{
|
||||
id: "q1",
|
||||
prompt: "Pick one",
|
||||
type: "preview",
|
||||
options: [{ value: "a", label: "A", preview: "Preview A" }],
|
||||
},
|
||||
],
|
||||
});
|
||||
state = applyNumberShortcut(state, 2);
|
||||
|
||||
const lines: string[] = [];
|
||||
renderQuestionScreen({
|
||||
editor: mockEditor("", ["┌────┐", "", "└────┘"]),
|
||||
lines,
|
||||
options: getRenderableOptions(state.questions[0]),
|
||||
question: state.questions[0],
|
||||
state,
|
||||
theme: mockTheme(),
|
||||
width: 80,
|
||||
});
|
||||
|
||||
assert(lines.some((line) => line.includes("Type your own")));
|
||||
assert(lines.some((line) => line.includes("Type answer...")));
|
||||
const optionIndex = lines.findIndex((line) => line.includes("Type your own"));
|
||||
const inputIndex = lines.findIndex((line) => line.includes("Type answer..."));
|
||||
assert.equal(inputIndex, optionIndex + 1);
|
||||
assert(!lines.some((line) => line.includes("asdasddasdasdasdere")));
|
||||
});
|
||||
|
||||
+31
-2
@@ -93,9 +93,13 @@ test("preview questions keep their type and option previews", () => {
|
||||
assert.equal(state.questions[0].options[0].preview, "Example");
|
||||
assert.equal(
|
||||
getRenderableOptions(state.questions[0]).at(-1)?.isCustomOption,
|
||||
undefined
|
||||
true
|
||||
);
|
||||
assert.equal(getRenderableOptions(state.questions[0]).length, 1);
|
||||
assert.equal(
|
||||
getRenderableOptions(state.questions[0]).at(-1)?.label,
|
||||
"Type your own"
|
||||
);
|
||||
assert.equal(getRenderableOptions(state.questions[0]).length, 2);
|
||||
});
|
||||
|
||||
test("createInitialState rejects duplicate question ids", () => {
|
||||
@@ -529,6 +533,31 @@ test("preview questions can store selected option notes for submission", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("preview questions support custom answers", () => {
|
||||
let state = createInitialState({
|
||||
questions: [
|
||||
{
|
||||
id: "preview",
|
||||
prompt: "Pick layout",
|
||||
type: "preview",
|
||||
options: [{ value: "compact", label: "Compact", preview: "A" }],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
state = applyNumberShortcut(state, 2);
|
||||
state = submitCustomAnswer(state, "Something else");
|
||||
|
||||
assert.deepEqual(toAskResult(state).answers.preview, {
|
||||
values: ["Something else"],
|
||||
labels: ["Something else"],
|
||||
indices: [],
|
||||
customText: "Something else",
|
||||
note: undefined,
|
||||
optionNotes: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
test("tab navigation wraps including submit tab", () => {
|
||||
let state = createInitialState(sampleParams());
|
||||
state = moveTab(state, -1);
|
||||
|
||||
Reference in New Issue
Block a user