Skip to content

Commit fe24974

Browse files
Fix tests
1 parent 3fb7821 commit fe24974

File tree

4 files changed

+32
-12
lines changed

4 files changed

+32
-12
lines changed

src/hooks/__tests__/useMultiVfoProcessor.test.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ describe("useMultiVfoProcessor", () => {
115115
});
116116
}
117117

118+
// Wait for async VFO initialization
119+
await act(async () => {
120+
await new Promise((resolve) => setTimeout(resolve, 100));
121+
});
122+
118123
// Process samples
119124
await act(async () => {
120125
await result.current.processSamples(samples);
@@ -180,6 +185,11 @@ describe("useMultiVfoProcessor", () => {
180185
});
181186
}
182187

188+
// Wait for async VFO initialization
189+
await act(async () => {
190+
await new Promise((resolve) => setTimeout(resolve, 100));
191+
});
192+
183193
// Process samples
184194
await act(async () => {
185195
await result.current.processSamples(samples);
@@ -267,6 +277,11 @@ describe("useMultiVfoProcessor", () => {
267277
samples.push({ I: Math.random(), Q: Math.random() });
268278
}
269279

280+
// Wait for async VFO initialization
281+
await act(async () => {
282+
await new Promise((resolve) => setTimeout(resolve, 100));
283+
});
284+
270285
// Process samples
271286
await act(async () => {
272287
await result.current.processSamples(samples);
@@ -279,8 +294,8 @@ describe("useMultiVfoProcessor", () => {
279294
const disabledVfo = vfos.find((v) => !v.audioEnabled);
280295

281296
expect(enabledVfo?.metrics?.samplesProcessed).toBeGreaterThan(0);
282-
// Disabled VFO should not have metrics updated
283-
expect(disabledVfo?.metrics).toBeUndefined();
297+
// Disabled VFO should not have metrics updated (or remain at initial 0)
298+
expect(disabledVfo?.metrics?.samplesProcessed).toBe(0);
284299
});
285300
});
286301
});

src/hooks/useMultiVfoProcessor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
204204
};
205205

206206
void initializeVfos();
207-
}, [vfos, getAllVfos]); // Re-run when VFO map changes
207+
}, [vfos]); // Re-run when VFO map changes
208208

209209
/**
210210
* Process IQ samples through all active VFOs

src/pages/Monitor.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
useDiagnostics,
4040
useSignalLevel,
4141
useVfo,
42+
useStore,
4243
} from "../store";
4344
// import { shouldUseMockSDR } from "../utils/e2e";
4445
import { updateBulkCachedRDSData } from "../store/rdsCache";
@@ -201,8 +202,12 @@ const Monitor: React.FC = () => {
201202
}
202203

203204
// Route samples to multi-VFO processor
204-
// The processSamples function handles empty VFO checks internally
205-
if (vfoProcessor.isReady) {
205+
// Check for active VFOs directly from store to avoid stale closures
206+
const vfos = useStore.getState().getAllVfos();
207+
const hasActiveVfos = vfos.some((v) => v.audioEnabled);
208+
209+
if (hasActiveVfos) {
210+
// processSamples handles initialization checks internally via refs
206211
vfoProcessor.processSamples(samples).catch((error: unknown) => {
207212
console.error("VFO processing error:", error);
208213
});

src/utils/webAudioUtils.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ export function createAudioBufferFromSamples(
9797
const rightChannel = new Float32Array(numFrames);
9898

9999
// Deinterleave stereo samples (numFrames guaranteed <= samples.length / 2)
100-
// TypeScript requires ?? 0 due to noUncheckedIndexedAccess: true in tsconfig.json
100+
// Use non-null assertion (!) as bounds are guaranteed by numFrames calculation
101101
for (let i = 0; i < numFrames; i++) {
102102
const leftIdx = i * 2;
103103
const rightIdx = i * 2 + 1;
104-
leftChannel[i] = samples[leftIdx] ?? 0;
105-
rightChannel[i] = samples[rightIdx] ?? 0;
104+
leftChannel[i] = samples[leftIdx]!;
105+
rightChannel[i] = samples[rightIdx]!;
106106
}
107107

108108
buffer.copyToChannel(leftChannel, 0);
@@ -133,16 +133,16 @@ export function mixAudioBuffers(buffers: Float32Array[]): Float32Array {
133133
const len = Math.min(buffer.length, mixed.length);
134134
for (let i = 0; i < len; i++) {
135135
// Float32Array elements are initialized to 0 and accessed within bounds
136-
// ?? 0 required due to noUncheckedIndexedAccess: true in tsconfig.json
137-
mixed[i] = (mixed[i] ?? 0) + (buffer[i] ?? 0);
136+
// Use non-null assertion (!) as bounds are guaranteed by len calculation
137+
mixed[i] = mixed[i]! + buffer[i]!;
138138
}
139139
}
140140

141141
// Normalize by buffer count to prevent clipping
142142
const scale = 1 / buffers.length;
143143
for (let i = 0; i < mixed.length; i++) {
144-
// ?? 0 required due to noUncheckedIndexedAccess: true in tsconfig.json
145-
mixed[i] = (mixed[i] ?? 0) * scale;
144+
// Use non-null assertion (!) as bounds are guaranteed by loop condition
145+
mixed[i] = mixed[i]! * scale;
146146
}
147147

148148
return mixed;

0 commit comments

Comments
 (0)