Skip to content

Commit fccd1b8

Browse files
committed
warnings: add initial warnings
1 parent ec31be5 commit fccd1b8

File tree

7 files changed

+483
-55
lines changed

7 files changed

+483
-55
lines changed

deps.edn

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
:extra-deps {djblue/portal #_{:clj-kondo/ignore [:deps.edn]} {:mvn/version "RELEASE"}}
3737
:jvm-opts ["--enable-native-access=ALL-UNNAMED"]}
3838
:test {:extra-paths ["test"]
39-
:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
39+
:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}
40+
metosin/malli {:mvn/version "0.19.1"}}
4041
:main-opts ["-m" "kaocha.runner"]
4142
:jvm-opts ["--enable-native-access=ALL-UNNAMED"]}
4243
:nrepl {:extra-deps {nrepl/nrepl {:mvn/version "1.3.1"}}

dev/user.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
(ns user
2-
(:require [eden.core]
3-
[clojure.datafy]))
1+
(ns user (:require [clojure.datafy]))
42

53
(defmacro capture-env
64
"Capture local bindings.
@@ -48,3 +46,5 @@
4846
(defonce _add-tap-only-once (add-tap submit))
4947
(defn selected [] (selected p))
5048
(defn popen [] (open p))))
49+
50+
(require '[eden.core])

src/eden/report.clj

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,29 @@
33
(defmulti print-warning :type)
44

55
(defmethod print-warning :missing-key [{:keys [directive key template]}]
6-
(println (format " Missing key: %s for directive %s in template %s" key directive template)))
6+
(println (format " Missing key: %s for directive %s in template %s"
7+
key directive template)))
8+
9+
(defmethod print-warning :missing-render-template [{:keys [lang template parent]}]
10+
(println (format " Missing template: %s (lang: %s) while rendering %s"
11+
template lang parent)))
12+
13+
(defmethod print-warning :missing-page-content [{:keys [lang spec parent] :as w}]
14+
(println (format " Missing content: %s (lang: %s) while rendering %s"
15+
(:data spec) lang parent))
16+
(prn w))
17+
18+
(defmethod print-warning :not-a-string [{:keys [form lang]}]
19+
(println (format " Missing string value for template: '%s' (lang: %s)"
20+
(pr-str form)
21+
lang)))
22+
23+
(defmethod print-warning :missing-include-template [{:keys [directive template]}]
24+
(println (format " Missing include template: %s for %s"
25+
template directive)))
26+
27+
(defmethod print-warning :missing-template [{:keys [lang template]}]
28+
(println (format " Missing template: %s (lang: %s). Create template or specify :template in content " template lang)))
729

830
(defmethod print-warning :default [{:keys [type] :as warning}]
931
(println "Unknown warning:" type)
@@ -12,8 +34,10 @@
1234
(defn print-build-report [ctx]
1335
(when-let [warnings (seq (into #{} (:warnings ctx)))]
1436
(println "\n⚠️ Warnings")
15-
(doseq [warning warnings]
16-
(print-warning warning)))
37+
(doseq [[content-key content-warnings] (sort-by first (group-by #(or (:parent %) (:content-key %)) warnings))]
38+
(println "\n" content-key)
39+
(doseq [warning content-warnings]
40+
(print-warning warning))))
1741

1842
(when-let [error (:error ctx)]
1943
(println (format "\n❌ Build failed: %s" error))))

src/eden/site_generator.clj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
(do (warn! context
7474
{:type :missing-key
7575
:template (some-> context :data :template)
76+
:content-key (:content-key context)
7677
:key processed-key
7778
:directive :eden/get})
7879
[:span.missing-content (str "[:eden/get " processed-key "]")]))
@@ -257,6 +258,7 @@
257258
{:data processed-render-spec}
258259
processed-render-spec)
259260

261+
parent-content-key (:content-key context)
260262
content-key (:data final-spec)
261263

262264
lang (or (:lang context)
@@ -268,6 +270,8 @@
268270
(warn! context
269271
{:type :missing-page-content
270272
:directive :eden/render
273+
:parent parent-content-key
274+
:content-key content-key
271275
:lang lang
272276
:spec final-spec}))
273277

@@ -280,6 +284,8 @@
280284
(warn! context
281285
{:type :missing-render-template
282286
:directive :eden/render
287+
:parent parent-content-key
288+
:content-key content-key
283289
:lang lang
284290
:template template-key
285291
:spec final-spec})))]
@@ -317,6 +323,7 @@
317323
(warn! context
318324
{:type :missing-include-template
319325
:directive :eden/include
326+
:content-key (:content-key context)
320327
:template processed-template-name}))]
321328
(process template (update context :data merge override-context))))
322329

