-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b727874
Showing
6 changed files
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.idea/ | ||
*.iml | ||
.nrepl-port | ||
target/ | ||
.cpcache/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# eql-inspect | ||
|
||
Utility functions to get information about queries and data. | ||
|
||
## Usage | ||
|
||
Add to your `deps.edn` | ||
```clojure | ||
net.molequedeideias/eql-inspect {:git/url "https://github.com/molequedeideias/eql-inspect" | ||
:sha "..."} | ||
``` | ||
|
||
> TIP: This isn't "eql validation". | ||
### Quick example: | ||
|
||
```clojure | ||
(require '[net.molequedeideias.eql-inspect :as eql-inspect]) | ||
|
||
(eql-inspect/explain-data {::eql-inspect/value {:a 42 :b 42} | ||
::eql-inspect/alias-key :as | ||
::eql-inspect/query [:a {:b [:c]} :d {:e [:f]}]}) | ||
=> {:net.molequedeideias.eql-inspect/value {:a 42, :b 42}, | ||
:net.molequedeideias.eql-inspect/alias-key :as, | ||
:net.molequedeideias.eql-inspect/query [:a {:b [:c]} :d {:e [:f]}], | ||
:net.molequedeideias.eql-inspect/problems ({:property :c, | ||
:dispatch-key :c, | ||
:path [:b], | ||
:value 42, | ||
:problem :net.molequedeideias.eql-inspect/expect-collection} | ||
{:property :d, | ||
:dispatch-key :d, | ||
:path [], | ||
:problem :net.molequedeideias.eql-inspect/missing-value} | ||
{:property :e, | ||
:dispatch-key :e, | ||
:path [], | ||
:query [:f], | ||
:problem :net.molequedeideias.eql-inspect/missing-value})} | ||
``` | ||
|
||
Checkout `test` dir for more exaples | ||
|
||
### Real World usage | ||
|
||
My current usage is on a REST API. | ||
|
||
My REST HANDLERS describe which data it need in `EQL` | ||
|
||
Once this handle throws, I use this library to give a better error to my API Consumer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{:deps {edn-query-language/eql {:mvn/version "1.0.0"}} | ||
:aliases {:dev {:extra-paths ["test"] | ||
:extra-deps {com.wsscode/pathom {:mvn/version "2.2.30"} | ||
org.clojure/clojure {:mvn/version "1.10.1"} | ||
org.clojure/test.check {:mvn/version "0.10.0"}}}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
(ns net.molequedeideias.eql-inspect | ||
(:require [edn-query-language.core :as eql])) | ||
|
||
(defn explain-query-xf | ||
[{::keys [value path alias-key] | ||
:or {path []} | ||
:as opts}] | ||
(comp (map (fn [{:keys [dispatch-key children params] :as node}] | ||
(let [property (if (contains? opts ::alias-key) | ||
(get params alias-key dispatch-key) | ||
dispatch-key) | ||
problem (cond-> {:property property | ||
:dispatch-key dispatch-key | ||
:path path} | ||
children (assoc :query (eql/ast->query {:type :root :children children})))] | ||
(cond | ||
(map? value) (if-not (contains? value property) | ||
[(assoc problem | ||
:problem ::missing-value)] | ||
(sequence | ||
(explain-query-xf (assoc opts | ||
::value (get value property) | ||
::path (conj path property))) | ||
children)) | ||
(coll? value) (into [] | ||
(comp (map-indexed | ||
(fn [idx value] | ||
(sequence | ||
(explain-query-xf (assoc opts | ||
::value value | ||
::path (conj path idx))) | ||
[node]))) | ||
cat) | ||
value) | ||
:else [(assoc problem | ||
:value value | ||
:problem ::expect-collection)])))) | ||
cat)) | ||
|
||
(defn explain-data | ||
[{::keys [query] :as opts}] | ||
(let [problems (sequence | ||
(explain-query-xf opts) | ||
(:children (eql/query->ast query)))] | ||
(when-not (empty? problems) | ||
(assoc opts | ||
::problems problems)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
(ns net.molequedeideias.eql-inspect-test | ||
(:require [clojure.test :refer [deftest is testing]] | ||
[net.molequedeideias.eql-inspect :as eql-inspect])) | ||
|
||
(defn problems | ||
[query value] | ||
(some-> (eql-inspect/explain-data {::eql-inspect/value value | ||
::eql-inspect/alias-key :as | ||
::eql-inspect/query query}) | ||
#_(doto clojure.pprint/pprint) | ||
::eql-inspect/problems | ||
vec)) | ||
|
||
(deftest explain-query | ||
(testing | ||
"simple" | ||
(is (= [{:dispatch-key :b | ||
:path [] | ||
:problem ::eql-inspect/missing-value | ||
:property :b}] | ||
(problems [:a :b] | ||
{:a 1})))) | ||
(testing | ||
"coll of coll of coll" | ||
(is (= [{:property :b | ||
:dispatch-key :b | ||
:problem ::eql-inspect/missing-value | ||
:path [0 0 0]}] | ||
(problems [:a :b] | ||
[[[{:a 1}]]])))) | ||
(testing | ||
"nested" | ||
(is (= [{:dispatch-key :d | ||
:property :d | ||
:problem ::eql-inspect/missing-value | ||
:path [:b]}] | ||
(problems [:a {:b [:c :d]}] | ||
{:a 1 | ||
:b {:c 42}})))) | ||
(testing | ||
"nested with coll" | ||
(is (= [{:dispatch-key :c | ||
:problem ::eql-inspect/missing-value | ||
:property :c | ||
:path [:b 1]} | ||
{:dispatch-key :d | ||
:property :d | ||
:problem ::eql-inspect/missing-value | ||
:path [:b 0]}] | ||
(problems [:a {:b [:c :d]}] | ||
{:a 1 | ||
:b [{:c 42} | ||
{:d 42}]})))) | ||
(testing | ||
"nested with coll and join" | ||
(is (= [{:dispatch-key :c | ||
:problem ::eql-inspect/missing-value | ||
:path [:b 1] | ||
:property :c} | ||
{:dispatch-key :d | ||
:problem ::eql-inspect/missing-value | ||
:path [:b 0] | ||
:property :d | ||
:query [:e :f]} | ||
{:dispatch-key :f | ||
:problem ::eql-inspect/missing-value | ||
:path [:b 1 :d 0] | ||
:property :f}] | ||
(problems [:a {:b [:c {:d [:e :f]}]}] | ||
{:a 1 | ||
:b [{:c 42} | ||
{:d [{:e 42}]}]})))) | ||
(testing | ||
"nested with root missing" | ||
(is (= [{:dispatch-key :b | ||
:path [] | ||
:property :b | ||
:problem ::eql-inspect/missing-value | ||
:query [:c :d]}] | ||
(problems [:a {:b [:c :d]}] | ||
{:a 1})))) | ||
(testing | ||
"simple with alias" | ||
(is (= [{:dispatch-key :b | ||
:property :c | ||
:problem ::eql-inspect/missing-value | ||
:path []}] | ||
(problems `[:a (:b {:as :c})] | ||
{:a 1})))) | ||
(testing | ||
"join with alias" | ||
(is (= [{:dispatch-key :d | ||
:problem ::eql-inspect/missing-value | ||
:property :e | ||
:path [:c]}] | ||
(problems `[:a | ||
{(:b {:as :c}) | ||
[(:d {:as :e})]}] | ||
{:a 42 | ||
:c {:d 42}})))) | ||
(testing | ||
"join with value" | ||
(is (= [{:dispatch-key :c | ||
:property :c | ||
:problem ::eql-inspect/expect-collection | ||
:value 42 | ||
:path [:b]}] | ||
(problems `[:a | ||
{:b [:c]}] | ||
{:a 42 | ||
:b 42}))))) |