Files
PodTui/tests/cavacore-init-reuse.test.ts
Michael Freno 09d5732b55 fix(cava): identical init re-uses the live plan
cava_init/destroy churn leaks the old plan's FFTW work buffers —
upstream frees only its own struct. init() now serializes the config
and no-ops when unchanged, so pipeline restarts (focus/episode churn)
keep the live plan instead of leaking a new one each cycle.
2026-09-06 18:46:42 -04:00

59 lines
1.6 KiB
TypeScript

/**
* CavaCore.init() must be a no-op for an identical config: re-initializing
* the same plan leaks the old plan's native FFTW work buffers, so pipeline
* restarts (focus/episode churn) have to re-USE the live plan.
*/
import { test, expect } from "bun:test"
import { CavaCore } from "../src/utils/cavacore"
function stubLib() {
const calls = { init: 0, destroy: 0 }
let plans = 0
const lib = {
symbols: {
cava_init: () => {
calls.init++
return { p: ++plans }
},
cava_execute: () => {},
cava_destroy: () => {
calls.destroy++
},
},
close: () => {},
}
return { lib, calls }
}
test("identical init config reuses the plan", () => {
const { lib, calls } = stubLib()
const cava = new CavaCore(lib as never)
const cfg = { bars: 64, sampleRate: 22050, channels: 1, autosens: 0 }
cava.init(cfg)
cava.init(cfg)
cava.init(cfg)
expect(calls.init).toBe(1)
expect(cava.isReady).toBe(true)
})
test("changed config re-inits, destroying the old plan", () => {
const { lib, calls } = stubLib()
const cava = new CavaCore(lib as never)
cava.init({ bars: 64, sampleRate: 22050, channels: 1, autosens: 0 })
cava.init({ bars: 32, sampleRate: 22050, channels: 1, autosens: 0 })
expect(calls.init).toBe(2)
expect(calls.destroy).toBe(1)
expect(cava.bars).toBe(32)
})
test("init after destroy creates a fresh plan", () => {
const { lib, calls } = stubLib()
const cava = new CavaCore(lib as never)
const cfg = { bars: 64, sampleRate: 22050, channels: 1, autosens: 0 }
cava.init(cfg)
cava.destroy()
cava.init(cfg)
expect(calls.init).toBe(2)
expect(cava.isReady).toBe(true)
})