Setting the file. One moment.
Frame Packets Test · Faceless Explainer · heygen-com/hyperframes · Skills Docs
ContentsBack to the top of the page (opens in a new tab)
scripts/ frame-packets.test.mjs
JavaScript · 66 lines · 3 KB
9 function write ( path , contents ) {
10 mkdirSync ( dirname (path), { recursive: true });
11 writeFileSync (path, contents);
12 }
13
14 test ( "packets inline the blueprint body and the Scene-cited rule recipes" , () => {
15 const project = mkdtempSync ( join ( tmpdir (), "fev-packets-" ));
16 write ( join (project, "frame.md" ), "# tokens \n " );
17 write (
18 join (project, "STORYBOARD.md" ),
19 `--- \n format: 1920x1080 \n --- \n\n ## Frame 1 — Hook \n\n - duration: 3s \n - src: compositions/frames/01-hook.html \n - blueprint: dataviz-countup \n - scene: hero stat punches in \n\n Scene 1 (0.0–1.5s): the stat enters via spring-pop-entrance, then counting-dynamic-scale runs the tally. \n\n ## Frame 2 — Freeform \n\n - duration: 4s \n - src: compositions/frames/02-freeform.html \n - blueprint: compose \n\n Scene 1 (0.0–4.0s): a quiet hold, no named motion. \n ` ,
20 );
21
22 const result = buildFramePackets ({ projectDir: project });
23 assert. equal (result. length , 2 );
24
25 const hook = readFileSync (result[ 0 ].path, "utf8" );
26 assert. match (hook, /## Selected blueprint: dataviz-countup/ );
27 assert. match (hook, /## Selected motion rule: spring-pop-entrance/ );
28 assert. match (hook, /## Selected motion rule: counting-dynamic-scale/ );
29 assert. match (hook, /RULES_DIR: / );
30
31 const freeform = readFileSync (result[ 1 ].path, "utf8" );
32 assert. doesNotMatch (freeform, /## Selected blueprint/ );
33 assert. doesNotMatch (freeform, /## Selected motion rule/ );
34 });
35
36 test ( "_role.md is the core contract + this workflow's delta, verbatim" , () => {
37 const project = mkdtempSync ( join ( tmpdir (), "fev-role-" ));
38 write ( join (project, "frame.md" ), "# tokens \n " );
39 write (
40 join (project, "STORYBOARD.md" ),
41 `--- \n format: 1920x1080 \n --- \n\n ## Frame 1 — Hook \n\n - duration: 3s \n - src: compositions/frames/01-hook.html \n ` ,
42 );
43
44 buildFramePackets ({ projectDir: project });
45 const rolePath = join (project, ".hyperframes" , "frame-packets" , "_role.md" );
46 assert. ok ( existsSync (rolePath));
47 const role = readFileSync (rolePath, "utf8" );
48 assert. match (role, /# Frame worker — core contract/ );
49 assert. match (role, /# Frame worker — faceless-explainer delta/ );
50 });
51
52 test ( "packet validation is atomic and leaves no partial output on overflow" , () => {
53 const project = mkdtempSync ( join ( tmpdir (), "fev-atomic-" ));
54 const outDir = join (project, ".hyperframes" , "frame-packets" );
55 write ( join (project, "frame.md" ), "# tokens \n " );
56 write (
57 join (project, "STORYBOARD.md" ),
58 `--- \n format: 1920x1080 \n --- \n\n ## Frame 1 — Big \n\n - duration: 3s \n - src: compositions/frames/01-big.html \n\n ${"padding line \n " . repeat ( 300 ) }` ,
59 );
60
61 assert. throws (
62 () => buildFramePackets ({ projectDir: project, outDir, maxPacketBytes: 2_000 }),
63 /limit 2000/ ,
64 );
65 assert. equal ( existsSync (outDir), false );
66 });