mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
test(studio): add T5b rotation+motion build-patches characterization (#1258)
Extends manualEditsDomPatches.test.ts with rotation and motion pairs. Same 4-pattern structure: populated, empty, clear restores originals, build/clear symmetry. Merges duplicate manualEditsTypes import block.
This commit is contained in:
@@ -7,8 +7,11 @@ import {
|
||||
STUDIO_OFFSET_Y_PROP,
|
||||
STUDIO_WIDTH_PROP,
|
||||
STUDIO_HEIGHT_PROP,
|
||||
STUDIO_ROTATION_PROP,
|
||||
STUDIO_PATH_OFFSET_ATTR,
|
||||
STUDIO_BOX_SIZE_ATTR,
|
||||
STUDIO_ROTATION_ATTR,
|
||||
STUDIO_ROTATION_DRAFT_ATTR,
|
||||
STUDIO_ORIGINAL_TRANSLATE_ATTR,
|
||||
STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR,
|
||||
STUDIO_ORIGINAL_WIDTH_ATTR,
|
||||
@@ -24,13 +27,26 @@ import {
|
||||
STUDIO_ORIGINAL_SCALE_ATTR,
|
||||
STUDIO_ORIGINAL_TRANSFORM_ORIGIN_ATTR,
|
||||
STUDIO_ORIGINAL_DISPLAY_ATTR,
|
||||
STUDIO_ORIGINAL_ROTATE_ATTR,
|
||||
STUDIO_ORIGINAL_INLINE_ROTATE_ATTR,
|
||||
STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR,
|
||||
STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR,
|
||||
} from "./manualEditsTypes";
|
||||
import {
|
||||
STUDIO_MOTION_ATTR,
|
||||
STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR,
|
||||
STUDIO_MOTION_ORIGINAL_OPACITY_ATTR,
|
||||
STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR,
|
||||
} from "./studioMotionTypes";
|
||||
import {
|
||||
buildPathOffsetPatches,
|
||||
buildClearPathOffsetPatches,
|
||||
buildBoxSizePatches,
|
||||
buildClearBoxSizePatches,
|
||||
buildRotationPatches,
|
||||
buildClearRotationPatches,
|
||||
buildMotionPatches,
|
||||
buildClearMotionPatches,
|
||||
} from "./manualEditsDomPatches";
|
||||
|
||||
/* ── helpers ── */
|
||||
@@ -210,3 +226,117 @@ describe("buildBoxSizePatches / buildClearBoxSizePatches", () => {
|
||||
assertClearCoversKeys(buildBoxSizePatches(e), buildClearBoxSizePatches(e));
|
||||
});
|
||||
});
|
||||
|
||||
/* ── Rotation ────────────────────────────────────────────────────────────── */
|
||||
|
||||
describe("buildRotationPatches / buildClearRotationPatches", () => {
|
||||
function populatedRotEl(): HTMLElement {
|
||||
const e = div();
|
||||
e.style.setProperty(STUDIO_ROTATION_PROP, "45");
|
||||
e.style.setProperty("rotate", "45deg");
|
||||
e.style.setProperty("transform-origin", "left center");
|
||||
e.style.setProperty("display", "block");
|
||||
e.setAttribute(STUDIO_ORIGINAL_ROTATE_ATTR, "0deg");
|
||||
e.setAttribute(STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, "0deg");
|
||||
e.setAttribute(STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR, "center center");
|
||||
e.setAttribute(STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, "flex");
|
||||
return e;
|
||||
}
|
||||
|
||||
it("populated: captures rotation styles, attrs, and transform-display marker in declaration order", () => {
|
||||
const ops = buildRotationPatches(populatedRotEl());
|
||||
expect(ops).toEqual([
|
||||
{ type: "inline-style", property: STUDIO_ROTATION_PROP, value: "45" },
|
||||
{ type: "inline-style", property: "rotate", value: "45deg" },
|
||||
{ type: "inline-style", property: "transform-origin", value: "left center" },
|
||||
{ type: "inline-style", property: "display", value: "block" },
|
||||
{ type: "attribute", property: STUDIO_ROTATION_ATTR, value: "true" },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_ROTATE_ATTR, value: "0deg" },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, value: "0deg" },
|
||||
{
|
||||
type: "attribute",
|
||||
property: STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR,
|
||||
value: "center center",
|
||||
},
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, value: "flex" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("empty: bare element yields only the rotation marker", () => {
|
||||
expect(buildRotationPatches(div())).toEqual([
|
||||
{ type: "attribute", property: STUDIO_ROTATION_ATTR, value: "true" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("clear: restores rotate and transform-origin from orig attrs, nulls draft attr", () => {
|
||||
const e = div();
|
||||
e.setAttribute(STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, "30deg");
|
||||
e.setAttribute(STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR, "top left");
|
||||
e.setAttribute(STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, "grid");
|
||||
const ops = buildClearRotationPatches(e);
|
||||
expect(ops).toEqual([
|
||||
{ type: "inline-style", property: STUDIO_ROTATION_PROP, value: null },
|
||||
{ type: "inline-style", property: "rotate", value: "30deg" },
|
||||
{ type: "inline-style", property: "transform-origin", value: "top left" },
|
||||
{ type: "attribute", property: STUDIO_ROTATION_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_ROTATION_DRAFT_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_ROTATE_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR, value: null },
|
||||
{ type: "inline-style", property: "display", value: "grid" },
|
||||
{ type: "attribute", property: STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, value: null },
|
||||
]);
|
||||
});
|
||||
|
||||
it("build/clear symmetry: clear addresses every {type,property} key that build emits", () => {
|
||||
const e = populatedRotEl();
|
||||
assertClearCoversKeys(buildRotationPatches(e), buildClearRotationPatches(e));
|
||||
});
|
||||
});
|
||||
|
||||
/* ── Motion ──────────────────────────────────────────────────────────────── */
|
||||
|
||||
describe("buildMotionPatches / buildClearMotionPatches", () => {
|
||||
const MOTION_JSON = '{"kind":"gsap-motion","start":0,"duration":1}';
|
||||
|
||||
function populatedMotionEl(): HTMLElement {
|
||||
const e = div();
|
||||
e.setAttribute(STUDIO_MOTION_ATTR, MOTION_JSON);
|
||||
e.setAttribute(STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR, "translateX(0)");
|
||||
e.setAttribute(STUDIO_MOTION_ORIGINAL_OPACITY_ATTR, "1");
|
||||
e.setAttribute(STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR, "visible");
|
||||
return e;
|
||||
}
|
||||
|
||||
it("populated: captures motion JSON and all three original attrs when motion attr is present", () => {
|
||||
const ops = buildMotionPatches(populatedMotionEl());
|
||||
expect(ops).toEqual([
|
||||
{ type: "attribute", property: STUDIO_MOTION_ATTR, value: MOTION_JSON },
|
||||
{
|
||||
type: "attribute",
|
||||
property: STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR,
|
||||
value: "translateX(0)",
|
||||
},
|
||||
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_OPACITY_ATTR, value: "1" },
|
||||
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR, value: "visible" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("empty: returns [] when STUDIO_MOTION_ATTR is absent", () => {
|
||||
expect(buildMotionPatches(div())).toEqual([]);
|
||||
});
|
||||
|
||||
it("clear: always nulls all four motion attrs regardless of element state", () => {
|
||||
expect(buildClearMotionPatches(div())).toEqual([
|
||||
{ type: "attribute", property: STUDIO_MOTION_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_OPACITY_ATTR, value: null },
|
||||
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR, value: null },
|
||||
]);
|
||||
});
|
||||
|
||||
it("build/clear symmetry: clear addresses every {type,property} key that build emits", () => {
|
||||
const e = populatedMotionEl();
|
||||
assertClearCoversKeys(buildMotionPatches(e), buildClearMotionPatches(e));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user