Files
WechatExplorer/tests/unit/wcdb-close.test.ts
T
Nanin 34b86af0be perf: 加速语音转写缓存命中
迁移旧版语音转写缓存,并将补迁失败降级为一次性失败状态。

按账号和消息标识优先命中兼容缓存,未命中时才读取音频并计算哈希;导出缓存命中后合并异步刷新知识索引。

补充迁移、缓存快速路径、批量语音读取和导出流程测试。
2026-08-12 20:01:40 +08:00

96 lines
3.3 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import { Wcdb4Client } from '../../src/main/wcdb4-client'
function setPrivate(target: object, key: string, value: unknown): void {
Reflect.set(target, key, value)
}
describe('Wcdb4Client shutdown', () => {
it('waits for tracked Koffi calls before shutting down the native runtime', async () => {
const client = Object.create(Wcdb4Client.prototype) as Wcdb4Client
const shutdown = vi.fn(() => 0)
const inFlight = new Set<Promise<unknown>>()
let finishCall: (() => void) | undefined
const pending = new Promise<void>((resolve) => {
finishCall = resolve
})
inFlight.add(pending)
void pending.then(() => inFlight.delete(pending))
setPrivate(client, 'nativeCallsInFlight', inFlight)
setPrivate(client, 'handle', 1)
setPrivate(client, 'wcdbShutdown', shutdown)
setPrivate(client, 'monitorStarted', false)
setPrivate(client, 'displayNameCache', new Map())
setPrivate(client, 'avatarCache', new Map())
setPrivate(client, 'sessionStatusCache', new Map())
setPrivate(client, 'groupNicknameCache', new Map())
const closing = client.closeAsync(1_000)
expect(shutdown).not.toHaveBeenCalled()
finishCall?.()
await expect(closing).resolves.toBe(true)
if (process.platform === 'win32') {
expect(shutdown).not.toHaveBeenCalled()
} else {
expect(shutdown).toHaveBeenCalledOnce()
}
})
it('restores async batch voice results to request order', async () => {
const client = Object.create(Wcdb4Client.prototype) as Wcdb4Client
setPrivate(client, 'wcdbGetVoiceDataBatch', vi.fn())
setPrivate(
client,
'callJsonAsync',
vi.fn().mockResolvedValue([
{ index: 1, success: false, error: 'missing' },
{ index: 0, Success: true, hex: 'aabb' }
])
)
await expect(
client.getVoiceDataBatch([
{ sessionId: 'a', createTime: 1, localId: 10, candidates: ['a'] },
{ sessionId: 'b', createTime: 2, localId: 20, candidates: ['b'] }
])
).resolves.toEqual([
{ success: true, hex: 'aabb', error: '' },
{ success: false, hex: undefined, error: 'missing' }
])
})
it('uses the async Koffi path for a single voice lookup and releases the result', async () => {
const client = Object.create(Wcdb4Client.prototype) as Wcdb4Client
const nativePointer = { value: 'aabb' }
const freeString = vi.fn()
const nativeFunction = {
async: vi.fn((...args: unknown[]) => {
const outHex = args.at(-2) as [unknown]
const callback = args.at(-1) as (error: unknown, code: number) => void
outHex[0] = nativePointer
queueMicrotask(() => callback(null, 0))
})
}
setPrivate(client, 'wcdbGetVoiceData', nativeFunction)
setPrivate(client, 'wcdbFreeString', freeString)
setPrivate(client, 'handle', 1)
setPrivate(client, 'closing', false)
setPrivate(client, 'nativeCallsInFlight', new Set())
setPrivate(
client,
'decodeHexPtr',
vi.fn(() => 'aabb')
)
await expect(client.getVoiceData('session', 100, ['session'], 10, 20)).resolves.toEqual({
success: true,
hex: 'aabb',
error: ''
})
expect(nativeFunction.async).toHaveBeenCalledOnce()
expect(freeString).toHaveBeenCalledWith(nativePointer)
})
})