mirror of
https://github.com/penpot/penpot.git
synced 2025-08-03 18:08:21 +02:00
🎉 Add frontend tests for creating and renaming components
This commit is contained in:
parent
676ce9b68d
commit
c127978dd2
7 changed files with 409 additions and 148 deletions
39
frontend/tests/app/test_helpers/events.cljs
Normal file
39
frontend/tests/app/test_helpers/events.cljs
Normal file
|
@ -0,0 +1,39 @@
|
|||
(ns app.test-helpers.events
|
||||
(:require [cljs.test :as t :include-macros true]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.workspace :as dw]))
|
||||
|
||||
;; ---- Helpers to manage global events
|
||||
|
||||
(defn do-update
|
||||
"Execute an update event and returns the new state."
|
||||
[event state]
|
||||
(ptk/update event state))
|
||||
|
||||
(defn do-watch
|
||||
"Execute a watch event and return an observable, that
|
||||
emits once a list with all new events."
|
||||
[event state]
|
||||
(->> (ptk/watch event state nil)
|
||||
(rx/reduce conj [])))
|
||||
|
||||
(defn do-watch-update
|
||||
"Execute a watch event and return an observable, that
|
||||
emits once the new state, after all new events applied
|
||||
in sequence (considering they are all update events)."
|
||||
[event state]
|
||||
(->> (do-watch event state)
|
||||
(rx/map (fn [new-events]
|
||||
(reduce
|
||||
(fn [new-state new-event]
|
||||
(do-update new-event new-state))
|
||||
state
|
||||
new-events)))))
|
||||
|
90
frontend/tests/app/test_helpers/libraries.cljs
Normal file
90
frontend/tests/app/test_helpers/libraries.cljs
Normal file
|
@ -0,0 +1,90 @@
|
|||
(ns app.test-helpers.libraries
|
||||
(:require [cljs.test :as t :include-macros true]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries-helpers :as dwlh]
|
||||
[app.test-helpers.pages :as thp]))
|
||||
|
||||
;; ---- Helpers to manage libraries and synchronization
|
||||
|
||||
(defn is-instance-root
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (some? (:component-id shape)))
|
||||
(t/is (= (:component-root? shape) true)))
|
||||
|
||||
(defn is-instance-subroot
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (some? (:component-id shape)))
|
||||
(t/is (nil? (:component-root? shape))))
|
||||
|
||||
(defn is-instance-head
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (some? (:component-id shape))))
|
||||
|
||||
(defn is-instance-child
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (nil? (:component-id shape)))
|
||||
(t/is (nil? (:component-file shape)))
|
||||
(t/is (nil? (:component-root? shape))))
|
||||
|
||||
(defn is-noninstance
|
||||
[shape]
|
||||
(t/is (nil? (:shape-ref shape)))
|
||||
(t/is (nil? (:component-id shape)))
|
||||
(t/is (nil? (:component-file shape)))
|
||||
(t/is (nil? (:component-root? shape)))
|
||||
(t/is (nil? (:remote-synced? shape)))
|
||||
(t/is (nil? (:touched shape))))
|
||||
|
||||
(defn is-from-file
|
||||
[shape file]
|
||||
(t/is (= (:component-file shape)
|
||||
(:id file))))
|
||||
|
||||
(defn resolve-instance-and-master
|
||||
[state root-inst-id]
|
||||
(let [page (thp/current-page state)
|
||||
root-inst (cph/get-shape page root-inst-id)
|
||||
|
||||
file (dwlh/get-local-file state)
|
||||
component (cph/get-component
|
||||
(:component-id root-inst)
|
||||
(:id file)
|
||||
file
|
||||
nil)
|
||||
|
||||
shapes-inst (cph/get-object-with-children
|
||||
root-inst-id
|
||||
(:objects page))
|
||||
shapes-master (cph/get-object-with-children
|
||||
(:shape-ref root-inst)
|
||||
(:objects component))
|
||||
|
||||
unique-refs (into #{} (map :shape-ref shapes-inst))
|
||||
|
||||
master-exists? (fn [shape]
|
||||
(t/is (some #(= (:id %) (:shape-ref shape))
|
||||
shapes-master)))]
|
||||
|
||||
;; Validate that the instance tree is well constructed
|
||||
(t/is (is-instance-root (first shapes-inst)))
|
||||
(run! is-instance-child (rest shapes-inst))
|
||||
(run! is-noninstance shapes-master)
|
||||
(t/is (= (count shapes-inst)
|
||||
(count shapes-master)
|
||||
(count unique-refs)))
|
||||
(run! master-exists? shapes-inst)
|
||||
|
||||
[shapes-inst shapes-master component]))
|
||||
|
106
frontend/tests/app/test_helpers/pages.cljs
Normal file
106
frontend/tests/app/test_helpers/pages.cljs
Normal file
|
@ -0,0 +1,106 @@
|
|||
(ns app.test-helpers.pages
|
||||
(:require [cljs.test :as t :include-macros true]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.libraries-helpers :as dwlh]))
|
||||
|
||||
;; ---- Helpers to manage pages and objects
|
||||
|
||||
(def current-file-id (uuid/next))
|
||||
|
||||
(def initial-state
|
||||
{:current-file-id current-file-id
|
||||
:current-page-id nil
|
||||
:workspace-local dw/workspace-local-default
|
||||
:workspace-data {:id current-file-id
|
||||
:components {}
|
||||
:pages []
|
||||
:pages-index {}}
|
||||
:workspace-libraries {}})
|
||||
|
||||
(def ^:private idmap (atom {}))
|
||||
|
||||
(defn reset-idmap! []
|
||||
(reset! idmap {}))
|
||||
|
||||
(defn current-page
|
||||
[state]
|
||||
(let [page-id (:current-page-id state)]
|
||||
(get-in state [:workspace-data :pages-index page-id])))
|
||||
|
||||
(defn id
|
||||
[label]
|
||||
(get @idmap label))
|
||||
|
||||
(defn get-shape
|
||||
[state label]
|
||||
(let [page (current-page state)]
|
||||
(get-in page [:objects (id label)])))
|
||||
|
||||
(defn sample-page
|
||||
([state] (sample-page state {}))
|
||||
([state {:keys [id name] :as props
|
||||
:or {id (uuid/next)
|
||||
name "page1"}}]
|
||||
|
||||
(swap! idmap assoc :page id)
|
||||
(-> state
|
||||
(assoc :current-page-id id)
|
||||
(update :workspace-data
|
||||
cp/process-changes
|
||||
[{:type :add-page
|
||||
:id id
|
||||
:name name}]))))
|
||||
|
||||
(defn sample-shape
|
||||
([state label type] (sample-shape state type {}))
|
||||
([state label type props]
|
||||
(let [page (current-page state)
|
||||
frame (cph/get-top-frame (:objects page))
|
||||
shape (-> (cp/make-minimal-shape type)
|
||||
(gsh/setup {:x 0 :y 0 :width 1 :height 1})
|
||||
(merge props))]
|
||||
(swap! idmap assoc label (:id shape))
|
||||
(update state :workspace-data
|
||||
cp/process-changes
|
||||
[{:type :add-obj
|
||||
:id (:id shape)
|
||||
:page-id (:id page)
|
||||
:frame-id (:id frame)
|
||||
:obj shape}]))))
|
||||
|
||||
(defn group-shapes
|
||||
([state label ids] (group-shapes state label ids "Group-"))
|
||||
([state label ids prefix]
|
||||
(let [page (current-page state)
|
||||
shapes (dwg/shapes-for-grouping (:objects page) ids)
|
||||
|
||||
[group rchanges uchanges]
|
||||
(dwg/prepare-create-group (:id page) shapes prefix true)]
|
||||
|
||||
(swap! idmap assoc label (:id group))
|
||||
(update state :workspace-data
|
||||
cp/process-changes rchanges))))
|
||||
|
||||
(defn make-component
|
||||
[state label ids]
|
||||
(let [page (current-page state)
|
||||
|
||||
[group rchanges uchanges]
|
||||
(dwlh/generate-add-component ids
|
||||
(:objects page)
|
||||
(:id page)
|
||||
current-file-id)]
|
||||
|
||||
(swap! idmap assoc label (:id group))
|
||||
(update state :workspace-data
|
||||
cp/process-changes rchanges)))
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue