refactor(desktop): session-scoped voice runtime, STT/LLM ports, caption ownership and meeting export fixes
This commit is contained in:
parent
0adedf5e7b
commit
83cf9133ac
39 changed files with 4787 additions and 1061 deletions
72
apps/desktop/tests/main/shutdown-registry.test.ts
Normal file
72
apps/desktop/tests/main/shutdown-registry.test.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// tests/main/shutdown-registry.test.ts
|
||||
// 종료 등록부 — 역순 정리, 멱등, 멈춘 항목이 종료를 막지 않음.
|
||||
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { ShutdownRegistry } from '../../src/main/shutdown-registry'
|
||||
|
||||
describe('ShutdownRegistry', () => {
|
||||
it('등록의 역순으로 정리한다', async () => {
|
||||
const order: string[] = []
|
||||
const registry = new ShutdownRegistry()
|
||||
registry.register({ name: 'a', dispose: () => { order.push('a') } })
|
||||
registry.register({ name: 'b', dispose: async () => { order.push('b') } })
|
||||
registry.register({ name: 'c', dispose: () => { order.push('c') } })
|
||||
|
||||
const report = await registry.disposeAll(1000)
|
||||
expect(order).toEqual(['c', 'b', 'a'])
|
||||
expect(report.completed).toEqual(['c', 'b', 'a'])
|
||||
})
|
||||
|
||||
it('여러 번 불러도 한 번만 정리한다', async () => {
|
||||
const dispose = vi.fn()
|
||||
const registry = new ShutdownRegistry()
|
||||
registry.register({ name: 'x', dispose })
|
||||
await Promise.all([registry.disposeAll(1000), registry.disposeAll(1000)])
|
||||
await registry.disposeAll(1000)
|
||||
expect(dispose).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('실패한 항목은 기록하고 나머지를 계속 정리한다', async () => {
|
||||
const onError = vi.fn()
|
||||
const later = vi.fn()
|
||||
const registry = new ShutdownRegistry({ onError })
|
||||
registry.register({ name: 'later', dispose: later })
|
||||
registry.register({ name: 'throws', dispose: () => { throw new Error('sync boom') } })
|
||||
registry.register({ name: 'rejects', dispose: async () => { throw new Error('async boom') } })
|
||||
|
||||
const report = await registry.disposeAll(1000)
|
||||
expect(report.failed).toEqual(['rejects', 'throws'])
|
||||
expect(report.completed).toEqual(['later'])
|
||||
expect(later).toHaveBeenCalledTimes(1)
|
||||
expect(onError).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('멈춘 항목이 있어도 상한 시간 안에 끝나고, 남은 항목의 dispose 는 걸어 둔다', async () => {
|
||||
vi.useFakeTimers()
|
||||
try {
|
||||
const last = vi.fn()
|
||||
const registry = new ShutdownRegistry()
|
||||
registry.register({ name: 'last', dispose: last })
|
||||
registry.register({ name: 'hangs', dispose: () => new Promise<void>(() => undefined) })
|
||||
|
||||
const running = registry.disposeAll(500)
|
||||
await vi.advanceTimersByTimeAsync(501)
|
||||
const report = await running
|
||||
|
||||
expect(report.timedOut).toEqual(['hangs', 'last'])
|
||||
// 기다리진 않지만 동기 구간(프로세스 kill 등)은 실행된다
|
||||
expect(last).toHaveBeenCalledTimes(1)
|
||||
} finally {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('등록 취소한 항목은 정리하지 않는다', async () => {
|
||||
const dispose = vi.fn()
|
||||
const registry = new ShutdownRegistry()
|
||||
const unregister = registry.register({ name: 'x', dispose })
|
||||
unregister()
|
||||
await registry.disposeAll(1000)
|
||||
expect(dispose).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue