import test from "node:test"; import assert from "node:assert/strict"; import { SOMETHING_ELSE_LABEL, SOMETHING_ELSE_VALUE, allQuestionsAnswered, createAnsweredResult, createCancelledResult, createCustomAnswer, createPredefinedAnswer, nextTabAfterAnswer, normalizeQuestions, summarizeAnswers, } from "./question-core.mjs"; test("normalizeQuestions adds default labels and appends the Something else option", () => { const [question] = normalizeQuestions([ { id: "scope", prompt: "Which scope fits best?", options: [{ value: "small", label: "Small change" }], }, ]); assert.equal(question.label, "Q1"); assert.deepEqual(question.options[0], { value: "small", label: "Small change" }); assert.deepEqual(question.options.at(-1), { value: SOMETHING_ELSE_VALUE, label: SOMETHING_ELSE_LABEL, }); }); test("normalizeQuestions keeps provided labels and descriptions intact before the synthetic option", () => { const [question] = normalizeQuestions([ { id: "priority", label: "Priority", prompt: "Which priority?", options: [ { value: "p0", label: "P0", description: "Need this now" }, { value: "p1", label: "P1" }, ], }, ]); assert.equal(question.label, "Priority"); assert.deepEqual(question.options.slice(0, 2), [ { value: "p0", label: "P0", description: "Need this now" }, { value: "p1", label: "P1" }, ]); assert.equal(question.options[2].label, SOMETHING_ELSE_LABEL); }); test("answer helpers preserve machine values and summary lines distinguish predefined vs custom answers", () => { const questions = normalizeQuestions([ { id: "scope", label: "Scope", prompt: "Which scope fits best?", options: [{ value: "small", label: "Small change" }], }, { id: "notes", label: "Notes", prompt: "Anything else?", options: [{ value: "none", label: "No extra notes" }], }, ]); const predefined = createPredefinedAnswer("scope", questions[0].options[0], 1); const custom = createCustomAnswer("notes", "Needs to work with tmux"); assert.deepEqual(predefined, { id: "scope", value: "small", label: "Small change", wasCustom: false, index: 1, }); assert.deepEqual(custom, { id: "notes", value: "Needs to work with tmux", label: "Needs to work with tmux", wasCustom: true, }); assert.deepEqual(summarizeAnswers(questions, [predefined, custom]), [ "Scope: user selected: 1. Small change", "Notes: user wrote: Needs to work with tmux", ]); }); test("createCancelledResult returns a structured cancelled payload", () => { const questions = normalizeQuestions([ { id: "scope", prompt: "Which scope fits best?", options: [{ value: "small", label: "Small change" }], }, ]); assert.deepEqual(createCancelledResult(questions), { questions, answers: [], cancelled: true, }); }); test("createAnsweredResult keeps answers in question order", () => { const questions = normalizeQuestions([ { id: "scope", label: "Scope", prompt: "Which scope fits best?", options: [{ value: "small", label: "Small change" }], }, { id: "notes", label: "Notes", prompt: "Anything else?", options: [{ value: "none", label: "No extra notes" }], }, ]); const second = createCustomAnswer("notes", "Custom note"); const first = createPredefinedAnswer("scope", questions[0].options[0], 1); const result = createAnsweredResult(questions, [second, first]); assert.equal(result.cancelled, false); assert.deepEqual(result.answers.map((answer) => answer.id), ["scope", "notes"]); }); test("allQuestionsAnswered only returns true when every question has an answer", () => { const questions = normalizeQuestions([ { id: "scope", prompt: "Scope?", options: [{ value: "small", label: "Small" }], }, { id: "priority", prompt: "Priority?", options: [{ value: "p1", label: "P1" }], }, ]); const answers = new Map([ ["scope", createPredefinedAnswer("scope", questions[0].options[0], 1)], ]); assert.equal(allQuestionsAnswered(questions, answers), false); answers.set("priority", createCustomAnswer("priority", "Ship this week")); assert.equal(allQuestionsAnswered(questions, answers), true); }); test("nextTabAfterAnswer advances through questions and then to the submit tab", () => { assert.equal(nextTabAfterAnswer(0, 3), 1); assert.equal(nextTabAfterAnswer(1, 3), 2); assert.equal(nextTabAfterAnswer(2, 3), 3); });