fix(tui): render mini markdown in mono mode (#38313)
This commit is contained in:
parent
a3e2cc0dcd
commit
e12ec8681b
6 changed files with 147 additions and 6 deletions
|
|
@ -1,7 +1,8 @@
|
|||
import { afterEach, expect, test } from "bun:test"
|
||||
import type { SessionMessageAssistantTool } from "@opencode-ai/client/promise"
|
||||
import { RGBA, SyntaxStyle } from "@opentui/core"
|
||||
import { CliRenderEvents, MarkdownRenderable, RGBA, SyntaxStyle, TextRenderable } from "@opentui/core"
|
||||
import { MockTreeSitterClient, createTestRenderer, type TestRenderer } from "@opentui/core/testing"
|
||||
import { monoSnapshot } from "../../src/mini/mono"
|
||||
import { RunScrollbackStream } from "../../src/mini/scrollback.surface"
|
||||
import { entryGroupKey } from "../../src/mini/scrollback.writer"
|
||||
import { RUN_THEME_FALLBACK, type RunTheme } from "../../src/mini/theme"
|
||||
|
|
@ -67,6 +68,7 @@ async function setup(
|
|||
wrote?: boolean
|
||||
theme?: RunTheme
|
||||
onThemeRelease?: (theme: RunTheme) => void
|
||||
mono?: boolean
|
||||
} = {},
|
||||
) {
|
||||
const out = await createTestRenderer({
|
||||
|
|
@ -77,6 +79,7 @@ async function setup(
|
|||
consoleMode: "disabled",
|
||||
})
|
||||
active.push(out.renderer)
|
||||
if (input.mono) out.renderer.on(CliRenderEvents.EXTERNAL_OUTPUT, monoSnapshot)
|
||||
|
||||
const treeSitterClient = new MockTreeSitterClient({ autoResolveTimeout: 0 })
|
||||
treeSitterClient.setMockResult({ highlights: [] })
|
||||
|
|
@ -87,6 +90,7 @@ async function setup(
|
|||
treeSitterClient,
|
||||
wrote: input.wrote ?? false,
|
||||
onThemeRelease: input.onThemeRelease,
|
||||
mono: input.mono,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
@ -203,6 +207,42 @@ test("theme swaps preserve streamed markdown parser state", async () => {
|
|||
}
|
||||
})
|
||||
|
||||
test("renders monochrome scrollback as ASCII markdown", async () => {
|
||||
const out = await setup({ mono: true, width: 60 })
|
||||
const output: string[] = []
|
||||
out.renderer.on(CliRenderEvents.EXTERNAL_OUTPUT, (event) => {
|
||||
output.push(decoder.decode(event.snapshot.getRealCharBytes(true)))
|
||||
})
|
||||
|
||||
try {
|
||||
await out.scrollback.append(assistant("# H"))
|
||||
expect(Reflect.get(out.scrollback, "active")?.renderable).toBeInstanceOf(MarkdownRenderable)
|
||||
await out.scrollback.append(assistant('éading →\n\n> “quote”\n\n---\n\n| A | B |\n| - | - |\n| α | β |'))
|
||||
await out.scrollback.complete()
|
||||
out.renderer.writeToScrollback((ctx) => ({
|
||||
root: new TextRenderable(ctx.renderContext, {
|
||||
content: "plain │ emoji 🙂",
|
||||
width: ctx.width,
|
||||
height: 1,
|
||||
}),
|
||||
width: ctx.width,
|
||||
height: 1,
|
||||
trailingNewline: false,
|
||||
}))
|
||||
|
||||
const rendered = output.join("").replace(/ +\n/g, "\n")
|
||||
expect(rendered).toContain("# H?ading ->")
|
||||
expect(rendered).toContain('| "quote"')
|
||||
expect(rendered).toContain("------------------------------------------------------------")
|
||||
expect(rendered).toContain("? ?")
|
||||
expect(rendered).toContain("plain ? emoji ?")
|
||||
expect(rendered).not.toMatch(/[^\x00-\x7f]/)
|
||||
} finally {
|
||||
out.scrollback.destroy()
|
||||
destroy(claim(out.renderer))
|
||||
}
|
||||
})
|
||||
|
||||
function user(text: string): StreamCommit {
|
||||
return {
|
||||
kind: "user",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue