94a0c287e0
- 新增 shared/utils/update-progress.ts:进度事件解析/百分比钳制/文案格式化(纯函数) - 新增 shared/components/UpdateProgressBar.vue:两页共用,失败态琥珀色并停在断点 百分比、总大小未知走不确定态 - useVersionUpdate:先挂监听再发桥调用(避免丢首帧),监听 pywebview-update-progress (Python 侧 evaluate_js 推送,同 pywebview-download-progress 约定);失败保留上次进度 - 测试:tests/update-progress.test.ts(8 用例) 兼容:老客户端没有该事件源,进度条不出现,其余行为不变(优雅降级)。 注:本仓库 modules-withdraw / modules-image-video 有 3 个既存失败用例(隔离复现), 与本次改动无关;全仓库仅新增测试引用本次新增模块。
121 lines
4.4 KiB
TypeScript
121 lines
4.4 KiB
TypeScript
import { test } from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
|
||
import {
|
||
formatBytes,
|
||
formatUpdateProgressText,
|
||
normalizeUpdateProgress,
|
||
updateProgressPercent,
|
||
type UpdateProgress,
|
||
} from '../src/shared/utils/update-progress.ts'
|
||
|
||
function progressOf(partial: Partial<UpdateProgress>): UpdateProgress {
|
||
return {
|
||
status: 'downloading',
|
||
message: '',
|
||
downloaded: 0,
|
||
total: 0,
|
||
percent: -1,
|
||
...partial,
|
||
}
|
||
}
|
||
|
||
test('更新进度:正常进度帧解析出字节数与百分比', () => {
|
||
const progress = normalizeUpdateProgress({
|
||
status: 'downloading',
|
||
message: '正在下载更新包...',
|
||
downloaded: 62914560,
|
||
total: 104857600,
|
||
percent: 60,
|
||
error: '',
|
||
})
|
||
assert.ok(progress, '合法事件必须解析成功')
|
||
assert.equal(progress.status, 'downloading')
|
||
assert.equal(progress.downloaded, 62914560)
|
||
assert.equal(progress.total, 104857600)
|
||
assert.equal(progress.percent, 60)
|
||
assert.equal(updateProgressPercent(progress), 60)
|
||
})
|
||
|
||
test('更新进度:状态缺失或非法的事件必须丢弃(不得把进度打回初始态)', () => {
|
||
assert.equal(normalizeUpdateProgress(null), null)
|
||
assert.equal(normalizeUpdateProgress(undefined), null)
|
||
assert.equal(normalizeUpdateProgress({}), null)
|
||
assert.equal(normalizeUpdateProgress({ downloaded: 100 }), null)
|
||
assert.equal(normalizeUpdateProgress({ status: 'unknown-stage' }), null)
|
||
assert.equal(normalizeUpdateProgress('downloading'), null)
|
||
})
|
||
|
||
test('更新进度:缺字段的脏事件按 0 字节/未知总大小兜底,不产生 NaN', () => {
|
||
const progress = normalizeUpdateProgress({ status: 'failed', message: '下载失败' })
|
||
assert.ok(progress)
|
||
assert.equal(progress.downloaded, 0)
|
||
assert.equal(progress.total, 0)
|
||
assert.equal(progress.percent, -1, '缺百分比按未知处理')
|
||
assert.equal(updateProgressPercent(progress), -1, '未知总大小走不确定态')
|
||
assert.equal(Number.isNaN(progress.downloaded), false)
|
||
})
|
||
|
||
test('更新进度:百分比越界钳制到 0-100,负值视为不确定态', () => {
|
||
assert.equal(updateProgressPercent(progressOf({ percent: 120 })), 100)
|
||
assert.equal(updateProgressPercent(progressOf({ percent: -5 })), -1)
|
||
assert.equal(updateProgressPercent(progressOf({ percent: 99.6 })), 100, '四舍五入取整')
|
||
assert.equal(updateProgressPercent(null), -1)
|
||
})
|
||
|
||
test('更新进度文案:下载中显示百分比与已下载/总大小', () => {
|
||
const text = formatUpdateProgressText(progressOf({
|
||
downloaded: 62914560,
|
||
total: 104857600,
|
||
percent: 60,
|
||
}))
|
||
assert.equal(text, '正在下载更新包 60%(60.0 MB/100.0 MB)')
|
||
})
|
||
|
||
test('更新进度文案:总大小未知时显示已下载量,刚开始时退回阶段文案', () => {
|
||
assert.equal(
|
||
formatUpdateProgressText(progressOf({ downloaded: 3145728, percent: -1 })),
|
||
'正在下载更新包(已下载 3.0 MB)',
|
||
)
|
||
assert.equal(
|
||
formatUpdateProgressText(progressOf({ message: '正在准备下载更新包...' })),
|
||
'正在准备下载更新包...',
|
||
)
|
||
})
|
||
|
||
test('更新进度文案:校验中/已就绪/失败直接用 Python 侧说明(失败停在断点处)', () => {
|
||
assert.equal(
|
||
formatUpdateProgressText(progressOf({
|
||
status: 'verifying',
|
||
message: '安装包下载完成,正在校验完整性...',
|
||
})),
|
||
'安装包下载完成,正在校验完整性...',
|
||
)
|
||
assert.equal(
|
||
formatUpdateProgressText(progressOf({
|
||
status: 'ready',
|
||
message: '安装包已就绪,正在启动更新程序,程序即将退出...',
|
||
percent: 100,
|
||
})),
|
||
'安装包已就绪,正在启动更新程序,程序即将退出...',
|
||
)
|
||
const failed = progressOf({
|
||
status: 'failed',
|
||
message: '下载中断(65536/307510 字节),断点已保留,请重试续传',
|
||
downloaded: 65536,
|
||
total: 307510,
|
||
percent: 21.3,
|
||
})
|
||
assert.equal(formatUpdateProgressText(failed), '下载中断(65536/307510 字节),断点已保留,请重试续传')
|
||
assert.equal(updateProgressPercent(failed), 21, '失败时进度条停在断点百分比')
|
||
assert.equal(formatUpdateProgressText(null), '')
|
||
})
|
||
|
||
test('更新进度文案:字节数格式化覆盖 KB/MB 与异常输入', () => {
|
||
assert.equal(formatBytes(0), '0 MB')
|
||
assert.equal(formatBytes(-1), '0 MB')
|
||
assert.equal(formatBytes(Number.NaN), '0 MB')
|
||
assert.equal(formatBytes(512 * 1024), '512 KB')
|
||
assert.equal(formatBytes(3 * 1024 * 1024), '3.0 MB')
|
||
})
|