test(core): address review feedback on T6a / T10 / T7 stubs#1268
Conversation
miguel-heygen
left a comment
There was a problem hiding this comment.
All three gaps addressed correctly.
✅ Fixed
T6a — tl.fromTo corpus: FROMTO_SCRIPT covers the third parser method with negative x/y values that exercise the UnaryExpression arm in resolveNode. fromto.parsed.json correctly introduces fromProperties (from-vars) as a separate field from properties (to-vars) — the schema extension is consistent with what R7 would expect. fromto.serialized.js emits the correct three-argument form (tl.fromTo(sel, fromVars, toVars, pos)). Dropping breatheRepeats from COMPLEX_SCRIPT is fine — it was unreachable by a tl.* call and the golden is unaffected.
T10 — edge cases: All four new stubs in "applyDraft edge cases" are substantive spec constraints:
- Overwrite-not-accumulate on rapid drags (easy R7 bug)
- Idempotent revert (crash risk if called mid-setup)
- Opacity re-evaluated per-call (not cached on drag start)
- Nested
data-hf-rootexclusion scoped to outermost only — this is the one I'd most expect an implementer to get wrong by accident
The missing getElementTimings stub for absent data-start/data-end on a valid data-hf-id element closes the only gap in the timing contract (defined-but-empty vs undefined return).
T7 — T3 parity: Now 5 stubs matching T3 exactly. The original naming concern (over-specifying [data-hf-id=…] selector syntax) is resolved — all stubs name behavioral contracts, not implementation details.
Still open from prior review
P2 from #1263: parseAndSerialize has no labeled error boundary — a throw in the parser vs serializer step produces an undifferentiated failure. Still worth adding before T6b/c; not blocking here.
Approved.
james-russo-rames-d-jusso
left a comment
There was a problem hiding this comment.
Round-2 / round-1-of-the-feedback-PR review. Walked the delta against the prior stack head (#1267 tip → #1268 tip is ~60 lines of net-new content, the rest of the +934 is the rebased stack content against main). All three feedback items I raised on T6a / T10 / T7 are addressed with the exact fix shape suggested.
What was addressed
[T6a corpus gap — tl.fromTo + negative numbers] RESOLVED CLEAN. gsapParser.golden.test.ts:62-68 adds FROMTO_SCRIPT with two tl.fromTo(target, fromArg, toArg, position) calls, including x: -200 and y: -30 to exercise the UnaryExpression arm in resolveNode. The generated fromto.parsed.json shows the parser materializes both halves as separate properties and fromProperties fields under method: "fromTo" — that's a distinct schema branch from to/from, so the swap-PR regression diff will now surface fromTo-specific behavior changes. The accompanying breatheRepeats removal from COMPLEX_SCRIPT (called out as dead in my round-1 review) landed too. Comment block at line 60 documents exactly why FROMTO_SCRIPT exists ("three-argument AST path and negative numeric literals"). ✓
[T10 stub split + edge cases + missing timings path] RESOLVED CLEAN. Three changes in previewAdapter.test.ts:
- Lines 29 + 31 split the original combined stub into two — moveDraft + resizeDraft addressed independently, so a failing R7 implementation of one no longer masks the other.
- New
applyDraft edge cases (R7 implementation contract)describe block at lines 38-54 captures all four edges I called out:- "second applyDraft before revert/commit overwrites first draft — does not accumulate (dx/dy)" (concurrent gestures)
- "revertDraft is safe to call when no gesture is in progress" (idempotent)
- "elementAtPoint filtering is stable when playhead changes mid-drag — opacity re-evaluated per call" (playhead motion)
- "stage-root exclusion applies only to the outermost data-hf-root; nested sub-composition roots count as targets" (nested roots)
- Lines 71-73 add the missing
getElementTimings"data-hf-id present but data-start/data-end missing" stub.
Each edge case is phrased as a concrete invariant (not just a topic) — R7's implementor flips them from it.todo to it(…) without ambiguity. Exactly the shape I asked for. ✓
[T7 surface asymmetry] RESOLVED CLEAN — went with option (b). sourceMutation.test.ts:370-380 is now five stubs matching T3:
- updates inline style by data-hf-id
- updates text content by data-hf-id (new)
- updates attribute by data-hf-id (new)
- data-hf-id attribute survives the patch
- hfId lookup falls through to selector when hfId not found (new)
The asymmetry-clarification I was looking for materialized as the actual code path: Core's findTargetElement exposes the same patch types as Studio's findTagByTarget. PR body confirms: "Core patchElementInHtml supports the same patch types as Studio sourcePatcher." That answer's load-bearing for R1, and now it's pinned in the test file. ✓
Two tiny nits worth catching
[nit — gsapParser.golden.test.ts docstring is stale] The header at lines 9-12 still says "Three representative scripts: minimal / moderate / complex". Now four. One line:
* complex — stagger, chained .from()/.to(), const/defaults (vpn-youtube-spot)
+* fromTo — two tl.fromTo calls with negative positions (hero-reveal)
*/[nit — "stage root" vs. "outermost root" phrasing in T10] Line 17:
it.todo("returns null for the stage root (data-hf-root)");Reads as "the (singular) stage root" — but the edge case at line 52 clarifies that nested sub-composition data-hf-root elements count as targets. The two stubs are reconcilable on careful read but a first-time reader of just the first describe block could implement "any data-hf-root is excluded." Tightening the first stub to "returns null for the outermost stage root (data-hf-root)" makes the contract self-contained at the first encounter.
Process note
This PR collapses the entire 7-PR Graphite stack (#1257 through #1267) onto main as a single follow-up. additions: 934 / deletions: 37 against main so the diff looks huge; against the prior stack head it's ~60 lines of net-new feedback-addressing content. Reviewers walking this fresh might want to focus on the four files actually touched beyond the stack scope: gsapParser.golden.test.ts (+25), previewAdapter.test.ts (+24), sourceMutation.test.ts (+8), plus the two new fromto.* golden files.
Verdict
Every concrete code suggestion from round 1 landed verbatim — the WEIGHT_TOKENS_SORTED-style "you picked exactly the fix shape I described" pattern, applied across three different files this round. Two doc/phrasing nits worth a 30-second polish before merge, otherwise clean from where I sit. Leaving as a comment.
— Review by Rames D Jusso
e926c74 to
564bd4b
Compare
5a7e312 to
3385925
Compare
T6a (#1263): add fromTo corpus script (third parser method) with negative position values to exercise UnaryExpression arm; drop unused breatheRepeats from COMPLEX_SCRIPT; generate fromto.parsed.json + fromto.serialized.js goldens. T10 (#1262): split applyDraft move/resize into two stubs; add applyDraft edge- case describe block (concurrent gestures, idempotent revert, playhead-change stability, nested sub-composition root); add getElementTimings stub for absent data-start/end on a data-hf-id element. T7 (#1267): expand to full parity with T3 — add text-content, attribute, and fallthrough stubs (Core sourceMutation supports all patch types via patchElementInHtml).
3385925 to
bf0e4af
Compare

What
Addresses review feedback on PRs #1263 (T6a), #1262 (T10), and #1267 (T7) from the SDK test-plan stack.
Why
Reviewer (james-russo) identified three substantive gaps across the stack that should be closed before R1 begins:
tl.toandtl.fromwere covered;tl.fromTo(third parser method) was unexercised, leaving the Meriyah swap without a regression gate for that branch.applyDraftstub too coarse — Single stub covering both move and resize payloads; four gesture edge cases (concurrent gestures, idempotent revert, playhead-change stability, nested roots) not pinned before R7 starts.patchElementInHtmlsupports the same patch types as StudiosourcePatcher, so T7 stubs should match T3's surface.How
T6a: Added
FROMTO_SCRIPTwith twotl.fromTo()calls including negative positions (x: -200,y: -30), covering the three-argument AST path and theUnaryExpressionarm inresolveNode. Generatedfromto.parsed.jsonandfromto.serialized.jsgoldens. Dropped unusedbreatheRepeatsfromCOMPLEX_SCRIPT(never reached atl.*call; removing it has no effect on the golden output as the preamble never captured it).T10: Split
"applyDraft accepts both move (dx/dy) and resize (w/h) payloads"into two stubs. Added new"applyDraft edge cases"describe block with four stubs pinning gesture interaction invariants. Added missinggetElementTimingsstub for the absentdata-start/data-endpath.T7: Added three stubs for text-content, attribute, and fallthrough, bringing T7 to full parity with T3 (5 stubs each).
Test plan
bun run --cwd packages/core test— 1311 pass, 28 todo (8 new todos from T10/T7 stubs, 2 new passing tests from fromTo golden)