@zhushanwen/pi-ask-user 6.0.1 → 7.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,11 +11,9 @@ import {
11
11
  LEFT,
12
12
  mockTui,
13
13
  multiQ,
14
- multiQWithComment,
15
14
  RIGHT,
16
15
  singleQ,
17
16
  singleQMulti,
18
- singleQWithComment,
19
17
  stubTheme,
20
18
  TAB,
21
19
  UP,
@@ -44,14 +42,14 @@ describe("AskUserComponent — single question", () => {
44
42
  c.handleInput(ENTER);
45
43
  expect(result.val).not.toBeUndefined();
46
44
  expect(result.val!.cancelled).toBe(false);
47
- expect(result.val!.answers["Which DB?"]).toBe("Postgres");
45
+ expect(result.val!.answers["Which DB?"]).toEqual({ selected: ["Postgres"], other: null });
48
46
  });
49
47
 
50
48
  it("C-3: moves cursor down then confirms second option", () => {
51
49
  const { c, result } = make([singleQ]);
52
50
  c.handleInput(DOWN);
53
51
  c.handleInput(ENTER);
54
- expect(result.val!.answers["Which DB?"]).toBe("SQLite");
52
+ expect(result.val!.answers["Which DB?"]).toEqual({ selected: ["SQLite"], other: null });
55
53
  });
56
54
 
57
55
  it("C-4: Esc shows confirm overlay; second Esc cancels (single)", () => {
@@ -110,9 +108,9 @@ describe("AskUserComponent — multi question tab nav", () => {
110
108
  c.handleInput(ENTER);
111
109
  // Submit tab: Enter
112
110
  c.handleInput(ENTER);
113
- expect(result.val!.answers["Q1"]).toBe("A");
114
- expect(result.val!.answers["Q2"]).toBe("X");
115
- expect(result.val!.answers["Q3"]).toBe("M");
111
+ expect(result.val!.answers["Q1"]).toEqual({ selected: ["A"], other: null });
112
+ expect(result.val!.answers["Q2"]).toEqual({ selected: ["X"], other: null });
113
+ expect(result.val!.answers["Q3"]).toEqual({ selected: ["M"], other: null });
116
114
  });
117
115
 
118
116
  it("C-9: Submit tab blocks when not all confirmed", () => {
@@ -140,22 +138,31 @@ describe("AskUserComponent — multi question tab nav", () => {
140
138
  c.handleInput(ENTER); // Q2 → Q3
141
139
  c.handleInput(ENTER); // Q3 → Submit
142
140
  c.handleInput(ENTER); // Submit
143
- expect(result.val!.answers["Q1"]).toBe("B");
141
+ expect(result.val!.answers["Q1"]).toEqual({ selected: ["B"], other: null });
144
142
  });
145
143
 
146
- it("C-15: leaving multi-select tab auto-confirms answered selection", () => {
147
- // Use 2 questions: Q1 single, Q2 multi-select
148
- const twoQ: Question[] = [
149
- { question: "Q1", header: "First", options: [{ label: "A" }, { label: "B" }] },
150
- { question: "Q2", header: "Second", options: [{ label: "X" }, { label: "Y" }], multiSelect: true },
144
+ it("C-15/C-S3: leaving multi-select tab auto-confirms answered selection (Submit 直达 + 中间 tab)", () => {
145
+ // C-15 C-S3 合并(TC-04):两用例同走 handleOptionsInput ←/→ → gotoTab →
146
+ // autoConfirmIfAnswered()(component.ts:420-421 同一分支),并入后保留双方独有断言:
147
+ // - C-15:multi-select toggle 直达 Submit tab Enter 提交成功(all confirmed)
148
+ // - C-S3:multi-select toggle 切到中间 tab(非 Submit)auto-confirm 也生效
149
+ const threeQ: Question[] = [
150
+ { question: "Q1", header: "First", options: [{ label: "A" }, { label: "B" }], multiSelect: true },
151
+ { question: "Q2", header: "Second", options: [{ label: "X" }, { label: "Y" }] },
152
+ { question: "Q3", header: "Third", options: [{ label: "M" }, { label: "N" }], multiSelect: true },
151
153
  ];
152
- const { c, result } = make(twoQ);
153
- c.handleInput(ENTER); // Q1 select A → Q2
154
- c.handleInput(" "); // Q2 toggle X (no Enter-confirm)
155
- c.handleInput(RIGHT); // → Submit, should auto-confirm Q2
156
- c.handleInput(ENTER); // Submit (all confirmed)
157
- expect(result.val!.answers["Q1"]).toBe("A");
158
- expect(result.val!.answers["Q2"]).toBe("X");
154
+ const { c, result } = make(threeQ);
155
+ // C-S3 路径:Q1 multi toggle A(不 Enter-confirm)→ RIGHT 切到中间 tab Q2 Q1 被 auto-confirm
156
+ c.handleInput(" "); // Q1 toggle A
157
+ c.handleInput(RIGHT); // → Q2(中间 tab),auto-confirm Q1
158
+ c.handleInput(ENTER); // Q2 select X → Q3
159
+ // C-15 路径:Q3 multi toggle M(不 Enter-confirm)→ RIGHT 直达 Submit → Q3 被 auto-confirm
160
+ c.handleInput(" "); // Q3 toggle M
161
+ c.handleInput(RIGHT); // → Submit,auto-confirm Q3
162
+ c.handleInput(ENTER); // Submit(all confirmed:Q1/Q3 由 auto-confirm,Q2 由 Enter-confirm)
163
+ expect(result.val!.answers["Q1"]).toEqual({ selected: ["A"], other: null }); // auto-confirm 生效(C-S3 断言)
164
+ expect(result.val!.answers["Q2"]).toEqual({ selected: ["X"], other: null });
165
+ expect(result.val!.answers["Q3"]).toEqual({ selected: ["M"], other: null }); // auto-confirm 生效(C-15 断言)
159
166
  });
160
167
 
161
168
  it("C-S1: multi-select Enter 同时选中光标项再确认(与单选 Enter 对称)", () => {
@@ -163,29 +170,12 @@ describe("AskUserComponent — multi question tab nav", () => {
163
170
  const { c, result } = make([singleQMulti]);
164
171
  // singleQMulti: [Auth, Search],光标初始在 Auth(0)
165
172
  c.handleInput(DOWN); // 光标移到 Search(1),未 toggle
166
- c.handleInput(ENTER); // Enter 应同时选中 Search + confirm + allowComment comment
167
- // 断言进入了评论模式(说明 Enter 确认了,而非 no-op)
168
- const lines = c.render(60);
169
- expect(lines.some((l) => l.toLowerCase().includes("comment"))).toBe(true);
170
- c.handleInput(ENTER); // 跳过评论 → submit(单问题)
171
- expect(result.val!.answers["Which features?"]).toBe("Search");
173
+ c.handleInput(ENTER); // Enter 应同时选中 Search + confirm → submit(单问题)
174
+ expect(result.val).not.toBeUndefined();
175
+ expect(result.val!.answers["Which features?"]).toEqual({ selected: ["Search"], other: null });
172
176
  });
173
177
 
174
- it("C-S3: auto-confirm(←/→ 切 tab)跳过评论输入行,仅 Enter 路径才进评论", () => {
175
- // S-3 锁定:allowComment 的问题,←/→ 切走只 auto-confirm,不进评论模式
176
- const twoQMulti: Question[] = [
177
- { question: "Q1", header: "First", options: [{ label: "A" }, { label: "B" }], multiSelect: true, allowComment: true },
178
- { question: "Q2", header: "Second", options: [{ label: "X" }, { label: "Y" }] },
179
- ];
180
- const { c, result } = make(twoQMulti);
181
- c.handleInput(" "); // Q1 toggle A
182
- c.handleInput(RIGHT); // → Q2,auto-confirm Q1,不进评论
183
- // 验证:当前在 Q2(非 Q1 的评论模式)。Q2 选 X → Submit
184
- c.handleInput(ENTER); // Q2 select X → Submit
185
- c.handleInput(ENTER); // Submit
186
- expect(result.val!.answers["Q1"]).toBe("A"); // auto-confirm 生效
187
- expect(result.val!.answers["Q2"]).toBe("X");
188
- });
178
+
189
179
 
190
180
  it("C-REG-R6: Other 录入→重进清空→Submit 应回到未答(confirmed 不变式)", () => {
191
181
  // 回归 MUST_FIX: freeform 空 Enter 清空 freeTextValue 后须重置 confirmed=false
@@ -247,7 +237,7 @@ describe("AskUserComponent — single-select", () => {
247
237
  c.handleInput("o");
248
238
  c.handleInput("m");
249
239
  c.handleInput(ENTER); // save freeText → submit (single question)
250
- expect(result.val!.answers["Which DB?"]).toBe("custom");
240
+ expect(result.val!.answers["Which DB?"]).toEqual({ selected: [], other: "custom" });
251
241
  });
252
242
  });
253
243
 
@@ -268,13 +258,12 @@ describe("AskUserComponent — multi-select toggle", () => {
268
258
  expect(lines.some((l) => l.includes("[ ]") && l.includes("Auth"))).toBe(true);
269
259
  });
270
260
 
271
- it("C-24 (AC-18): multi-select toggle does NOT trigger comment mode", () => {
272
- // singleQMulti has allowComment:true + multiSelect:true
273
- const { c } = make([singleQMulti]);
274
- c.handleInput(" "); // toggle — should NOT enter comment mode
261
+ it("C-24 (AC-18): multi-select toggle does NOT confirm/advance", () => {
262
+ const { c, result } = make([singleQMulti]);
263
+ c.handleInput(" "); // toggle 只标记选中,不确认不离开
264
+ expect(result.val).toBeUndefined();
275
265
  const lines = c.render(60);
276
- // No comment prompt shown
277
- expect(lines.some((l) => l.toLowerCase().includes("comment"))).toBe(false);
266
+ expect(lines.some((l) => l.includes("[✓]") && l.includes("Auth"))).toBe(true);
278
267
  });
279
268
  });
280
269
 
@@ -345,7 +334,7 @@ describe("AskUserComponent — Other free-text editor", () => {
345
334
  c.handleInput("x");
346
335
  c.handleInput(ENTER);
347
336
  expect(result.val).not.toBeUndefined();
348
- expect(result.val!.answers["Which DB?"]).toBe("x");
337
+ expect(result.val!.answers["Which DB?"]).toEqual({ selected: [], other: "x" });
349
338
  });
350
339
 
351
340
  it("C-30: editor Enter empty clears freeText (single → stays in form)", () => {
@@ -472,108 +461,6 @@ describe("AskUserComponent — multi-char paste in editor", () => {
472
461
  });
473
462
  });
474
463
 
475
- // ── 5f. 评论流程(FR-4.6 / FR-11 / AC-6/12/17)─────────
476
- describe("AskUserComponent — comment flow", () => {
477
- it("C-33: single-select + allowComment Enter enters comment mode", () => {
478
- const { c } = make([singleQWithComment]);
479
- c.handleInput(ENTER); // select Postgres
480
- const lines = c.render(60);
481
- expect(lines.some((l) => l.toLowerCase().includes("comment"))).toBe(true);
482
- });
483
-
484
- it("C-34 (AC-12): comment Enter empty skips and submits (single)", () => {
485
- const { c, result } = make([singleQWithComment]);
486
- c.handleInput(ENTER); // select → comment mode
487
- c.handleInput(ENTER); // empty comment → skip → submit
488
- expect(result.val).not.toBeUndefined();
489
- expect(result.val!.answers["Which DB? (with comment)"]).toBe("Postgres");
490
- });
491
-
492
- it("C-35: comment Enter with text saves comment", () => {
493
- const { c, result } = make([singleQWithComment]);
494
- c.handleInput(ENTER); // select → comment mode
495
- c.handleInput("f");
496
- c.handleInput("a");
497
- c.handleInput("s");
498
- c.handleInput("t");
499
- c.handleInput(ENTER); // save comment → submit
500
- expect(result.val!.answers["Which DB? (with comment)"]).toBe("Postgres — fast");
501
- });
502
-
503
- it("C-38: multi-select + allowComment: Enter after toggle enters comment", () => {
504
- const { c } = make([singleQMulti]);
505
- c.handleInput(" "); // toggle Auth
506
- c.handleInput(ENTER); // confirm → comment mode
507
- const lines = c.render(60);
508
- expect(lines.some((l) => l.toLowerCase().includes("comment"))).toBe(true);
509
- });
510
-
511
- it("C-39: Other + allowComment: freeText then comment", () => {
512
- const { c, result } = make([singleQWithComment]);
513
- // Navigate to Other
514
- c.handleInput(DOWN);
515
- c.handleInput(DOWN);
516
- c.handleInput(ENTER); // open freeform
517
- c.handleInput("c");
518
- c.handleInput("u");
519
- c.handleInput("s");
520
- c.handleInput("t");
521
- c.handleInput("o");
522
- c.handleInput("m");
523
- c.handleInput(ENTER); // save freeText → allowComment → comment mode
524
- c.handleInput(ENTER); // empty comment → skip → submit
525
- expect(result.val!.answers["Which DB? (with comment)"]).toBe("custom");
526
- });
527
-
528
- it("C-36 (AC-17): comment Esc skips comment and advances (single)", () => {
529
- const { c, result } = make([singleQWithComment]);
530
- c.handleInput(ENTER); // select Postgres → comment mode
531
- c.handleInput(ESC); // Esc in comment = skip comment → advance → submit
532
- expect(result.val).not.toBeUndefined();
533
- // commentValue stays null (no prior comment), answer is the selected option
534
- expect(result.val!.answers["Which DB? (with comment)"]).toBe("Postgres");
535
- });
536
-
537
- it("C-36b (AC-17): comment Esc advances to next tab (multi-question)", () => {
538
- const { c, result } = make(multiQWithComment);
539
- // Q1 (allowComment): select A → comment mode
540
- c.handleInput(ENTER); // select A → comment mode
541
- c.handleInput(ESC); // Esc in comment = skip → advance to Q2
542
- // Q2: select X → Submit
543
- c.handleInput(ENTER); // select X → Submit
544
- c.handleInput(ENTER); // Submit
545
- expect(result.val).not.toBeUndefined();
546
- expect(result.val!.answers["Q1"]).toBe("A");
547
- expect(result.val!.answers["Q2"]).toBe("X");
548
- });
549
-
550
- it("C-36c (AC-17): Esc-in-comment discards typed text (vs Enter which saves)", () => {
551
- // Contrast: typing then Enter would save commentValue and append " — keep".
552
- // Esc should discard the typed editor text and advance without attaching it.
553
- const { c, result } = make([singleQWithComment]);
554
- c.handleInput(ENTER); // select Postgres → comment mode
555
- c.handleInput("k");
556
- c.handleInput("e");
557
- c.handleInput("e");
558
- c.handleInput("p");
559
- c.handleInput(ESC); // Esc in comment = discard typed text → advance → submit
560
- expect(result.val).not.toBeUndefined();
561
- // No " — keep" suffix: Esc did not commit the typed text
562
- expect(result.val!.answers["Which DB? (with comment)"]).toBe("Postgres");
563
- });
564
-
565
- it("C-37: answer + comment combined format 'label — note'", () => {
566
- const { c, result } = make([singleQWithComment]);
567
- c.handleInput(ENTER); // select Postgres → comment mode
568
- c.handleInput("n");
569
- c.handleInput("o");
570
- c.handleInput("t");
571
- c.handleInput("e");
572
- c.handleInput(ENTER); // save comment → submit
573
- expect(result.val!.answers["Which DB? (with comment)"]).toBe("Postgres — note");
574
- });
575
- });
576
-
577
464
  // ── 5g. 防重入(FR-12)─────────────────────────────────
578
465
  describe("AskUserComponent — re-entry guard", () => {
579
466
  it("C-40: ignores input after resolution (submit)", () => {
@@ -658,16 +545,17 @@ describe("AskUserComponent — Submit tab", () => {
658
545
  });
659
546
 
660
547
  it("C-46: Submit Enter when all confirmed submits", () => {
661
- const { c, result } = make(multiQWithComment);
662
- // Q1 (allowComment): select A comment mode skip
663
- c.handleInput(ENTER); // select A
664
- c.handleInput(ENTER); // skip comment → Q2
665
- // Q2: select X
666
- c.handleInput(ENTER); // → Submit
548
+ const twoQ: Question[] = [
549
+ { question: "Q1", header: "First", options: [{ label: "A" }, { label: "B" }] },
550
+ { question: "Q2", header: "Second", options: [{ label: "X" }, { label: "Y" }] },
551
+ ];
552
+ const { c, result } = make(twoQ);
553
+ c.handleInput(ENTER); // Q1 select A Q2
554
+ c.handleInput(ENTER); // Q2 select X → Submit
667
555
  c.handleInput(ENTER); // Submit
668
556
  expect(result.val).not.toBeUndefined();
669
- expect(result.val!.answers["Q1"]).toBe("A");
670
- expect(result.val!.answers["Q2"]).toBe("X");
557
+ expect(result.val!.answers["Q1"]).toEqual({ selected: ["A"], other: null });
558
+ expect(result.val!.answers["Q2"]).toEqual({ selected: ["X"], other: null });
671
559
  });
672
560
 
673
561
  it("C-S12: Submit tab Left navigates to last question tab", () => {
@@ -806,7 +694,7 @@ describe("AskUserComponent — confirm-checkmark, Esc-back, Tab browsing", () =>
806
694
  // ── 5l. 新行为:←/→ 不切 tab、Other Enter 切 freeform 原生、Submit tab focus ──
807
695
  describe("AskUserComponent — new behavior (post-refactor)", () => {
808
696
  it("C-NEW-1: multi-select Other + Enter opens freeform; Other row turns into [ ] <input>█ in-place", () => {
809
- // singleQMulti: [Auth, Search],多选 + allowComment
697
+ // singleQMulti: [Auth, Search],多选
810
698
  const { c, result } = make([singleQMulti]);
811
699
  // 1) Space toggle Auth
812
700
  c.handleInput(" ");
@@ -827,16 +715,15 @@ describe("AskUserComponent — new behavior (post-refactor)", () => {
827
715
  expect(lines.some((l) => l.includes("Search"))).toBe(true);
828
716
  // [✓] 标记的 Auth 仍存在(toggle 状态保留)
829
717
  expect(lines.some((l) => l.includes("[✓]") && l.includes("Auth"))).toBe(true);
830
- // 4) 输 "redis" → Enter 保存 → allowComment → comment mode
718
+ // 4) 输 "redis" → Enter 保存 → submit(单问题)
831
719
  c.handleInput("r");
832
720
  c.handleInput("e");
833
721
  c.handleInput("d");
834
722
  c.handleInput("i");
835
723
  c.handleInput("s");
836
- c.handleInput(ENTER); // 保存 freeText → comment mode
837
- c.handleInput(ENTER); // 跳过评论 → submit(单问题)
724
+ c.handleInput(ENTER); // 保存 freeText → submit
838
725
  // 答案含多选 toggle 项 + Other 自定义
839
- expect(result.val!.answers["Which features?"]).toBe("Auth, redis");
726
+ expect(result.val!.answers["Which features?"]).toEqual({ selected: ["Auth"], other: "redis" });
840
727
  });
841
728
 
842
729
  it("C-NEW-2: ←/→ on question tab switches tabs (→ next, ← previous; ← no wrap at first)", () => {
@@ -877,17 +764,19 @@ describe("AskUserComponent — new behavior (post-refactor)", () => {
877
764
  });
878
765
 
879
766
  it("C-NEW-4: Submit tab Enter on Submit focus (all confirmed) submits", () => {
880
- // multiQWithComment: Q1 allowComment, Q2 plain
881
- const { c, result } = make(multiQWithComment);
767
+ const twoQ: Question[] = [
768
+ { question: "Q1", header: "First", options: [{ label: "A" }, { label: "B" }] },
769
+ { question: "Q2", header: "Second", options: [{ label: "X" }, { label: "Y" }] },
770
+ ];
771
+ const { c, result } = make(twoQ);
882
772
  // 答完 Q1 + Q2
883
- c.handleInput(ENTER); // Q1 select A → comment mode
884
- c.handleInput(ENTER); // skip comment → Q2
773
+ c.handleInput(ENTER); // Q1 select A → Q2
885
774
  c.handleInput(ENTER); // Q2 select X → Submit tab(Q2 是最后一个问题,advance 到 Submit)
886
775
  // 已经在 Submit tab,focus=Submit,按 Enter 提交
887
776
  c.handleInput(ENTER);
888
777
  expect(result.val).not.toBeUndefined();
889
- expect(result.val!.answers["Q1"]).toBe("A");
890
- expect(result.val!.answers["Q2"]).toBe("X");
778
+ expect(result.val!.answers["Q1"]).toEqual({ selected: ["A"], other: null });
779
+ expect(result.val!.answers["Q2"]).toEqual({ selected: ["X"], other: null });
891
780
  });
892
781
 
893
782
  it("C-NEW-5: Submit tab Enter on Cancel focus cancels (no confirm overlay)", () => {
@@ -8,7 +8,7 @@ import { describe, expect, it } from "vitest";
8
8
  import { makeE2E } from "./e2e-harness";
9
9
 
10
10
  // ── E2E-1: 单问题无评论 — 选第二项提交 ─────────────────
11
- describe("E2E-1: single question, no comment — pick 2nd option", () => {
11
+ describe("E2E-1: single question — pick 2nd option", () => {
12
12
  const questions = [
13
13
  {
14
14
  question: "Which DB?",
@@ -27,58 +27,11 @@ describe("E2E-1: single question, no comment — pick 2nd option", () => {
27
27
  expect(result.content[0].text).toContain("SQLite");
28
28
  // Data contract
29
29
  expect(details.cancelled).toBe(false);
30
- expect(details.answers["Which DB?"]).toBe("SQLite");
30
+ expect(details.answers["Which DB?"]).toEqual({ selected: ["SQLite"], other: null });
31
31
  expect(details.questions.length).toBe(1);
32
32
  });
33
33
  });
34
34
 
35
- // ── E2E-2: 单问题 + allowComment — 选项 + 评论拼接 ─────
36
- describe("E2E-2: single question + allowComment — option + comment joined", () => {
37
- const questions = [
38
- {
39
- question: "Which DB?",
40
- allowComment: true,
41
- options: [{ label: "Postgres" }, { label: "SQLite" }],
42
- },
43
- ];
44
-
45
- it("joins selected option with comment via ' — '", async () => {
46
- const e = makeE2E(questions);
47
- // Enter 选 Postgres → 进评论模式 → 输 "fast" → Enter 保存(allowComment 分支)
48
- e.keys(["\r", "f", "a", "s", "t", "\r"]);
49
- const result = await e.getExecuted();
50
- const details = result.details;
51
-
52
- expect(details.cancelled).toBe(false);
53
- expect(details.answers["Which DB?"]).toBe("Postgres — fast");
54
- expect(result.content[0].text).toContain("Postgres — fast");
55
- });
56
- });
57
-
58
- // ── E2E-3: 单问题 + allowComment — Enter 空评论跳过 ─────
59
- describe("E2E-3: single question + allowComment — Enter in comment skips", () => {
60
- const questions = [
61
- {
62
- question: "Which DB?",
63
- allowComment: true,
64
- options: [{ label: "Postgres" }, { label: "SQLite" }],
65
- },
66
- ];
67
-
68
- it("empty Enter in comment mode keeps option without ' — ' suffix", async () => {
69
- const e = makeE2E(questions);
70
- // Enter 选 Postgres → 直接 Enter 评论模式跳过(AC-12)
71
- e.keys(["\r", "\r"]);
72
- const result = await e.getExecuted();
73
- const details = result.details;
74
-
75
- expect(details.cancelled).toBe(false);
76
- // 不含 " — " 分隔符
77
- expect(details.answers["Which DB?"]).toBe("Postgres");
78
- expect(details.answers["Which DB?"]).not.toContain("—");
79
- });
80
- });
81
-
82
35
  // ── E2E-4: 多问题提交 — 逐题选择后 Submit tab 提交(S-11)──────
83
36
  describe("E2E-4: multi-question submit — answer each then Submit tab", () => {
84
37
  const questions = [
@@ -96,8 +49,8 @@ describe("E2E-4: multi-question submit — answer each then Submit tab", () => {
96
49
  const details = result.details;
97
50
 
98
51
  expect(details.cancelled).toBe(false);
99
- expect(details.answers["Q1"]).toBe("A");
100
- expect(details.answers["Q2"]).toBe("X");
52
+ expect(details.answers["Q1"]).toEqual({ selected: ["A"], other: null });
53
+ expect(details.answers["Q2"]).toEqual({ selected: ["X"], other: null });
101
54
  expect(result.content[0].text).toContain("Q1");
102
55
  expect(result.content[0].text).toContain("Q2");
103
56
  });
@@ -121,7 +74,7 @@ describe("E2E-5: multi-select — Space toggle two options then Enter", () => {
121
74
  const details = result.details;
122
75
 
123
76
  expect(details.cancelled).toBe(false);
124
- expect(details.answers["Which features?"]).toBe("Auth, Search");
77
+ expect(details.answers["Which features?"]).toEqual({ selected: ["Auth", "Search"], other: null });
125
78
  });
126
79
  });
127
80
 
@@ -140,7 +93,7 @@ describe("E2E-6: Other free-text — type custom answer", () => {
140
93
  const details = result.details;
141
94
 
142
95
  expect(details.cancelled).toBe(false);
143
- expect(details.answers["Which DB?"]).toBe("redis");
96
+ expect(details.answers["Which DB?"]).toEqual({ selected: [], other: "redis" });
144
97
  });
145
98
  });
146
99
 
@@ -40,19 +40,9 @@ export const singleQ: Question = {
40
40
  ],
41
41
  };
42
42
 
43
- export const singleQWithComment: Question = {
44
- question: "Which DB? (with comment)",
45
- allowComment: true,
46
- options: [
47
- { label: "Postgres", description: "Battle-tested" },
48
- { label: "SQLite", description: "Embedded" },
49
- ],
50
- };
51
-
52
43
  export const singleQMulti: Question = {
53
44
  question: "Which features?",
54
45
  multiSelect: true,
55
- allowComment: true,
56
46
  options: [
57
47
  { label: "Auth", description: "OAuth + session" },
58
48
  { label: "Search", description: "Full-text" },
@@ -70,11 +60,6 @@ export const multiQ: Question[] = [
70
60
  { question: "Q3", header: "Third", options: [{ label: "M" }, { label: "N" }] },
71
61
  ];
72
62
 
73
- export const multiQWithComment: Question[] = [
74
- { question: "Q1", header: "First", allowComment: true, options: [{ label: "A" }, { label: "B" }] },
75
- { question: "Q2", header: "Second", options: [{ label: "X" }, { label: "Y" }] },
76
- ];
77
-
78
63
  // ── Aliases (PAGE_UP/PAGE_DOWN for W1 tests, PGUP/PGDN for W3 tests) ──
79
64
  export const PAGE_UP = "\x1b[5~";
80
65
  export const PAGE_DOWN = "\x1b[6~";