160 lines
4.5 KiB
JavaScript
160 lines
4.5 KiB
JavaScript
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);
|
|
});
|