Skip to main content
Browse the docs

The developer docs are currently available in Chinese only. The SDK, the CLI and every code sample work the same in any language.

Chapter 10

测试

@uniflow/plugin-sdk/testing 迷你宿主

@uniflow/plugin-sdk/testing 的 createTestHost 是一个内存里的迷你宿主:你的插件代码经与应用相同的运行时与消息协议执行 (结构化复制、错误还原、调用结束后能力作废都一样),宿主一侧按应用的规则实现:参数按 schema 校验、权限裁剪、read 模式只读、 模型来源的写命令先 describe 再确认、撤销栈、日历只能改自己的事件、存储的名字规则与 64KB 上限。

TypeScript
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { createTestHost } from '@uniflow/plugin-sdk/testing'
import plugin from '../src/main'
import pluginJson from '../plugin.json'
import en from '../locales/en.json'

test('snooze 可以撤销', async () => {
  const host = createTestHost({
    pluginJson, definition: plugin, locales: { en },
    courses: [{ id: 'c1', name: 'Biology', code: 'BIO 101' }],
    assignments: [/* PluginAssignment */],
    events: [/* 用户自己的日历事件 */],
    fetch: { 'https://api.example.com/x': 'body' },      // network 权限的假下载
    openFile: () => ({ name: 'a.csv', text: 'q,a' }),    // files.open 的假对话框
    confirm: (description) => true,                     // 模型来源写命令的确认
  })
  const r = await host.run('snooze', { assignmentId: 'a1' }, { source: 'agent' })
  assert.equal(r.ok, true)
  assert.deepEqual(host.confirmations, ['把「Lab 3」隐藏到 …'])
  assert.equal((await host.undo()).ok, true)
  assert.deepEqual(host.storage(), { snoozed: {} })
})
host 上的 说明
run(action, args, { source }) source: 'ui'(默认,界面)/ 'agent'(模型:写命令先确认、agentVisible:false 的命令调不到)
undo() 撤销最近一次可撤销的写命令
storage() / deviceStorage() 存储的快照 { 集合: { id: data } }
events() 日历事件快照
confirmations / saved / panels 确认卡片文字 / files.save 写了什么 / openPanel 的参数
setLocale(lang)、t 切换语言、取文案

测什么:每个命令至少覆盖正常路径、参数错误、前置条件错误(describe 里就拒绝)、撤销;纯计算逻辑抽成纯函数单独测 (模板里的 src/sessions.ts、src/due.ts)。迷你宿主是应用的忠实缩影但不是应用本身:发布前在应用里(开发者模式)走一遍。