This commit is contained in:
+31
-9
@@ -5,7 +5,8 @@ import { createSignal } from "solid-js";
|
||||
import { build } from "../scripts/build.js";
|
||||
import type { QuotaStatus } from "../src/quota.js";
|
||||
|
||||
type SlotRender = (input: { readonly sessionID: string }) => JSX.Element;
|
||||
type SidebarSlotRender = (input: { readonly sessionID: string }) => JSX.Element;
|
||||
type HomeSlotRender = (input: Record<string, never>) => JSX.Element;
|
||||
|
||||
const status = (plan: string, remaining: number): QuotaStatus => ({
|
||||
plan,
|
||||
@@ -30,9 +31,13 @@ test("built quota slot stays reactive across pending, empty, failure, update, an
|
||||
);
|
||||
const { default: plugin } = tui;
|
||||
const pending = Promise.withResolvers<QuotaStatus | null>();
|
||||
const responses: Array<() => Promise<QuotaStatus | null>> = [() => pending.promise];
|
||||
const responses: Array<() => Promise<QuotaStatus | null>> = [
|
||||
async () => status("home", 90),
|
||||
() => pending.promise,
|
||||
];
|
||||
let statusCalls = 0;
|
||||
let slotRender: SlotRender | undefined;
|
||||
let sidebarRender: SidebarSlotRender | undefined;
|
||||
let homeRender: HomeSlotRender | undefined;
|
||||
let notifyUpdated: (() => void) | undefined;
|
||||
|
||||
const quota = {
|
||||
@@ -52,8 +57,17 @@ test("built quota slot stays reactive across pending, empty, failure, update, an
|
||||
const contextFixture = {
|
||||
client: { rpc: () => quota },
|
||||
ui: {
|
||||
slot(claim: { render: SlotRender }) {
|
||||
slotRender = claim.render;
|
||||
slot(claim: {
|
||||
append: "home.footer.status" | "sidebar.footer";
|
||||
render: HomeSlotRender | SidebarSlotRender;
|
||||
}) {
|
||||
if (claim.append === "home.footer.status") {
|
||||
// SAFETY: The home slot renderer receives the empty home slot input.
|
||||
homeRender = claim.render as HomeSlotRender;
|
||||
} else {
|
||||
// SAFETY: The only other fixture path is the session-aware sidebar slot.
|
||||
sidebarRender = claim.render as SidebarSlotRender;
|
||||
}
|
||||
return () => undefined;
|
||||
},
|
||||
},
|
||||
@@ -63,10 +77,18 @@ test("built quota slot stays reactive across pending, empty, failure, update, an
|
||||
// members implemented by this focused rendering fixture.
|
||||
const context = Object.assign({} as Plugin.Context, contextFixture);
|
||||
const cleanup = await plugin.setup(context);
|
||||
if (!slotRender || !notifyUpdated) throw new Error("Plugin did not register its slot");
|
||||
if (!sidebarRender || !homeRender || !notifyUpdated)
|
||||
throw new Error("Plugin did not register its slots");
|
||||
|
||||
const renderHome = homeRender;
|
||||
const home = await testRender(() => renderHome({}), { width: 70, height: 5 });
|
||||
await home.waitForFrame((frame) => frame.includes("ChatGPT quota (home)"));
|
||||
expect(home.captureCharFrame()).toContain("5h: 90% · due");
|
||||
expect(statusCalls).toBe(1);
|
||||
home.renderer.destroy();
|
||||
|
||||
const [sessionID, setSessionID] = createSignal("session-one");
|
||||
const renderSlot = slotRender;
|
||||
const renderSlot = sidebarRender;
|
||||
const setup = await testRender(
|
||||
() =>
|
||||
renderSlot({
|
||||
@@ -94,13 +116,13 @@ test("built quota slot stays reactive across pending, empty, failure, update, an
|
||||
throw new Error("disconnected");
|
||||
});
|
||||
notifyUpdated();
|
||||
await setup.waitFor(() => statusCalls === 3);
|
||||
await setup.waitFor(() => statusCalls === 4);
|
||||
expect(setup.captureCharFrame()).not.toContain("ChatGPT quota");
|
||||
|
||||
responses.push(async () => status("pro", 42));
|
||||
setSessionID("session-two");
|
||||
await setup.waitForFrame((frame) => frame.includes("ChatGPT quota (pro)"));
|
||||
expect(statusCalls).toBe(4);
|
||||
expect(statusCalls).toBe(5);
|
||||
} finally {
|
||||
setup.renderer.destroy();
|
||||
if (cleanup) await cleanup();
|
||||
|
||||
Reference in New Issue
Block a user