Skip to content

Commit a91e997

Browse files
committed
fix(test): make two platform-dependent tests pass off Windows, and clear lint
Turning CI on for feat/ai-edition surfaced failures that had been invisible because ci.yml only ran on main. None were caused by the docs work. compositorViewService: the absolute-pin test hardcoded "C:/vendor/ffmpeg", which path.isAbsolute rejects on POSIX, so the pin got nested under the crate dir. Spell it through path.resolve and assert the behaviour instead of one platform's drive letter. The production code was right. whisperServer: two tests wrote a fake helper binary with the default mode, which is not executable on POSIX, so the manager refused it before reaching the assertion under test. Write it 0o755. Lint: biome format across 11 files, plus five dead variables it would only remove under --unsafe. Each checked for side effects first — run_wcpp's reported_rtf was written and never read (rtf is recomputed from wall_s), and e2e-pipeline-smoke keeps its dynamic import, only dropping the unused binding.
1 parent ed1118b commit a91e997

14 files changed

Lines changed: 248 additions & 171 deletions

electron/native-bridge/services/compositorViewService.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,15 @@ describe("ffmpegSharedBinCandidates", () => {
5252
});
5353

5454
it("keeps an absolute pin absolute rather than nesting it under the crate dir", () => {
55-
writeCargoConfig(tmpRoot, `FFMPEG_DIR = "C:/vendor/ffmpeg"`);
55+
// `path.isAbsolute` is platform-dependent — "C:/vendor" is absolute on
56+
// Windows and relative on POSIX — so spell the pin through path.resolve
57+
// and assert the behaviour rather than one platform's drive letter.
58+
const absolutePin = path.resolve("/vendor/ffmpeg").replace(/\\/g, "/");
59+
writeCargoConfig(tmpRoot, `FFMPEG_DIR = "${absolutePin}"`);
5660
const candidates = ffmpegSharedBinCandidates(tmpRoot).map((p) => p.replace(/\\/g, "/"));
5761

58-
expect(candidates[0]).toBe("C:/vendor/ffmpeg/bin");
62+
expect(candidates[0]).toBe(`${absolutePin}/bin`);
63+
expect(candidates[0]).not.toContain("poc-d3d");
5964
});
6065

