config-v2.test.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /** @jsxImportSource @opentui/solid */
  2. import { testRender } from "@opentui/solid"
  3. import { expect, test } from "bun:test"
  4. import { Schema } from "effect"
  5. import { resolve, ConfigProvider, Info, useConfig, type Interface } from "../src/config"
  6. import { settings } from "../src/component/dialog-config"
  7. test("validates mini replay settings", () => {
  8. const decode = Schema.decodeUnknownSync(Info)
  9. expect(decode({ mini: { replay: false, replay_limit: 50 } })).toEqual({
  10. mini: { replay: false, replay_limit: 50 },
  11. })
  12. expect(() => decode({ mini: { replay_limit: 0 } })).toThrow()
  13. expect(() => decode({ mini: { replay_limit: 1.5 } })).toThrow()
  14. })
  15. test("validates the session tabs setting", () => {
  16. const decode = Schema.decodeUnknownSync(Info)
  17. expect(decode({ tabs: { enabled: true, layout: "vertical" } })).toEqual({
  18. tabs: { enabled: true, layout: "vertical" },
  19. })
  20. expect(() => decode({ tabs: { layout: true } })).toThrow()
  21. expect(() => decode({ tabs: { enabled: "on" } })).toThrow()
  22. expect(decode({ prompt: { image_preview: true } })).toEqual({ prompt: { image_preview: true } })
  23. expect(decode({ session: { image_preview: true } })).toEqual({ session: { image_preview: true } })
  24. })
  25. test("resolves nested config and keybind defaults", () => {
  26. const config = resolve(
  27. {
  28. keybinds: { leader: "ctrl+o" },
  29. leader: { timeout: 500 },
  30. scroll: { speed: 2, acceleration: true },
  31. diffs: { view: "split" },
  32. debug: { devtools: true },
  33. },
  34. { terminalSuspend: true },
  35. )
  36. expect(config.leader.timeout).toBe(500)
  37. expect(config.keybinds.get("leader")?.[0]?.key).toBe("ctrl+o")
  38. expect(config.scroll).toEqual({ speed: 2, acceleration: true })
  39. expect(config.diffs).toEqual({ view: "split" })
  40. expect(config.debug).toEqual({ devtools: true })
  41. expect(config.tabs).toEqual({ enabled: true, scope: "cwd", layout: "horizontal" })
  42. })
  43. test("shows resolved tab defaults in settings", () => {
  44. expect(settings.find((setting) => setting.path.join(".") === "tabs.enabled")?.default).toBe(true)
  45. expect(settings.find((setting) => setting.path.join(".") === "tabs.scope")?.default).toBe("cwd")
  46. expect(settings.find((setting) => setting.path.join(".") === "tabs.layout")?.default).toBe("horizontal")
  47. })
  48. test("provides config and its host interface", async () => {
  49. const config = resolve({}, { terminalSuspend: true })
  50. let current = {}
  51. const service: Interface = {
  52. get: async () => current,
  53. update: async (update) => {
  54. const draft: Record<string, any> = { ...current }
  55. update(draft)
  56. current = draft
  57. return draft
  58. },
  59. }
  60. let context: ReturnType<typeof useConfig> | undefined
  61. function Consumer() {
  62. context = useConfig()
  63. return <text>{`${context.data.mouse ? "mouse" : "none"} ${context.data.keybinds.get("leader")?.[0]?.key}`}</text>
  64. }
  65. const app = await testRender(() => (
  66. <ConfigProvider config={config} service={service}>
  67. <Consumer />
  68. </ConfigProvider>
  69. ))
  70. try {
  71. await app.renderOnce()
  72. expect(app.captureCharFrame()).toContain("mouse ctrl+x")
  73. if (!context) throw new Error("Config context was not provided")
  74. await context.update((draft) => {
  75. draft.mouse = false
  76. draft.keybinds = { leader: "ctrl+o" }
  77. })
  78. await app.renderOnce()
  79. expect(app.captureCharFrame()).toContain("none ctrl+o")
  80. } finally {
  81. app.renderer.destroy()
  82. }
  83. })