checkpoint before gfm ast parser design

This commit is contained in:
lix-2026
2026-05-08 00:41:03 +08:00
parent e8ba12e461
commit c620b9e40c
41 changed files with 12270 additions and 263 deletions
@@ -26,6 +26,7 @@ function reduceTreeRuntimeForTest(request: RuntimeRequest) {
const state = request.state ?? {};
const action = request.action ?? {};
const env = request.environment ?? {};
const selection = (state.selection ?? {}) as Record<string, unknown>;
const rows = Array.isArray(env.rows) ? env.rows as Array<Record<string, unknown>> : [];
const rowId = typeof action.targetRowId === "string" ? action.targetRowId : null;
const targetRow = rows.find((row) => row.rowId === rowId) ?? {};
@@ -49,12 +50,28 @@ function reduceTreeRuntimeForTest(request: RuntimeRequest) {
targetRowId: rowId,
target,
fileCount: action.fileCount ?? 0,
}]
: [];
}]
: [];
const selectedRowId = typeof action.rowId === "string" ? action.rowId : null;
const nextSelection =
action.kind === "selectRow" && selectedRowId
? { selectedRowIds: [selectedRowId], anchorRowId: selectedRowId, focusedRowId: selectedRowId }
: action.kind === "clearSelection"
? { selectedRowIds: [], anchorRowId: null, focusedRowId: null }
: selection;
return {
requestId: request.requestId,
mode: "fileTree",
state: { mode: "fileTree", state },
state: {
mode: "fileTree",
state: {
activeRowId: (state as Record<string, unknown>).activeRowId ?? null,
selection: nextSelection,
dragRowIds: (state as Record<string, unknown>).dragRowIds ?? [],
dragEffect: (state as Record<string, unknown>).dragEffect ?? null,
dropTargetRowId: (state as Record<string, unknown>).dropTargetRowId ?? null,
},
},
domPatches: [{ kind: "fileTreeState" }],
hostEvents,
commandEvents: [],
@@ -414,6 +431,69 @@ describe("tree-shell-surface", () => {
});
});
it("file tree surface 应支持空白区清空选择", async () => {
const runtimeReducerMock = mockTreeRuntimeReducer();
const targetProjectionItem: KernelFileTreeProjectionItem = {
rowId: "doc:doc_target",
nodeId: "doc_target",
parentNodeId: null,
projectionKind: "file_tree",
title: "目标页面",
depth: 0,
position: 0,
childCount: 0,
expandable: false,
expandedByDefault: false,
nodeType: "page",
rowKind: "document",
iconHint: "page",
capabilities: ["open", "select", "context-menu"],
resourceMeta: {
resourceKind: "document",
documentId: "doc_target",
workspaceId: "ws_1",
iconHint: "page",
},
};
await act(async () => {
root.render(
<SidebarTreeSurface
mode="filetree"
rendererFamily="rust_family"
workspaceId="ws_1"
treeShellEnabled
rows={[]}
treeShellItems={[targetProjectionItem]}
activeId=""
onRowClick={() => undefined}
onRowDoubleClick={() => undefined}
onRowContextMenu={() => undefined}
onToggleExpand={() => undefined}
onCreateChild={() => undefined}
/>,
);
});
const targetRow = container.querySelector('[data-testid="filetree-doc-row"][data-row-id="doc:doc_target"]') as HTMLElement | null;
const treeRoot = container.querySelector('[data-rust-filetree-renderer="dom_v1"]') as HTMLElement | null;
expect(targetRow).not.toBeNull();
expect(treeRoot).not.toBeNull();
await act(async () => {
targetRow?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
});
await waitForRuntimeReducer(runtimeReducerMock);
expect(targetRow?.getAttribute("data-selected")).toBe("true");
await act(async () => {
treeRoot?.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
await Promise.resolve();
});
expect(targetRow?.getAttribute("data-selected")).toBe("false");
});
it("picker surface 在 rust_family 下也应挂到默认 Rust/WASM DOM shell host", async () => {
const onPick = vi.fn();