// @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);
});
});