@deepseek-ai/dsh-client-test-runtime 0.1.2-alpha.5 → 0.1.3-alpha.2
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/README.i18n.yaml +2 -2
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/lib/index.js +8 -1
- package/lib/types/index.d.ts +11 -1
- package/package.json +30 -30
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/test-support/client-runtime/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 4ab70ecb6db7ae7d1844d8141b34daf7bd19a3dc
|
|
6
|
+
README.zh.md: c3265d7cdcadaf55c0744b13267ac5e64d6b47a6
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
`dsh-client-test-runtime` gives a browser feature spec a real jsdom test bench: it assembles a Cordis context, the renderer-owned slot registry, and the production `UiSession` adapter around typed Session and Workspace Controller doubles. Feature suites exercise declaration, registration, scoping, stores, injection, rendering, updates, and disposal without copying production renderer or adapter logic. Suites publish Session lifecycle state, Workspace state, projection values, and Conversation events through typed fixtures, then use local DOM snapshot roots, scoped Testing Library queries, and fail-loud service checks. It is not part of the product plugin graph (no `dsh.client`); feature packages depend on it in `devDependencies` only.
|
|
12
|
+
`dsh-client-test-runtime` gives a browser feature spec a real jsdom test bench: it assembles a Cordis context, the renderer-owned slot registry, and the production `UiSession` adapter around typed Session and Workspace Controller doubles. A default file-upload stub satisfies features that declare the service and rejects if a test starts an upload without replacing it. Feature suites exercise declaration, registration, scoping, stores, injection, rendering, updates, and disposal without copying production renderer or adapter logic. Suites publish Session lifecycle state, Workspace state, projection values, and Conversation events through typed fixtures, then use local DOM snapshot roots, scoped Testing Library queries, and fail-loud service checks. It is not part of the product plugin graph (no `dsh.client`); feature packages depend on it in `devDependencies` only.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -40,7 +40,7 @@ expect(view.container).toMatchSnapshot()
|
|
|
40
40
|
await runtime.dispose()
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
`mount` prechecks required services and fails loud when one is missing — `provide(name, value)` supplies an extra service first. `storeOf(key, scopeKey)` returns the live store instance the renderer hands a slot's component for identity and action-driven-write assertions.
|
|
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
44
|
|
|
45
45
|
### Local DOM snapshots
|
|
46
46
|
|
|
@@ -101,7 +101,7 @@ The bench copies no production logic: it mounts the production `SlotRegistry`, p
|
|
|
101
101
|
|
|
102
102
|
### Lifecycle
|
|
103
103
|
|
|
104
|
-
`create()` builds a fresh context, mounts the slot and conversation registries, installs the renderer, and provides the session/workspace doubles. `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.
|
|
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
105
|
|
|
106
106
|
</details>
|
|
107
107
|
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,7 @@ kind: "package-library"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
`dsh-client-test-runtime` 让浏览器功能测试拥有真实的 jsdom 测试台:它把 Cordis 上下文、渲染器拥有的 slot 注册表与生产 `UiSession` 适配器组装在带类型的 Session 和 Workspace Controller
|
|
12
|
+
`dsh-client-test-runtime` 让浏览器功能测试拥有真实的 jsdom 测试台:它把 Cordis 上下文、渲染器拥有的 slot 注册表与生产 `UiSession` 适配器组装在带类型的 Session 和 Workspace Controller 替身周围。默认文件上传替身可满足声明该服务的功能;测试若没有替换它却发起上传,就会明确失败。功能套件无需复制生产渲染器或适配器逻辑,即可检验声明、注册、作用域、store、注入、渲染、更新与销毁。套件通过带类型 fixture 发布 Session 生命周期状态、Workspace 状态、projection 值与 Conversation 事件,再使用局部 DOM 快照根、限定范围的 Testing Library 查询与自明的服务缺失检查。它不属于产品插件图(无 `dsh.client`);feature 包仅以 `devDependencies` 依赖之。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -40,7 +40,7 @@ expect(view.container).toMatchSnapshot()
|
|
|
40
40
|
await runtime.dispose()
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
`mount` 会预检必需服务,缺失时自明报错——先用 `provide(name, value)`
|
|
43
|
+
`mount` 会预检必需服务,缺失时自明报错——先用 `provide(name, value)` 提供额外服务。运行时会提供不可用的 `fileUpload` 替身,使装配可以挂载;测试上传行为时,需要在挂载前替换 `runtime.fileUpload.upload`。`storeOf(key, scopeKey)` 返回渲染器交给 slot 组件的实时 store 实例,用于身份与动作驱动写入断言。
|
|
44
44
|
|
|
45
45
|
### 局部 DOM 快照
|
|
46
46
|
|
|
@@ -101,7 +101,7 @@ expect(view.getByRole('alert')).toHaveTextContent('goal/not-found')
|
|
|
101
101
|
|
|
102
102
|
### 生命周期
|
|
103
103
|
|
|
104
|
-
`create()` 构建全新上下文,挂载 slot 与会话注册表,安装渲染器,并提供 session/workspace
|
|
104
|
+
`create()` 构建全新上下文,挂载 slot 与会话注册表,安装渲染器,并提供 session/workspace 替身和明确失败的文件上传替身。`mount` 在启动 fiber 前对照上下文检查每个已声明注入,使缺失提供方自明报错而非永久挂起。`dispose()` 先卸载 React 树,再 dispose feature fiber、释放根注册、dispose 已铸 session scope 并清除持久化 store 状态;每个公共修改器都包裹在 act 中,因此测试无需自行处理 SlotCore 微任务批处理或 React `act`。
|
|
105
105
|
|
|
106
106
|
</details>
|
|
107
107
|
|
package/lib/index.js
CHANGED
|
@@ -1064,7 +1064,7 @@ function usePinnedBrowserLanguages(primary, ...rest) {
|
|
|
1064
1064
|
/**
|
|
1065
1065
|
* jsdom slot test runtime: a real small runtime — Cordis `Context`, the
|
|
1066
1066
|
* renderer-owned `SlotRegistry`, the `ui-session` adapter, and the UI renderer — assembled around
|
|
1067
|
-
* test-owned session/workspace doubles, so feature specs exercise
|
|
1067
|
+
* test-owned session/workspace doubles and a fail-loud file-upload stub, so feature specs exercise
|
|
1068
1068
|
* declaration, registration, scope, store, inject, rendering, updates, and
|
|
1069
1069
|
* disposal without hand-building the machinery per suite.
|
|
1070
1070
|
*
|
|
@@ -1182,6 +1182,8 @@ var SlotTestRuntime = class SlotTestRuntime {
|
|
|
1182
1182
|
sessions;
|
|
1183
1183
|
/** Workspaces double (list observable, recorded intent actions). */
|
|
1184
1184
|
workspaces;
|
|
1185
|
+
/** Mutable file-upload stub; replace `upload` in suites that exercise the capability. */
|
|
1186
|
+
fileUpload;
|
|
1185
1187
|
stabilizer = async (fn) => {
|
|
1186
1188
|
await act(async () => {
|
|
1187
1189
|
await fn();
|
|
@@ -1202,8 +1204,13 @@ var SlotTestRuntime = class SlotTestRuntime {
|
|
|
1202
1204
|
this.root = new TestRoot(slots, this.stabilizer);
|
|
1203
1205
|
this.sessions = new TestSessions(this.stabilizer, ctx);
|
|
1204
1206
|
this.workspaces = new TestWorkspaces(this.stabilizer);
|
|
1207
|
+
this.fileUpload = {
|
|
1208
|
+
available: false,
|
|
1209
|
+
upload: () => Promise.reject(/* @__PURE__ */ new Error("client test runtime: file upload is not stubbed"))
|
|
1210
|
+
};
|
|
1205
1211
|
ctx.provide("sessions", this.sessions);
|
|
1206
1212
|
ctx.provide("workspaces", this.workspaces);
|
|
1213
|
+
ctx.provide("fileUpload", this.fileUpload);
|
|
1207
1214
|
this.disposeWorkspaceSource = slots.provideRoot({ hooks: { workspaces: this.workspaces.list } });
|
|
1208
1215
|
const renderer = createSlotRenderer();
|
|
1209
1216
|
slots.install({ renderRoot: (host, ownerProps) => {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* jsdom slot test runtime: a real small runtime — Cordis `Context`, the
|
|
3
3
|
* renderer-owned `SlotRegistry`, the `ui-session` adapter, and the UI renderer — assembled around
|
|
4
|
-
* test-owned session/workspace doubles, so feature specs exercise
|
|
4
|
+
* test-owned session/workspace doubles and a fail-loud file-upload stub, so feature specs exercise
|
|
5
5
|
* declaration, registration, scope, store, inject, rendering, updates, and
|
|
6
6
|
* disposal without hand-building the machinery per suite.
|
|
7
7
|
*
|
|
@@ -16,6 +16,7 @@ import type { RenderResult } from '@testing-library/react';
|
|
|
16
16
|
import type { queries } from '@testing-library/dom';
|
|
17
17
|
import type { BoundFunctions } from '@testing-library/dom';
|
|
18
18
|
import { SlotRegistry } from '@deepseek-ai/dsh-client-ui-renderer/client';
|
|
19
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
19
20
|
import type { ChildrenDecl, ComposedProps, HostObservable, OwnerOf, SlotComponent, SlotMap, SlotRenderer, SnapshotSelectorHook, StoreInstanceLike } from '@deepseek-ai/dsh-client-ui-slots';
|
|
20
21
|
import { TestSessions } from './sessions.ts';
|
|
21
22
|
import { TestWorkspaces } from './workspaces.ts';
|
|
@@ -77,6 +78,13 @@ export interface FeatureHandle {
|
|
|
77
78
|
*/
|
|
78
79
|
dispose(): Promise<void>;
|
|
79
80
|
}
|
|
81
|
+
/** Mutable fail-loud file-upload stub installed by {@link SlotTestRuntime}. */
|
|
82
|
+
export interface TestFileUpload {
|
|
83
|
+
/** Availability reported to the feature under test. */
|
|
84
|
+
available: boolean;
|
|
85
|
+
/** Test-supplied upload behavior; the default rejects every call. */
|
|
86
|
+
upload: (sessionId: SessionId, ...args: unknown[]) => Promise<unknown>;
|
|
87
|
+
}
|
|
80
88
|
/**
|
|
81
89
|
* The test-owned 'root' occupant: declares the child slots a suite needs
|
|
82
90
|
* through the REAL `slots.register`, with a caller-supplied minimal frame —
|
|
@@ -120,6 +128,8 @@ export declare class SlotTestRuntime {
|
|
|
120
128
|
readonly sessions: TestSessions;
|
|
121
129
|
/** Workspaces double (list observable, recorded intent actions). */
|
|
122
130
|
readonly workspaces: TestWorkspaces;
|
|
131
|
+
/** Mutable file-upload stub; replace `upload` in suites that exercise the capability. */
|
|
132
|
+
readonly fileUpload: TestFileUpload;
|
|
123
133
|
private readonly stabilizer;
|
|
124
134
|
private host;
|
|
125
135
|
private readonly views;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-test-runtime",
|
|
3
3
|
"description": "jsdom slot test runtime: real Cordis Context + SlotRegistry + UI renderer with test-owned session/workspace doubles for feature specs",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -30,42 +30,42 @@
|
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"react": "^18.2.0",
|
|
32
32
|
"react-dom": "^18.2.0",
|
|
33
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.1.
|
|
34
|
-
"@deepseek-ai/dsh-
|
|
35
|
-
"@deepseek-ai/dsh-
|
|
36
|
-
"@deepseek-ai/dsh-client-
|
|
37
|
-
"@deepseek-ai/dsh-client-
|
|
38
|
-
"@deepseek-ai/dsh-client-ui-
|
|
39
|
-
"@deepseek-ai/dsh-client-ui-
|
|
40
|
-
"@deepseek-ai/dsh-client-ui-
|
|
41
|
-
"@deepseek-ai/dsh-client-ui-
|
|
42
|
-
"@deepseek-ai/dsh-client-ui-
|
|
43
|
-
"@deepseek-ai/dsh-
|
|
44
|
-
"@deepseek-ai/dsh-
|
|
45
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.5",
|
|
33
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.3-alpha.2",
|
|
34
|
+
"@deepseek-ai/dsh-attachment": "^0.1.3-alpha.2",
|
|
35
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.3-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-client-store": "^0.1.3-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.3-alpha.2",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.3-alpha.2",
|
|
39
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.3-alpha.2",
|
|
40
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.3-alpha.2",
|
|
41
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.3-alpha.2",
|
|
42
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-subagent": "^0.1.3-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
46
45
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
47
|
-
"@deepseek-ai/dsh-
|
|
46
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
|
|
47
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.3-alpha.2"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/react": "~18.3.1",
|
|
51
51
|
"@types/react-dom": "~18.3.0",
|
|
52
52
|
"react": "^18.2.0",
|
|
53
53
|
"react-dom": "^18.2.0",
|
|
54
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.1.
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-client-
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-chat": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-
|
|
62
|
-
"@deepseek-ai/dsh-client-
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.
|
|
64
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/dsh-
|
|
67
|
-
"@deepseek-ai/
|
|
68
|
-
"@deepseek-ai/
|
|
54
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.3-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.3-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-attachment": "^0.1.3-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.3-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-store": "^0.1.3-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.3-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.3-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.3-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.3-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.3-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-subagent": "^0.1.3-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
|
|
68
|
+
"@deepseek-ai/cordis": "^4.0.2"
|
|
69
69
|
},
|
|
70
70
|
"files": [
|
|
71
71
|
"lib/index.js",
|