Files
SubMiner/src/renderer/modals/subtitle-generation-view.test.ts
T

115 lines
4.0 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
describeGenerationModel,
describeGenerationProgress,
describeGenerationRecommendation,
describeGenerationTools,
describeGenerationVad,
} from './subtitle-generation-view';
test('only confirmed NVIDIA CUDA support recommends turbo', () => {
assert.deepEqual(describeGenerationRecommendation({ kind: 'unavailable' }), {
model: 'small',
text: 'NVIDIA CUDA acceleration was not confirmed. small is recommended.',
});
assert.deepEqual(
describeGenerationRecommendation({ kind: 'nvidia-cuda', gpuName: 'NVIDIA RTX 5070 Ti' }),
{
model: 'large-v3-turbo',
text: 'NVIDIA CUDA is available with NVIDIA RTX 5070 Ti. large-v3-turbo is recommended.',
},
);
});
test('missing tools block generation and list every install instruction', () => {
const found = { kind: 'found', path: '/usr/bin/tool' } as const;
assert.deepEqual(
describeGenerationTools({ ffmpeg: found, ffprobe: found, whisper: found, vad: null }),
{
ready: true,
text: 'whisper.cpp and FFmpeg are installed.',
},
);
assert.deepEqual(
describeGenerationTools({
ffmpeg: { kind: 'missing', message: 'ffmpeg was not found on PATH.' },
ffprobe: found,
whisper: found,
vad: { kind: 'missing', message: 'whisper-vad-speech-segments was not found on PATH.' },
}),
{
ready: false,
text: 'ffmpeg was not found on PATH. whisper-vad-speech-segments was not found on PATH.',
},
);
});
test('only a missing managed model offers a download', () => {
assert.deepEqual(describeGenerationModel({ kind: 'missing', path: '/models/small.bin' }), {
ready: false,
download: true,
text: 'Download a speech model to get started.',
});
for (const kind of ['managed', 'external'] as const) {
const model = describeGenerationModel({ kind, path: '/models/ggml-small.bin' });
assert.equal(model.ready, true);
assert.equal(model.download, false);
}
assert.deepEqual(
describeGenerationModel({
kind: 'invalid',
path: '/missing/model.bin',
message: 'Configured model does not exist.',
}),
{
ready: false,
download: false,
text: 'Configured model does not exist.',
},
);
});
test('generation progress distinguishes measured work from indeterminate stages', () => {
assert.deepEqual(
describeGenerationProgress({ stage: 'transcribe', percent: 42.8, message: 'Transcribing' }),
{
stage: 'Recognizing Japanese speech',
percent: 42.8,
label: '42%',
},
);
assert.deepEqual(describeGenerationProgress({ stage: 'extract', message: 'Extracting audio' }), {
stage: 'Preparing audio',
percent: null,
label: 'Working...',
});
assert.equal(
describeGenerationProgress({ stage: 'download', percent: 0, message: '' }).label,
'0%',
);
assert.equal(
describeGenerationProgress({ stage: 'download', percent: Number.NaN, message: '' }).percent,
null,
);
assert.equal(
describeGenerationProgress({ stage: 'write', percent: 120, message: '' }).percent,
100,
);
});
test('optional speech detection only gates generation when selected', () => {
const missing = { kind: 'missing', path: '/vad.bin' } as const;
assert.equal(describeGenerationVad({ enabled: false, model: missing }).ready, true);
assert.equal(describeGenerationVad({ enabled: false, model: missing }).download, false);
assert.equal(describeGenerationVad({ enabled: true, model: missing }).ready, false);
assert.equal(describeGenerationVad({ enabled: true, model: missing }).download, true);
assert.equal(
describeGenerationVad({ enabled: true, model: { kind: 'managed', path: '/vad.bin' } }).ready,
true,
);
const invalid = { kind: 'invalid', path: '/vad.bin', message: 'Cannot read model' } as const;
assert.equal(describeGenerationVad({ enabled: true, model: invalid }).download, false);
assert.equal(describeGenerationVad({ enabled: false, model: invalid }).ready, true);
});