alonso.torres 0c97afd032 ✨ Add operations and cases to the composable component suites
The composable runners could edit, add, remove and move children, swap
and switch, but not run the other component operations. New nodes run
each one through the production generator in the pure runner and the
real event in the frontend interpreter:
- Detach, UpdateMain, DeleteComponent and RestoreComponent;
- Duplicate, and NestCopy (a copy moved into a main);
- EditText, with the automatic rename the text editor applies;
- MoveShape (frontend only, through the sidebar) and MoveToCell;
- swap-shape and reset on any copy head;
- Undo with a step count, and an edit undone before its sync (frontend
  only).

New cases, all with the undo/redo round trip:
- Q, R, S, T, U: detach, update main, delete and restore, duplicate
  and nest, at nesting depths 0 to 2;
- V, W, X: a new edit after undo, three undos over nested cascades, an
  undo before the edit's sync;
- Y: text overrides against main text edits;
- Z: a main child move;
- AA to AF: swap outcomes on values and structure, and the grid cell
  of a swapped child;
- AG, AH, AI: the plugin suite's slot alignment cases.

The plugin suite gets OpDetach, OpSwap and OpReset, names that keep
the roles of two nestable components apart, Assert.knownFailure, and
ports of cases Q, AA, AB and K's reset.

Supporting changes: nodes can record what they created
(IAppliedResult); create-component takes a size, since with 0.01
frames the frontend reflows split undo entries at points that depend
on timing (F43); the interpreter ends the text measurement headless,
so text steps settle; tm/known-failure pins the wrong value a known
bug gives in a case assertion; the interpreter no longer moves its
undo baseline after a skipped optional, which cut the end-of-variant
round trip short.