@@ -360,6 +367,8 @@
360367
(str/replace s variable value)
361368
(do (warn! context {:type :not-a-string
362369
:directive :eden/t
370+
:lang (:lang context)
371+
:content-key (:content-key context)
363372
:value value
364373
:template-variable variable
365374
:template-string string-template

test/eden/site_generator_test.clj

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -223,39 +223,6 @@
223223
:lang :en
224224
:templates {:sidebar [:h2 [:eden/get :hello]]}}))))
225225

226-
227-
(testing "simple component, content not found"
228-
(let [warnings (atom [])]
229-
(is (= [:span.missing-content "[:eden/render :this-page-is-not-found]"]
230-
(sg/process [:eden/render :this-page-is-not-found]
231-
{:content {:en {:sidebar {:hello "world"}}}
232-
:warn! #(swap! warnings conj %)
233-
:lang :en
234-
:templates {:sidebar [:h2 [:eden/get :hello]]}})))
235-
(is (= 1 (count @warnings)))
236-
(is (= [{:type :missing-page-content,
237-
:directive :eden/render
238-
:lang :en,
239-
:spec {:data :this-page-is-not-found}}]
240-
@warnings))))
241-
242-
(testing "simple component, template not found"
243-
(let [warnings (atom [])]
244-
(is (= [:span.missing-content "[:eden/render :sidebar]"]
245-
(sg/process [:eden/render :sidebar]
246-
{:content {:en {:sidebar {:hello "world"
247-
:template :my-nonexistent-template}}}
248-
:warn! #(swap! warnings conj %)
249-
:lang :en
250-
:templates {:sidebar [:h2 [:eden/get :hello]]}})))
251-
(is (= 1 (count @warnings)))
252-
(is (= [{:type :missing-render-template
253-
:directive :eden/render
254-
:lang :en
255-
:template :my-nonexistent-template
256-
:spec {:data :sidebar}}]
257-
@warnings))))
258-
259226
(testing "simple component, page has template"
260227
(is (= [:p "I am foo"]
261228
(sg/process [:eden/render :sidebar]
@@ -357,21 +324,7 @@
357324
[:p "Language: " [:eden/get :language]]]]]]
358325
{:data {:user {:name "user name"
359326
:preferences {:theme "dark"
360-
:language "braile"}}}}))))
361-
362-
(testing "missing key"
363-
(let [warnings (atom [])]
364-
(is (= [[:p [:span.missing-content "[:eden/get :value]"]]]
365-
(sg/process [:eden/with :foo
366-
[:p [:eden/get :value]]]
367-
{:warn! #(swap! warnings conj %)})))
368-
369-
(let [relevant-warnings (filter #(= (:type %) :with-directive-data-not-found) @warnings)]
370-
(is (= 1 (count relevant-warnings)))
371-
(is (= {:type :with-directive-data-not-found,
372-
:data-key :foo
373-
:data nil}
374-
(first relevant-warnings)))))))
327+
:language "braile"}}}})))))
375328

