mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-12 15:20:13 +00:00
fix(lint): float slop in overlapping_clips_same_track compare (#1851)
parseFloat('0.1') + parseFloat('0.2') = 0.30000000000000004, so authored
adjacencies whose sum is exact in decimal drift a few ulps and fire the
overlap rule under the strict compare.
Compare on end - start > 1e-6 instead — 11 orders above the worst observed
drift, 4 below one 60fps frame.
This commit is contained in:
@@ -384,6 +384,24 @@ describe("composition rules", () => {
|
|||||||
window.__timelines = window.__timelines || {};
|
window.__timelines = window.__timelines || {};
|
||||||
window.__timelines["c1"] = gsap.timeline({ paused: true });
|
window.__timelines["c1"] = gsap.timeline({ paused: true });
|
||||||
</script>
|
</script>
|
||||||
|
</body></html>`;
|
||||||
|
const result = await lintHyperframeHtml(html);
|
||||||
|
const finding = result.findings.find((f) => f.code === "overlapping_clips_same_track");
|
||||||
|
expect(finding).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not flag adjacencies where parseFloat + add drifts by a few ulps", async () => {
|
||||||
|
// parseFloat("0.1") + parseFloat("0.2") = 0.30000000000000004
|
||||||
|
const html = `
|
||||||
|
<html><body>
|
||||||
|
<div data-composition-id="c1" data-width="1920" data-height="1080">
|
||||||
|
<div class="clip" data-start="0.1" data-duration="0.2" data-track-index="0">A</div>
|
||||||
|
<div class="clip" data-start="0.3" data-duration="0.2" data-track-index="0">B</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
window.__timelines = window.__timelines || {};
|
||||||
|
window.__timelines["c1"] = gsap.timeline({ paused: true });
|
||||||
|
</script>
|
||||||
</body></html>`;
|
</body></html>`;
|
||||||
const result = await lintHyperframeHtml(html);
|
const result = await lintHyperframeHtml(html);
|
||||||
const finding = result.findings.find((f) => f.code === "overlapping_clips_same_track");
|
const finding = result.findings.find((f) => f.code === "overlapping_clips_same_track");
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ const MAX_COMPOSITION_LINES = 300;
|
|||||||
const MAX_TIMED_ELEMENTS_PER_TRACK = 3;
|
const MAX_TIMED_ELEMENTS_PER_TRACK = 3;
|
||||||
const TRACK_DENSITY_EXEMPT_TAGS = new Set(["audio", "script", "style", "video"]);
|
const TRACK_DENSITY_EXEMPT_TAGS = new Set(["audio", "script", "style", "video"]);
|
||||||
|
|
||||||
|
// `parseFloat("0.1") + parseFloat("0.2") = 0.30000000000000004`. Sub-second
|
||||||
|
// authored adjacencies survive parse + add as a value a few ulps above the
|
||||||
|
// next clip's start; a strict `>` fires the overlap rule on adjacencies that
|
||||||
|
// are exact in the source HTML. 1μs sits ~11 orders of magnitude above the
|
||||||
|
// observed drift (worst ~2e-16s across every realistic decimal pair) and 4
|
||||||
|
// below one 60fps frame (~16.67ms), so this only ever swallows float slop.
|
||||||
|
const OVERLAP_EPSILON_SECONDS = 1e-6;
|
||||||
|
|
||||||
function countPhysicalLines(source: string): number {
|
function countPhysicalLines(source: string): number {
|
||||||
if (source.length === 0) return 0;
|
if (source.length === 0) return 0;
|
||||||
|
|
||||||
@@ -406,7 +414,7 @@ export const compositionRules: Array<(ctx: LintContext) => HyperframeLintFinding
|
|||||||
const current = clips[i];
|
const current = clips[i];
|
||||||
const next = clips[i + 1];
|
const next = clips[i + 1];
|
||||||
if (!current || !next) continue;
|
if (!current || !next) continue;
|
||||||
if (current.end > next.start) {
|
if (current.end - next.start > OVERLAP_EPSILON_SECONDS) {
|
||||||
findings.push({
|
findings.push({
|
||||||
code: "overlapping_clips_same_track",
|
code: "overlapping_clips_same_track",
|
||||||
severity: "error",
|
severity: "error",
|
||||||
|
|||||||
Reference in New Issue
Block a user