Thanks for the great contribution @glifocat! This is a really well-structured skill — clean package, thorough docs, and solid test coverage. Hope to see more skills like this from you!
116 lines
3.8 KiB
TypeScript
116 lines
3.8 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
describe('use-local-whisper skill package', () => {
|
|
const skillDir = path.resolve(__dirname, '..');
|
|
|
|
it('has a valid manifest', () => {
|
|
const manifestPath = path.join(skillDir, 'manifest.yaml');
|
|
expect(fs.existsSync(manifestPath)).toBe(true);
|
|
|
|
const content = fs.readFileSync(manifestPath, 'utf-8');
|
|
expect(content).toContain('skill: use-local-whisper');
|
|
expect(content).toContain('version: 1.0.0');
|
|
expect(content).toContain('src/transcription.ts');
|
|
expect(content).toContain('voice-transcription');
|
|
});
|
|
|
|
it('declares voice-transcription as a dependency', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'manifest.yaml'),
|
|
'utf-8',
|
|
);
|
|
expect(content).toContain('depends:');
|
|
expect(content).toContain('voice-transcription');
|
|
});
|
|
|
|
it('has no structured operations (no new npm deps needed)', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'manifest.yaml'),
|
|
'utf-8',
|
|
);
|
|
expect(content).toContain('structured: {}');
|
|
});
|
|
|
|
it('has the modified transcription file', () => {
|
|
const filePath = path.join(skillDir, 'modify', 'src', 'transcription.ts');
|
|
expect(fs.existsSync(filePath)).toBe(true);
|
|
});
|
|
|
|
it('has an intent file for the modified file', () => {
|
|
const intentPath = path.join(skillDir, 'modify', 'src', 'transcription.ts.intent.md');
|
|
expect(fs.existsSync(intentPath)).toBe(true);
|
|
|
|
const content = fs.readFileSync(intentPath, 'utf-8');
|
|
expect(content).toContain('whisper.cpp');
|
|
expect(content).toContain('transcribeAudioMessage');
|
|
expect(content).toContain('isVoiceMessage');
|
|
expect(content).toContain('Invariants');
|
|
});
|
|
|
|
it('uses whisper-cli (not OpenAI) for transcription', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'modify', 'src', 'transcription.ts'),
|
|
'utf-8',
|
|
);
|
|
|
|
// Uses local whisper.cpp CLI
|
|
expect(content).toContain('whisper-cli');
|
|
expect(content).toContain('execFileAsync');
|
|
expect(content).toContain('WHISPER_BIN');
|
|
expect(content).toContain('WHISPER_MODEL');
|
|
expect(content).toContain('ggml-base.bin');
|
|
|
|
// Does NOT use OpenAI
|
|
expect(content).not.toContain('openai');
|
|
expect(content).not.toContain('OpenAI');
|
|
expect(content).not.toContain('OPENAI_API_KEY');
|
|
expect(content).not.toContain('readEnvFile');
|
|
});
|
|
|
|
it('preserves the public API (transcribeAudioMessage and isVoiceMessage)', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'modify', 'src', 'transcription.ts'),
|
|
'utf-8',
|
|
);
|
|
|
|
expect(content).toContain('export async function transcribeAudioMessage(');
|
|
expect(content).toContain('msg: WAMessage');
|
|
expect(content).toContain('sock: WASocket');
|
|
expect(content).toContain('Promise<string | null>');
|
|
expect(content).toContain('export function isVoiceMessage(');
|
|
expect(content).toContain('downloadMediaMessage');
|
|
});
|
|
|
|
it('preserves fallback message strings', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'modify', 'src', 'transcription.ts'),
|
|
'utf-8',
|
|
);
|
|
|
|
expect(content).toContain('[Voice Message - transcription unavailable]');
|
|
});
|
|
|
|
it('includes ffmpeg conversion step', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'modify', 'src', 'transcription.ts'),
|
|
'utf-8',
|
|
);
|
|
|
|
expect(content).toContain('ffmpeg');
|
|
expect(content).toContain("'-ar', '16000'");
|
|
expect(content).toContain("'-ac', '1'");
|
|
});
|
|
|
|
it('cleans up temp files in finally block', () => {
|
|
const content = fs.readFileSync(
|
|
path.join(skillDir, 'modify', 'src', 'transcription.ts'),
|
|
'utf-8',
|
|
);
|
|
|
|
expect(content).toContain('finally');
|
|
expect(content).toContain('unlinkSync');
|
|
});
|
|
});
|