mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-12 07:09:59 +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["c1"] = gsap.timeline({ paused: true });
|
||||
</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>`;
|
||||
const result = await lintHyperframeHtml(html);
|
||||
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 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 {
|
||||
if (source.length === 0) return 0;
|
||||
|
||||
@@ -406,7 +414,7 @@ export const compositionRules: Array<(ctx: LintContext) => HyperframeLintFinding
|
||||
const current = clips[i];
|
||||
const next = clips[i + 1];
|
||||
if (!current || !next) continue;
|
||||
if (current.end > next.start) {
|
||||
if (current.end - next.start > OVERLAP_EPSILON_SECONDS) {
|
||||
findings.push({
|
||||
code: "overlapping_clips_same_track",
|
||||
severity: "error",
|
||||
|
||||
Reference in New Issue
Block a user