question.shared.test.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { describe, expect, test } from "bun:test"
  2. import type { QuestionRequest } from "@opencode-ai/sdk/v2"
  3. import {
  4. createQuestionBodyState,
  5. questionConfirm,
  6. questionReject,
  7. questionSave,
  8. questionSelect,
  9. questionSetSelected,
  10. questionStoreCustom,
  11. questionSubmit,
  12. questionSync,
  13. } from "@opencode-ai/cli/mini/question.shared"
  14. function req(input: Partial<QuestionRequest> = {}): QuestionRequest {
  15. return {
  16. id: "question-1",
  17. sessionID: "session-1",
  18. questions: [
  19. {
  20. question: "Mode?",
  21. header: "Mode",
  22. options: [{ label: "chunked", description: "Incremental output" }],
  23. multiple: false,
  24. },
  25. ],
  26. ...input,
  27. }
  28. }
  29. describe("run question shared", () => {
  30. test("replies immediately for a single-select question", () => {
  31. const out = questionSelect(createQuestionBodyState("question-1"), req())
  32. expect(out.reply).toEqual({
  33. requestID: "question-1",
  34. answers: [["chunked"]],
  35. })
  36. })
  37. test("advances multi-question flows and submits from confirm", () => {
  38. const ask = req({
  39. questions: [
  40. {
  41. question: "Mode?",
  42. header: "Mode",
  43. options: [{ label: "chunked", description: "Incremental output" }],
  44. multiple: false,
  45. },
  46. {
  47. question: "Output?",
  48. header: "Output",
  49. options: [
  50. { label: "yes", description: "Show tool output" },
  51. { label: "no", description: "Hide tool output" },
  52. ],
  53. multiple: false,
  54. },
  55. ],
  56. })
  57. let state = questionSelect(createQuestionBodyState("question-1"), ask).state
  58. expect(state.tab).toBe(1)
  59. state = questionSetSelected(state, 1)
  60. state = questionSelect(state, ask).state
  61. expect(questionConfirm(ask, state)).toBe(true)
  62. expect(questionSubmit(ask, state)).toEqual({
  63. requestID: "question-1",
  64. answers: [["chunked"], ["no"]],
  65. })
  66. })
  67. test("toggles answers for multiple-choice questions", () => {
  68. const ask = req({
  69. questions: [
  70. {
  71. question: "Tags?",
  72. header: "Tags",
  73. options: [{ label: "bug", description: "Bug fix" }],
  74. multiple: true,
  75. },
  76. ],
  77. })
  78. let state = questionSelect(createQuestionBodyState("question-1"), ask).state
  79. expect(state.answers).toEqual([["bug"]])
  80. state = questionSelect(state, ask).state
  81. expect(state.answers).toEqual([[]])
  82. })
  83. test("stores and submits custom answers", () => {
  84. let state = questionSetSelected(createQuestionBodyState("question-1"), 1)
  85. let next = questionSelect(state, req())
  86. expect(next.state.editing).toBe(true)
  87. state = questionStoreCustom(next.state, 0, " custom mode ")
  88. next = questionSave(state, req())
  89. expect(next.reply).toEqual({
  90. requestID: "question-1",
  91. answers: [["custom mode"]],
  92. })
  93. })
  94. test("resets state when the request id changes and builds reject payloads", () => {
  95. const state = questionSetSelected(createQuestionBodyState("question-1"), 1)
  96. expect(questionSync(state, "question-1")).toBe(state)
  97. expect(questionSync(state, "question-2")).toEqual(createQuestionBodyState("question-2"))
  98. expect(questionReject(req())).toEqual({
  99. requestID: "question-1",
  100. })
  101. })
  102. })