376329
(deftest eden-include
377330
(testing "simple include"
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
(ns eden.site-generator-test.warning-examples
2+
"Example warnings for each type, used for:
3+
1. Visual inspection of report output
4+
2. Testing report formatting
5+
3. Documentation of warning structures
6+
7+
All examples must validate against their schemas in warnings-test namespace.
8+
Run (print-all-examples) to see formatted output of all warning types."
9+
(:require [eden.site-generator-test.warnings-test :as wt]
10+
[eden.report :as report]
11+
[malli.core :as m]
12+
[malli.error :as me]))
13+
14+
(def warnings
15+
[{:type :missing-key
16+
:template :home
17+
:content-key :index
18+
:key :page-title
19+
:directive :eden/get}
20+
21+
{:type :missing-path
22+
:directive :eden/get-in
23+
:path [:user :profile :avatar]}
24+
25+
{:type :missing-config-key
26+
:path [:social :twitter :api-key]}
27+
28+
{:type :missing-collection-key
29+
:key :products}
30+
31+
{:type :unsupported-eden-each-collection-spec
32+
:original-key "invalid-string"
33+
:context {} ; Would have full context in real scenario
34+
:body [:div "..."]
35+
:key "invalid-string"}
36+
37+
{:type :missing-page-content
38+
:directive :eden/render
39+
:lang :en
40+
:spec {:data :about-page}
41+
:parent :home
42+
:content-key :about-page}
43+
44+
{:type :missing-render-template
45+
:directive :eden/render
46+
:lang :en
47+
:template :product-detail
48+
:spec {:data :product}
49+
:parent :shop
50+
:content-key :product}
51+
52+
{:type :with-directive-data-not-found
53+
:data-key :user-preferences
54+
:data {:user-id 123 :user-name "John"}}
55+
56+
{:type :missing-include-template
57+
:directive :eden/include
58+
:template :header-navigation
59+
:content-key :home}
60+
61+
{:type :missing-body-in-context
62+
:directive :eden/body
63+
:content-key :blog-post}
64+
65+
{:type :invalid-key-or-path
66+
:path "should-be-keyword-or-vector"
67+
:directive :eden/t}
68+
69+
{:type :not-a-string
70+
:directive :eden/t
71+
:content-key :dashboard
72+
:lang :en
73+
:value 42
74+
:template-variable "{{count}}"
75+
:template-string "You have {{count}} messages"
76+
:form [:eden/t :message-count {:count 42}]}
77+
78+
{:type :unknown-directive
79+
:directive :eden/custom-thing}
80+
81+
{:type :missing-content
82+
:content-key :privacy-policy
83+
:message "Page :privacy-policy not found in any language"}])
84+
85+
(defn print-examples []
86+
(let [{:keys [valid errors]}
87+
(reduce (fn [agg w]
88+
(if (m/validate wt/Warning w)
89+
(update agg :valid conj w)
90+
(update agg :errors conj (let [explained (m/explain wt/Warning w)]
91+
{:value w
92+
:explain explained
93+
:humanized (me/humanize explained)}))))
94+
{:valid [] :errors []}
95+
warnings)
96+
warnings-by-type (group-by :type valid)]
97+
98+
(doseq [[type warnings] warnings-by-type]
99+
(println type "examples")
100+
(doseq [w warnings]
101+
(report/print-warning w)))
102+
103+
(when (seq errors)
104+
(println "\nErrors:")
105+
(let [{missing true other false}
106+
(group-by #(= (-> % :explain :errors first :type) ::m/invalid-dispatch-value) errors)]
107+
(when (seq missing)
108+
(println " Missing schemas")
109+
(doseq [missing-schema (into #{} (map (comp :type :value)) missing)]
110+
(println " " missing-schema))
111+
(println))
112+
113+
(when (seq other)
114+
(println " Invalid warnings")
115+
(doseq [{:keys [value humanized]} other]
116+
(print " ")
117+
(pr humanized)
118+
(print " - ")
119+
(prn value)
120+
(println))
121+
(println))))))
122+
123+
(comment
124+
(print-examples))

0 commit comments

Comments
 (0)