import { describe, expect, it } from "@suaveplan/testing/runner"; import fc from "fast-check"; import { BeatDetector } from "../src/detector/beat-detector.js"; import { makeMetronome } from "./fixtures.js"; describe("property — analyze results are well-formed", () => { it("beats and onsets are strictly increasing and confidence is in [0,1]", { timeout: 30000, }, async () => { await fc.assert( fc.asyncProperty( fc.integer({ min: 80, max: 160 }), fc.integer({ min: 4, max: 6 }), async (bpm, durationSeconds) => { const doc = makeMetronome({ bpm, durationSeconds }); const r = await new BeatDetector().analyze(doc); expect(r.confidence).toBeGreaterThanOrEqual(0); expect(r.confidence).toBeLessThanOrEqual(1); for (let i = 1; i < r.beats.length; i++) { expect(r.beats[i]).toBeGreaterThan(r.beats[i - 1]!); } for (let i = 1; i < r.onsets.length; i++) { expect(r.onsets[i]).toBeGreaterThan(r.onsets[i - 1]!); } expect(r.bpm).toBeGreaterThanOrEqual(60); expect(r.bpm).toBeLessThanOrEqual(200); } ), { numRuns: 3 } ); }); });