mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
🚧 WIP Step 9, fix naming conventions
This commit is contained in:
parent
c16233f841
commit
8d04530e07
@ -34,7 +34,7 @@
|
||||
"Options:\n"
|
||||
summary "\n\n"
|
||||
"No command is implemented yet. Upcoming tickets add:\n"
|
||||
" run benchmark standard fixtures and operations\n"
|
||||
" run benchmark standard scenes and operations\n"
|
||||
" ab feature A/B matrix\n"
|
||||
" compare offline comparison of two result files\n\n"
|
||||
"Commands, options and reporting arrive with the later renderer\n"
|
||||
|
||||
@ -5,17 +5,17 @@
|
||||
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
(ns benches.render-wasm.scenes.builder
|
||||
"Construction macros for renderer benchmark fixtures.
|
||||
"Construction macros for renderer benchmark scenes.
|
||||
|
||||
Runtime helpers and scope state live in the sibling `builder.cljs`.
|
||||
|
||||
Usage:
|
||||
|
||||
(fixture {:seed 42
|
||||
:defaults {:rect {:x (gen-int 0 1920)}}}
|
||||
(scene {:seed 42
|
||||
:defaults {:rect {:x (gen-int 0 1920)}}}
|
||||
(rect) ; anonymous, generated attrs
|
||||
(rect {:x 10}) ; literal x over the generated rest
|
||||
(rect :hero {}) ; label stored in instance :refs
|
||||
(rect :hero {}) ; label stored in snapshot :refs
|
||||
(frame {:x 0 :y 0 :width 100 :height 100}
|
||||
(rect))
|
||||
(group :tiles {}
|
||||
@ -36,8 +36,8 @@
|
||||
and functions defined outside the scope work inside the body. Scopes
|
||||
cannot nest and a body exception unwinds without leaking state.")
|
||||
|
||||
(defmacro fixture
|
||||
"Runs `body` in a fixture scope and returns the validated snapshot."
|
||||
(defmacro scene
|
||||
"Runs `body` in a scene scope and returns the validated snapshot."
|
||||
[params & body]
|
||||
`(let [params# ~params
|
||||
state# (benches.render-wasm.scenes.builder/start params#)]
|
||||
@ -47,7 +47,7 @@
|
||||
(benches.render-wasm.scenes.builder/finish! state#))))
|
||||
|
||||
(defmacro rect
|
||||
"Adds one rectangle to the current fixture scope and returns its uuid.
|
||||
"Adds one rectangle to the current scene scope and returns its uuid.
|
||||
|
||||
Forms: `(rect)`, `(rect attrs)`, `(rect label)`, `(rect label attrs)`.
|
||||
A one-argument call is resolved at runtime: a map is `attrs`, anything
|
||||
@ -76,7 +76,7 @@
|
||||
~attrs)))
|
||||
|
||||
(defmacro circle
|
||||
"Adds one ellipse to the current fixture scope and returns its uuid.
|
||||
"Adds one ellipse to the current scene scope and returns its uuid.
|
||||
|
||||
Forms: `(circle)`, `(circle attrs)`, `(circle label)`, `(circle label attrs)`.
|
||||
A one-argument call is resolved at runtime: a map is `attrs`, anything
|
||||
|
||||
@ -5,22 +5,23 @@
|
||||
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
(ns benches.render-wasm.scenes.builder
|
||||
"Scoped construction for renderer benchmark fixtures.
|
||||
"Scoped construction for renderer benchmark scenes.
|
||||
|
||||
A fixture scope owns one seeded generator, one object map, and one label
|
||||
map. Shape constructors add themselves to the current parent: `rect`, and
|
||||
the `frame`/`group`/`bool` container scopes. The scope returns a validated
|
||||
snapshot in the ticket02 contract `{:objects ... :refs ...}`.
|
||||
A scene scope owns one seeded generator, one object map, and one label
|
||||
map. Shape constructors add themselves to the current parent: `rect`,
|
||||
`circle`, and the `frame`/`group`/`bool` container scopes. The scope
|
||||
returns a validated snapshot in the ticket02 contract
|
||||
`{:objects ... :refs ...}`.
|
||||
|
||||
Construction is synchronous by design: the scope and the current parent
|
||||
are carried by dynamic vars, so `let`, `doseq` and functions defined
|
||||
outside the scope all work inside a fixture. Fixture scopes cannot nest
|
||||
outside the scope all work inside a scene. Scene scopes cannot nest
|
||||
and body exceptions unwind without leaving state behind. A container whose
|
||||
body throws is marked unfinished and `finish!` rejects the instance, so a
|
||||
caught exception cannot silently produce a half-built scene.
|
||||
|
||||
Defaults follow the same theme: `*defaults*` maps a shape type to an
|
||||
attribute generator map, bound by the `fixture` macro from the scope
|
||||
attribute generator map, bound by the `scene` macro from the scope
|
||||
params. Per-shape attrs are merged over the generated values, so a recipe
|
||||
can override anything locally and rebind `*defaults*` around a section.
|
||||
|
||||
@ -148,11 +149,11 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:dynamic *state*
|
||||
"Current fixture scope; bound by the `fixture` macro."
|
||||
"Current scene scope; bound by the `scene` macro."
|
||||
nil)
|
||||
|
||||
(def ^:dynamic *defaults*
|
||||
"Per-shape-type attribute generator maps bound by the `fixture` macro,
|
||||
"Per-shape-type attribute generator maps bound by the `scene` macro,
|
||||
e.g. `{:rect {:x (gen-int 0 1920) ...}}`. Values are literals or one-arg
|
||||
functions of the scope random source."
|
||||
{})
|
||||
@ -165,15 +166,15 @@
|
||||
(defn- check-seed!
|
||||
[seed]
|
||||
(when-not (and (integer? seed) (<= 0 seed) (< seed 4294967296))
|
||||
(throw (ex-info "fixture scope requires an integer :seed in [0, 2^32)"
|
||||
(throw (ex-info "scene scope requires an integer :seed in [0, 2^32)"
|
||||
{:type ::invalid-seed
|
||||
:seed seed}))))
|
||||
|
||||
(defn start
|
||||
"Starts a fixture scope. Returns the scope state atom."
|
||||
"Starts a scene scope. Returns the scope state atom."
|
||||
[params]
|
||||
(when (some? *state*)
|
||||
(throw (ex-info "fixture scopes cannot nest"
|
||||
(throw (ex-info "scene scopes cannot nest"
|
||||
{:type ::nested-scope})))
|
||||
(check-seed! (:seed params))
|
||||
(let [seed (:seed params)
|
||||
@ -193,7 +194,7 @@
|
||||
(defn- ensure-state
|
||||
[state]
|
||||
(or state
|
||||
(throw (ex-info "shape used outside a fixture scope"
|
||||
(throw (ex-info "shape used outside a scene scope"
|
||||
{:type ::outside-scope}))))
|
||||
|
||||
(defn- resolve-attr
|
||||
@ -212,7 +213,7 @@
|
||||
[state label id]
|
||||
(when (some? label)
|
||||
(when (contains? (:refs @state) label)
|
||||
(throw (ex-info (str "duplicate fixture label: " label)
|
||||
(throw (ex-info (str "duplicate scene label: " label)
|
||||
{:type ::duplicate-label
|
||||
:label label})))
|
||||
(swap! state assoc-in [:refs label] id)))
|
||||
@ -384,9 +385,9 @@
|
||||
bool (-> bool (merge inherited) (merge supplied))
|
||||
|
||||
;; `path/update-bool-shape` dispatches to `path/wasm:calc-bool-content`,
|
||||
;; the renderer override, so fixture content would depend on renderer
|
||||
;; the renderer override, so scene content would depend on renderer
|
||||
;; initialization and A/B configuration. Compose the pure helpers:
|
||||
;; fixture generation is untimed and must not vary with the renderer
|
||||
;; scene generation is untimed and must not vary with the renderer
|
||||
;; being compared.
|
||||
content (path/calc-bool-content bool (:objects scope))
|
||||
bool (path/update-geometry bool content)]
|
||||
@ -456,7 +457,7 @@
|
||||
[state]
|
||||
(let [{:keys [objects refs unfinished]} @state]
|
||||
(when (seq unfinished)
|
||||
(throw (ex-info "fixture contains an unfinished container"
|
||||
(throw (ex-info "scene contains an unfinished container"
|
||||
{:type ::unfinished-container
|
||||
:ids (vec (keys unfinished))})))
|
||||
(let [instance {:objects objects
|
||||
|
||||
@ -5,19 +5,19 @@
|
||||
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
(ns benches.render-wasm.scenes.common
|
||||
"Utilities shared by generated and saved-page fixtures.
|
||||
"Utilities shared by generated and saved-page scenes.
|
||||
|
||||
A fixture instance is
|
||||
A scene snapshot is
|
||||
`{:objects {uuid shape ...} :refs {label uuid ...}}`.
|
||||
|
||||
- `:objects` is a Penpot page object map.
|
||||
- `:refs` is an instance-local lookup from custom labels to object uuids.
|
||||
- `:refs` is a snapshot-local lookup from custom labels to object uuids.
|
||||
|
||||
A fixture instance is just static data (a 'snapshot'). It is independent of
|
||||
A scene snapshot is just static data. It is independent of
|
||||
camera, operations, WASM buffers and renderer calls, and it never mutates after
|
||||
upload.
|
||||
|
||||
Validation uses penpot's facilities, so that benchmark fixtures follow editor
|
||||
Validation uses penpot's facilities, so that benchmark scenes follow editor
|
||||
semantics. We do check reachability from the root here because neither the
|
||||
editor validator nor file loading guarantees it.
|
||||
|
||||
@ -34,24 +34,24 @@
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
(def schema:instance
|
||||
"Envelope schema for a fixture snapshot."
|
||||
[:map {:title "RendererBenchmarkFixture"}
|
||||
(def schema:snapshot
|
||||
"Envelope schema for a scene snapshot."
|
||||
[:map {:title "RendererBenchmarkSceneSnapshot"}
|
||||
[:objects ctp/schema:objects]
|
||||
[:refs [:map-of :any ::sm/uuid]]])
|
||||
|
||||
(defn- fail!
|
||||
[hint data]
|
||||
(throw (ex-info (str "Invalid fixture instance: " hint)
|
||||
(merge {:type ::invalid-fixture
|
||||
(throw (ex-info (str "Invalid scene snapshot: " hint)
|
||||
(merge {:type ::invalid-snapshot
|
||||
:hint hint}
|
||||
data))))
|
||||
|
||||
(defn- check-schema!
|
||||
[instance]
|
||||
(when-not (sm/validate schema:instance instance)
|
||||
(fail! "instance does not match the fixture schema"
|
||||
{::sm/explain (sm/explain schema:instance instance)})))
|
||||
(when-not (sm/validate schema:snapshot instance)
|
||||
(fail! "instance does not match the scene snapshot schema"
|
||||
{::sm/explain (sm/explain schema:snapshot instance)})))
|
||||
|
||||
(defn- check-root!
|
||||
[instance]
|
||||
@ -140,7 +140,7 @@
|
||||
|
||||
`cfv/validate-shape` checks parent/child links, frame ids and geometry
|
||||
with editor semantics. The file and page only carry the uuids the
|
||||
validation error schema requires; fixtures contain no component shapes.
|
||||
validation error schema requires; scenes contain no component shapes.
|
||||
Unreachable objects never reach this walk; `check-reachability!` owns
|
||||
them."
|
||||
[instance]
|
||||
@ -160,9 +160,9 @@
|
||||
:target target})))))
|
||||
|
||||
(defn validate!
|
||||
"Validates a fixture instance and returns it unchanged.
|
||||
"Validates a scene snapshot and returns it unchanged.
|
||||
|
||||
Throws `ex-info` with `{:type ::invalid-fixture :hint ...}` when the
|
||||
Throws `ex-info` with `{:type ::invalid-snapshot :hint ...}` when the
|
||||
snapshot is invalid. Schema failures also carry `::sm/explain`.
|
||||
|
||||
Reachability runs before the production validator, because that walk
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
|
||||
Distributes rectangles over the canvas with varied sizes, translucent
|
||||
fills and centered strokes, all drawn from the scope's seeded generator.
|
||||
`build` produces the fixture snapshot; `defscene` and `defcase` declare
|
||||
`build` produces the scene snapshot; `defscene` and `defcase` declare
|
||||
the scene and its standard cases. The three cases share parameters, so
|
||||
they render the same scene. The path and effect fixtures arrive in
|
||||
they render the same scene. The path and effect scenes arrive in
|
||||
tickets07/08.
|
||||
|
||||
Operation bodies are deferred to tickets05/06. The intended threaded
|
||||
@ -59,18 +59,18 @@
|
||||
:r4 (sb/gen-int 0 24)})
|
||||
|
||||
(defn build
|
||||
"Builds the seeded rectangle fixture. `params` requires `:seed`; the other
|
||||
"Builds the seeded rectangle scene. `params` requires `:seed`; the other
|
||||
keys default to the standard case parameters."
|
||||
[params]
|
||||
(let [params (merge default-params params)]
|
||||
(sb/fixture {:seed (:seed params)
|
||||
:root {:x 0
|
||||
:y 0
|
||||
:width (:width params)
|
||||
:height (:height params)}
|
||||
:defaults {:rect (rect-defaults params)}}
|
||||
(doseq [_ (range (:count params))]
|
||||
(sb/rect)))))
|
||||
(sb/scene {:seed (:seed params)
|
||||
:root {:x 0
|
||||
:y 0
|
||||
:width (:width params)
|
||||
:height (:height params)}
|
||||
:defaults {:rect (rect-defaults params)}}
|
||||
(doseq [_ (range (:count params))]
|
||||
(sb/rect)))))
|
||||
|
||||
(core/defscene :rects
|
||||
{:version 1
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
(ns frontend-tests.benches.boolean-fixture-test
|
||||
(ns frontend-tests.benches.boolean-test
|
||||
(:require
|
||||
[app.common.types.path :as path]
|
||||
[app.common.uuid :as uuid]
|
||||
@ -16,10 +16,10 @@
|
||||
(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]})))
|
||||
instance (b/scene {: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 (helpers/children-of instance uuid/zero))
|
||||
children (helpers/children-of instance (:id bool))]
|
||||
(t/is (= :bool (:type bool)))
|
||||
@ -34,10 +34,10 @@
|
||||
(t/is (= [0 0 100 100] (helpers/selrect bool)))))
|
||||
|
||||
(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})))
|
||||
(let [instance (b/scene {: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)))))
|
||||
@ -46,52 +46,52 @@
|
||||
(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}
|
||||
difference (b/fixture {:seed 1}
|
||||
(b/bool {:bool-type :difference}
|
||||
(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]})))
|
||||
difference (b/scene {:seed 1}
|
||||
(b/bool {:bool-type :difference}
|
||||
(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 (helpers/children-of difference uuid/zero))]
|
||||
(t/is (= [red] (:fills diff-bool)))
|
||||
(t/is (= blur (:blur diff-bool)))))
|
||||
|
||||
(t/deftest supplied-styles-override-inherited
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/bool {:bool-type :union :fills []}
|
||||
(b/rect {:x 0 :y 0 :width 10 :height 10
|
||||
:fills [{:fill-color "#ff0000" :fill-opacity 1}]})
|
||||
(b/rect {:x 5 :y 0 :width 10 :height 10
|
||||
:fills [{:fill-color "#0000ff" :fill-opacity 1}]})))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/bool {:bool-type :union :fills []}
|
||||
(b/rect {:x 0 :y 0 :width 10 :height 10
|
||||
: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 (helpers/children-of instance uuid/zero))]
|
||||
(t/is (= [] (:fills bool)))))
|
||||
|
||||
(t/deftest nil-styles-do-not-count-as-supplied
|
||||
(let [red {:fill-color "#ff0000" :fill-opacity 1}
|
||||
blue {:fill-color "#0000ff" :fill-opacity 1}
|
||||
instance (b/fixture {:seed 1}
|
||||
(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]})))
|
||||
instance (b/scene {:seed 1}
|
||||
(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 (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})))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/bool {:bool-type :difference}
|
||||
(b/rect {:x 10 :y 20 :width 30 :height 40})))
|
||||
bool (first (helpers/children-of instance uuid/zero))]
|
||||
(t/is (= 1 (count (:shapes 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
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/bool {:bool-type :union}
|
||||
(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}))
|
||||
(b/rect {:x 200 :y 0 :width 50 :height 50})))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/bool {:bool-type :union}
|
||||
(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}))
|
||||
(b/rect {:x 200 :y 0 :width 50 :height 50})))
|
||||
outer (first (helpers/children-of instance uuid/zero))
|
||||
inner (first (helpers/children-of instance (:id outer)))]
|
||||
(t/is (= :bool (:type inner)))
|
||||
@ -100,11 +100,11 @@
|
||||
(t/is (= (:selrect outer) (path/calc-selrect (:content outer))))))
|
||||
|
||||
(t/deftest bool-inside-frame-keeps-frame-ids
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/frame {:x 0 :y 0 :width 200 :height 200}
|
||||
(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}))))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/frame {:x 0 :y 0 :width 200 :height 200}
|
||||
(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 (helpers/children-of instance uuid/zero))
|
||||
bool (first (helpers/children-of instance (:id frame)))
|
||||
rects (helpers/children-of instance (:id bool))]
|
||||
@ -114,11 +114,11 @@
|
||||
(t/is (= [(:id bool) (:id bool)] (mapv :parent-id rects)))))
|
||||
|
||||
(t/deftest bool-inside-group-derives-group-bounds
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/group {}
|
||||
(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}))))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/group {}
|
||||
(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 (helpers/children-of instance uuid/zero))
|
||||
bool (first (helpers/children-of instance (:id group)))]
|
||||
(t/is (= :bool (:type bool)))
|
||||
@ -126,7 +126,7 @@
|
||||
(t/is (= uuid/zero (:frame-id bool)))))
|
||||
|
||||
(t/deftest empty-bool-is-rejected
|
||||
(let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool {:bool-type :union})))]
|
||||
(let [data (helpers/failure-data #(b/scene {:seed 1} (b/bool {:bool-type :union})))]
|
||||
(t/is (= ::b/empty-bool (:type data)))))
|
||||
|
||||
(t/deftest caught-empty-bool-still-fails-finish
|
||||
@ -142,7 +142,7 @@
|
||||
(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 (helpers/failure-data #(b/fixture {:seed 1} (b/bool attrs (b/rect))))]
|
||||
(let [data (helpers/failure-data #(b/scene {: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)))))
|
||||
|
||||
@ -152,23 +152,23 @@
|
||||
{:bool-type :union :transform-inverse "m"}
|
||||
{:bool-type :union :flip-x true}
|
||||
{:bool-type :union :flip-y true}]]
|
||||
(let [data (helpers/failure-data #(b/fixture {:seed 1} (b/bool attrs (b/rect))))]
|
||||
(let [data (helpers/failure-data #(b/scene {: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 (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))))]
|
||||
(:type (helpers/failure-data #(b/scene {:seed 1} (b/bool {:name "B"} (b/rect)))))))
|
||||
(let [data (helpers/failure-data #(b/scene {:seed 1} (b/bool {:bool-type :merge} (b/rect))))]
|
||||
(t/is (= ::b/bool-type (:type data)))
|
||||
(t/is (= :merge (:bool-type data)))
|
||||
(t/is (= #{:union :difference :intersection :exclude} (set (:supported data))))))
|
||||
|
||||
(t/deftest frame-child-is-rejected
|
||||
(let [data (helpers/failure-data
|
||||
#(b/fixture {:seed 1}
|
||||
(b/bool {:bool-type :union}
|
||||
(b/frame {:x 0 :y 0 :width 10 :height 10}
|
||||
(b/rect)))))]
|
||||
#(b/scene {:seed 1}
|
||||
(b/bool {:bool-type :union}
|
||||
(b/frame {:x 0 :y 0 :width 10 :height 10}
|
||||
(b/rect)))))]
|
||||
(t/is (= ::b/frame-in-bool (:type data)))
|
||||
(t/is (uuid? (:child data)))))
|
||||
|
||||
@ -179,10 +179,10 @@
|
||||
(fn [& _]
|
||||
(throw (ex-info "renderer override ran during generation"
|
||||
{:type ::unexpected-renderer-call}))))
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(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})))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(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 (helpers/children-of instance uuid/zero))]
|
||||
(t/is (= [0 0 100 100] (helpers/selrect bool))))
|
||||
(finally
|
||||
@ -190,7 +190,7 @@
|
||||
|
||||
(t/deftest non-map-bool-attrs-are-rejected
|
||||
(t/is (= ::b/invalid-attrs
|
||||
(:type (helpers/failure-data #(b/fixture {:seed 1} (b/bool :hero (b/rect)))))))
|
||||
(:type (helpers/failure-data #(b/scene {:seed 1} (b/bool :hero (b/rect)))))))
|
||||
(let [state (helpers/run-scope {:seed 1}
|
||||
(fn []
|
||||
(try
|
||||
@ -18,7 +18,7 @@
|
||||
([params] (rects/build (merge {:seed 42 :count 5} params))))
|
||||
|
||||
(defn- add-tile
|
||||
"Helper defined outside a fixture scope, called from inside one."
|
||||
"Helper defined outside a scene scope, called from inside one."
|
||||
[index]
|
||||
(b/rect [:tile index] {:x (* 10 index)}))
|
||||
|
||||
@ -60,11 +60,11 @@
|
||||
(t/is (= 800 (get-in instance [:objects uuid/zero :width])))
|
||||
(t/is (= 600 (get-in instance [:objects uuid/zero :height])))))
|
||||
|
||||
(t/deftest labels-are-instance-local
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/rect)
|
||||
(b/rect :hero {})
|
||||
(b/rect [:tile 1] {}))
|
||||
(t/deftest labels-are-snapshot-local
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/rect)
|
||||
(b/rect :hero {})
|
||||
(b/rect [:tile 1] {}))
|
||||
refs (:refs instance)
|
||||
children (helpers/child-ids instance uuid/zero)]
|
||||
(t/is (= #{:hero [:tile 1]} (set (keys refs))))
|
||||
@ -72,20 +72,20 @@
|
||||
(t/is (= (get refs [:tile 1]) (nth children 2)))))
|
||||
|
||||
(t/deftest attrs-override-generated-values
|
||||
(let [instance (b/fixture {:seed 1
|
||||
:defaults {:rect {:x (b/gen-int 0 100)}}}
|
||||
(b/rect {:x 7 :fills []}))
|
||||
(let [instance (b/scene {:seed 1
|
||||
:defaults {:rect {:x (b/gen-int 0 100)}}}
|
||||
(b/rect {:x 7 :fills []}))
|
||||
rect (first (helpers/root-shapes instance))]
|
||||
(t/is (= 7 (:x rect)))
|
||||
(t/is (= [] (:fills rect)))))
|
||||
|
||||
(t/deftest ordinary-forms-work-inside-the-scope
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(let [first-id (b/rect)]
|
||||
(t/is (uuid? first-id)))
|
||||
(doseq [index (range 3)]
|
||||
(add-tile index))
|
||||
(b/rect :last {:x 99}))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(let [first-id (b/rect)]
|
||||
(t/is (uuid? first-id)))
|
||||
(doseq [index (range 3)]
|
||||
(add-tile index))
|
||||
(b/rect :last {:x 99}))
|
||||
refs (:refs instance)
|
||||
rects (helpers/root-shapes instance)]
|
||||
(t/is (= 5 (count rects)))
|
||||
@ -96,17 +96,17 @@
|
||||
|
||||
(t/deftest duplicate-labels-are-rejected
|
||||
(let [data (helpers/failure-data
|
||||
#(b/fixture {:seed 1}
|
||||
(b/rect :dup {})
|
||||
(b/rect :dup {})))]
|
||||
#(b/scene {:seed 1}
|
||||
(b/rect :dup {})
|
||||
(b/rect :dup {})))]
|
||||
(t/is (= ::b/duplicate-label (:type data)))
|
||||
(t/is (= :dup (:label data)))))
|
||||
|
||||
(t/deftest failed-builds-leak-no-state
|
||||
(let [clean (build)]
|
||||
(helpers/failure-data #(b/fixture {:seed 99}
|
||||
(b/rect :dup {})
|
||||
(b/rect :dup {})))
|
||||
(helpers/failure-data #(b/scene {:seed 99}
|
||||
(b/rect :dup {})
|
||||
(b/rect :dup {})))
|
||||
(t/is (= clean (build)))))
|
||||
|
||||
(t/deftest rect-outside-scope-is-rejected
|
||||
@ -115,48 +115,48 @@
|
||||
|
||||
(t/deftest nested-scopes-are-rejected
|
||||
(let [data (helpers/failure-data
|
||||
#(b/fixture {:seed 1}
|
||||
(b/fixture {:seed 2}
|
||||
(b/rect))))]
|
||||
#(b/scene {:seed 1}
|
||||
(b/scene {:seed 2}
|
||||
(b/rect))))]
|
||||
(t/is (= ::b/nested-scope (:type data)))))
|
||||
|
||||
(t/deftest invalid-seeds-are-rejected
|
||||
(t/is (= ::b/invalid-seed
|
||||
(:type (helpers/failure-data #(b/fixture {} (b/rect))))))
|
||||
(:type (helpers/failure-data #(b/scene {} (b/rect))))))
|
||||
(t/is (= ::b/invalid-seed
|
||||
(:type (helpers/failure-data #(b/fixture {:seed -1} (b/rect))))))
|
||||
(:type (helpers/failure-data #(b/scene {:seed -1} (b/rect))))))
|
||||
(t/is (= ::b/invalid-seed
|
||||
(:type (helpers/failure-data #(b/fixture {:seed 4294967296} (b/rect)))))))
|
||||
(:type (helpers/failure-data #(b/scene {:seed 4294967296} (b/rect)))))))
|
||||
|
||||
(t/deftest runtime-attrs-maps-are-resolved
|
||||
(let [attrs {:x 11}
|
||||
instance (b/fixture {:seed 1}
|
||||
(b/rect attrs))
|
||||
instance (b/scene {:seed 1}
|
||||
(b/rect attrs))
|
||||
rect (first (helpers/root-shapes instance))]
|
||||
(t/is (= 11 (:x rect)))))
|
||||
|
||||
(t/deftest single-label-form-is-supported
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/rect :solo))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/rect :solo))
|
||||
id (get (:refs instance) :solo)]
|
||||
(t/is (uuid? id))
|
||||
(t/is (= [id] (helpers/child-ids instance uuid/zero)))))
|
||||
|
||||
(t/deftest built-instance-feeds-the-snapshot-api
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/rect :hero {}))
|
||||
(t/deftest built-snapshot-feeds-the-scene-api
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/rect :hero {}))
|
||||
order (common/upload-order instance)
|
||||
hero-id (common/ref-id instance :hero)]
|
||||
(t/is (= [uuid/zero hero-id] (mapv :id order)))))
|
||||
|
||||
(t/deftest invalid-labels-are-rejected
|
||||
(let [data (helpers/failure-data #(b/fixture {:seed 1} (b/rect "hero" {})))]
|
||||
(let [data (helpers/failure-data #(b/scene {: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}))
|
||||
instance (b/scene {:seed 1}
|
||||
(b/rect {:type :circle :id other :parent-id other}))
|
||||
rect (first (helpers/root-shapes instance))]
|
||||
(t/is (= :rect (:type rect)))
|
||||
(t/is (not= other (:id rect)))
|
||||
@ -164,9 +164,9 @@
|
||||
|
||||
(t/deftest root-protected-keys-cannot-be-overridden
|
||||
(let [other (uuid/custom 9 8)
|
||||
instance (b/fixture {:seed 1
|
||||
:root {:id other :type :rect :width 10}}
|
||||
(b/rect))
|
||||
instance (b/scene {:seed 1
|
||||
:root {:id other :type :rect :width 10}}
|
||||
(b/rect))
|
||||
root (get-in instance [:objects uuid/zero])]
|
||||
(t/is (= uuid/zero (:id root)))
|
||||
(t/is (= :frame (:type root)))
|
||||
@ -174,18 +174,18 @@
|
||||
|
||||
(t/deftest attrs-override-generated-fills
|
||||
(let [fill {:fill-color "#ffffff" :fill-opacity 1}
|
||||
instance (b/fixture {:seed 1}
|
||||
(b/rect {:fills [fill]}))
|
||||
instance (b/scene {:seed 1}
|
||||
(b/rect {:fills [fill]}))
|
||||
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 5)
|
||||
:fills (b/gen-vector (b/gen-fill))}}}
|
||||
(b/rect))
|
||||
(let [instance (b/scene {:seed 3
|
||||
:defaults {:rect {:opacity (b/gen-float 0.5 0.6)
|
||||
:x (b/gen-one-of [4 5])
|
||||
:r1 (b/gen-int 3 5)
|
||||
:fills (b/gen-vector (b/gen-fill))}}}
|
||||
(b/rect))
|
||||
rect (first (helpers/root-shapes instance))]
|
||||
(t/is (<= 0.5 (:opacity rect) 0.6))
|
||||
(t/is (contains? #{4 5} (:x rect)))
|
||||
@ -197,35 +197,35 @@
|
||||
(t/is (= ::b/no-values (:type data)))))
|
||||
|
||||
(t/deftest circle-creates-ellipse-type
|
||||
(let [instance (b/fixture {:seed 1}
|
||||
(b/circle {:x 10 :y 20 :width 30 :height 40}))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/circle {:x 10 :y 20 :width 30 :height 40}))
|
||||
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 (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 12)}}}
|
||||
(b/circle))
|
||||
(let [instance (b/scene {:seed 3
|
||||
:defaults {:circle {:x (b/gen-int 10 12)}}}
|
||||
(b/circle))
|
||||
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))
|
||||
(let [instance (b/scene {:seed 1
|
||||
:defaults {:rect {:x 999}}}
|
||||
(b/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
|
||||
:defaults {:circle {:x (b/gen-int 0 800)
|
||||
:y (b/gen-int 0 600)
|
||||
:width (b/gen-int 5 15)
|
||||
:height (b/gen-int 5 15)}}}
|
||||
(doseq [_ (range 40)]
|
||||
(b/circle)))
|
||||
(let [instance (b/scene {:seed 7
|
||||
:defaults {:circle {:x (b/gen-int 0 800)
|
||||
:y (b/gen-int 0 600)
|
||||
:width (b/gen-int 5 15)
|
||||
:height (b/gen-int 5 15)}}}
|
||||
(doseq [_ (range 40)]
|
||||
(b/circle)))
|
||||
circles (helpers/root-shapes instance)]
|
||||
(t/is (= 40 (count circles)))
|
||||
(t/is (every? #(<= 0 (:x %) 800) circles))
|
||||
@ -234,8 +234,8 @@
|
||||
(t/is (every? #(<= 5 (:height %) 15) circles))))
|
||||
|
||||
(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}))
|
||||
(let [instance (b/scene {:seed 1}
|
||||
(b/circle {:x 0 :y 0 :width 20 :height 20 :rx 5 :ry 7}))
|
||||
circle (first (helpers/root-shapes instance))]
|
||||
(t/is (= [5 7] [(:rx circle) (:ry circle)]))))
|
||||
|
||||
|
||||
@ -12,10 +12,10 @@
|
||||
[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})))
|
||||
(let [instance (builder/scene {: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 (helpers/children-of instance uuid/zero))
|
||||
rects (helpers/children-of instance (:id frame))]
|
||||
(t/is (= :frame (:type frame)))
|
||||
@ -28,10 +28,10 @@
|
||||
(t/is (= [100 100] [(:width frame) (:height frame)]))))
|
||||
|
||||
(t/deftest nested-frames-keep-frame-ids
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(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}))))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(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 (helpers/children-of instance uuid/zero))
|
||||
inner (first (helpers/children-of instance (:id outer)))
|
||||
rect (first (helpers/children-of instance (:id inner)))]
|
||||
@ -43,10 +43,10 @@
|
||||
(t/is (= [20 20] [(:x rect) (:y rect)]))))
|
||||
|
||||
(t/deftest group-derives-bounds-from-children
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(builder/group {}
|
||||
(builder/rect {:x 10 :y 20 :width 30 :height 40})
|
||||
(builder/rect {:x 50 :y 80 :width 10 :height 10})))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/group {}
|
||||
(builder/rect {:x 10 :y 20 :width 30 :height 40})
|
||||
(builder/rect {:x 50 :y 80 :width 10 :height 10})))
|
||||
group (first (helpers/children-of instance uuid/zero))
|
||||
rects (helpers/children-of instance (:id group))]
|
||||
(t/is (= :group (:type group)))
|
||||
@ -56,11 +56,11 @@
|
||||
(t/is (every? #(= (:id group) (:parent-id %)) rects))))
|
||||
|
||||
(t/deftest nested-groups-derive-inside-out
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(builder/group {:name "Outer"}
|
||||
(builder/rect {:x 0 :y 0 :width 10 :height 10})
|
||||
(builder/group {:name "Inner"}
|
||||
(builder/rect {:x 100 :y 100 :width 10 :height 10}))))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/group {:name "Outer"}
|
||||
(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 (helpers/children-of instance uuid/zero))
|
||||
inner (second (helpers/children-of instance (:id outer)))]
|
||||
(t/is (= :group (:type inner)))
|
||||
@ -70,10 +70,10 @@
|
||||
[(:x outer) (:y outer) (:width outer) (:height outer)]))))
|
||||
|
||||
(t/deftest group-inside-frame-points-at-the-frame
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(builder/frame {:x 0 :y 0 :width 200 :height 200}
|
||||
(builder/group {}
|
||||
(builder/rect {:x 10 :y 10 :width 10 :height 10}))))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/frame {:x 0 :y 0 :width 200 :height 200}
|
||||
(builder/group {}
|
||||
(builder/rect {:x 10 :y 10 :width 10 :height 10}))))
|
||||
frame (first (helpers/children-of instance uuid/zero))
|
||||
group (first (helpers/children-of instance (:id frame)))
|
||||
rect (first (helpers/children-of instance (:id group)))]
|
||||
@ -82,20 +82,20 @@
|
||||
(t/is (= (:id group) (:parent-id rect)))))
|
||||
|
||||
(t/deftest masked-group-takes-the-first-child-geometry
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(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})))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(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 (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)]))))
|
||||
|
||||
(t/deftest container-labels-are-instance-local
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(builder/frame :hero {:x 0 :y 0 :width 10 :height 10}
|
||||
(builder/group [:g 1] {}
|
||||
(builder/rect))))
|
||||
(t/deftest container-labels-are-snapshot-local
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/frame :hero {:x 0 :y 0 :width 10 :height 10}
|
||||
(builder/group [:g 1] {}
|
||||
(builder/rect))))
|
||||
refs (:refs instance)]
|
||||
(t/is (= #{:hero [:g 1]} (set (keys refs))))
|
||||
(t/is (= (get refs :hero) (first (helpers/child-ids instance uuid/zero))))
|
||||
@ -103,29 +103,29 @@
|
||||
(t/is (= 1 (count (helpers/child-ids instance uuid/zero))))))
|
||||
|
||||
(t/deftest empty-group-is-rejected
|
||||
(let [data (helpers/failure-data #(builder/fixture {:seed 1} (builder/group {})))]
|
||||
(let [data (helpers/failure-data #(builder/scene {:seed 1} (builder/group {})))]
|
||||
(t/is (= ::builder/empty-group (:type data)))))
|
||||
|
||||
(t/deftest group-geometry-attrs-are-rejected
|
||||
(let [data (helpers/failure-data
|
||||
#(builder/fixture {:seed 1}
|
||||
(builder/group {:x 1}
|
||||
(builder/rect))))]
|
||||
#(builder/scene {:seed 1}
|
||||
(builder/group {:x 1}
|
||||
(builder/rect))))]
|
||||
(t/is (= ::builder/group-geometry (:type data)))
|
||||
(t/is (= :x (:key data)))))
|
||||
|
||||
(t/deftest frame-requires-bounds
|
||||
(let [data (helpers/failure-data
|
||||
#(builder/fixture {:seed 1}
|
||||
(builder/frame {:name "F"}
|
||||
(builder/rect))))]
|
||||
#(builder/scene {:seed 1}
|
||||
(builder/frame {:name "F"}
|
||||
(builder/rect))))]
|
||||
(t/is (= ::builder/frame-bounds (:type data)))))
|
||||
|
||||
(t/deftest runtime-attrs-expressions-are-accepted
|
||||
(let [frame-attrs {:x 0 :y 0 :width 10 :height 10}
|
||||
instance (builder/fixture {:seed 1}
|
||||
(builder/frame frame-attrs
|
||||
(builder/rect)))
|
||||
instance (builder/scene {:seed 1}
|
||||
(builder/frame frame-attrs
|
||||
(builder/rect)))
|
||||
frame (first (helpers/children-of instance uuid/zero))]
|
||||
(t/is (= :frame (:type frame)))
|
||||
(t/is (= 10 (:width frame)))))
|
||||
@ -133,8 +133,8 @@
|
||||
(t/deftest non-map-attrs-are-rejected
|
||||
(t/is (= ::builder/invalid-attrs
|
||||
(:type (helpers/failure-data
|
||||
#(builder/fixture {:seed 1}
|
||||
(builder/frame :hero (builder/rect)))))))
|
||||
#(builder/scene {:seed 1}
|
||||
(builder/frame :hero (builder/rect)))))))
|
||||
(let [state (helpers/run-scope {:seed 1}
|
||||
(fn []
|
||||
(try
|
||||
@ -144,27 +144,27 @@
|
||||
|
||||
(t/deftest non-numeric-frame-bounds-are-rejected
|
||||
(let [data (helpers/failure-data
|
||||
#(builder/fixture {:seed 1}
|
||||
(builder/frame {:x 0 :y 0 :width "100" :height 10}
|
||||
(builder/rect))))]
|
||||
#(builder/scene {:seed 1}
|
||||
(builder/frame {:x 0 :y 0 :width "100" :height 10}
|
||||
(builder/rect))))]
|
||||
(t/is (= ::builder/frame-bounds (:type data)))
|
||||
(t/is (= :width (:invalid data)))))
|
||||
|
||||
(t/deftest duplicate-container-labels-are-rejected
|
||||
(let [data (helpers/failure-data
|
||||
#(builder/fixture {:seed 1}
|
||||
(builder/frame :dup {:x 0 :y 0 :width 10 :height 10}
|
||||
(builder/rect))
|
||||
(builder/group :dup {}
|
||||
(builder/rect))))]
|
||||
#(builder/scene {:seed 1}
|
||||
(builder/frame :dup {:x 0 :y 0 :width 10 :height 10}
|
||||
(builder/rect))
|
||||
(builder/group :dup {}
|
||||
(builder/rect))))]
|
||||
(t/is (= ::builder/duplicate-label (:type data)))
|
||||
(t/is (= :dup (:label data)))))
|
||||
|
||||
(t/deftest frame-inside-group-keeps-frame-ids
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(builder/group {}
|
||||
(builder/frame {:x 0 :y 0 :width 50 :height 50}
|
||||
(builder/rect))))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/group {}
|
||||
(builder/frame {:x 0 :y 0 :width 50 :height 50}
|
||||
(builder/rect))))
|
||||
group (first (helpers/children-of instance uuid/zero))
|
||||
frame (first (helpers/children-of instance (:id group)))
|
||||
rect (first (helpers/children-of instance (:id frame)))]
|
||||
@ -174,10 +174,10 @@
|
||||
(t/is (= (:id frame) (:frame-id rect)))))
|
||||
|
||||
(t/deftest group-of-container-derives-bounds
|
||||
(let [instance (builder/fixture {:seed 1}
|
||||
(builder/group {}
|
||||
(builder/group {}
|
||||
(builder/rect {:x 5 :y 5 :width 10 :height 10}))))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/group {}
|
||||
(builder/group {}
|
||||
(builder/rect {:x 5 :y 5 :width 10 :height 10}))))
|
||||
outer (first (helpers/children-of instance uuid/zero))
|
||||
inner (first (helpers/children-of instance (:id outer)))]
|
||||
(t/is (= [5 5 10 10]
|
||||
@ -187,8 +187,8 @@
|
||||
(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}))
|
||||
(let [instance (builder/scene {:seed 1}
|
||||
(builder/frame {:x 0 :y 0 :width 10 :height 10}))
|
||||
frame (first (helpers/children-of instance uuid/zero))]
|
||||
(t/is (= [] (helpers/child-ids instance (:id frame))))))
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
(ns frontend-tests.benches.fixture-test
|
||||
(ns frontend-tests.benches.scene-snapshot-test
|
||||
(:require
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.shape :as cts]
|
||||
@ -12,8 +12,8 @@
|
||||
[benches.render-wasm.scenes.common :as common]
|
||||
[cljs.test :as t :include-macros true]))
|
||||
|
||||
(defn- sample-instance
|
||||
"Simple tiny fixture: root frame with one rectangle."
|
||||
(defn- sample-snapshot
|
||||
"Simple tiny scene: root frame with one rectangle."
|
||||
[]
|
||||
(let [rect-id (uuid/custom 1 1)
|
||||
rect (cts/setup-shape {:id rect-id :type :rect :name "Rect"
|
||||
@ -74,11 +74,11 @@
|
||||
|
||||
(t/deftest canonical-example-is-valid
|
||||
(t/testing "validate! returns the same instance"
|
||||
(let [instance (sample-instance)]
|
||||
(let [instance (sample-snapshot)]
|
||||
(t/is (identical? instance (common/validate! instance)))))
|
||||
|
||||
(t/testing "the envelope schema accepts the example"
|
||||
(t/is (true? (sm/validate common/schema:instance (sample-instance))))))
|
||||
(t/is (true? (sm/validate common/schema:snapshot (sample-snapshot))))))
|
||||
|
||||
(t/deftest nested-hierarchy-is-valid
|
||||
(let [instance (nested-instance)]
|
||||
@ -94,7 +94,7 @@
|
||||
(t/is (= [uuid/zero] (mapv :id (common/upload-order instance))))))
|
||||
|
||||
(t/deftest upload-order-starts-at-root
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
ids (mapv :id (common/upload-order instance))]
|
||||
(t/is (= [uuid/zero (common/ref-id instance :rect)] ids))))
|
||||
|
||||
@ -139,75 +139,75 @@
|
||||
(mapv :name (common/upload-order instance))))))
|
||||
|
||||
(t/deftest ref-id-resolves-labels
|
||||
(let [instance (sample-instance)]
|
||||
(let [instance (sample-snapshot)]
|
||||
(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)
|
||||
(let [instance (sample-snapshot)
|
||||
data (validation-error (update instance :objects dissoc uuid/zero))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= uuid/zero (:id data)))))
|
||||
|
||||
(t/deftest non-frame-root-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
data (validation-error (assoc-in instance [:objects uuid/zero :type] :rect))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= uuid/zero (:id data)))))
|
||||
|
||||
(t/deftest root-with-non-zero-parent-id-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
data (validation-error
|
||||
(assoc-in instance [:objects uuid/zero :parent-id] (uuid/custom 9 9)))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= uuid/zero (:id data)))))
|
||||
|
||||
(t/deftest object-key-must-match-shape-id
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
rect (get-in instance [:objects (common/ref-id instance :rect)])
|
||||
data (validation-error (assoc-in instance [:objects (uuid/custom 7 7)] rect))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= (:id rect) (:shape-id data)))))
|
||||
|
||||
(t/deftest missing-child-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
bogus (uuid/custom 3 3)
|
||||
data (validation-error
|
||||
(assoc-in instance [:objects uuid/zero :shapes] [bogus]))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= bogus (:child data)))))
|
||||
|
||||
(t/deftest child-not-listed-by-parent-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
rect-id (common/ref-id instance :rect)
|
||||
data (validation-error (assoc-in instance [:objects uuid/zero :shapes] []))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (: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)
|
||||
(let [instance (sample-snapshot)
|
||||
rect-id (common/ref-id instance :rect)
|
||||
data (validation-error
|
||||
(assoc-in instance [:objects rect-id :parent-id] (uuid/custom 9 7)))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (: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)
|
||||
(let [instance (sample-snapshot)
|
||||
rect-id (common/ref-id instance :rect)
|
||||
data (validation-error
|
||||
(assoc-in instance [:objects uuid/zero :shapes] [rect-id rect-id]))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= "an object is reachable more than once" (:hint data)))
|
||||
(t/is (= rect-id (:id data)))))
|
||||
|
||||
(t/deftest shape-listing-itself-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
data (validation-error
|
||||
(assoc-in instance [:objects uuid/zero :shapes] [uuid/zero]))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= "root must not be a descendant of itself" (:hint data)))
|
||||
(t/is (= uuid/zero (:id data)))))
|
||||
|
||||
@ -223,11 +223,11 @@
|
||||
:parent-id c1-id :frame-id c2-id
|
||||
:shapes [c1-id]})
|
||||
data (validation-error
|
||||
(assoc (sample-instance) :objects
|
||||
(assoc (get (sample-instance) :objects)
|
||||
(assoc (sample-snapshot) :objects
|
||||
(assoc (get (sample-snapshot) :objects)
|
||||
c1-id shape1
|
||||
c2-id shape2)))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= "object is not reachable from the root" (:hint data)))
|
||||
(t/is (contains? #{c1-id c2-id} (:id data)))))
|
||||
|
||||
@ -242,20 +242,20 @@
|
||||
:x 0 :y 0 :width 10 :height 10
|
||||
:parent-id a-id :frame-id uuid/zero
|
||||
:shapes [a-id]})
|
||||
instance (-> (sample-instance)
|
||||
instance (-> (sample-snapshot)
|
||||
(assoc-in [:objects uuid/zero :shapes] [a-id])
|
||||
(assoc-in [:objects a-id] shape-a)
|
||||
(assoc-in [:objects b-id] shape-b))
|
||||
data (validation-error instance)]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (: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)
|
||||
(let [instance (sample-snapshot)
|
||||
rect-id (common/ref-id instance :rect)
|
||||
data (validation-error (assoc-in instance [:objects rect-id :shapes] 5))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= "shape :shapes must be a vector" (:hint data)))
|
||||
(t/is (= rect-id (:id data)))))
|
||||
|
||||
@ -264,53 +264,53 @@
|
||||
a1-id (common/ref-id instance :a1)
|
||||
data (validation-error
|
||||
(assoc-in instance [:objects a1-id :frame-id] uuid/zero))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= :invalid-frame (:code data)))
|
||||
(t/is (= a1-id (:shape-id data)))))
|
||||
|
||||
(t/deftest missing-ref-target-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
data (validation-error
|
||||
(assoc-in instance [:refs :rect] (uuid/custom 6 6)))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (: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 (= ::common/invalid-fixture (:type data)))
|
||||
(let [data (validation-error (assoc-in (sample-snapshot) [:refs :rect] "not-a-uuid"))]
|
||||
(t/is (= ::common/invalid-snapshot (: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 (= ::common/invalid-fixture (:type data)))
|
||||
(let [data (validation-error (dissoc (sample-snapshot) :refs))]
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (some? (::sm/explain data)))))
|
||||
|
||||
(t/deftest non-canonical-shape-is-rejected
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
rect-id (common/ref-id instance :rect)
|
||||
data (validation-error (assoc-in instance [:objects rect-id] {:id rect-id}))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (: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 (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (= uuid/zero (:id data)))))
|
||||
|
||||
(t/testing "nil instance"
|
||||
(let [data (validation-error nil)]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (some? (::sm/explain data)))))
|
||||
|
||||
(t/testing "nil shape value"
|
||||
(let [instance (sample-instance)
|
||||
(let [instance (sample-snapshot)
|
||||
rect-id (common/ref-id instance :rect)
|
||||
data (validation-error (assoc-in instance [:objects rect-id] nil))]
|
||||
(t/is (= ::common/invalid-fixture (:type data)))
|
||||
(t/is (= ::common/invalid-snapshot (: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 (= ::common/invalid-fixture (:type data)))
|
||||
(let [data (validation-error (assoc-in (sample-snapshot) [:refs :rect] nil))]
|
||||
(t/is (= ::common/invalid-snapshot (:type data)))
|
||||
(t/is (some? (::sm/explain data))))))
|
||||
@ -1,5 +1,5 @@
|
||||
(ns frontend-tests.benches.test-helpers
|
||||
"Shared helpers for renderer benchmark fixture tests.
|
||||
"Shared helpers for renderer benchmark scene 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
|
||||
@ -19,18 +19,18 @@
|
||||
|
||||
(defn child-ids
|
||||
"Ids listed in the :shapes vector of `id`."
|
||||
[instance id]
|
||||
(get-in instance [:objects id :shapes]))
|
||||
[snapshot id]
|
||||
(get-in snapshot [:objects id :shapes]))
|
||||
|
||||
(defn children-of
|
||||
"Child shapes of `id` in order."
|
||||
[instance id]
|
||||
(mapv (:objects instance) (child-ids instance id)))
|
||||
[snapshot id]
|
||||
(mapv (:objects snapshot) (child-ids snapshot id)))
|
||||
|
||||
(defn root-shapes
|
||||
"Root children of a fixture instance in creation order."
|
||||
[instance]
|
||||
(children-of instance uuid/zero))
|
||||
"Root children of a scene snapshot in creation order."
|
||||
[snapshot]
|
||||
(children-of snapshot uuid/zero))
|
||||
|
||||
(defn run-scope
|
||||
"Runs `f` inside a raw scope and returns the scope state, so tests can
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user