Component tests#5
Draft
opcode81 wants to merge 29 commits into
Draft
Conversation
Add test case covering virtually all cases in the diagram of sync cases in the developer documentation. Changes in test principles: * transformations -> operations * operations can include tests * more well-defined roles of relevant shapes/items and more well-defined operations (particularly make-nested)
The propagation watcher (watch-component-changes) we start to exercise automatic component sync also schedules thumbnail renders on every component-changed event. Thumbnail rendering reaches dom/get-css-variable -> window.getComputedStyle, which has no window in the headless test runner. The render is async/queued, so it fired during a later test in the full suite and crashed the run (each test passed in isolation). Stub the public seam dwth/update-thumbnail to a no-op event via a :each before/after fixture (the same set!-and-restore pattern as the wasm-mock helpers, whose :after runs only after each async test's done). Scope is limited to this namespace; other suites see the real function. Full sync suite now stable: 8 tests, 120 assertions, green across repeated runs.
The sync-scenario operations tracked a single component lineage via flat situation roles (:main-child-rect, :remote-child-rect, ...). Swap needs several lineages to coexist (its target is a different component), and swapping replaces a level's head in place. Replace the flat roles with named component OBJECTS under :vars :components, each grouping that lineage's fields (main-component-id, remote/main head+rect, nesting-count, nesting-data, copies). Every level's nesting-data now also stores the swap-stable :nested-head-parent (a swap keeps the parent, so assertions re-resolve parent -> current head -> rect). create-component/make-nested/instantiate-copy/reset-copy-instance/ propagate-to-copy now take a lineage name. target-shape-id accepts a (situation -> id) function target so change-property can target a computed object field at apply-time; add tm/shape-by-id and lineage accessors. Case K migrated to the object API (88 assertions, unchanged). Full frontend suite green (8 tests, 120 assertions). Common scenario scaffolding test removed per the frontend-only testing policy; common suite green (7/30).
…vels) swap-component(name, level, target, :keep-touched?) drives the production generate-component-swap on a lineage's nesting level (its nested-head), replacing it with the target lineage's component. On the frontend it dispatches the real dwl/component-swap event, so the swap commits through the normal path and the watcher AUTOMATICALLY propagates it to copies — including the deeper nesting levels (each of which contains a copy derived from the swapped one). level-rect/level-color re-resolve a level's rect via the swap-stable nested-head-parent (parent -> current head -> rect), robust to the swap having replaced the head in place (Penpot keeps the head id, rewrites it to the new component, stamps a :swap-slot touched group). Case L proves the "single swap in copy" property: a swap at level i surfaces at level i AND the deeper levels via automatic propagation, while shallower levels are untouched. Frontend suite green (9 tests, 123 assertions).
Build a 3-level nesting, then OPTIONALLY swap the nested component at each level
for a differently-coloured target, and assert the colour at every level. Sweeps
all 2^3 subsets of {swap level 0,1,2}.
Established empirically (on the frontend) the propagation rule: a swap at level i
auto-propagates to level i and every OUTER (higher-index) level, until a swap at
a higher level overrides it. So the colour at level i is the applied swap at the
highest index j <= i, else base. The assertion derives this with a backward
search over the applied swaps, matching the spec's precedence model.
Frontend suite green (9 tests, 144 assertions), stable across repeated runs.
Record case L (swap sweep) and the swap-component operation; refresh the sync-scenario section to the component-OBJECT model (components dict, nesting-data with the swap-stable nested-head-parent) it had drifted from; note the swap propagation rule, the function-target form of target-shape-id, shape-by-id, and the dwl/component-swap frontend realisation. Add variant switch (keep-touched swap) as the next step and re-record the parked penpot#9304 regression-check reminder.
Extract a shared nesting helper (nest-in-new-outer-component) from make-nested, parametrising the inner-instantiation step and the seek-rect origin, so the same contain-outward mechanism serves both plain nesting and variant nesting. Add three variant scenario ops: - make-variant-container: builds a variant set synchronously via the add-variant test-helper idiom (container frame + member roots as children carrying the shared variant-id, then update-component stamps variant-id + variant-properties on each component) with explicit, chosen selector values. - make-nested-component-with-variant: nests a chosen variant member via the shared helper. - switch-variant: a frontend op driving the real variants-switch workspace event (discovers the sibling in the container, routes through component-swap keep-touched? true), with a structure-blind target (role | label | fn) and a nested-head-of target fn. Case M (Design A): introduce one variant instance at the innermost level, wrap it with plain nesting, and assert that switching the single variant head propagates outward to every enclosing level — the variant-switch flavour of case L's swap. Plain make-nested now seeks the current :main-rect (not the fixed origin) so the nesting resolves whether prior nestings were plain or variant. All existing cases (common 7/30, frontend B-F/I/K 88/L 24) remain green; case M is 6/0.
…l switch sweep nested-head was set to the inner copy introduced at each level, but per spec it should be the DEEPEST instance: the descendant of the inner copy head that corresponds to the origin instance (remote-head). The bug was latent for case L (single-layer nesting, where the two coincide) but surfaced for variant nesting, where the variant sits below an outer wrapper at each level. - Compute nested-head via self-or-descendant-corresponding-to (new helper that, unlike descendant-corresponding-to, also matches the head itself — needed at level 0 where the inner copy head IS the origin image). - nest-in-new-outer-component now takes seek-head-id alongside seek-rect-id and seeks the FIXED deepest origin (:remote-head/:remote-rect) for both. - make-nested-component-with-variant re-points :remote-head/:remote-rect to the variant member: nesting a variant makes that member the new deepest origin, so subsequent plain make-nested descends to the variant's image (its nested-head) at every level. With nested-head now pointing at the variant at every level, switch-variant can target any level, so case M becomes the full per-level sweep (case L's exact precedence asserter) rather than a single innermost switch. All cases remain green: common 7/30; frontend B-F/I, K 88, L 24, M now 24.
…iant op Pure rename (record MakeNested -> MakeNestedComponent, constructor, the instance? check in the frontend interpreter, all call sites, and comments). Reads as a sibling of make-nested-component-with-variant; the bare name no longer implies 'component' by omission. No behaviour change: common 7/30, frontend K 88 / L 24 / M 24 (and others) remain green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WIP; See the new memory