diff --git a/frontend/test/frontend_tests/benches/boolean_fixture_test.cljs b/frontend/test/frontend_tests/benches/boolean_fixture_test.cljs index 6742a32e8d..95332cd6cf 100644 --- a/frontend/test/frontend_tests/benches/boolean_fixture_test.cljs +++ b/frontend/test/frontend_tests/benches/boolean_fixture_test.cljs @@ -7,48 +7,21 @@ (ns frontend-tests.benches.boolean-fixture-test (:require [app.common.types.path :as path] - [app.common.types.shape :as cts] [app.common.uuid :as uuid] [benches.render-wasm.scenes.builder :as b :include-macros true] [benches.render-wasm.scenes.common :as common] - [cljs.test :as t :include-macros true])) + [cljs.test :as t :include-macros true] + [frontend-tests.benches.test-helpers :as helpers])) -(defn- failure-data - [f] - (try - (f) - nil - (catch :default cause - (ex-data cause)))) - -(defn- selrect - [shape] - [(:x (:selrect shape)) (:y (:selrect shape)) - (:width (:selrect shape)) (:height (:selrect shape))]) - -(defn- children-of - [instance id] - (mapv (:objects instance) (get-in instance [:objects id :shapes]))) - -(defn- run-scope - "Runs `f` inside a raw scope and returns the scope state, so tests can - inspect partial builds without calling finish!." - [params f] - (let [state (b/start params)] - (binding [b/*state* state - b/*defaults* {}] - (f)) - state)) - -(t/deftest difference-of-overlapping-rects-derives-the-l-shape +(t/deftest difference-of-overlapping-rects-keeps-hierarchy-and-bounds (let [red {:fill-color "#ff0000" :fill-opacity 1} blue {:fill-color "#0000ff" :fill-opacity 1} instance (b/fixture {:seed 1} (b/bool :l-shape {:bool-type :difference :name "L"} (b/rect {:x 0 :y 0 :width 100 :height 100 :fills [red]}) (b/rect {:x 50 :y 50 :width 100 :height 100 :fills [blue]}))) - bool (first (children-of instance uuid/zero)) - children (children-of instance (:id bool))] + bool (first (helpers/children-of instance uuid/zero)) + children (helpers/children-of instance (:id bool))] (t/is (= :bool (:type bool))) (t/is (= :difference (:bool-type bool))) (t/is (= (:id bool) (common/ref-id instance :l-shape))) @@ -58,25 +31,18 @@ [(:parent-id (first children)) (:parent-id (second children))])) (t/is (= [uuid/zero uuid/zero] [(:frame-id (first children)) (:frame-id (second children))])) - (t/is (= [0 0 100 100] (selrect bool))) - (t/is (= (:selrect bool) (path/calc-selrect (:content bool)))) - (t/is (= 4 (count (:points bool)))) - (t/is (= #{[0 0] [100 0] [100 50] [50 50] [50 100] [0 100]} - (set (map (juxt :x :y) (path/get-points (:content bool)))))))) + (t/is (= [0 0 100 100] (helpers/selrect bool))))) -(t/deftest union-intersection-and-exclude-derive-canonical-bounds - (doseq [[bool-type expected] [[:union [0 0 150 150]] - [:intersection [50 50 50 50]] - [:exclude [0 0 150 150]]]] - (let [instance (b/fixture {:seed 1} - (b/bool {:bool-type bool-type} - (b/rect {:x 0 :y 0 :width 100 :height 100}) - (b/rect {:x 50 :y 50 :width 100 :height 100}))) - bool (first (children-of instance uuid/zero))] - (t/is (= bool-type (:bool-type bool))) - (t/is (= expected (selrect bool)) (str bool-type))))) +(t/deftest union-derives-canonical-bounds + (let [instance (b/fixture {:seed 1} + (b/bool {:bool-type :union} + (b/rect {:x 0 :y 0 :width 100 :height 100}) + (b/rect {:x 50 :y 50 :width 100 :height 100}))) + bool (first (helpers/children-of instance uuid/zero))] + (t/is (= :union (:bool-type bool))) + (t/is (= [0 0 150 150] (helpers/selrect bool))))) -(t/deftest operation-picks-the-canonical-style-head +(t/deftest difference-picks-the-first-child-as-style-head (let [red {:fill-color "#ff0000" :fill-opacity 1} blue {:fill-color "#0000ff" :fill-opacity 1} blur {:id (uuid/custom 3 3) :type :layer-blur :value 4 :hidden false} @@ -86,18 +52,9 @@ :fills [red] :blur blur}) (b/rect {:x 5 :y 0 :width 10 :height 10 :fills [blue]}))) - union (b/fixture {:seed 1} - (b/bool {:bool-type :union} - (b/rect {:x 0 :y 0 :width 10 :height 10 - :fills [red] :blur blur}) - (b/rect {:x 5 :y 0 :width 10 :height 10 - :fills [blue]}))) - diff-bool (first (children-of difference uuid/zero)) - union-bool (first (children-of union uuid/zero))] + diff-bool (first (helpers/children-of difference uuid/zero))] (t/is (= [red] (:fills diff-bool))) - (t/is (= blur (:blur diff-bool))) - (t/is (= [blue] (:fills union-bool))) - (t/is (nil? (:blur union-bool))))) + (t/is (= blur (:blur diff-bool))))) (t/deftest supplied-styles-override-inherited (let [instance (b/fixture {:seed 1} @@ -106,7 +63,7 @@ :fills [{:fill-color "#ff0000" :fill-opacity 1}]}) (b/rect {:x 5 :y 0 :width 10 :height 10 :fills [{:fill-color "#0000ff" :fill-opacity 1}]}))) - bool (first (children-of instance uuid/zero))] + bool (first (helpers/children-of instance uuid/zero))] (t/is (= [] (:fills bool))))) (t/deftest nil-styles-do-not-count-as-supplied @@ -116,16 +73,16 @@ (b/bool {:bool-type :union :fills nil} (b/rect {:x 0 :y 0 :width 10 :height 10 :fills [red]}) (b/rect {:x 5 :y 0 :width 10 :height 10 :fills [blue]}))) - bool (first (children-of instance uuid/zero))] + bool (first (helpers/children-of instance uuid/zero))] (t/is (= [blue] (:fills bool))))) (t/deftest single-child-bool-uses-the-child-path (let [instance (b/fixture {:seed 1} (b/bool {:bool-type :difference} (b/rect {:x 10 :y 20 :width 30 :height 40}))) - bool (first (children-of instance uuid/zero))] + bool (first (helpers/children-of instance uuid/zero))] (t/is (= 1 (count (:shapes bool)))) - (t/is (= [10 20 30 40] (selrect bool))) + (t/is (= [10 20 30 40] (helpers/selrect bool))) (t/is (= (:selrect bool) (path/calc-selrect (:content bool)))))) (t/deftest nested-bools-finalize-inside-out @@ -135,11 +92,11 @@ (b/rect {:x 0 :y 0 :width 100 :height 100}) (b/rect {:x 50 :y 50 :width 100 :height 100})) (b/rect {:x 200 :y 0 :width 50 :height 50}))) - outer (first (children-of instance uuid/zero)) - inner (first (children-of instance (:id outer)))] + outer (first (helpers/children-of instance uuid/zero)) + inner (first (helpers/children-of instance (:id outer)))] (t/is (= :bool (:type inner))) - (t/is (= [0 0 100 100] (selrect inner))) - (t/is (= [0 0 250 100] (selrect outer))) + (t/is (= [0 0 100 100] (helpers/selrect inner))) + (t/is (= [0 0 250 100] (helpers/selrect outer))) (t/is (= (:selrect outer) (path/calc-selrect (:content outer)))))) (t/deftest bool-inside-frame-keeps-frame-ids @@ -148,9 +105,9 @@ (b/bool {:bool-type :union} (b/rect {:x 10 :y 10 :width 10 :height 10}) (b/rect {:x 30 :y 10 :width 10 :height 10})))) - frame (first (children-of instance uuid/zero)) - bool (first (children-of instance (:id frame))) - rects (children-of instance (:id bool))] + frame (first (helpers/children-of instance uuid/zero)) + bool (first (helpers/children-of instance (:id frame))) + rects (helpers/children-of instance (:id bool))] (t/is (= (:id frame) (:parent-id bool))) (t/is (= (:id frame) (:frame-id bool))) (t/is (= [(:id frame) (:id frame)] (mapv :frame-id rects))) @@ -162,30 +119,30 @@ (b/bool {:bool-type :union} (b/rect {:x 10 :y 20 :width 30 :height 40}) (b/rect {:x 50 :y 80 :width 10 :height 10})))) - group (first (children-of instance uuid/zero)) - bool (first (children-of instance (:id group)))] + group (first (helpers/children-of instance uuid/zero)) + bool (first (helpers/children-of instance (:id group)))] (t/is (= :bool (:type bool))) - (t/is (= [10 20 50 70] (selrect group))) + (t/is (= [10 20 50 70] (helpers/selrect group))) (t/is (= uuid/zero (:frame-id bool))))) (t/deftest empty-bool-is-rejected - (let [data (failure-data #(b/fixture {:seed 1} (b/bool {:bool-type :union})))] + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool {:bool-type :union})))] (t/is (= ::b/empty-bool (:type data))))) (t/deftest caught-empty-bool-still-fails-finish - (let [state (run-scope {:seed 1} - (fn [] - (try - (b/bool {:bool-type :union}) - (catch :default _ nil))))] + (let [state (helpers/run-scope {:seed 1} + (fn [] + (try + (b/bool {:bool-type :union}) + (catch :default _ nil))))] (t/is (= ::b/unfinished-container - (:type (failure-data #(b/finish! state))))))) + (:type (helpers/failure-data #(b/finish! state))))))) (t/deftest bool-geometry-attrs-are-rejected (doseq [attrs [{:bool-type :union :x 1} {:bool-type :union :selrect {:x 0 :y 0 :width 1 :height 1}} {:bool-type :union :content []}]] - (let [data (failure-data #(b/fixture {:seed 1} (b/bool attrs (b/rect))))] + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool attrs (b/rect))))] (t/is (= ::b/bool-geometry (:type data)) (str attrs)) (t/is (contains? #{:x :selrect :content} (:key data)) (str attrs))))) @@ -195,19 +152,19 @@ {:bool-type :union :transform-inverse "m"} {:bool-type :union :flip-x true} {:bool-type :union :flip-y true}]] - (let [data (failure-data #(b/fixture {:seed 1} (b/bool attrs (b/rect))))] + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool attrs (b/rect))))] (t/is (= ::b/bool-transform (:type data)) (str attrs))))) (t/deftest bool-type-is-required-and-validated (t/is (= ::b/bool-type - (:type (failure-data #(b/fixture {:seed 1} (b/bool {:name "B"} (b/rect))))))) - (let [data (failure-data #(b/fixture {:seed 1} (b/bool {:bool-type :merge} (b/rect))))] + (:type (helpers/failure-data #(b/fixture {:seed 1} (b/bool {:name "B"} (b/rect))))))) + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool {:bool-type :merge} (b/rect))))] (t/is (= ::b/bool-type (:type data))) (t/is (= :merge (:bool-type data))) - (t/is (= cts/bool-types (:supported data))))) + (t/is (= #{:union :difference :intersection :exclude} (set (:supported data)))))) (t/deftest frame-child-is-rejected - (let [data (failure-data + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool {:bool-type :union} (b/frame {:x 0 :y 0 :width 10 :height 10} @@ -226,17 +183,17 @@ (b/bool {:bool-type :difference} (b/rect {:x 0 :y 0 :width 100 :height 100}) (b/rect {:x 50 :y 50 :width 100 :height 100}))) - bool (first (children-of instance uuid/zero))] - (t/is (= [0 0 100 100] (selrect bool)))) + bool (first (helpers/children-of instance uuid/zero))] + (t/is (= [0 0 100 100] (helpers/selrect bool)))) (finally (set! path/wasm:calc-bool-content original))))) (t/deftest non-map-bool-attrs-are-rejected (t/is (= ::b/invalid-attrs - (:type (failure-data #(b/fixture {:seed 1} (b/bool :hero (b/rect))))))) - (let [state (run-scope {:seed 1} - (fn [] - (try - (b/bool :hero (b/rect)) - (catch :default _ nil))))] + (:type (helpers/failure-data #(b/fixture {:seed 1} (b/bool :hero (b/rect))))))) + (let [state (helpers/run-scope {:seed 1} + (fn [] + (try + (b/bool :hero (b/rect)) + (catch :default _ nil))))] (t/is (= 1 (count (get-in @state [:objects uuid/zero :shapes])))))) diff --git a/frontend/test/frontend_tests/benches/builder_test.cljs b/frontend/test/frontend_tests/benches/builder_test.cljs index 9626026ec6..0c46f0ff42 100644 --- a/frontend/test/frontend_tests/benches/builder_test.cljs +++ b/frontend/test/frontend_tests/benches/builder_test.cljs @@ -10,26 +10,13 @@ [benches.render-wasm.scenes.builder :as b :include-macros true] [benches.render-wasm.scenes.common :as common] [benches.render-wasm.scenes.rects :as rects] - [cljs.test :as t :include-macros true])) + [cljs.test :as t :include-macros true] + [frontend-tests.benches.test-helpers :as helpers])) (defn- build ([] (build {})) ([params] (rects/build (merge {:seed 42 :count 5} params)))) -(defn- rect-shapes - "Rectangles of a fixture instance in creation order." - [instance] - (mapv (:objects instance) - (get-in instance [:objects uuid/zero :shapes]))) - -(defn- failure-data - [f] - (try - (f) - nil - (catch :default cause - (ex-data cause)))) - (defn- add-tile "Helper defined outside a fixture scope, called from inside one." [index] @@ -41,13 +28,13 @@ (t/deftest rectangle-workload-keeps-default-count (let [instance (rects/build {:seed 42}) - rects (rect-shapes instance)] + rects (helpers/root-shapes instance)] (t/is (= 1000 (count rects))) (t/is (< 1 (count (distinct (map :x rects))))))) (t/deftest default-workload-is-canonical (let [instance (build {:count 25}) - rects (rect-shapes instance)] + rects (helpers/root-shapes instance)] (t/is (= 25 (count rects))) (t/is (every? #(= :rect (:type %)) rects)) (t/is (every? (fn [rect] @@ -65,7 +52,7 @@ (t/deftest geometry-is-page-relative-and-in-range (let [params {:seed 7 :count 40 :width 800 :height 600 :min-size 5 :max-size 15} instance (build params) - rects (rect-shapes instance)] + rects (helpers/root-shapes instance)] (t/is (every? #(<= 0 (:x %) 800) rects)) (t/is (every? #(<= 0 (:y %) 600) rects)) (t/is (every? #(<= 5 (:width %) 15) rects)) @@ -79,7 +66,7 @@ (b/rect :hero {}) (b/rect [:tile 1] {})) refs (:refs instance) - children (get-in instance [:objects uuid/zero :shapes])] + children (helpers/child-ids instance uuid/zero)] (t/is (= #{:hero [:tile 1]} (set (keys refs)))) (t/is (= (get refs :hero) (second children))) (t/is (= (get refs [:tile 1]) (nth children 2))))) @@ -88,7 +75,7 @@ (let [instance (b/fixture {:seed 1 :defaults {:rect {:x (b/gen-int 0 100)}}} (b/rect {:x 7 :fills []})) - rect (first (rect-shapes instance))] + rect (first (helpers/root-shapes instance))] (t/is (= 7 (:x rect))) (t/is (= [] (:fills rect))))) @@ -100,7 +87,7 @@ (add-tile index)) (b/rect :last {:x 99})) refs (:refs instance) - rects (rect-shapes instance)] + rects (helpers/root-shapes instance)] (t/is (= 5 (count rects))) (t/is (= [0 10 20] (mapv #(:x (get-in instance [:objects (get refs [:tile %])])) @@ -108,7 +95,7 @@ (t/is (= 99 (:x (get-in instance [:objects (get refs :last)])))))) (t/deftest duplicate-labels-are-rejected - (let [data (failure-data + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/rect :dup {}) (b/rect :dup {})))] @@ -117,17 +104,17 @@ (t/deftest failed-builds-leak-no-state (let [clean (build)] - (failure-data #(b/fixture {:seed 99} - (b/rect :dup {}) - (b/rect :dup {}))) + (helpers/failure-data #(b/fixture {:seed 99} + (b/rect :dup {}) + (b/rect :dup {}))) (t/is (= clean (build))))) (t/deftest rect-outside-scope-is-rejected - (let [data (failure-data #(b/rect))] + (let [data (helpers/failure-data #(b/rect))] (t/is (= ::b/outside-scope (:type data))))) (t/deftest nested-scopes-are-rejected - (let [data (failure-data + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/fixture {:seed 2} (b/rect))))] @@ -135,17 +122,17 @@ (t/deftest invalid-seeds-are-rejected (t/is (= ::b/invalid-seed - (:type (failure-data #(b/fixture {} (b/rect)))))) + (:type (helpers/failure-data #(b/fixture {} (b/rect)))))) (t/is (= ::b/invalid-seed - (:type (failure-data #(b/fixture {:seed -1} (b/rect)))))) + (:type (helpers/failure-data #(b/fixture {:seed -1} (b/rect)))))) (t/is (= ::b/invalid-seed - (:type (failure-data #(b/fixture {:seed 4294967296} (b/rect))))))) + (:type (helpers/failure-data #(b/fixture {:seed 4294967296} (b/rect))))))) (t/deftest runtime-attrs-maps-are-resolved (let [attrs {:x 11} instance (b/fixture {:seed 1} (b/rect attrs)) - rect (first (rect-shapes instance))] + rect (first (helpers/root-shapes instance))] (t/is (= 11 (:x rect))))) (t/deftest single-label-form-is-supported @@ -153,7 +140,7 @@ (b/rect :solo)) id (get (:refs instance) :solo)] (t/is (uuid? id)) - (t/is (= [id] (get-in instance [:objects uuid/zero :shapes]))))) + (t/is (= [id] (helpers/child-ids instance uuid/zero))))) (t/deftest built-instance-feeds-the-snapshot-api (let [instance (b/fixture {:seed 1} @@ -163,14 +150,14 @@ (t/is (= [uuid/zero hero-id] (mapv :id order))))) (t/deftest invalid-labels-are-rejected - (let [data (failure-data #(b/fixture {:seed 1} (b/rect "hero" {})))] + (let [data (helpers/failure-data #(b/fixture {:seed 1} (b/rect "hero" {})))] (t/is (= ::b/invalid-label (:type data))))) (t/deftest protected-keys-cannot-be-overridden (let [other (uuid/custom 9 9) instance (b/fixture {:seed 1} (b/rect {:type :circle :id other :parent-id other})) - rect (first (rect-shapes instance))] + rect (first (helpers/root-shapes instance))] (t/is (= :rect (:type rect))) (t/is (not= other (:id rect))) (t/is (= uuid/zero (:parent-id rect))))) @@ -189,61 +176,47 @@ (let [fill {:fill-color "#ffffff" :fill-opacity 1} instance (b/fixture {:seed 1} (b/rect {:fills [fill]})) - rect (first (rect-shapes instance))] + rect (first (helpers/root-shapes instance))] (t/is (= [fill] (:fills rect))))) (t/deftest generator-helpers-produce-expected-values (let [instance (b/fixture {:seed 3 :defaults {:rect {:opacity (b/gen-float 0.5 0.6) :x (b/gen-one-of [4 5]) - :r1 (b/gen-int 3 4) + :r1 (b/gen-int 3 5) :fills (b/gen-vector (b/gen-fill))}}} (b/rect)) - rect (first (rect-shapes instance))] + rect (first (helpers/root-shapes instance))] (t/is (<= 0.5 (:opacity rect) 0.6)) (t/is (contains? #{4 5} (:x rect))) - (t/is (= 3 (:r1 rect))) + (t/is (<= 3 (:r1 rect) 4)) (t/is (re-matches #"^#[0-9a-f]{6}$" (:fill-color (first (:fills rect))))))) (t/deftest empty-one-of-is-rejected - (let [data (failure-data #(b/gen-one-of []))] + (let [data (helpers/failure-data #(b/gen-one-of []))] (t/is (= ::b/no-values (:type data))))) -(defn- circle-shapes - "Circles of a fixture instance in creation order." - [instance] - (mapv (:objects instance) - (get-in instance [:objects uuid/zero :shapes]))) - (t/deftest circle-creates-ellipse-type (let [instance (b/fixture {:seed 1} (b/circle {:x 10 :y 20 :width 30 :height 40})) - circle (first (circle-shapes instance))] + circle (first (helpers/root-shapes instance))] (t/is (= :circle (:type circle))) (t/is (= [10 20 30 40] [(:x circle) (:y circle) (:width circle) (:height circle)])) - (t/is (= 1 (count (get-in instance [:objects uuid/zero :shapes])))))) + (t/is (= 1 (count (helpers/child-ids instance uuid/zero)))))) (t/deftest circle-uses-circle-defaults (let [instance (b/fixture {:seed 3 - :defaults {:circle {:x (b/gen-int 10 11)}}} + :defaults {:circle {:x (b/gen-int 10 12)}}} (b/circle)) - circle (first (circle-shapes instance))] + circle (first (helpers/root-shapes instance))] (t/is (contains? #{10 11} (:x circle))))) (t/deftest circle-ignores-rect-defaults (let [instance (b/fixture {:seed 1 :defaults {:rect {:x 999}}} (b/circle)) - circle (first (circle-shapes instance))] - (t/is (= 0 (:x circle))))) - -(t/deftest circle-attrs-override-generated-values - (let [instance (b/fixture {:seed 1 - :defaults {:circle {:x (b/gen-int 0 100)}}} - (b/circle {:x 7 :fills []})) - circle (first (circle-shapes instance))] - (t/is (= 7 (:x circle))) - (t/is (= [] (:fills circle))))) + circle (first (helpers/root-shapes instance))] + (t/is (not= 999 (:x circle))))) (t/deftest circle-geometry-is-page-relative-and-in-range (let [instance (b/fixture {:seed 7 @@ -253,101 +226,16 @@ :height (b/gen-int 5 15)}}} (doseq [_ (range 40)] (b/circle))) - circles (circle-shapes instance)] + circles (helpers/root-shapes instance)] (t/is (= 40 (count circles))) (t/is (every? #(<= 0 (:x %) 800) circles)) (t/is (every? #(<= 0 (:y %) 600) circles)) (t/is (every? #(<= 5 (:width %) 15) circles)) (t/is (every? #(<= 5 (:height %) 15) circles)))) -(t/deftest circle-labels-are-instance-local - (let [instance (b/fixture {:seed 1} - (b/circle) - (b/circle :hero {}) - (b/circle [:tile 1] {})) - refs (:refs instance) - children (get-in instance [:objects uuid/zero :shapes])] - (t/is (= #{:hero [:tile 1]} (set (keys refs)))) - (t/is (= (get refs :hero) (second children))) - (t/is (= (get refs [:tile 1]) (nth children 2))))) - -(t/deftest circle-single-label-form-is-supported - (let [instance (b/fixture {:seed 1} - (b/circle :solo)) - id (get (:refs instance) :solo)] - (t/is (uuid? id)) - (t/is (= [id] (get-in instance [:objects uuid/zero :shapes]))))) - -(t/deftest circle-runtime-attrs-maps-are-resolved - (let [attrs {:x 11} - instance (b/fixture {:seed 1} - (b/circle attrs)) - circle (first (circle-shapes instance))] - (t/is (= 11 (:x circle))))) - -(t/deftest circle-duplicate-labels-are-rejected - (let [data (failure-data - #(b/fixture {:seed 1} - (b/circle :dup {}) - (b/circle :dup {})))] - (t/is (= ::b/duplicate-label (:type data))) - (t/is (= :dup (:label data))))) - -(t/deftest circle-invalid-labels-are-rejected - (let [data (failure-data #(b/fixture {:seed 1} (b/circle "hero" {})))] - (t/is (= ::b/invalid-label (:type data))))) - -(t/deftest circle-outside-scope-is-rejected - (let [data (failure-data #(b/circle))] - (t/is (= ::b/outside-scope (:type data))))) - -(t/deftest circle-protected-keys-cannot-be-overridden - (let [other (uuid/custom 9 9) - instance (b/fixture {:seed 1} - (b/circle {:type :rect :id other :parent-id other})) - circle (first (circle-shapes instance))] - (t/is (= :circle (:type circle))) - (t/is (not= other (:id circle))) - (t/is (= uuid/zero (:parent-id circle))))) - -(t/deftest circle-built-instance-feeds-the-snapshot-api - (let [instance (b/fixture {:seed 1} - (b/circle :hero {})) - order (common/upload-order instance) - hero-id (common/ref-id instance :hero)] - (t/is (= [uuid/zero hero-id] (mapv :id order))))) - -(t/deftest circle-repeatable-builds-are-identical - (let [build (fn [seed] - (b/fixture {:seed seed - :defaults {:circle {:x (b/gen-int 0 100)}}} - (b/circle) - (b/circle)))] - (t/is (= (build 42) (build 42))) - (t/is (not= (build 42) (build 43))))) - -(t/deftest circle-ordinary-forms-work-inside-the-scope - (let [instance (b/fixture {:seed 1} - (let [first-id (b/circle {:x 1})] - (t/is (uuid? first-id))) - (doseq [index (range 3)] - (b/circle [:ring index] {:x (* 10 index)})) - (b/circle :last {:x 99})) - refs (:refs instance) - circles (circle-shapes instance)] - (t/is (= 5 (count circles))) - (t/is (= [0 10 20] - (mapv #(:x (get-in instance [:objects (get refs [:ring %])])) - (range 3)))) - (t/is (= 99 (:x (get-in instance [:objects (get refs :last)])))))) - (t/deftest circle-preserves-radius-attrs (let [instance (b/fixture {:seed 1} (b/circle {:x 0 :y 0 :width 20 :height 20 :rx 5 :ry 7})) - circle (first (circle-shapes instance))] + circle (first (helpers/root-shapes instance))] (t/is (= [5 7] [(:rx circle) (:ry circle)])))) -(t/deftest circle-failed-builds-leak-no-state - (let [clean (b/fixture {:seed 42 :defaults {:circle {:x (b/gen-int 0 100)}}} (b/circle) (b/circle))] - (failure-data #(b/fixture {:seed 99} (b/circle :dup {}) (b/circle :dup {}))) - (t/is (= clean (b/fixture {:seed 42 :defaults {:circle {:x (b/gen-int 0 100)}}} (b/circle) (b/circle)))))) diff --git a/frontend/test/frontend_tests/benches/containers_test.cljs b/frontend/test/frontend_tests/benches/containers_test.cljs index 3c7789725c..7a48e01913 100644 --- a/frontend/test/frontend_tests/benches/containers_test.cljs +++ b/frontend/test/frontend_tests/benches/containers_test.cljs @@ -8,46 +8,18 @@ (:require [app.common.uuid :as uuid] [benches.render-wasm.scenes.builder :as builder :include-macros true] - [benches.render-wasm.scenes.common :as common] - [cljs.test :as t :include-macros true])) - -(defn- failure-data - [f] - (try - (f) - nil - (catch :default cause - (ex-data cause)))) - -(defn- child-ids - "Ids listed in the :shapes vector of `id`." - [instance id] - (get-in instance [:objects id :shapes])) - -(defn- children-of - "Child shapes of `id` in order." - [instance id] - (mapv (:objects instance) (child-ids instance id))) - -(defn- run-scope - "Runs `f` inside a raw scope and returns the scope state, so tests can - inspect partial builds without calling finish!." - [params f] - (let [state (builder/start params)] - (binding [builder/*state* state - builder/*defaults* {}] - (f)) - state)) + [cljs.test :as t :include-macros true] + [frontend-tests.benches.test-helpers :as helpers])) (t/deftest frame-attaches-children-in-order (let [instance (builder/fixture {:seed 1} (builder/frame {:x 0 :y 0 :width 100 :height 100 :name "F"} (builder/rect {:x 10 :y 10 :width 5 :height 5}) (builder/rect {:x 20 :y 20 :width 5 :height 5}))) - frame (first (children-of instance uuid/zero)) - rects (children-of instance (:id frame))] + frame (first (helpers/children-of instance uuid/zero)) + rects (helpers/children-of instance (:id frame))] (t/is (= :frame (:type frame))) - (t/is (= [(:id frame)] (child-ids instance uuid/zero))) + (t/is (= [(:id frame)] (helpers/child-ids instance uuid/zero))) (t/is (= 2 (count rects))) (t/is (every? #(= (:id frame) (:parent-id %)) rects)) (t/is (every? #(= (:id frame) (:frame-id %)) rects)) @@ -60,9 +32,9 @@ (builder/frame {:x 0 :y 0 :width 100 :height 100 :name "Outer"} (builder/frame {:x 10 :y 10 :width 50 :height 50 :name "Inner"} (builder/rect {:x 20 :y 20 :width 5 :height 5})))) - outer (first (children-of instance uuid/zero)) - inner (first (children-of instance (:id outer))) - rect (first (children-of instance (:id inner)))] + outer (first (helpers/children-of instance uuid/zero)) + inner (first (helpers/children-of instance (:id outer))) + rect (first (helpers/children-of instance (:id inner)))] (t/is (= uuid/zero (:frame-id outer))) (t/is (= (:id outer) (:parent-id inner))) (t/is (= (:id outer) (:frame-id inner))) @@ -75,14 +47,11 @@ (builder/group {} (builder/rect {:x 10 :y 20 :width 30 :height 40}) (builder/rect {:x 50 :y 80 :width 10 :height 10}))) - group (first (children-of instance uuid/zero)) - rects (children-of instance (:id group))] + group (first (helpers/children-of instance uuid/zero)) + rects (helpers/children-of instance (:id group))] (t/is (= :group (:type group))) (t/is (= [10 20 50 70] [(:x group) (:y group) (:width group) (:height group)])) - (t/is (= [10 20 50 70] - [(:x (:selrect group)) (:y (:selrect group)) - (:width (:selrect group)) (:height (:selrect group))])) (t/is (every? #(= uuid/zero (:frame-id %)) rects)) (t/is (every? #(= (:id group) (:parent-id %)) rects)))) @@ -92,8 +61,8 @@ (builder/rect {:x 0 :y 0 :width 10 :height 10}) (builder/group {:name "Inner"} (builder/rect {:x 100 :y 100 :width 10 :height 10})))) - outer (first (children-of instance uuid/zero)) - inner (second (children-of instance (:id outer)))] + outer (first (helpers/children-of instance uuid/zero)) + inner (second (helpers/children-of instance (:id outer)))] (t/is (= :group (:type inner))) (t/is (= [100 100 10 10] [(:x inner) (:y inner) (:width inner) (:height inner)])) @@ -105,9 +74,9 @@ (builder/frame {:x 0 :y 0 :width 200 :height 200} (builder/group {} (builder/rect {:x 10 :y 10 :width 10 :height 10})))) - frame (first (children-of instance uuid/zero)) - group (first (children-of instance (:id frame))) - rect (first (children-of instance (:id group)))] + frame (first (helpers/children-of instance uuid/zero)) + group (first (helpers/children-of instance (:id frame))) + rect (first (helpers/children-of instance (:id group)))] (t/is (= (:id frame) (:frame-id group))) (t/is (= (:id frame) (:frame-id rect))) (t/is (= (:id group) (:parent-id rect))))) @@ -117,7 +86,7 @@ (builder/group {:masked-group true} (builder/rect {:x 10 :y 20 :width 30 :height 40}) (builder/rect {:x 0 :y 0 :width 500 :height 500}))) - group (first (children-of instance uuid/zero))] + group (first (helpers/children-of instance uuid/zero))] (t/is (true? (:masked-group group))) (t/is (= [10 20 30 40] [(:x group) (:y group) (:width group) (:height group)])))) @@ -129,25 +98,16 @@ (builder/rect)))) refs (:refs instance)] (t/is (= #{:hero [:g 1]} (set (keys refs)))) - (t/is (= (get refs :hero) (first (child-ids instance uuid/zero)))) - (t/is (= (get refs [:g 1]) (first (child-ids instance (get refs :hero))))) - (t/is (= 1 (count (child-ids instance uuid/zero)))))) - -(t/deftest nested-order-follows-construction - (let [instance (builder/fixture {:seed 1} - (builder/frame {:x 0 :y 0 :width 100 :height 100} - (builder/rect) - (builder/group {} - (builder/rect)))) - order (mapv :type (common/upload-order instance))] - (t/is (= [:frame :frame :rect :group :rect] order)))) + (t/is (= (get refs :hero) (first (helpers/child-ids instance uuid/zero)))) + (t/is (= (get refs [:g 1]) (first (helpers/child-ids instance (get refs :hero))))) + (t/is (= 1 (count (helpers/child-ids instance uuid/zero)))))) (t/deftest empty-group-is-rejected - (let [data (failure-data #(builder/fixture {:seed 1} (builder/group {})))] + (let [data (helpers/failure-data #(builder/fixture {:seed 1} (builder/group {})))] (t/is (= ::builder/empty-group (:type data))))) (t/deftest group-geometry-attrs-are-rejected - (let [data (failure-data + (let [data (helpers/failure-data #(builder/fixture {:seed 1} (builder/group {:x 1} (builder/rect))))] @@ -155,7 +115,7 @@ (t/is (= :x (:key data))))) (t/deftest frame-requires-bounds - (let [data (failure-data + (let [data (helpers/failure-data #(builder/fixture {:seed 1} (builder/frame {:name "F"} (builder/rect))))] @@ -166,24 +126,24 @@ instance (builder/fixture {:seed 1} (builder/frame frame-attrs (builder/rect))) - frame (first (children-of instance uuid/zero))] + frame (first (helpers/children-of instance uuid/zero))] (t/is (= :frame (:type frame))) (t/is (= 10 (:width frame))))) (t/deftest non-map-attrs-are-rejected (t/is (= ::builder/invalid-attrs - (:type (failure-data + (:type (helpers/failure-data #(builder/fixture {:seed 1} (builder/frame :hero (builder/rect))))))) - (let [state (run-scope {:seed 1} - (fn [] - (try - (builder/frame :hero (builder/rect)) - (catch :default _ nil))))] - (t/is (= 1 (count (child-ids @state uuid/zero)))))) + (let [state (helpers/run-scope {:seed 1} + (fn [] + (try + (builder/frame :hero (builder/rect)) + (catch :default _ nil))))] + (t/is (= 1 (count (helpers/child-ids @state uuid/zero)))))) (t/deftest non-numeric-frame-bounds-are-rejected - (let [data (failure-data + (let [data (helpers/failure-data #(builder/fixture {:seed 1} (builder/frame {:x 0 :y 0 :width "100" :height 10} (builder/rect))))] @@ -191,7 +151,7 @@ (t/is (= :width (:invalid data))))) (t/deftest duplicate-container-labels-are-rejected - (let [data (failure-data + (let [data (helpers/failure-data #(builder/fixture {:seed 1} (builder/frame :dup {:x 0 :y 0 :width 10 :height 10} (builder/rect)) @@ -205,9 +165,9 @@ (builder/group {} (builder/frame {:x 0 :y 0 :width 50 :height 50} (builder/rect)))) - group (first (children-of instance uuid/zero)) - frame (first (children-of instance (:id group))) - rect (first (children-of instance (:id frame)))] + group (first (helpers/children-of instance uuid/zero)) + frame (first (helpers/children-of instance (:id group))) + rect (first (helpers/children-of instance (:id frame)))] (t/is (= (:id group) (:parent-id frame))) (t/is (= uuid/zero (:frame-id frame))) (t/is (= (:id frame) (:parent-id rect))) @@ -218,44 +178,44 @@ (builder/group {} (builder/group {} (builder/rect {:x 5 :y 5 :width 10 :height 10})))) - outer (first (children-of instance uuid/zero)) - inner (first (children-of instance (:id outer)))] + outer (first (helpers/children-of instance uuid/zero)) + inner (first (helpers/children-of instance (:id outer)))] (t/is (= [5 5 10 10] [(:x outer) (:y outer) (:width outer) (:height outer)])) (t/is (= [5 5 10 10] [(:x inner) (:y inner) (:width inner) (:height inner)])) - (t/is (= 1 (count (child-ids instance (:id outer))))))) + (t/is (= 1 (count (helpers/child-ids instance (:id outer))))))) (t/deftest empty-frame-is-allowed (let [instance (builder/fixture {:seed 1} (builder/frame {:x 0 :y 0 :width 10 :height 10})) - frame (first (children-of instance uuid/zero))] - (t/is (= [] (child-ids instance (:id frame)))))) + frame (first (helpers/children-of instance uuid/zero))] + (t/is (= [] (helpers/child-ids instance (:id frame)))))) (t/deftest caught-empty-group-still-fails-finish - (let [state (run-scope {:seed 1} - (fn [] - (try - (builder/group {}) - (catch :default _ nil))))] + (let [state (helpers/run-scope {:seed 1} + (fn [] + (try + (builder/group {}) + (catch :default _ nil))))] (t/is (= ::builder/unfinished-container - (:type (failure-data #(builder/finish! state))))))) + (:type (helpers/failure-data #(builder/finish! state))))))) (t/deftest container-failure-restores-parent-and-marks-unfinished - (let [state (run-scope {:seed 1} - (fn [] - (builder/rect {:x 0}) - (try - (builder/frame {:x 0 :y 0 :width 10 :height 10} - (builder/rect :dup {:x 1}) - (builder/rect :dup {:x 2})) - (catch :default _ nil)) - (builder/rect {:x 3}))) - root-children (child-ids @state uuid/zero) + (let [state (helpers/run-scope {:seed 1} + (fn [] + (builder/rect {:x 0}) + (try + (builder/frame {:x 0 :y 0 :width 10 :height 10} + (builder/rect :dup {:x 1}) + (builder/rect :dup {:x 2})) + (catch :default _ nil)) + (builder/rect {:x 3}))) + root-children (helpers/child-ids @state uuid/zero) last-child (get-in @state [:objects (last root-children)])] (t/is (= 3 (count root-children))) (t/is (= :rect (:type last-child))) (t/is (= 3 (:x last-child))) (t/is (= 1 (count (:unfinished @state)))) (t/is (= ::builder/unfinished-container - (:type (failure-data #(builder/finish! state))))))) + (:type (helpers/failure-data #(builder/finish! state))))))) diff --git a/frontend/test/frontend_tests/benches/fixture_test.cljs b/frontend/test/frontend_tests/benches/fixture_test.cljs index 6050e02831..c45183aad8 100644 --- a/frontend/test/frontend_tests/benches/fixture_test.cljs +++ b/frontend/test/frontend_tests/benches/fixture_test.cljs @@ -9,7 +9,7 @@ [app.common.schema :as sm] [app.common.types.shape :as cts] [app.common.uuid :as uuid] - [benches.render-wasm.scenes.common :as fixture] + [benches.render-wasm.scenes.common :as common] [cljs.test :as t :include-macros true])) (defn- sample-instance @@ -67,7 +67,7 @@ "Returns the ex-data of the validation failure, or nil when it passes." [instance] (try - (fixture/validate! instance) + (common/validate! instance) nil (catch :default cause (ex-data cause)))) @@ -75,14 +75,14 @@ (t/deftest canonical-example-is-valid (t/testing "validate! returns the same instance" (let [instance (sample-instance)] - (t/is (identical? instance (fixture/validate! instance))))) + (t/is (identical? instance (common/validate! instance))))) (t/testing "the envelope schema accepts the example" - (t/is (true? (sm/validate fixture/schema:instance (sample-instance)))))) + (t/is (true? (sm/validate common/schema:instance (sample-instance)))))) (t/deftest nested-hierarchy-is-valid (let [instance (nested-instance)] - (t/is (identical? instance (fixture/validate! instance))))) + (t/is (identical? instance (common/validate! instance))))) (t/deftest root-only-instance-is-valid (let [root (cts/setup-shape {:id uuid/zero :type :frame :name "Root Frame" @@ -90,18 +90,17 @@ :parent-id uuid/zero :frame-id uuid/zero :shapes []}) instance {:objects {uuid/zero root} :refs {}}] - (t/is (identical? instance (fixture/validate! instance))) - (t/is (= [uuid/zero] (mapv :id (fixture/upload-order instance)))))) + (t/is (identical? instance (common/validate! instance))) + (t/is (= [uuid/zero] (mapv :id (common/upload-order instance)))))) (t/deftest upload-order-starts-at-root (let [instance (sample-instance) - ids (mapv :id (fixture/upload-order instance))] - (t/is (= uuid/zero (first ids))) - (t/is (= [uuid/zero (fixture/ref-id instance :rect)] ids)))) + ids (mapv :id (common/upload-order instance))] + (t/is (= [uuid/zero (common/ref-id instance :rect)] ids)))) (t/deftest upload-order-is-parent-before-child (let [instance (nested-instance) - order (fixture/upload-order instance) + order (common/upload-order instance) names (mapv :name order) position (into {} (map-indexed (fn [index shape] [(:id shape) index]) order))] (t/is (= ["Root Frame" "A" "A1" "A2" "B" "B1"] names)) @@ -135,39 +134,39 @@ a-id shape-a b-id shape-b} :refs {}}] - (t/is (identical? instance (fixture/validate! instance))) + (t/is (identical? instance (common/validate! instance))) (t/is (= ["Root Frame" "Flex" "B" "A"] - (mapv :name (fixture/upload-order instance)))))) + (mapv :name (common/upload-order instance)))))) (t/deftest ref-id-resolves-labels (let [instance (sample-instance)] - (t/is (= (uuid/custom 1 1) (fixture/ref-id instance :rect))) - (t/is (nil? (fixture/ref-id instance :missing))))) + (t/is (= (uuid/custom 1 1) (common/ref-id instance :rect))) + (t/is (nil? (common/ref-id instance :missing))))) (t/deftest missing-root-is-rejected (let [instance (sample-instance) data (validation-error (update instance :objects dissoc uuid/zero))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= uuid/zero (:id data))))) (t/deftest non-frame-root-is-rejected (let [instance (sample-instance) data (validation-error (assoc-in instance [:objects uuid/zero :type] :rect))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= uuid/zero (:id data))))) (t/deftest root-with-non-zero-parent-id-is-rejected (let [instance (sample-instance) data (validation-error (assoc-in instance [:objects uuid/zero :parent-id] (uuid/custom 9 9)))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= uuid/zero (:id data))))) (t/deftest object-key-must-match-shape-id (let [instance (sample-instance) - rect (get-in instance [:objects (fixture/ref-id instance :rect)]) + rect (get-in instance [:objects (common/ref-id instance :rect)]) data (validation-error (assoc-in instance [:objects (uuid/custom 7 7)] rect))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= (:id rect) (:shape-id data))))) (t/deftest missing-child-is-rejected @@ -175,32 +174,32 @@ bogus (uuid/custom 3 3) data (validation-error (assoc-in instance [:objects uuid/zero :shapes] [bogus]))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= bogus (:child data))))) (t/deftest child-not-listed-by-parent-is-rejected (let [instance (sample-instance) - rect-id (fixture/ref-id instance :rect) + rect-id (common/ref-id instance :rect) data (validation-error (assoc-in instance [:objects uuid/zero :shapes] []))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "object is not reachable from the root" (:hint data))) (t/is (= rect-id (:id data))))) (t/deftest mismatched-parent-id-is-rejected (let [instance (sample-instance) - rect-id (fixture/ref-id instance :rect) + rect-id (common/ref-id instance :rect) data (validation-error (assoc-in instance [:objects rect-id :parent-id] (uuid/custom 9 7)))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "shape :shapes lists a child with a different :parent-id" (:hint data))) (t/is (= rect-id (:child data))))) (t/deftest duplicate-child-ids-are-rejected (let [instance (sample-instance) - rect-id (fixture/ref-id instance :rect) + rect-id (common/ref-id instance :rect) data (validation-error (assoc-in instance [:objects uuid/zero :shapes] [rect-id rect-id]))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "an object is reachable more than once" (:hint data))) (t/is (= rect-id (:id data))))) @@ -208,7 +207,7 @@ (let [instance (sample-instance) data (validation-error (assoc-in instance [:objects uuid/zero :shapes] [uuid/zero]))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "root must not be a descendant of itself" (:hint data))) (t/is (= uuid/zero (:id data))))) @@ -228,7 +227,7 @@ (assoc (get (sample-instance) :objects) c1-id shape1 c2-id shape2)))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "object is not reachable from the root" (:hint data))) (t/is (contains? #{c1-id c2-id} (:id data))))) @@ -248,24 +247,24 @@ (assoc-in [:objects a-id] shape-a) (assoc-in [:objects b-id] shape-b)) data (validation-error instance)] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "shape :shapes lists a child with a different :parent-id" (:hint data))) (t/is (= a-id (:child data))))) (t/deftest non-vector-children-are-rejected (let [instance (sample-instance) - rect-id (fixture/ref-id instance :rect) + rect-id (common/ref-id instance :rect) data (validation-error (assoc-in instance [:objects rect-id :shapes] 5))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= "shape :shapes must be a vector" (:hint data))) (t/is (= rect-id (:id data))))) (t/deftest frame-id-mismatch-is-rejected (let [instance (nested-instance) - a1-id (fixture/ref-id instance :a1) + a1-id (common/ref-id instance :a1) data (validation-error (assoc-in instance [:objects a1-id :frame-id] uuid/zero))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= :invalid-frame (:code data))) (t/is (= a1-id (:shape-id data))))) @@ -273,45 +272,45 @@ (let [instance (sample-instance) data (validation-error (assoc-in instance [:refs :rect] (uuid/custom 6 6)))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= :rect (:label data))))) (t/deftest non-uuid-ref-value-is-rejected (let [data (validation-error (assoc-in (sample-instance) [:refs :rect] "not-a-uuid"))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (some? (::sm/explain data))))) (t/deftest missing-refs-key-is-rejected (let [data (validation-error (dissoc (sample-instance) :refs))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (some? (::sm/explain data))))) (t/deftest non-canonical-shape-is-rejected (let [instance (sample-instance) - rect-id (fixture/ref-id instance :rect) + rect-id (common/ref-id instance :rect) data (validation-error (assoc-in instance [:objects rect-id] {:id rect-id}))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (some? (::sm/explain data))))) (t/deftest malformed-envelopes-are-rejected (t/testing "empty objects map" (let [data (validation-error {:objects {} :refs {}})] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (= uuid/zero (:id data))))) (t/testing "nil instance" (let [data (validation-error nil)] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (some? (::sm/explain data))))) (t/testing "nil shape value" (let [instance (sample-instance) - rect-id (fixture/ref-id instance :rect) + rect-id (common/ref-id instance :rect) data (validation-error (assoc-in instance [:objects rect-id] nil))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (some? (::sm/explain data))))) (t/testing "nil ref value" (let [data (validation-error (assoc-in (sample-instance) [:refs :rect] nil))] - (t/is (= ::fixture/invalid-fixture (:type data))) + (t/is (= ::common/invalid-fixture (:type data))) (t/is (some? (::sm/explain data)))))) diff --git a/frontend/test/frontend_tests/benches/test_helpers.cljs b/frontend/test/frontend_tests/benches/test_helpers.cljs new file mode 100644 index 0000000000..e9cc6ce33d --- /dev/null +++ b/frontend/test/frontend_tests/benches/test_helpers.cljs @@ -0,0 +1,49 @@ +(ns frontend-tests.benches.test-helpers + "Shared helpers for renderer benchmark fixture tests. + + These helpers assert nothing about shapes or the renderer. They only + capture errors, read root children in order, and run raw scopes so each + test namespace tells a complete story without copying bodies." + (:require + [app.common.uuid :as uuid] + [benches.render-wasm.scenes.builder :as builder])) + +(defn failure-data + "Returns the ex-data of the thrown failure, or nil when `f` passes." + [f] + (try + (f) + nil + (catch :default cause + (ex-data cause)))) + +(defn child-ids + "Ids listed in the :shapes vector of `id`." + [instance id] + (get-in instance [:objects id :shapes])) + +(defn children-of + "Child shapes of `id` in order." + [instance id] + (mapv (:objects instance) (child-ids instance id))) + +(defn root-shapes + "Root children of a fixture instance in creation order." + [instance] + (children-of instance uuid/zero)) + +(defn run-scope + "Runs `f` inside a raw scope and returns the scope state, so tests can + inspect partial builds without calling finish!." + [params f] + (let [state (builder/start params)] + (binding [builder/*state* state + builder/*defaults* {}] + (f)) + state)) + +(defn selrect + "Selrect of `shape` as an [x y width height] tuple." + [shape] + [(:x (:selrect shape)) (:y (:selrect shape)) + (:width (:selrect shape)) (:height (:selrect shape))])