runtime.boot.test.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { afterEach, describe, expect, mock, spyOn, test } from "bun:test"
  2. import { OpenCode } from "@opencode-ai/client/promise"
  3. import { resolveMiniSettings, resolveModelInfo, resolveRunTuiConfig } from "../../src/mini/runtime.boot"
  4. import { catalogModel, catalogProvider } from "./fixture/catalog"
  5. import { createTuiResolvedConfig } from "../fixture/tui-runtime"
  6. describe("run runtime boot", () => {
  7. afterEach(() => {
  8. mock.restore()
  9. })
  10. test("falls back to default tui keymap config when config load fails", async () => {
  11. const result = await resolveRunTuiConfig(Promise.reject(new Error("boom")))
  12. expect(result.keybinds.get("leader")?.[0]?.key).toBe("ctrl+x")
  13. expect(result.leader.timeout).toBe(2000)
  14. expect(result.keybinds.get("command.palette.show")?.[0]?.key).toBe("ctrl+p")
  15. expect(result.keybinds.get("variant.cycle")?.[0]?.key).toBe("ctrl+t")
  16. expect(result.keybinds.get("session.interrupt")?.[0]?.key).toBe("escape")
  17. expect(result.keybinds.get("prompt.history.previous")?.[0]?.key).toBe("up")
  18. expect(result.keybinds.get("prompt.history.next")?.[0]?.key).toBe("down")
  19. expect(result.keybinds.get("prompt.clear")?.[0]?.key).toBe("ctrl+c")
  20. expect(result.keybinds.get("input.submit")?.[0]?.key).toBe("return")
  21. expect(result.keybinds.get("input.newline")?.[0]?.key).toBe("shift+return,ctrl+return,ctrl+j")
  22. expect(result.keybinds.get("prompt.queue")?.[0]?.key).toBe("alt+return")
  23. })
  24. test("preserves shared config while resolving independent Mini defaults", async () => {
  25. const result = await resolveRunTuiConfig(
  26. createTuiResolvedConfig({
  27. theme: { mode: "light" },
  28. leader: { timeout: 450 },
  29. }),
  30. )
  31. expect(result.theme).toEqual({ mode: "light" })
  32. expect(result.leader.timeout).toBe(450)
  33. expect(resolveMiniSettings(result)).toEqual({
  34. thinking: "hide",
  35. shell_output: "hide",
  36. turn_summary: "show",
  37. footer: "show",
  38. splash: "show",
  39. mono: false,
  40. })
  41. expect(
  42. resolveMiniSettings({
  43. mini: {
  44. thinking: "show",
  45. shell_output: "show",
  46. turn_summary: "hide",
  47. footer: "hide",
  48. splash: "hide",
  49. mono: true,
  50. },
  51. }),
  52. ).toEqual({
  53. thinking: "show",
  54. shell_output: "show",
  55. turn_summary: "hide",
  56. footer: "hide",
  57. splash: "hide",
  58. mono: true,
  59. })
  60. })
  61. test("loads v2 providers and models for model selector data", async () => {
  62. const sdk = OpenCode.make({ baseUrl: "https://opencode.test" })
  63. const location = { directory: "/workspace", project: { id: "proj_1", directory: "/workspace" } }
  64. const providerList = spyOn(sdk.provider, "list").mockResolvedValue({
  65. location,
  66. data: [catalogProvider("openai", "OpenAI")],
  67. } as never)
  68. spyOn(sdk.model, "list").mockResolvedValue({
  69. location,
  70. data: [catalogModel({ id: "gpt-5", providerID: "openai", variants: ["high", "minimal"] })],
  71. } as never)
  72. await expect(resolveModelInfo(sdk, { directory: "/workspace" })).resolves.toEqual({
  73. providers: [
  74. {
  75. id: "openai",
  76. name: "OpenAI",
  77. models: {
  78. "gpt-5": {
  79. name: "gpt-5",
  80. cost: {
  81. input: 0,
  82. },
  83. limit: {
  84. context: 128_000,
  85. },
  86. status: "active",
  87. variants: {
  88. high: {},
  89. minimal: {},
  90. },
  91. },
  92. },
  93. },
  94. ],
  95. })
  96. expect(providerList).toHaveBeenCalledWith({
  97. location: {
  98. directory: "/workspace",
  99. },
  100. })
  101. })
  102. })