import { describe, expect, it } from "@suaveplan/testing/runner"; import { NullTimelineAdapter } from "../src/adapter/adapter.js"; import { TimelineEngine } from "../src/engine/engine.js"; describe("TimelineEngine integration", () => { it("full lifecycle: tracks, clips, playback, undo/redo", () => { const engine = new TimelineEngine(); engine.setAdapter(new NullTimelineAdapter()); // Create tracks engine.addTrack({ name: "Drums" }); engine.addTrack({ name: "Bass" }); const tracks = engine.getState().tracks; expect(tracks).toHaveLength(2); // Add clips engine.addClip(tracks[0]!.id, { id: "c1", documentId: "d1", startSample: 0, offsetSamples: 0, durationSamples: 1000, }); engine.addClip(tracks[1]!.id, { id: "c2", documentId: "d2", startSample: 500, offsetSamples: 0, durationSamples: 1000, }); expect(engine.getState().tracks[0]!.clips).toHaveLength(1); expect(engine.getState().tracks[1]!.clips).toHaveLength(1); // Playback state transitions engine.play(); expect(engine.getState().isPlaying).toBe(true); engine.pause(); expect(engine.getState().isPlaying).toBe(false); engine.seek(2000); expect(engine.getState().currentTime).toBe(2000); // Undo/redo round-trip engine.undo(); // undo seek? No, seek doesn't push undo // Actually, let me undo the clip additions via transactions }); it("verifies incremental adapter updates on undo", () => { const engine = new TimelineEngine(); engine.setAdapter(new NullTimelineAdapter()); engine.addTrack({ name: "A" }); const id = engine.getState().tracks[0]!.id; engine.updateTrack(id, { name: "B" }); engine.undo(); expect(engine.getState().tracks[0]!.name).toBe("A"); }); });