3232 * 副作用:只挂 React 树 + 读写 jsdom 的 `localStorage`;不写盘、不发请求。
3333 */
3434import { act , cleanup , fireEvent , render , screen , waitFor , within } from "@testing-library/react" ;
35- import { useRef } from "react" ;
3635import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
37- import type { Note } from "../../types" ;
38- import type { NoteEditHandle } from "../NoteEditView" ;
39- import type { NoteViewSlot , ViewSpec } from "../../views/registry" ;
4036import { viewsFor } from "../../views/registry" ;
41- import { columnSpec } from "../../shell/columnRegistry" ;
42- import { useColumnLayout } from "../../hooks/useColumnLayout" ;
4337import { Toast } from "../../ui/primitives" ;
44- import NotesReadingColumn from "./NotesReadingColumn " ;
38+ import { HarnessHost , MEMORY_KEY , handleOf , noop , note , type HarnessProps } from "./readingColumnTestKit " ;
4539
4640const { invokeMock } = vi . hoisted ( ( ) => ( { invokeMock : vi . fn ( ) } ) ) ;
4741vi . mock ( "@tauri-apps/api/core" , ( ) => ( {
@@ -50,71 +44,8 @@ vi.mock("@tauri-apps/api/core", () => ({
5044} ) ) ;
5145vi . mock ( "../RichEditorView" , ( ) => ( { default : ( ) => < div data-testid = "editor-stub" /> } ) ) ;
5246
53- const note : Note = {
54- id : 1 ,
55- title : "标题" ,
56- content : "# 正文\n内容段落" ,
57- source : "session" ,
58- session_id : 42 ,
59- rule_version : null ,
60- purify_stats : null ,
61- tags : "[]" ,
62- properties : null ,
63- pin : 0 ,
64- group_id : null ,
65- created_at : 1 ,
66- updated_at : 2 ,
67- } ;
68-
69- const noop = vi . fn ( ) ;
70- const MEMORY_KEY = "view:default:note" ;
71-
72- /** 注入的编辑器出口(`NoteEditHandle` 契约一字未改 —— 这行是 C4「不改接口」的编译期锚) */
73- function handleOf ( flushSave : ( ) => Promise < void > ) : NoteEditHandle {
74- return { flushSave, getContent : ( ) => note . content } ;
75- }
76-
77- interface HarnessProps {
78- readonly views ?: readonly ViewSpec < NoteViewSlot > [ ] ;
79- readonly editing ?: boolean ;
80- readonly selected ?: Note | null ;
81- readonly handle ?: NoteEditHandle | null ;
82- /** 批 7 T17:卡片流那条链的 ms 出口(F11 用;缺省 = 今天的形态) */
83- readonly onOpenSession ?: ( sessionId : number ) => void ;
84- readonly onOpenSessionAt ?: ( sessionId : number , ms : number ) => void ;
85- }
86-
87- /** 页面形态的宿主:真 `useColumnLayout` + 真注册表清单(与 `NotesPage` 的那一行同源) */
88- function Harness ( { views = viewsFor ( "note" ) , editing = false , selected = note , handle = null , onOpenSession, onOpenSessionAt } : HarnessProps ) {
89- const outlineCol = useColumnLayout ( "notes-outline" , columnSpec ( "notes-outline" ) ) ;
90- const editorRef = useRef < NoteEditHandle | null > ( handle ) ;
91- return (
92- < NotesReadingColumn
93- selected = { selected }
94- editing = { editing }
95- setEditing = { noop }
96- readerSearch = { null }
97- noteColors = { { } }
98- groups = { [ ] }
99- editorRef = { editorRef }
100- outlineCol = { outlineCol }
101- onChanged = { noop }
102- onError = { noop }
103- onOpenAi = { noop }
104- onOpenModelCard = { noop }
105- onSelectionAction = { noop }
106- onPinToggle = { noop }
107- onDelete = { noop }
108- onTaskToggle = { noop }
109- onTagClick = { noop }
110- onOpenSession = { onOpenSession }
111- onOpenSessionAt = { onOpenSessionAt }
112- onImageOpen = { noop }
113- onCleanNotice = { noop }
114- views = { views }
115- />
116- ) ;
117- }
47+ /** 页面形态的宿主:夹具与挂载工具已搬到 `./readingColumnTestKit` —— 本行只补「真注册表清单」这个默认值(夹具件不得 import 注册表,理由见该件文件头)。 */
48+ const Harness = ( { views = viewsFor ( "note" ) , ...rest } : Partial < HarnessProps > ) => < HarnessHost views = { views } { ...rest } /> ;
11849
11950/** 当前 `aria-pressed` 为真的段文本(= 切换器的受控值;`ViewSwitcher` 用 `aria-pressed` 承载选中态) */
12051const pressedLabel = ( ) : string => {
0 commit comments