mirror of
https://github.com/insistence/RuoYi-Vue3-FastAPI.git
synced 2026-10-16 22:51:11 +00:00
feat: 支持 v2 插件、独立前端和签名制品发布 (#130)
* feat: 支持 v2 插件、原生扩展与签名发布 * fix: 修复测试 * feat: 增强宿主 SDK、运行观测与制品维护能力 * feat: 增强文件传输、配置观测与本地开发能力 * feat: 支持 SSE 实时事件流并完善开发脚手架 * feat: 完善长连接鉴权复核与关闭回收 * feat: 增强生命周期与任务关闭可靠性 * feat: 收紧健康检查契约并补齐前端与真实网络验收 * feat: 增加SDK溯源与离线更新工具并验证跨版本兼容 * feat: 增加持久化业务示例与受控 Python 交付 * feat: 增加统一运行诊断与多worker状态观测 * feat: 增加固定目标发布等待与自动验收 * fix: 修复多环境插件部署前缀与代理配置不一致 * fix: 修复测试
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { compileScript, parse } from '@vue/compiler-sfc'
|
||||
import { computed, effectScope, nextTick, reactive, ref, watch } from 'vue'
|
||||
|
||||
const source = readFileSync(
|
||||
new URL('../../src/views/system/plugin/components/PluginConfigStatus.vue', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
const { descriptor } = parse(source)
|
||||
const compiled = compileScript(descriptor, { id: 'config-status-test' })
|
||||
const script = compiled.scriptSetupAst
|
||||
.filter((statement) => statement.type !== 'ImportDeclaration')
|
||||
.map((statement) => descriptor.scriptSetup.content.slice(statement.start, statement.end))
|
||||
.join('\n')
|
||||
const setup = new Function(
|
||||
'computed',
|
||||
'ref',
|
||||
'watch',
|
||||
'onBeforeUnmount',
|
||||
'defineProps',
|
||||
'getPluginConfigStatus',
|
||||
`${script}\nreturn { data, loading, error, refresh, statusText }`
|
||||
)
|
||||
const props = reactive({ pluginId: 'first_plugin', refreshKey: 0 })
|
||||
const calls = []
|
||||
let unmount
|
||||
const scope = effectScope()
|
||||
const state = scope.run(() =>
|
||||
setup(
|
||||
computed,
|
||||
ref,
|
||||
watch,
|
||||
(callback) => {
|
||||
unmount = callback
|
||||
},
|
||||
() => props,
|
||||
(pluginId, signal) =>
|
||||
new Promise((resolve, reject) => {
|
||||
calls.push({ pluginId, signal, resolve, reject })
|
||||
})
|
||||
)
|
||||
)
|
||||
assert.equal(calls[0].pluginId, 'first_plugin')
|
||||
props.pluginId = 'second_plugin'
|
||||
await nextTick()
|
||||
assert.equal(calls[0].signal.aborted, true)
|
||||
calls[1].resolve({ data: { state: 'restart_required', pendingWorkers: 2 } })
|
||||
await nextTick()
|
||||
calls[0].resolve({ data: { state: 'observed_match', matchedWorkers: 1 } })
|
||||
await nextTick()
|
||||
assert.match(state.statusText.value, /2 个已观测进程.*待重启/)
|
||||
|
||||
// 保存成功后主动重查,不用旧状态冒充最新保存版本。
|
||||
props.refreshKey++
|
||||
await nextTick()
|
||||
assert.equal(state.data.value, null)
|
||||
calls[2].resolve({ data: { state: 'observed_match', matchedWorkers: 2 } })
|
||||
await nextTick()
|
||||
assert.match(state.statusText.value, /已观测进程.*匹配/)
|
||||
assert.equal(state.loading.value, false)
|
||||
const failed = state.refresh()
|
||||
calls[3].reject(new Error('unavailable'))
|
||||
await failed
|
||||
assert.equal(state.data.value, null)
|
||||
assert.match(state.error.value, /查询失败/)
|
||||
const retry = state.refresh()
|
||||
calls[4].resolve({ data: { state: 'unobserved' } })
|
||||
await retry
|
||||
assert.match(state.statusText.value, /尚不能确认|尚未观测/)
|
||||
const closing = state.refresh()
|
||||
unmount()
|
||||
scope.stop()
|
||||
assert.equal(calls[5].signal.aborted, true)
|
||||
calls[5].reject(new Error('cancelled'))
|
||||
await closing
|
||||
assert.equal(state.error.value, '')
|
||||
Reference in New Issue
Block a user