@deepseek-ai/dsh-client-test-runtime 0.1.2-rc.1 → 0.1.5-alpha.1
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: 616eab2cd5ef03ae4e514ca335b0c60b43d62cf0
|
|
6
|
+
README.zh.md: 08effcef7eaacad67b5496507925337e772d4ce9
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
`dsh-client-test-runtime`
|
|
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
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`
|
|
12
|
+
`dsh-client-test-runtime` 让浏览器功能测试在 jsdom 中检验生产 slot、store、渲染、更新与销毁行为,而无需重实现 UI 运行时。测试作者可以发布带类型的 Session、Workspace、projection 与 Conversation fixture,查询 slot 局部 DOM 根,并脚本化 Remote 应答或失败。缺失服务、未打桩的会话行为与意外文件上传都会在调用点失败,销毁则保持幂等。仅限仓内、面向浏览器的 Vitest 套件通过 `devDependencies` 使用本包;它不是产品插件或通用 Node 测试框架。
|
|
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.5-alpha.1",
|
|
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-api-workspace-controller": "^0.1.
|
|
35
|
-
"@deepseek-ai/dsh-attachment": "^0.1.
|
|
36
|
-
"@deepseek-ai/dsh-client-connection": "^0.1.
|
|
37
|
-
"@deepseek-ai/dsh-client-
|
|
38
|
-
"@deepseek-ai/dsh-client-ui-
|
|
39
|
-
"@deepseek-ai/dsh-client-
|
|
40
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.
|
|
41
|
-
"@deepseek-ai/dsh-client-ui-session": "^0.1.
|
|
42
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.
|
|
43
|
-
"@deepseek-ai/dsh-
|
|
44
|
-
"@deepseek-ai/dsh-
|
|
45
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.1.
|
|
33
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.5-alpha.1",
|
|
34
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.5-alpha.1",
|
|
35
|
+
"@deepseek-ai/dsh-attachment": "^0.1.5-alpha.1",
|
|
36
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.1",
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.5-alpha.1",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-alpha.1",
|
|
39
|
+
"@deepseek-ai/dsh-client-store": "^0.1.5-alpha.1",
|
|
40
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.1",
|
|
41
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.5-alpha.1",
|
|
42
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.5-alpha.1",
|
|
43
|
+
"@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
|
|
44
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.1",
|
|
45
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.1",
|
|
46
46
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
47
|
-
"@deepseek-ai/dsh-
|
|
47
|
+
"@deepseek-ai/dsh-subagent": "^0.1.5-alpha.1"
|
|
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-workspace-controller": "^0.1.
|
|
55
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.1.
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-client-connection": "^0.1.
|
|
58
|
-
"@deepseek-ai/dsh-client-
|
|
59
|
-
"@deepseek-ai/dsh-
|
|
60
|
-
"@deepseek-ai/dsh-client-ui-
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/
|
|
67
|
-
"@deepseek-ai/dsh-
|
|
68
|
-
"@deepseek-ai/
|
|
54
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.1.5-alpha.1",
|
|
55
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.5-alpha.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-store": "^0.1.5-alpha.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.1",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.5-alpha.1",
|
|
59
|
+
"@deepseek-ai/dsh-attachment": "^0.1.5-alpha.1",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.5-alpha.1",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.5-alpha.1",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.1",
|
|
64
|
+
"@deepseek-ai/dsh-subagent": "^0.1.5-alpha.1",
|
|
65
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.1",
|
|
66
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
67
|
+
"@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-alpha.1"
|
|
69
69
|
},
|
|
70
70
|
"files": [
|
|
71
71
|
"lib/index.js",
|