test(core): golden test-01 end-to-end capture → queue → note

Refs #1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-09-27 16:54:51 +04:00
parent 88ef2bde24
commit 1b23554658
2 changed files with 67 additions and 0 deletions

11
tests/fixtures/test-01.note.md vendored Normal file
View File

@ -0,0 +1,11 @@
---
voice-id: "20260927-111503-0000"
voice-status: "inserted"
voice-device: "test-device"
voice-audio: "[[voice/source/20260927-111503-0000.m4a]]"
voice-mime: "audio/mp4"
voice-attempts: 0
---
![[voice/source/20260927-111503-0000.m4a]]
Это тестовая запись для проверки распознавания речи с помощью модели WHISPER, для сравнения между двух конкретных моделей.

56
tests/golden.test.ts Normal file
View File

@ -0,0 +1,56 @@
import { existsSync, readdirSync, readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { saveCapture } from '../src/core/capture';
import { QueueRunner } from '../src/core/queue';
import { MemoryNotes, MemoryRecordings, ScriptedTranscriber, TestEnv } from './fakes';
const FIXTURES = fileURLToPath(new URL('./fixtures/', import.meta.url));
const MIME: Record<string, string> = { m4a: 'audio/mp4', webm: 'audio/webm', ogg: 'audio/ogg' };
const cases = readdirSync(FIXTURES)
.filter((f) => f.endsWith('.note.md'))
.map((f) => f.slice(0, -'.note.md'.length));
function audioFor(name: string): { file: string; mime: string } {
for (const ext of Object.keys(MIME)) {
const file = `${FIXTURES}${name}.${ext}`;
if (existsSync(file)) return { file, mime: MIME[ext] };
}
throw new Error(`нет аудиофикстуры tests/fixtures/${name}.m4a (или .webm/.ogg) для эталона ${name}.note.md`);
}
function toArrayBuffer(buf: Buffer): ArrayBuffer {
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer;
}
describe('golden', () => {
it('has at least one case', () => {
expect(cases.length).toBeGreaterThan(0);
});
for (const name of cases) {
it(name, async () => {
const { file, mime } = audioFor(name);
const audio = toArrayBuffer(readFileSync(file));
const transcript = readFileSync(`${FIXTURES}${name}.txt`, 'utf8');
const expected = readFileSync(`${FIXTURES}${name}.note.md`, 'utf8');
const env = new TestEnv();
const notes = new MemoryNotes();
const recordings = new MemoryRecordings();
const transcriber = new ScriptedTranscriber([{ ok: true, text: transcript }]);
const path = await saveCapture(
{ recordings, notes, env },
{ chunks: [audio], mime, startedAt: env.now(), endedAt: new Date(env.now().getTime() + 47_000), interrupted: false },
);
await new QueueRunner({ recordings, notes, transcriber, env }).tick();
expect(path).toBe('voice/inbox/2026-09-27 14-15-03.md');
expect(transcriber.calls).toHaveLength(1);
expect(transcriber.calls[0].mime).toBe(mime);
expect(Buffer.from(transcriber.calls[0].audio).equals(Buffer.from(audio))).toBe(true);
expect(notes.files.get(path!)).toBe(expected);
});
}
});