// @vitest-environment jsdom import { describe, expect, it } from "vitest"; import { extendRootDurationInSource, patchRootCompositionDuration, readRootCompositionDuration, } from "./rootDuration"; describe("extendRootDurationInSource", () => { it("extends data-duration when the new end is bigger than the root duration", () => { const source = [ `
`, `
`, `
`, ].join("\n"); expect(extendRootDurationInSource(source, 5.25)).toContain( `data-composition-id="main" data-duration="5.25"`, ); }); it("does nothing when the new end is smaller than or equal to the root duration", () => { const source = `
`; expect(extendRootDurationInSource(source, 5)).toBe(source); expect(extendRootDurationInSource(source, 6)).toBe(source); }); it("leaves non-root data-duration attributes untouched by the extension", () => { const source = [ `
`, `
`, ].join("\n"); const patched = extendRootDurationInSource(source, 7); expect(patched).toContain(`
`); expect(patched).toContain(`
`); }); // Reviewer round-2 finding #3: the old regex was attribute-ORDER-dependent and // double-quotes-only, so these hand-authored variants silently no-op'd. it("extends when data-duration is declared BEFORE data-composition-id", () => { const source = `
`; expect(extendRootDurationInSource(source, 9)).toBe( `
`, ); }); it("extends when attributes use single quotes", () => { const source = `
`; expect(extendRootDurationInSource(source, 9)).toBe( `
`, ); }); it("extends with swapped order AND single quotes AND extra whitespace", () => { const source = `
x
`; expect(extendRootDurationInSource(source, 9)).toBe( `
x
`, ); }); }); describe("readRootCompositionDuration", () => { it("reads the root duration regardless of attribute order or quote style", () => { expect( readRootCompositionDuration(`
`), ).toBe(4); expect( readRootCompositionDuration(`
`), ).toBe(4); expect( readRootCompositionDuration(`
`), ).toBe(4.5); }); it("reads the FIRST composition when several are present", () => { const source = [ `
`, `
`, ].join("\n"); expect(readRootCompositionDuration(source)).toBe(10); }); it("returns null when there is no composition root", () => { expect(readRootCompositionDuration(`
`)).toBeNull(); }); it("returns null when the root has no data-duration attribute", () => { expect(readRootCompositionDuration(`
`)).toBeNull(); }); }); describe("patchRootCompositionDuration", () => { it("rewrites only the root's data-duration value, preserving surrounding bytes", () => { const source = [ ``, `
`, ` `, `
`, ].join("\n"); const patched = patchRootCompositionDuration(source, "8"); expect(patched).toBe( [ ``, `
`, ` `, `
`, ].join("\n"), ); }); it("keeps single-quote style when rewriting", () => { expect( patchRootCompositionDuration(`
`, "8"), ).toBe(`
`); }); it("is a no-op when the root has no data-duration attribute", () => { const source = `
`; expect(patchRootCompositionDuration(source, "8")).toBe(source); }); });