config-v2.test.tsx 3.2 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, TabPosition, useConfig, type Interface } from "../src/config"
  6. import { settingID, 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, position: "right" } })).toEqual({
  18. tabs: { enabled: true, position: "right" },
  19. })
  20. expect(() => decode({ tabs: { position: "vertical" } })).toThrow()
  21. expect(() => decode({ tabs: { enabled: "on" } })).toThrow()
  22. })
  23. test("resolves nested config and keybind defaults", () => {
  24. const config = resolve(
  25. {
  26. keybinds: { leader: "ctrl+o" },
  27. leader: { timeout: 500 },
  28. scroll: { speed: 2, acceleration: true },
  29. diffs: { view: "split" },
  30. debug: { devtools: true },
  31. },
  32. { terminalSuspend: true },
  33. )
  34. expect(config.leader.timeout).toBe(500)
  35. expect(config.keybinds.get("leader")?.[0]?.key).toBe("ctrl+o")
  36. expect(config.scroll).toEqual({ speed: 2, acceleration: true })
  37. expect(config.diffs).toEqual({ view: "split" })
  38. expect(config.debug).toEqual({ devtools: true })
  39. expect(config.tabs).toEqual({ enabled: true, scope: "cwd", position: "top" })
  40. })
  41. test("shows resolved tab defaults in settings", () => {
  42. expect(settings.find((setting) => settingID(setting) === "tabs.enabled")?.default).toBe(true)
  43. expect(settings.find((setting) => settingID(setting) === "tabs.scope")?.default).toBe("cwd")
  44. const position = settings.find((setting) => settingID(setting) === "tabs.position")
  45. expect(position?.default).toBe("top")
  46. expect(position?.values).toBe(TabPosition.literals)
  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. })