@crazx/dsh-client-test-runtime 0.1.5-alpha.1.zw.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +150 -0
- package/README.zh.md +150 -0
- package/lib/index.js +1377 -0
- package/lib/types/fixtures.d.ts +71 -0
- package/lib/types/index.d.ts +212 -0
- package/lib/types/locale-env.d.ts +9 -0
- package/lib/types/remote.d.ts +58 -0
- package/lib/types/sessions.d.ts +276 -0
- package/lib/types/settings-remote.d.ts +83 -0
- package/lib/types/settings-scope.d.ts +29 -0
- package/lib/types/snapshot.d.ts +14 -0
- package/lib/types/translate.d.ts +16 -0
- package/lib/types/workspaces.d.ts +89 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/test-support/client-runtime/README.md
|
|
5
|
+
README.md: 616eab2cd5ef03ae4e514ca335b0c60b43d62cf0
|
|
6
|
+
README.zh.md: 08effcef7eaacad67b5496507925337e772d4ce9
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "jsdom slot test runtime for browser feature specs, for test authors exercising slots, stores, and rendering against production machinery."
|
|
3
|
+
kind: "package-library"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-client-test-runtime
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`dsh-client-test-runtime` lets browser feature specs exercise production slot, store, rendering, update, and disposal behavior in jsdom without reimplementing the UI runtime. Test authors can publish typed Session, Workspace, projection, and Conversation fixtures, query slot-local DOM roots, and script Remote replies or failures. Missing services, unstubbed session behavior, and unexpected file uploads fail at the call site, while disposal is idempotent. Use it only from in-repository browser-oriented Vitest suites through `devDependencies`; it is not a product plugin or general Node test harness.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
This package gives a browser feature spec a real runtime to mount against: create the bench, declare the slots your feature occupies, mount the feature plugin, render a slot, assert on the local view, and dispose — with no second implementation of production logic.
|
|
29
|
+
|
|
30
|
+
### Setting up a feature spec
|
|
31
|
+
|
|
32
|
+
`SlotTestRuntime.create()` assembles the runtime, `declare(children)` registers an auto frame whose per-key `<div data-slot>` wrappers become snapshot roots, `mount(plugin)` runs the feature on a real fiber, and `renderSlot(key, owner)` returns the slot-local view with scoped queries and in-place updates:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
const runtime = await SlotTestRuntime.create()
|
|
36
|
+
await runtime.declare({ 'feature-slot': {} })
|
|
37
|
+
const handle = await runtime.mount(FeaturePlugin)
|
|
38
|
+
const view = runtime.renderSlot('feature-slot', { owner: props })
|
|
39
|
+
expect(view.container).toMatchSnapshot()
|
|
40
|
+
await runtime.dispose()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`mount` prechecks required services and fails loud when one is missing — `provide(name, value)` supplies an extra service first. The runtime provides an unavailable `fileUpload` stub so assemblies can mount; replace `runtime.fileUpload.upload` before mounting when a test exercises upload behavior. `storeOf(key, scopeKey)` returns the live store instance the renderer hands a slot's component for identity and action-driven-write assertions.
|
|
44
|
+
|
|
45
|
+
### Local DOM snapshots
|
|
46
|
+
|
|
47
|
+
A registered snapshot serializer folds CSS-module class hashes (`_frame_a1b2c3` → `frame`) so `.snap` files stay structural, and collapses `<svg>` internals to a `data-content` fingerprint. Suites needing a custom page frame use `root.declare(children, Frame)` instead of the auto frame; `dispose()` tears down views, feature fibers, minted scopes, and persisted store state on one axis and is idempotent.
|
|
48
|
+
|
|
49
|
+
### Scripting Remote answers and failures
|
|
50
|
+
|
|
51
|
+
`TestRemote` is the double for the `ctx.remote` face: it registers itself plus one service per scripted namespace so a plugin injecting `remote.<name>` unparks, drives `$on` subscriptions from an explicit test event driver, and exposes `$host` as a plain mutable field a spec assigns to script a homed or non-loopback Host. This package is also where a UI spec takes the `RemoteError` constructor as a value — the `dsh-api-remotes` facade cannot carry it, because a value import from a spec would pull that assembly's unbuilt `/remote` artifact chain.
|
|
52
|
+
|
|
53
|
+
Script a failure by the code the Host would answer with, and assert the same way production code discriminates — on `code`, never on the class:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
import { RemoteError } from '@deepseek-ai/dsh-client-test-runtime'
|
|
57
|
+
|
|
58
|
+
remote.goals.create.mockResolvedValue({
|
|
59
|
+
ok: false,
|
|
60
|
+
error: new RemoteError('goal/not-found', 'goal "g1" does not exist', { goalId: 'g1' }),
|
|
61
|
+
})
|
|
62
|
+
expect(view.getByRole('alert')).toHaveTextContent('goal/not-found')
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### When to use it
|
|
66
|
+
|
|
67
|
+
Use the bench for feature suites that exercise slots, stores, rendering, and disposal under a real runtime — the production `SlotRegistry`, renderer, and provide-bundle materialization are mounted, never reimplemented. It is browser-side test infrastructure: it never reaches a model request, and feature packages depend on it in `devDependencies` only.
|
|
68
|
+
|
|
69
|
+
### What can go wrong
|
|
70
|
+
|
|
71
|
+
- **A declared service is not provided** — `mount` fails loud with the missing names; `provide()` them first.
|
|
72
|
+
- **A render is attempted before `declare`** — `renderSlot` fails loud; declare the key first.
|
|
73
|
+
- **A spec calls an unstubbed verb on a session behavior stub** — fixture stubs fail loud by design, so a missing stub surfaces at the call site rather than silently passing.
|
|
74
|
+
|
|
75
|
+
-----
|
|
76
|
+
|
|
77
|
+
<a id="understand-the-implementation"></a>
|
|
78
|
+
## Understand the implementation
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary>Implementation internals — click to expand</summary>
|
|
82
|
+
|
|
83
|
+
This section explains the design of the bench; the observable behavior is fully covered in [Use this package](#use-this-package).
|
|
84
|
+
|
|
85
|
+
### Design
|
|
86
|
+
|
|
87
|
+
The bench copies no production logic: it mounts the production `SlotRegistry`, production renderer, and `UiSession` adapter. `TestSessions` and `TestWorkspaces` implement the owner interfaces that features consume through Cordis, each fixture Session implements `SessionFace`, and `stubSettingsScope` implements `SettingsScope`. `UiSession` derives standard renderer sources from those Controller bindings. Unstubbed `ISession` behavior fails with the missing method name.
|
|
88
|
+
|
|
89
|
+
### Source map
|
|
90
|
+
|
|
91
|
+
| File | Role |
|
|
92
|
+
|---|---|
|
|
93
|
+
| [`src/index.ts`](src/index.ts) | `SlotTestRuntime` assembly, `TestRoot`, auto frame, `mount`/`dispose` |
|
|
94
|
+
| [`src/sessions.ts`](src/sessions.ts) + [`src/workspaces.ts`](src/workspaces.ts) | `ISessions`/`IWorkspaces` test doubles and `FixtureSession` behavior stubs |
|
|
95
|
+
| [`src/fixtures.ts`](src/fixtures.ts) | Plain fixture builders: conversation snapshots, workspace list state |
|
|
96
|
+
| [`src/snapshot.ts`](src/snapshot.ts) | DOM snapshot serializer (class-hash folding, `<svg>` fingerprint) |
|
|
97
|
+
| [`src/remote.ts`](src/remote.ts) | `TestRemote` double for host RPC, `RemoteError` value re-export |
|
|
98
|
+
| [`src/translate.ts`](src/translate.ts) + [`src/locale-env.ts`](src/locale-env.ts) | Translation and pinned-browser-language test helpers |
|
|
99
|
+
| [`src/settings-scope.ts`](src/settings-scope.ts) | `stubSettingsScope` with test-driven publications and a write spy |
|
|
100
|
+
| — | No runtime invariant companion is published; this test-support package owns no production event stream or mutable data — it assembles the runtime SlotRegistry and renderer (whose packages own their invariants) around test doubles; its own behavior is exercised by its package tests. |
|
|
101
|
+
|
|
102
|
+
### Lifecycle
|
|
103
|
+
|
|
104
|
+
`create()` builds a fresh context, mounts the slot and conversation registries, installs the renderer, and provides the session/workspace doubles plus the fail-loud file-upload stub. `mount` checks every declared injection against the context before starting the fiber, so a missing provider fails loud instead of suspending forever. `dispose()` unmounts React trees first, then disposes feature fibers, releases the root registration, disposes minted session scopes, and clears persisted store state; every public mutator is act-wrapped, so tests never handle SlotCore microtask batching or React `act` themselves.
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
-----
|
|
109
|
+
|
|
110
|
+
<a id="further-exploration"></a>
|
|
111
|
+
## Further Exploration
|
|
112
|
+
|
|
113
|
+
Read these pages when the package-level contract is not enough. They move from the bench to the production machinery it mounts and the tests that use it.
|
|
114
|
+
|
|
115
|
+
- [ui-session](../../client/ui-session/README.md) — the production adapter that derives standard Slot sources from the Controller doubles.
|
|
116
|
+
- [UI slots package](../../client/ui-slots/README.md) — the `SlotRegistry` contract the bench mounts.
|
|
117
|
+
- [UI renderer package](../../client/ui-renderer/README.md) — the renderer the bench installs.
|
|
118
|
+
- [Testing policy](../../../docs/testing.md) — the coverage tiers and browser snapshot lane.
|
|
119
|
+
- [Test-support group map](../README.md) — sibling harnesses and support packages.
|
|
120
|
+
|
|
121
|
+
-----
|
|
122
|
+
|
|
123
|
+
<a id="model-experience"></a>
|
|
124
|
+
## Model Experience
|
|
125
|
+
|
|
126
|
+
None, as this package is browser-side test infrastructure; nothing here reaches a model request.
|
|
127
|
+
|
|
128
|
+
#### KV Cache effect
|
|
129
|
+
|
|
130
|
+
None; this package neither assembles nor sends a provider request.
|
|
131
|
+
|
|
132
|
+
## Known Limitations and Deferred Work
|
|
133
|
+
|
|
134
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
These limits define how the bench is consumed. They are current package constraints, not a task backlog.
|
|
138
|
+
|
|
139
|
+
- **Vitest and jsdom only** — every consumer is an in-repository browser-oriented Vitest suite. The package is not a product plugin or a general Node test harness.
|
|
140
|
+
- **Session, Conversation, and Chat fixtures stay separate** — `sessionSnapshot` contains only Session Controller state, `conversationSnapshot` contains target-neutral Conversation state, and `chatSnapshot` contains Chat target state. Assembly tests provide Session event entries instead of adding Conversation or Chat fields to `SessionSnapshot`.
|
|
141
|
+
|
|
142
|
+
<a id="dev-note"></a>
|
|
143
|
+
### Dev Note
|
|
144
|
+
|
|
145
|
+
<details>
|
|
146
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
147
|
+
|
|
148
|
+
None.
|
|
149
|
+
|
|
150
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向浏览器功能测试的 jsdom slot 测试运行时,供测试作者针对生产机制检验 slot、store 与渲染。"
|
|
3
|
+
kind: "package-library"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-client-test-runtime
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`dsh-client-test-runtime` 让浏览器功能测试在 jsdom 中检验生产 slot、store、渲染、更新与销毁行为,而无需重实现 UI 运行时。测试作者可以发布带类型的 Session、Workspace、projection 与 Conversation fixture,查询 slot 局部 DOM 根,并脚本化 Remote 应答或失败。缺失服务、未打桩的会话行为与意外文件上传都会在调用点失败,销毁则保持幂等。仅限仓内、面向浏览器的 Vitest 套件通过 `devDependencies` 使用本包;它不是产品插件或通用 Node 测试框架。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
本包让浏览器功能测试拥有可挂载的真实运行时:创建测试台,声明你的功能所占用的 slot,挂载功能插件,渲染一个 slot,在局部视图上断言,然后 dispose(资源释放)——全程不存在生产逻辑的第二份实现。
|
|
29
|
+
|
|
30
|
+
### 搭建功能测试
|
|
31
|
+
|
|
32
|
+
`SlotTestRuntime.create()` 组装运行时,`declare(children)` 注册一个自动 frame,其逐 key 的 `<div data-slot>` 包裹层成为快照根,`mount(plugin)` 在真实 fiber 上运行功能,`renderSlot(key, owner)` 返回带限定查询与原位更新的 slot 局部视图:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
const runtime = await SlotTestRuntime.create()
|
|
36
|
+
await runtime.declare({ 'feature-slot': {} })
|
|
37
|
+
const handle = await runtime.mount(FeaturePlugin)
|
|
38
|
+
const view = runtime.renderSlot('feature-slot', { owner: props })
|
|
39
|
+
expect(view.container).toMatchSnapshot()
|
|
40
|
+
await runtime.dispose()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`mount` 会预检必需服务,缺失时自明报错——先用 `provide(name, value)` 提供额外服务。运行时会提供不可用的 `fileUpload` 替身,使装配可以挂载;测试上传行为时,需要在挂载前替换 `runtime.fileUpload.upload`。`storeOf(key, scopeKey)` 返回渲染器交给 slot 组件的实时 store 实例,用于身份与动作驱动写入断言。
|
|
44
|
+
|
|
45
|
+
### 局部 DOM 快照
|
|
46
|
+
|
|
47
|
+
注册的快照序列化器把 CSS-module 哈希类名折回语义名(`_frame_a1b2c3` → `frame`),使 `.snap` 文件只含结构,并把 `<svg>` 内部折叠为 `data-content` 指纹。需要自定义页面 frame 的套件改用 `root.declare(children, Frame)` 而非自动 frame;`dispose()` 沿单一轴拆除视图、feature fiber、已铸 scope 与持久化 store 状态,且幂等。
|
|
48
|
+
|
|
49
|
+
### 脚本化 Remote 应答与失败
|
|
50
|
+
|
|
51
|
+
`TestRemote` 是 `ctx.remote` 面的替身:它把自己连同每个被脚本化的命名空间各注册一个服务,使注入 `remote.<name>` 的插件得以解除挂起;`$on` 订阅由显式的测试事件驱动器推动;`$host` 是普通可变字段,套件直接赋值即可脚本化带 home 或非 loopback 的 Host。UI 套件也在本包取用 `RemoteError` 构造器这个值——`dsh-api-remotes` facade 承载不了它,因为从套件发起的值 import 会拉起该装配尚未构建的 `/remote` 产物链。
|
|
52
|
+
|
|
53
|
+
按 Host 会答的码来脚本化失败,并以生产代码同样的方式断言——判 `code`,绝不判类:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
import { RemoteError } from '@deepseek-ai/dsh-client-test-runtime'
|
|
57
|
+
|
|
58
|
+
remote.goals.create.mockResolvedValue({
|
|
59
|
+
ok: false,
|
|
60
|
+
error: new RemoteError('goal/not-found', 'goal "g1" does not exist', { goalId: 'g1' }),
|
|
61
|
+
})
|
|
62
|
+
expect(view.getByRole('alert')).toHaveTextContent('goal/not-found')
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 何时使用
|
|
66
|
+
|
|
67
|
+
当功能套件要在真实运行时下检验 slot、store、渲染与销毁时使用本测试台——生产 `SlotRegistry`、渲染器与 provide bundle 物化都会被挂载,绝不重实现。它是浏览器侧测试基础设施:永远不触及模型请求,feature 包仅以 `devDependencies` 依赖之。
|
|
68
|
+
|
|
69
|
+
### 可能出什么问题
|
|
70
|
+
|
|
71
|
+
- **已声明服务未提供**——`mount` 自明报错并列出缺失名称;请先用 `provide()` 提供。
|
|
72
|
+
- **在 `declare` 之前尝试渲染**——`renderSlot` 自明报错;请先声明该 key。
|
|
73
|
+
- **测试调用会话行为桩上未打桩的动词**——fixture 桩按设计自明报错,缺失的桩会在调用点浮现,而非静默通过。
|
|
74
|
+
|
|
75
|
+
-----
|
|
76
|
+
|
|
77
|
+
<a id="understand-the-implementation"></a>
|
|
78
|
+
## 理解实现
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary>实现细节——点击展开</summary>
|
|
82
|
+
|
|
83
|
+
本节解释测试台的设计;可观察行为已在[使用本包](#use-this-package)中完整说明。
|
|
84
|
+
|
|
85
|
+
### 设计
|
|
86
|
+
|
|
87
|
+
测试台不复制生产逻辑:它挂载生产 `SlotRegistry`、生产渲染器与 `UiSession` 适配器。`TestSessions` 与 `TestWorkspaces` 实现功能通过 Cordis 消费的 owner 接口,每个 fixture Session 实现 `SessionFace`,`stubSettingsScope` 实现 `SettingsScope`。`UiSession` 从这些 Controller binding 派生标准渲染器 source。未 stub 的 `ISession` 行为会携缺失方法名失败。
|
|
88
|
+
|
|
89
|
+
### 源码地图
|
|
90
|
+
|
|
91
|
+
| 文件 | 职责 |
|
|
92
|
+
|---|---|
|
|
93
|
+
| [`src/index.ts`](src/index.ts) | `SlotTestRuntime` 组装、`TestRoot`、自动 frame、`mount`/`dispose` |
|
|
94
|
+
| [`src/sessions.ts`](src/sessions.ts) + [`src/workspaces.ts`](src/workspaces.ts) | `ISessions`/`IWorkspaces` 测试替身与 `FixtureSession` 行为桩 |
|
|
95
|
+
| [`src/fixtures.ts`](src/fixtures.ts) | 普通 fixture 构造器:会话快照、workspace 列表状态 |
|
|
96
|
+
| [`src/snapshot.ts`](src/snapshot.ts) | DOM 快照序列化器(类名哈希折叠、`<svg>` 指纹) |
|
|
97
|
+
| [`src/remote.ts`](src/remote.ts) | 用于 host RPC 的 `TestRemote` 替身、`RemoteError` 值转出 |
|
|
98
|
+
| [`src/translate.ts`](src/translate.ts) + [`src/locale-env.ts`](src/locale-env.ts) | 翻译与固定浏览器语言测试辅助 |
|
|
99
|
+
| [`src/settings-scope.ts`](src/settings-scope.ts) | 带测试驱动发布与写入 spy 的 `stubSettingsScope` |
|
|
100
|
+
| — | 不发布运行时不变式伴生入口;所挂载的生产包拥有各自的不变式。 |
|
|
101
|
+
|
|
102
|
+
### 生命周期
|
|
103
|
+
|
|
104
|
+
`create()` 构建全新上下文,挂载 slot 与会话注册表,安装渲染器,并提供 session/workspace 替身和明确失败的文件上传替身。`mount` 在启动 fiber 前对照上下文检查每个已声明注入,使缺失提供方自明报错而非永久挂起。`dispose()` 先卸载 React 树,再 dispose feature fiber、释放根注册、dispose 已铸 session scope 并清除持久化 store 状态;每个公共修改器都包裹在 act 中,因此测试无需自行处理 SlotCore 微任务批处理或 React `act`。
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
-----
|
|
109
|
+
|
|
110
|
+
<a id="further-exploration"></a>
|
|
111
|
+
## 进一步探索
|
|
112
|
+
|
|
113
|
+
当包级约定不够用时阅读以下页面。它们从测试台逐步进入它所挂载的生产机制以及使用它的测试。
|
|
114
|
+
|
|
115
|
+
- [ui-session](../../client/ui-session/README.zh.md)——从 Controller 替身派生标准 Slot source 的生产适配器。
|
|
116
|
+
- [UI slots 包](../../client/ui-slots/README.zh.md)——测试台挂载的 `SlotRegistry` 约定。
|
|
117
|
+
- [UI renderer 包](../../client/ui-renderer/README.zh.md)——测试台安装的渲染器。
|
|
118
|
+
- [测试策略](../../../docs/testing.zh.md)——覆盖层级与浏览器快照流水线。
|
|
119
|
+
- [test-support 组地图](../README.zh.md)——兄弟 harness 与支持包。
|
|
120
|
+
|
|
121
|
+
-----
|
|
122
|
+
|
|
123
|
+
<a id="model-experience"></a>
|
|
124
|
+
## 模型体验
|
|
125
|
+
|
|
126
|
+
无;本包是浏览器侧测试基础设施,无一物到达模型请求。
|
|
127
|
+
|
|
128
|
+
#### KV Cache 影响
|
|
129
|
+
|
|
130
|
+
无;本包既不组装也不发送提供方请求。
|
|
131
|
+
|
|
132
|
+
## 已知限制与延期工作
|
|
133
|
+
|
|
134
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
这些限制说明本测试台如何被消费。它们是当前包约束,不是任务积压。
|
|
138
|
+
|
|
139
|
+
- **仅限 Vitest 与 jsdom**——所有消费方都是仓内、面向浏览器的 Vitest 套件。本包不是产品插件,也不是通用 Node 测试框架。
|
|
140
|
+
- **Session、Conversation 与 Chat fixture 保持分离**——`sessionSnapshot` 只包含 Session Controller 状态,`conversationSnapshot` 包含 target-neutral Conversation 状态,`chatSnapshot` 包含 Chat target 状态。组装测试提供 Session event entry,而不是向 `SessionSnapshot` 添加 Conversation 或 Chat 字段。
|
|
141
|
+
|
|
142
|
+
<a id="dev-note"></a>
|
|
143
|
+
### 开发备注
|
|
144
|
+
|
|
145
|
+
<details>
|
|
146
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
147
|
+
|
|
148
|
+
无。
|
|
149
|
+
|
|
150
|
+
</details>
|