test(tui): await diff tree context readiness (#37501)
Co-authored-by: James Long <longster@gmail.com>
This commit is contained in:
co-authored by
James Long
parent
44f7bb71c1
commit
651751405d
@@ -3,6 +3,7 @@ import { describe, expect, test } from "bun:test"
|
|||||||
import { RGBA } from "@opentui/core"
|
import { RGBA } from "@opentui/core"
|
||||||
import { testRender } from "@opentui/solid"
|
import { testRender } from "@opentui/solid"
|
||||||
import type { JSX } from "solid-js"
|
import type { JSX } from "solid-js"
|
||||||
|
import { onMount, type ParentProps } from "solid-js"
|
||||||
import { createTuiResolvedConfig } from "../../fixture/tui-runtime"
|
import { createTuiResolvedConfig } from "../../fixture/tui-runtime"
|
||||||
import { ThemeProvider } from "../../../src/context/theme"
|
import { ThemeProvider } from "../../../src/context/theme"
|
||||||
import { ConfigProvider } from "../../../src/config"
|
import { ConfigProvider } from "../../../src/config"
|
||||||
@@ -27,42 +28,33 @@ const theme = {
|
|||||||
|
|
||||||
describe("DiffViewerFileTree", () => {
|
describe("DiffViewerFileTree", () => {
|
||||||
test.skip("renders sorted hierarchical file rows", async () => {
|
test.skip("renders sorted hierarchical file rows", async () => {
|
||||||
const app = await testRender(
|
const lines = visibleLines(
|
||||||
() =>
|
await renderFrame(() => (
|
||||||
withTheme(() => (
|
<DiffViewerFileTree
|
||||||
<DiffViewerFileTree
|
width={32}
|
||||||
width={32}
|
files={[
|
||||||
files={[
|
{ file: "z-file.ts" },
|
||||||
{ file: "z-file.ts" },
|
{ file: "b/file.ts" },
|
||||||
{ file: "b/file.ts" },
|
{ file: "a/zeta.ts" },
|
||||||
{ file: "a/zeta.ts" },
|
{ file: "b/alpha.ts" },
|
||||||
{ file: "b/alpha.ts" },
|
{ file: "a/alpha.ts" },
|
||||||
{ file: "a/alpha.ts" },
|
]}
|
||||||
]}
|
loading={false}
|
||||||
loading={false}
|
error={undefined}
|
||||||
error={undefined}
|
theme={theme}
|
||||||
theme={theme}
|
focused={true}
|
||||||
focused={true}
|
/>
|
||||||
/>
|
)),
|
||||||
)),
|
|
||||||
{ width: 40, height: 20 },
|
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
expect(lines).toEqual([
|
||||||
await renderOnceSettled(app)
|
"▾ a",
|
||||||
const lines = visibleLines(app.captureCharFrame())
|
"│ ├─ alpha.ts ?",
|
||||||
|
"│ └─ zeta.ts ?",
|
||||||
expect(lines).toEqual([
|
"├─ ▾ b",
|
||||||
"▾ a",
|
"│ ├─ alpha.ts ?",
|
||||||
"│ ├─ alpha.ts ?",
|
"│ └─ file.ts ?",
|
||||||
"│ └─ zeta.ts ?",
|
])
|
||||||
"├─ ▾ b",
|
|
||||||
"│ ├─ alpha.ts ?",
|
|
||||||
"│ └─ file.ts ?",
|
|
||||||
])
|
|
||||||
} finally {
|
|
||||||
app.renderer.destroy()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test("keeps loading and error quiet while rendering an empty settled state", async () => {
|
test("keeps loading and error quiet while rendering an empty settled state", async () => {
|
||||||
@@ -152,41 +144,35 @@ describe("DiffViewerFileTree", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function renderFrame(component: () => JSX.Element) {
|
async function renderFrame(component: () => JSX.Element) {
|
||||||
const app = await testRender(() => withTheme(component), { width: 40, height: 10 })
|
const mounted = Promise.withResolvers<void>()
|
||||||
|
const app = await testRender(() => withTheme(component, mounted.resolve), { width: 40, height: 10 })
|
||||||
try {
|
try {
|
||||||
await renderOnceSettled(app)
|
await mounted.promise
|
||||||
return await captureSettledFrame(app)
|
await app.renderOnce()
|
||||||
|
await app.renderOnce()
|
||||||
|
return app.captureCharFrame()
|
||||||
} finally {
|
} finally {
|
||||||
app.renderer.destroy()
|
app.renderer.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderOnceSettled(app: Awaited<ReturnType<typeof testRender>>) {
|
function withTheme(component: () => JSX.Element, onReady = () => {}) {
|
||||||
await app.renderOnce()
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 25))
|
|
||||||
await app.renderOnce()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function captureSettledFrame(app: Awaited<ReturnType<typeof testRender>>) {
|
|
||||||
for (let attempt = 0; attempt < 5; attempt++) {
|
|
||||||
const frame = app.captureCharFrame()
|
|
||||||
if (visibleLines(frame).length > 0) return frame
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 25))
|
|
||||||
await app.renderOnce()
|
|
||||||
}
|
|
||||||
return app.captureCharFrame()
|
|
||||||
}
|
|
||||||
|
|
||||||
function withTheme(component: () => JSX.Element) {
|
|
||||||
return (
|
return (
|
||||||
<TestTuiContexts>
|
<TestTuiContexts>
|
||||||
<ConfigProvider config={createTuiResolvedConfig()}>
|
<ConfigProvider config={createTuiResolvedConfig()}>
|
||||||
<ThemeProvider mode="dark">{component()}</ThemeProvider>
|
<ThemeProvider mode="dark">
|
||||||
|
<Ready onReady={onReady}>{component()}</Ready>
|
||||||
|
</ThemeProvider>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</TestTuiContexts>
|
</TestTuiContexts>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ready(props: ParentProps<{ onReady: () => void }>) {
|
||||||
|
onMount(props.onReady)
|
||||||
|
return props.children
|
||||||
|
}
|
||||||
|
|
||||||
function visibleLines(frame: string) {
|
function visibleLines(frame: string) {
|
||||||
return frame
|
return frame
|
||||||
.split("\n")
|
.split("\n")
|
||||||
|
|||||||
Reference in New Issue
Block a user