Files
openswarm/electron/bundledModel.test.js
T

51 lines
2.8 KiB
JavaScript

// Dictation has to work the instant the app opens: press fn, talk, done. The model is 190MB and
// lived only as a runtime download, so a fresh install (or anyone offline, or on slow wifi) pressed
// fn into silence while it fetched. It is now staged into Resources/whisper at build time.
//
// resolveModelFile already prefers a bundled model over userData, so these pin the two halves that
// can silently drift: the build must stage it, and the resolver must look for the one we staged.
const test = require('node:test');
const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const SH = path.join(__dirname, 'scripts', 'build-whisper.sh');
const MODELS = require('./voice/whisperModels.js');
test('the build stages the DEFAULT model, the same one the resolver looks for', () => {
const sh = fs.readFileSync(SH, 'utf-8');
const wanted = MODELS.modelById(MODELS.DEFAULT_MODEL_ID).file;
assert.ok(sh.includes(wanted),
`build-whisper.sh must stage ${wanted}; the resolver checks resourceDir for exactly that name`);
});
test('a corrupt model is refused at build time rather than shipped', () => {
const sh = fs.readFileSync(SH, 'utf-8');
const expected = MODELS.modelById(MODELS.DEFAULT_MODEL_ID).sha256;
assert.ok(sh.includes(expected), 'the staged checksum must match the catalog');
assert.ok(sh.includes('checksum mismatch') && sh.includes('exit 1'),
'a truncated model ships silently and dies at the first press, so it must fail the build');
});
test('a build without the model FETCHES it rather than warning', () => {
// This used to assert only that a missing model printed a WARNING. A warning on the release path
// is indistinguishable from success, and the source is gitignored while releases are cut in a
// detached worktree, so every real cut took that branch. See whisperModelBundling.test.js.
const sh = fs.readFileSync(SH, 'utf-8');
assert.ok(sh.includes('MODEL_URL='), 'the build must be able to get the file itself');
assert.ok(!sh.includes('WITHOUT a bundled model (first fn press'),
'the old warn-and-continue branch must be gone');
});
test('the bundled model is NOT swept into app.asar', () => {
// It belongs in extraResources. Inside the asar it would cost every user the 181MB twice over,
// which is the regression removed on 2026-08-25.
const pkg = require('./package.json');
assert.ok(pkg.build.files.includes('!whisper') && pkg.build.files.includes('!whisper/**'));
// Platform-scoped: the entry lives under build.mac.extraResources, not build.extraResources.
const extra = JSON.stringify(pkg.build.mac.extraResources);
assert.ok(extra.includes('build-staging/whisper'), 'it reaches Resources via extraResources only');
assert.ok(extra.includes('"to":"whisper"') || extra.includes('"to": "whisper"'),
'and lands at Resources/whisper, which is what voiceResourceDir() resolves');
});