footer-keymap.test.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /** @jsxImportSource @opentui/solid */
  2. import { testRender } from "@opentui/solid"
  3. import { Keymap } from "../../src/context/keymap"
  4. import { resolve } from "../../src/config"
  5. import { expect, test } from "bun:test"
  6. import { createSignal } from "solid-js"
  7. import { RunFooterView } from "../../src/mini/footer.view"
  8. import { RUN_THEME_FALLBACK } from "../../src/mini/theme"
  9. import type { FooterState, FooterSubagentState, FooterView } from "../../src/mini/types"
  10. test("down opens subagents from an empty prompt", async () => {
  11. const [state] = createSignal<FooterState>({
  12. phase: "idle",
  13. status: "",
  14. notice: "",
  15. model: "gpt-5",
  16. usage: "",
  17. first: false,
  18. interrupt: 0,
  19. exit: 0,
  20. })
  21. const [view] = createSignal<FooterView>({ type: "prompt" })
  22. const [subagents] = createSignal<FooterSubagentState>({
  23. tabs: [
  24. {
  25. sessionID: "subagent-1",
  26. label: "Explore",
  27. description: "Inspect the keymap",
  28. status: "running",
  29. },
  30. ],
  31. details: {},
  32. permissions: [],
  33. forms: [],
  34. })
  35. const config = resolve(
  36. { keybinds: { editor_open: "none", session_queued_prompts: "none" } },
  37. { terminalSuspend: true },
  38. )
  39. function Harness() {
  40. return (
  41. <Keymap.Provider config={config}>
  42. <RunFooterView
  43. directory={() => "/tmp"}
  44. findFiles={async () => []}
  45. agents={() => []}
  46. references={() => []}
  47. commands={() => []}
  48. providers={() => undefined}
  49. currentAgent={() => "Build"}
  50. currentAgentID={() => "build"}
  51. currentAgentExplicit={() => false}
  52. currentModel={() => undefined}
  53. variants={() => []}
  54. currentVariant={() => undefined}
  55. state={state}
  56. view={view}
  57. subagent={subagents}
  58. theme={() => RUN_THEME_FALLBACK}
  59. miniSettings={() => ({
  60. thinking: "hide",
  61. shell_output: "hide",
  62. turn_summary: "show",
  63. footer: "show",
  64. splash: "show",
  65. mono: false,
  66. })}
  67. mono={false}
  68. onSubmit={() => true}
  69. onPermissionReply={() => {}}
  70. onFormReply={() => {}}
  71. onFormCancel={() => {}}
  72. onCycle={() => {}}
  73. onInterrupt={() => false}
  74. onEditorOpen={async () => undefined}
  75. onInputClear={() => {}}
  76. onExit={() => {}}
  77. onAgentSelect={() => {}}
  78. onModelSelect={() => {}}
  79. onVariantSelect={() => {}}
  80. onRows={() => {}}
  81. onLayout={() => {}}
  82. onStatus={() => {}}
  83. onMiniSettingChange={() => {}}
  84. />
  85. </Keymap.Provider>
  86. )
  87. }
  88. const app = await testRender(() => <Harness />, { width: 100, height: 8, kittyKeyboard: true })
  89. try {
  90. await app.renderOnce()
  91. expect(app.renderer.currentFocusedEditor?.plainText).toBe("")
  92. app.mockInput.pressArrow("down")
  93. await app.renderOnce()
  94. expect(app.captureCharFrame()).toContain("Select subagent")
  95. } finally {
  96. app.renderer.currentFocusedRenderable?.blur()
  97. app.renderer.currentFocusedEditor?.blur()
  98. app.renderer.destroy()
  99. }
  100. })