form.shared.test.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { describe, expect, test } from "bun:test"
  2. import type { FormField, FormInfo } from "@opencode-ai/client/promise"
  3. import {
  4. createFormBodyState,
  5. formAcknowledge,
  6. formAnswer,
  7. formCommitInput,
  8. formPick,
  9. formReply,
  10. formSetExternalReady,
  11. formSetField,
  12. formSetSelected,
  13. formUnsupported,
  14. formValidate,
  15. } from "../../src/mini/form.shared"
  16. function request(fields: FormField[]): FormInfo {
  17. return { id: "frm_1", sessionID: "ses_1", title: "Input", fields: fields as FormInfo["fields"] }
  18. }
  19. describe("Mini form state", () => {
  20. test("builds every supported answer and preserves owner location", () => {
  21. const form = request([
  22. { key: "choice", type: "string", options: [{ value: "fast", label: "Fast" }], default: "fast" },
  23. { key: "count", type: "number" },
  24. { key: "whole", type: "integer", default: 2 },
  25. { key: "enabled", type: "boolean", default: false },
  26. { key: "tags", type: "multiselect", options: [], custom: true },
  27. { key: "external", type: "external", url: "https://example.com/action" },
  28. ])
  29. let state = formSetField(createFormBodyState(form), form, 1)
  30. state = formCommitInput(state, form, "1.5")
  31. state = formSetField(state, form, 4)
  32. state = formSetSelected(state, 0)
  33. state = formPick(state, form)
  34. state = formCommitInput(state, form, "custom")
  35. state = formSetField(state, form, 5)
  36. state = formAcknowledge(formSetExternalReady(state, "external"), form)
  37. const answer = { choice: "fast", count: 1.5, whole: 2, enabled: false, tags: ["custom"], external: true }
  38. expect(formAnswer(form, state)).toEqual(answer)
  39. expect(formReply({ ...form, location: { directory: "/tmp", workspaceID: "wrk_1" } }, state)).toEqual({
  40. sessionID: "ses_1",
  41. formID: "frm_1",
  42. answer,
  43. location: { directory: "/tmp", workspaceID: "wrk_1" },
  44. })
  45. })
  46. test("rejects invalid and deliberately unsupported shapes", () => {
  47. const invalid = request([
  48. { key: "required", type: "string", required: true },
  49. { key: "external", type: "external", url: "https://example.com" },
  50. ])
  51. expect(formValidate(invalid, createFormBodyState(invalid))).toContain("Answer required")
  52. expect(formUnsupported(request([{ key: "value", type: "string", pattern: "^a" }]))).toContain("Pattern")
  53. expect(
  54. formUnsupported(
  55. request([
  56. { key: "toggle", type: "boolean" },
  57. { key: "value", type: "string", when: [{ key: "toggle", op: "eq", value: true }] },
  58. ]),
  59. ),
  60. ).toContain("Conditional")
  61. })
  62. })