80 lines
3.7 KiB
TypeScript
80 lines
3.7 KiB
TypeScript
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) }))
|
|
})
|