6166
it("starts at the arch-tagged native bin dir when there is no cargo pin to read", () => {

electron/stt/whisperServer.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ describe("WhisperServerManager", () => {
229229
dir,
230230
process.platform === "win32" ? "whisper-stt-server.exe" : "whisper-stt-server",
231231
);
232-
await fs.writeFile(fakeBinaryPath, "x");
232+
// mode 0o755: the manager refuses a helper it cannot execute, and the
233+
// default write mode is not executable on POSIX.
234+
await fs.writeFile(fakeBinaryPath, "x", { mode: 0o755 });
233235
const fakeChild = {
234236
stdout: { on: vi.fn() },
235237
stderr: { on: vi.fn() },
@@ -273,7 +275,9 @@ describe("WhisperServerManager", () => {
273275
dir,
274276
process.platform === "win32" ? "whisper-stt-server.exe" : "whisper-stt-server",
275277
);
276-
await fs.writeFile(fakeBinaryPath, "x");
278+
// Executable on purpose: this test asserts the *model* check fires, so
279+
// the binary must get past the executability check first.
280+
await fs.writeFile(fakeBinaryPath, "x", { mode: 0o755 });
277281
const mgr = new WhisperServerManager();
278282
await expect(
279283
mgr.start({

scripts/build-windows-compositor-addon.mjs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ function findVcVarsAll() {
5656
}
5757

5858
if (process.env.VSINSTALLDIR) {
59-
const candidate = path.join(process.env.VSINSTALLDIR, "VC", "Auxiliary", "Build", "vcvarsall.bat");
59+
const candidate = path.join(
60+
process.env.VSINSTALLDIR,
61+
"VC",
62+
"Auxiliary",
63+
"Build",
64+
"vcvarsall.bat",
65+
);
6066
if (fs.existsSync(candidate)) {
6167
return candidate;
6268
}
@@ -91,7 +97,14 @@ function findVcVarsAll() {
9197
return direct;
9298
}
9399
for (const edition of editions) {
94-
const nested = path.join(channelDir, edition, "VC", "Auxiliary", "Build", "vcvarsall.bat");
100+
const nested = path.join(
101+
channelDir,
102+
edition,
103+
"VC",
104+
"Auxiliary",
105+
"Build",
106+
"vcvarsall.bat",
107+
);
95108
if (fs.existsSync(nested)) {
96109
return nested;
97110
}
@@ -141,9 +154,14 @@ async function runInVsEnv(command) {
141154
);
142155
fs.writeFileSync(
143156
cmdPath,
144-
["@echo off", `call "${vcvarsAll}" x64`, "if errorlevel 1 exit /b %errorlevel%", command, "exit /b %errorlevel%", ""].join(
145-
"\r\n",
146-
),
157+
[
158+
"@echo off",
159+
`call "${vcvarsAll}" x64`,
160+
"if errorlevel 1 exit /b %errorlevel%",
161+
command,
162+
"exit /b %errorlevel%",
163+
"",
164+
].join("\r\n"),
147165
);
148166
try {
149167
await run("cmd.exe", ["/d", "/c", cmdPath], { cwd: POC_D3D_DIR });

scripts/build-windows-wgc-helper.mjs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ function findVcVarsAll() {
4343
}
4444

4545
if (process.env.VSINSTALLDIR) {
46-
const candidate = path.join(process.env.VSINSTALLDIR, "VC", "Auxiliary", "Build", "vcvarsall.bat");
46+
const candidate = path.join(
47+
process.env.VSINSTALLDIR,
48+
"VC",
49+
"Auxiliary",
50+
"Build",
51+
"vcvarsall.bat",
52+
);
4753
if (fs.existsSync(candidate)) {
4854
return candidate;
4955
}
@@ -82,7 +88,14 @@ function findVcVarsAll() {
8288
return direct;
8389
}
8490
for (const edition of editions) {
85-
const nested = path.join(channelDir, edition, "VC", "Auxiliary", "Build", "vcvarsall.bat");
91+
const nested = path.join(
92+
channelDir,
93+
edition,
94+
"VC",
95+
"Auxiliary",
96+
"Build",
97+
"vcvarsall.bat",
98+
);
8699
if (fs.existsSync(nested)) {
87100
return nested;
88101
}

scripts/check-docs.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ for (const file of files) {
113113
}
114114

115115
// No stale `docs/` path prefix.
116-
for (const [match] of text.matchAll(/(?<![\w/-])docs\/(?:architecture|engineering|testing|tests)\//g)) {
116+
for (const [match] of text.matchAll(
117+
/(?<![\w/-])docs\/(?:architecture|engineering|testing|tests)\//g,
118+
)) {
117119
errors.push(`${rel}: stale path prefix "${match}" (tree is technical-documentation/)`);
118120
}
119121

scripts/e2e-pipeline-smoke.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ const MODEL_PATH = join(
3939

4040
// Lazy import — only the type module + the bits we need. The main thing
4141
// we want to verify is that our Electron modules wire up correctly.
42-
const transcriptionContract = await import("../electron/stt/transcriptionContract.ts").catch(
43-
() => null,
44-
);
42+
// The binding is deliberately dropped: the import is attempted for its own
43+
// sake and the module's value is never read.
44+
await import("../electron/stt/transcriptionContract.ts").catch(() => null);
4545
// The .ts file isn't loadable directly via plain Node — that's fine, we
4646
// only need to confirm the actual server pipeline behaves correctly when
4747
// invoked the same way the IPC handler does.

scripts/fetch-ffmpeg.mjs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,12 @@ async function fetchSharedDlls(tag, binDir) {
287287
// --force same as the static exe, checked once we know what we'd extract.
288288
const alreadyVendored = fs
289289
.readdirSync(binDir, { withFileTypes: true })
290-
.some((e) => e.isFile() && e.name.toLowerCase().endsWith(".dll") && e.name.toLowerCase().startsWith("av"));
290+
.some(
291+
(e) =>
292+
e.isFile() &&
293+
e.name.toLowerCase().endsWith(".dll") &&
294+
e.name.toLowerCase().startsWith("av"),
295+
);
291296
if (alreadyVendored && !process.argv.includes("--force")) {
292297
console.log(`\nShared ffmpeg DLLs already present in ${binDir}. Use --force to re-vendor.`);
293298
return;
@@ -297,7 +302,8 @@ async function fetchSharedDlls(tag, binDir) {
297302
const tmp = await downloadAndExtract(spec);
298303
try {
299304
const exe = findExe(tmp, "ffmpeg.exe");
300-
if (!exe) throw new Error(`ffmpeg.exe not found inside ${spec.asset} (needed to verify licence)`);
305+
if (!exe)
306+
throw new Error(`ffmpeg.exe not found inside ${spec.asset} (needed to verify licence)`);
301307

302308
// Same source commit as the static build, but configure flags are a
303309
// separate BtbN job — verify this artifact's licence independently

tools/stt-eval/whispercpp-dtw-poc/harness/analyze.mjs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,42 @@ const dur = parseFloat(durationSec);
99
let text = "";
1010
let words = [];
1111
for (const seg of d.segments || []) {
12-
text += seg.text;
13-
for (const w of seg.words || []) words.push(w);
12+
text += seg.text;
13+
for (const w of seg.words || []) words.push(w);
1414
}
1515

1616
let monotonic = true;
1717
let maxBacktrack = 0;
1818
let coverageGaps = [];
1919
for (let i = 1; i < words.length; i++) {
20-
if (words[i].start < words[i - 1].start) {
21-
monotonic = false;
22-
maxBacktrack = Math.max(maxBacktrack, words[i - 1].start - words[i].start);
23-
}
24-
if (words[i].end < words[i].start) {
25-
coverageGaps.push(`word[${i}] '${words[i].word}' end<start`);
26-
}
20+
if (words[i].start < words[i - 1].start) {
21+
monotonic = false;
22+
maxBacktrack = Math.max(maxBacktrack, words[i - 1].start - words[i].start);
23+
}
24+
if (words[i].end < words[i].start) {
25+
coverageGaps.push(`word[${i}] '${words[i].word}' end<start`);
26+
}
2727
}
2828

2929
const lastWordEnd = words.length ? words[words.length - 1].end : 0;
3030
const zeroStartCount = words.filter((w, i) => i > 0 && w.start === 0).length;
3131

3232
console.log(
33-
JSON.stringify(
34-
{
35-
detected_language: d.detected_language,
36-
numSegments: (d.segments || []).length,
37-
numWords: words.length,
38-
text: text.trim(),
39-
monotonic,
40-
maxBacktrack,
41-
lastWordEnd,
42-
clipDuration: dur,
43-
zeroStartCountExcludingFirst: zeroStartCount,
44-
segmentsWithoutWords: (d.segments || []).filter((s) => !s.words || s.words.length === 0).length,
45-
},
46-
null,
47-
2
48-
)
33+
JSON.stringify(
34+
{
35+
detected_language: d.detected_language,
36+
numSegments: (d.segments || []).length,
37+
numWords: words.length,
38+
text: text.trim(),
39+
monotonic,
40+
maxBacktrack,
41+
lastWordEnd,
42+
clipDuration: dur,
43+
zeroStartCountExcludingFirst: zeroStartCount,
44+
segmentsWithoutWords: (d.segments || []).filter((s) => !s.words || s.words.length === 0)
45+
.length,
46+
},
47+
null,
48+
2,
49+
),
4950
);
Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
// debug_jfk.mjs — Compare wcpp-cpu-fp16 vs ct2-fp16 word-by-word for jfk.wav
22
import { promises as fs } from "node:fs";
3-
const a = JSON.parse(await fs.readFile("tools/stt-eval/whispercpp-dtw-poc/results/wcpp_cpu_fp16_jfk.json", "utf8"));
4-
const b = JSON.parse(await fs.readFile("tools/stt-eval/whispercpp-dtw-poc/results/ct2_fp16_jfk.json", "utf8"));
3+
4+
const a = JSON.parse(
5+
await fs.readFile("tools/stt-eval/whispercpp-dtw-poc/results/wcpp_cpu_fp16_jfk.json", "utf8"),
6+
);
7+
const b = JSON.parse(
8+
await fs.readFile("tools/stt-eval/whispercpp-dtw-poc/results/ct2_fp16_jfk.json", "utf8"),
9+
);
510
const wa = a.segments[0].words;
611
const wb = b.segments[0].words;
712
console.log("wcpp words:", wa.length, "ct2 words:", wb.length);
813
const maxN = Math.max(wa.length, wb.length);
914
for (let i = 0; i < maxN; i++) {
1015
const aw = wa[i] || { word: "<eof>", start: 0, end: 0 };
1116
const bw = wb[i] || { word: "<eof>", start: 0, end: 0 };
12-
const dw = aw.end - aw.start, dc = bw.end - bw.start;
17+
const dw = aw.end - aw.start,
18+
dc = bw.end - bw.start;
1319
const dStart = Math.abs(aw.start - bw.start) * 1000;
14-
const dEnd = Math.abs(aw.end - bw.end) * 1000;
20+
const dEnd = Math.abs(aw.end - bw.end) * 1000;
1521
console.log(
1622
` ${String(i).padStart(2)} ` +
17-
`wcpp=${aw.word.padEnd(15)}[${aw.start.toFixed(2)},${aw.end.toFixed(2)}] ` +
18-
`ct2 =${bw.word.padEnd(15)}[${bw.start.toFixed(2)},${bw.end.toFixed(2)}] ` +
19-
`Δs=${dStart.toFixed(0).padStart(5)}ms Δe=${dEnd.toFixed(0).padStart(5)}ms ` +
20-
`wcpp_dur=${(dw*1000).toFixed(0).padStart(5)}ms ct2_dur=${(dc*1000).toFixed(0).padStart(5)}ms`,
23+
`wcpp=${aw.word.padEnd(15)}[${aw.start.toFixed(2)},${aw.end.toFixed(2)}] ` +
24+
`ct2 =${bw.word.padEnd(15)}[${bw.start.toFixed(2)},${bw.end.toFixed(2)}] ` +
25+
`Δs=${dStart.toFixed(0).padStart(5)}ms Δe=${dEnd.toFixed(0).padStart(5)}ms ` +
26+
`wcpp_dur=${(dw * 1000).toFixed(0).padStart(5)}ms ct2_dur=${(dc * 1000).toFixed(0).padStart(5)}ms`,
2127
);
2228
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import fs from "fs";
2+
23
const [, , jsonPath] = process.argv;
34
const d = JSON.parse(fs.readFileSync(jsonPath, "utf8"));
45
process.stdout.write((d.segments || []).map((s) => s.text).join(""));

0 commit comments

Comments
 (0)