Initial Commit
This commit is contained in:
23
packages/media/audio/audio-transport/tests/exports.test.ts
Normal file
23
packages/media/audio/audio-transport/tests/exports.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import packageJson from "../package.json";
|
||||
|
||||
describe("package exports", () => {
|
||||
it("every feature module has a subpath export entry", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const subpaths = Object.keys(packageJson.exports).filter(
|
||||
(k) => k.startsWith("./") && k !== "./package.json" && k !== "."
|
||||
);
|
||||
const expected = [
|
||||
"./transport/transport",
|
||||
"./scheduler/scheduler",
|
||||
"./tick-source/tick-source",
|
||||
"./signal/signal",
|
||||
"./time/time",
|
||||
"./error-codes",
|
||||
];
|
||||
for (const exp of expected) {
|
||||
expect(subpaths).toContain(exp);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
import { describe, expect, it, vi } from "@suaveplan/testing/runner";
|
||||
import { TransportScheduler } from "../src/scheduler/scheduler.js";
|
||||
import { Transport } from "../src/transport/transport.js";
|
||||
|
||||
describe("integration", () => {
|
||||
it("identical FakeClock runs produce identical callback sequences", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
function run(clock: {
|
||||
now: () => number;
|
||||
advance: (s: number) => void;
|
||||
}) {
|
||||
const tr = new Transport({ clock: clock.now, bpm: 120, ppq: 192 });
|
||||
const scheduler = new TransportScheduler(tr, clock.now, {
|
||||
pollIntervalMs: 10,
|
||||
});
|
||||
const log: Array<{ id: number; time: number; ticks: number }> = [];
|
||||
let id = 1;
|
||||
tr.schedule(() => {
|
||||
log.push({ id: id++, time: tr.seconds, ticks: tr.ticks });
|
||||
}, "0:1:0");
|
||||
tr.start();
|
||||
scheduler.start();
|
||||
clock.advance(0.1);
|
||||
clock.advance(0.1);
|
||||
clock.advance(0.1);
|
||||
clock.advance(0.1);
|
||||
clock.advance(0.1);
|
||||
scheduler.stop();
|
||||
return log;
|
||||
}
|
||||
|
||||
const clockA = {
|
||||
t: 0,
|
||||
now: () => 0,
|
||||
advance: (s: number) => {
|
||||
clockA.t += s;
|
||||
clockA.now = () => clockA.t;
|
||||
},
|
||||
};
|
||||
clockA.now = () => clockA.t;
|
||||
const clockB = {
|
||||
t: 0,
|
||||
now: () => 0,
|
||||
advance: (s: number) => {
|
||||
clockB.t += s;
|
||||
clockB.now = () => clockB.t;
|
||||
},
|
||||
};
|
||||
clockB.now = () => clockB.t;
|
||||
|
||||
const logA = run(clockA);
|
||||
const logB = run(clockB);
|
||||
expect(logA).toEqual(logB);
|
||||
});
|
||||
|
||||
it("repeated callback times are sample-accurate under FakeClock", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const clock = { t: 0, now: () => 0 };
|
||||
clock.now = () => clock.t;
|
||||
const tr = new Transport({ clock: clock.now, bpm: 120, ppq: 192 });
|
||||
const cb = vi.fn();
|
||||
tr.scheduleRepeat(cb, "4n", "0:0:0");
|
||||
tr.start();
|
||||
// Manually process windows to simulate scheduler
|
||||
tr._processWindow(0, 0.6);
|
||||
// Fires at tick 0 (start) and tick 192 (0.5s)
|
||||
expect(cb).toHaveBeenCalledTimes(2);
|
||||
const secondCallTime = cb.mock.calls[1]![0];
|
||||
// The callback time should be close to the expected tick time (0.5s for quarter at 120bpm)
|
||||
expect(secondCallTime).toBeCloseTo(0.5, 2);
|
||||
});
|
||||
});
|
||||
41
packages/media/audio/audio-transport/tests/purity.test.ts
Normal file
41
packages/media/audio/audio-transport/tests/purity.test.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
|
||||
describe("universal purity", () => {
|
||||
it("dist references no browser or Node globals", { timeout: 5000 }, () => {
|
||||
// This test is a structural guard; the actual check happens at build time.
|
||||
// We verify the package.json sideEffects flag and absence of platform deps.
|
||||
const pkg = require("../package.json");
|
||||
expect(pkg.sideEffects).toBe(false);
|
||||
const deps = Object.keys(pkg.dependencies ?? {});
|
||||
for (const dep of deps) {
|
||||
expect(dep).not.toMatch(/^node:/);
|
||||
}
|
||||
});
|
||||
|
||||
it("dependency set is limited to the declared workspace deps and zod", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const pkg = require("../package.json");
|
||||
const deps = Object.keys(pkg.dependencies ?? {});
|
||||
const allowed = [
|
||||
"@opentelemetry/api",
|
||||
"@suaveplan/error",
|
||||
"@suaveplan/events",
|
||||
"@suaveplan/fsm",
|
||||
"@suaveplan/timing",
|
||||
"@suaveplan/types",
|
||||
"tslib",
|
||||
"zod",
|
||||
];
|
||||
for (const dep of deps) {
|
||||
expect(allowed).toContain(dep);
|
||||
}
|
||||
});
|
||||
|
||||
it("importing the package mutates no global state", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
// Re-importing should not throw or mutate globals.
|
||||
expect(() => import("../src/index")).not.toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user