Confirmed and pinned: F12 (resetting a nested swap clears the top
copy's overrides), F27 (the automatic text rename touches
:name-group), F29 (a second switch loses an override) and F44 (a
swapped grid child misses the main's cell changes). F43 also shows
through a plain sync at depth 2 (case Q).
2026-10-13 19:57:56 +02:00

128 lines
6.0 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS SUBSIDIARY SL
(ns frontend-tests.composable-tests.comp.sync-test
"Runs the shared composable component cases
(`app.common.test-helpers.composable.comp.cases`) against the REAL app
(frontend interpreter). In-file propagation is AUTOMATIC: a case contains
ONLY the user edit(s) (no propagate op); the app's component-change watcher
syncs copies on its own, and that is what the cases assert.
Async: each deftest uses `t/async`; `ftm/check` drives the store and calls
`done` when finished."
(:require
[app.common.test-helpers.composable.comp.cases :as cases]
[cljs.test :as t :include-macros true]
[frontend-tests.composable-tests.interpreter :as ftm]))
;; Disable thumbnail rendering for the duration of each (async) test: the
;; propagation watcher schedules thumbnail renders that reach `window`, absent in
;; the headless runner. `:each` `:after` runs only after the test's `done` fires
;; (same guarantee the wasm-mock fixtures rely on), so the no-op covers the whole
;; async lifetime and is scoped to THIS namespace. See ftm/install-thumbnail-noop!.
(t/use-fixtures :each
{:before ftm/install-thumbnail-noop!
:after ftm/restore-thumbnail!})
(t/deftest case-b-copy-override-survives-later-main-change
(t/async done (ftm/check done (cases/copy-override-survives-later-main-change))))
(t/deftest case-c-attribute-sweep-auto-propagates-to-clean-copy
(t/async done (ftm/check done (cases/attribute-sweep-propagates-to-clean-copy))))
(t/deftest case-d-add-shape-to-main-auto-propagates-to-clean-copy
(t/async done (ftm/check done (cases/add-shape-to-main-propagates-to-clean-copy))))
(t/deftest case-e-remove-shape-from-main-auto-propagates-to-clean-copy
(t/async done (ftm/check done (cases/remove-shape-from-main-propagates-to-clean-copy))))
(t/deftest case-f-move-shape-in-main-auto-propagates-order-to-clean-copy
(t/async done (ftm/check done (cases/move-shape-in-main-propagates-order-to-clean-copy))))
(t/deftest case-i-undo-reverts-edit-and-its-auto-propagation
(t/async done (ftm/check done (cases/undo-reverts-edit-and-its-propagation))))
(t/deftest case-p-redo-reapplies-edit-and-its-auto-propagation
(t/async done (ftm/check done (cases/redo-reapplies-edit-and-its-propagation))))
(t/deftest case-h-library-change-propagates-across-file-boundary-on-sync
(t/async done (ftm/check done (cases/library-change-propagates-across-file-boundary-on-sync))))
(t/deftest case-k-synchronisation-scenarios
(t/async done (ftm/check done (cases/synchronisation-scenarios))))
(t/deftest case-l-swap-scenarios
(t/async done (ftm/check done (cases/swap-scenarios))))
(t/deftest case-m-variant-switch-scenarios
(t/async done (ftm/check done (cases/variant-switch-scenarios))))
(t/deftest case-o-variant-switch-keeps-override-only-where-mains-agree
(t/async done (ftm/check done (cases/variant-switch-keeps-override-only-where-mains-agree))))
(t/deftest case-q-detach-keeps-nested-copies-linked
(t/async done (ftm/check done (cases/detach-keeps-nested-copies-linked))))
(t/deftest case-r-update-main-reaches-other-copies
(t/async done (ftm/check done (cases/update-main-reaches-other-copies))))
(t/deftest case-s-deleted-component-copies-sync-again-after-restore
(t/async done (ftm/check done (cases/deleted-component-copies-sync-again-after-restore))))
(t/deftest case-t-duplicated-copy-keeps-overrides-and-link
(t/async done (ftm/check done (cases/duplicated-copy-keeps-overrides-and-link))))
(t/deftest case-u-nested-copy-reaches-copies-of-the-receiving-main
(t/async done (ftm/check done (cases/nested-copy-reaches-copies-of-the-receiving-main))))
(t/deftest case-v-new-edit-after-undo-clears-redo
(t/async done (ftm/check done (cases/new-edit-after-undo-clears-redo))))
(t/deftest case-w-undo-several-steps-over-nested-cascades
(t/async done (ftm/check done (cases/undo-several-steps-over-nested-cascades))))
(t/deftest case-x-undo-before-sync-leaves-copies-unchanged
(t/async done (ftm/check done (cases/undo-before-sync-leaves-copies-unchanged))))
(t/deftest case-y-text-override-merges-with-main-text-change
(t/async done (ftm/check done (cases/text-override-merges-with-main-text-change))))
(t/deftest case-n-geometry-sync-with-rotated-instances
(t/async done (ftm/check done (cases/geometry-sync-with-rotated-instances))))
(t/deftest case-touched-copy-child-survives-main-rotation
(t/async done (ftm/check done (cases/touched-copy-child-survives-main-rotation))))
(t/deftest case-z-main-child-move-reaches-copies
(t/async done (ftm/check done (cases/main-child-move-reaches-copies))))
(t/deftest case-aa-copy-swap-survives-main-changes
(t/async done (ftm/check done (cases/copy-swap-survives-main-changes))))
(t/deftest case-ab-reset-of-nested-swap-keeps-top-copy-overrides
(t/async done (ftm/check done (cases/reset-of-nested-swap-keeps-top-copy-overrides))))
(t/deftest case-ac-second-variant-switch-keeps-root-overrides
(t/async done (ftm/check done (cases/second-variant-switch-keeps-root-overrides))))
(t/deftest case-ad-update-main-pushes-a-swapped-child
(t/async done (ftm/check done (cases/update-main-pushes-a-swapped-child))))
(t/deftest case-ae-detached-or-duplicated-swapped-copy-follows-its-component
(t/async done (ftm/check done (cases/detached-or-duplicated-swapped-copy-follows-its-component))))
(t/deftest case-af-grid-cell-move-reaches-a-swapped-copy-child
(t/async done (ftm/check done (cases/grid-cell-move-reaches-a-swapped-copy-child))))
(t/deftest case-ag-main-reorder-keeps-copy-sub-heads-aligned
(t/async done (ftm/check done (cases/main-reorder-keeps-copy-sub-heads-aligned))))
(t/deftest case-ah-copy-sub-head-delete-keeps-others-aligned
(t/async done (ftm/check done (cases/copy-sub-head-delete-keeps-others-aligned))))
(t/deftest case-ai-copy-sub-head-delete-and-reflow-keeps-others-aligned
(t/async done (ftm/check done (cases/copy-sub-head-delete-and-reflow-keeps-others-aligned))))