diff --git a/src/pluto/reader/errors.cljc b/src/pluto/reader/errors.cljc index 6c9af79..c4eec40 100644 --- a/src/pluto/reader/errors.cljc +++ b/src/pluto/reader/errors.cljc @@ -26,6 +26,7 @@ ::unknown-query ::unknown-event ::invalid-view + ::invalid-property-map ::invalid-block ::unsupported-test-type}) diff --git a/src/pluto/reader/views.cljc b/src/pluto/reader/views.cljc index df047c4..b1300af 100644 --- a/src/pluto/reader/views.cljc +++ b/src/pluto/reader/views.cljc @@ -19,6 +19,8 @@ :element vector? :block list?)) +(spec/def ::property-map (spec/map-of keyword? any?)) + (spec/def ::element (spec/cat :tag (spec/or :symbol symbol? :fn fn?) @@ -61,19 +63,22 @@ {:data v})) (defn- resolve-component-properties [ctx ext component properties] - (reduce-kv (fn [acc k v] - (let [{:keys [data errors]} (resolve-property ctx ext component k v)] - (errors/merge-errors (update acc :data assoc k data) - errors))) - {:data {} - :errors []} - properties)) + (if-let [explain (spec/explain-data ::property-map properties)] + {:errors [(errors/error ::errors/invalid-property-map properties {:explain-data explain})]} + (reduce-kv (fn [acc k v] + (let [{:keys [data errors]} (resolve-property ctx ext component k v)] + (errors/merge-errors (update acc :data assoc k data) + errors))) + {:data {} + :errors []} + properties))) (defn- resolve-properties-children [[properties? & children]] [(and (map? properties?) properties?) - (if (map? properties?) - children - (cons properties? children))]) + (cond + (map? properties?) children + (not (nil? properties?)) (cons properties? children) + :else children)]) (defn- parse-hiccup-element [ctx ext o] (let [explain diff --git a/test/pluto/reader/types_test.cljc b/test/pluto/reader/types_test.cljc index f2cf74b..da0227d 100644 --- a/test/pluto/reader/types_test.cljc +++ b/test/pluto/reader/types_test.cljc @@ -84,11 +84,11 @@ (is (= {:data {:students [{:firstname "John" :lastname "Doe"}]}} (types/resolve {} {} {:students [{:firstname :string :lastname :string :name? :string}]} {:students [{:firstname "John" :lastname "Doe"}]}))) - (is (= '[text nil] + (is (= '[text] (let [m (types/resolve {} '{views/screen [text]} {:screen :view :students [{:firstname :string :lastname :string :name? :string}]} {:screen ['screen] :students [{:firstname "John" :lastname "Doe"}]})] ((get-in m [:data :screen]) {})))) - (is (= '[text nil] + (is (= '[text] (let [m (types/resolve {} '{views/screen [text]} {:screen? :view :students [{:firstname :string :lastname :string :name? :string}]} {:screen ['screen] :students [{:firstname "John" :lastname "Doe" :name "Henry"}]})] ((get-in m [:data :screen]) {})))) diff --git a/test/pluto/reader/views_test.cljc b/test/pluto/reader/views_test.cljc index fe94617..be02536 100644 --- a/test/pluto/reader/views_test.cljc +++ b/test/pluto/reader/views_test.cljc @@ -54,3 +54,20 @@ (is (= {:errors [{::errors/type ::errors/unknown-reference, ::errors/value {:value 'views/unknown}}]} (types/resolve {:capacities {:components {'text {:value :text}}}} {'views/main ['text "Hello"]} :view ['views/unknown])))) + +(deftest invalid-view-element-spec-errors + (letfn [(p [view] (views/parse + {:capacities {:components {'text {:properties {:asdf :string} + :value :text}}}} + {} + view))] + (is (:errors (p '[text :sadf]))) + (is (:errors (p '[text {} {}]))) + + (is (not (:errors (p '[text [text]])))) + (is (not (:errors (p '[text {} 1 2 3 4 asdf])))) + + (is (:errors (p '[text {asdf "asdf"}])))) + + ) +