This commit is contained in:
2026-10-18 19:17:40 +07:00
parent 9542330125
commit c10ed2db01
10 changed files with 283 additions and 9 deletions
+79
View File
@@ -0,0 +1,79 @@
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { AudioOutput } from './audio-output.js'
import { parseWindowPreferences } from './window-settings.js'
const devices = [{ id: 'hdmi', label: 'HDMI' }, { id: 'usb', label: 'USB' }]
test('выбор сохраняется, применяется до запуска проигрывания и проверяет устройство', async () => {
const applied: string[] = []
const saved: string[] = []
const output = new AudioOutput('', async () => devices, async (id) => { applied.push(id) }, (id) => { saved.push(id) })
await output.refresh()
await output.select('hdmi')
await output.prepare(async (id) => { applied.push(`prepare:${id}`) })
assert.deepEqual(applied, ['hdmi', 'prepare:hdmi'])
assert.deepEqual(saved, ['hdmi'])
assert.equal(output.selected, 'hdmi')
await assert.rejects(output.select('missing'), /недоступно/)
await assert.rejects(output.select({ id: 'usb' }), /недоступно/)
assert.equal(output.selected, 'hdmi')
})
test('ошибка переключения или сохранения возвращает прежний выход', async () => {
for (const failure of ['apply', 'save']) {
const applied: string[] = []
const output = new AudioOutput('hdmi', async () => devices, async (id) => {
applied.push(id)
if (id === 'usb' && failure === 'apply') throw new Error('switch failed')
}, () => { if (failure === 'save') throw new Error('save failed') })
await output.refresh()
await assert.rejects(output.select('usb'), /failed/)
assert.equal(output.selected, 'hdmi')
assert.deepEqual(applied, ['usb', 'hdmi'])
}
})
test('отключение устройства сбрасывает выбор, повторное подключение не меняет его', async () => {
let available = devices
const saved: string[] = []
const output = new AudioOutput('hdmi', async () => available, async () => {}, (id) => { saved.push(id) })
await output.refresh()
assert.equal(output.selected, 'hdmi')
available = []
await output.refresh()
assert.equal(output.selected, '')
assert.match(output.notice, /отключено/)
assert.deepEqual(saved, [''])
available = devices
await output.refresh()
assert.equal(output.selected, '')
await output.select('usb')
assert.equal(output.notice, '')
})
test('быстрые переключения и подготовка нового окна выполняются по порядку', async () => {
const calls: string[] = []
let release: () => void = () => {}
const held = new Promise<void>((resolve) => { release = resolve })
const output = new AudioOutput('', async () => devices, async (id) => {
calls.push(id)
if (id === 'hdmi') await held
}, () => {})
await output.refresh()
const first = output.select('hdmi')
const second = output.select('usb')
const prepare = output.prepare(async (id) => { calls.push(`prepare:${id}`) })
await Promise.resolve()
assert.deepEqual(calls, ['hdmi'])
release()
await Promise.all([first, second, prepare])
assert.deepEqual(calls, ['hdmi', 'usb', 'prepare:usb'])
})
test('старые настройки совместимы, выбранный аудиовыход читается и валидируется', () => {
const old = { version: 1, control: null, display: null }
assert.equal(parseWindowPreferences(old).audioOutput, undefined)
assert.equal(parseWindowPreferences({ ...old, audioOutput: 'hdmi' }).audioOutput, 'hdmi')
assert.throws(() => parseWindowPreferences({ ...old, audioOutput: 123 }))
assert.throws(() => parseWindowPreferences({ ...old, audioOutput: 'a'.repeat(1025) }))
})