Created
January 30, 2017 20:32
-
-
Save williballenthin/267be361bb8dd0fe893f61e16425e036 to your computer and use it in GitHub Desktop.
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
(def tests [{:name "one top level prop" | |
:model {:top-level-prop "A"} | |
:query [:top-level-prop] | |
:expected {:top-level-prop "A"}} | |
{:name "pluck one top level prop" | |
:model {:top-level-prop "A" :other-prop "B"} | |
;; even though there are two props at the top level, | |
;; we are only asking for one. | |
:query [:top-level-prop] | |
:expected {:top-level-prop "A"}} | |
{:name "pluck two top level props" | |
:model {:top-level-prop "A" :other-prop "B" :prop-c "C"} | |
;; now we ask for two of the three props. | |
:query [:top-level-prop :other-prop] | |
:expected {:top-level-prop "A" :other-prop "B"}} | |
{:name "pluck top level vector" | |
:model {:top-level-prop ["A" "B" "C"] :other-prop "B"} | |
;; now we ask for two of the three props. | |
:query [:top-level-prop] | |
:expected {:top-level-prop ["A" "B" "C"]}} | |
{:name "subselect item from vector" | |
:model {:top-level-prop [{:a "a" :b "b"} {:a "AAA" :b "BBB"}] :other-prop "B"} | |
;; here we have a vector of complex maps. | |
;; select only the :a prop from each map in the vector. | |
:query [{:top-level-prop [:a]}] | |
:expected {:top-level-prop [{:a "a"} {:a "AAA"}]}} | |
{:name "subselect items from vector" | |
:model {:top-level-prop [{:a "a" :b "b" :c "c"} {:a "AAA" :b "BBB" :c "CCC"}] :other-prop "B"} | |
;; here we have a vector of complex maps. | |
;; select only the :a prop from each map in the vector. | |
:query [{:top-level-prop [:a :b]}] | |
:expected {:top-level-prop [{:a "a" :b "b"} {:a "AAA" :b "BBB"}]}} | |
{:name "nested subselect" | |
:model {:top-level-prop [{:a [{:aa "a" :bb "b"} | |
{:aa "aa" :bb "bb"}] | |
:b "Z"} | |
{:a [{:aa "A" :bb "B"} | |
{:aa "AA" :bb "BB"}] | |
:b "Z"}] | |
:other-prop "Z"} | |
;; here we want to sub-select an already sub-selected item. | |
;; we want to get all the {:a {:aa}} props, and none of the :b or :bb props. | |
:query [{:top-level-prop [{:a [:aa]}]}] | |
:expected {:top-level-prop [{:a [{:aa "a"} | |
{:aa "aa"}]} | |
{:a [{:aa "A"} | |
{:aa "AA"}]}]}} | |
{:name "simple by iden" | |
:model {:things/by-iden {"abc" "foo", "def" "bar"}} | |
;; note that we use double-[ | |
;; the first level is because the query is a list of things. | |
;; the second level is the ident [:things/by-iden "abc"] | |
:query [[:things/by-iden "abc"]] | |
:expected {[:things/by-iden "abc"] "foo"}} | |
{:name "by ident and join some props" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c "cc"}, "def" "bar"}} | |
;; note we use a { here to deref. | |
;; this means to sub-select a portion of the results. | |
;; so, we get the thing from [:things/by-iden "abc"] | |
;; and then select only the :a and :b props. | |
:query [{[:things/by-iden "abc"] [:a :b]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :b "bb"}}} | |
{:name "by ident and join one prop" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb"}, "def" "bar"}} | |
:query [{[:things/by-iden "abc"] [:a]}] | |
:expected {[:things/by-iden "abc"] {:a "aa"}}} | |
{:name "by ident with complex key" | |
:model {:things/by-iden {[1 2] {:a "aa" :b "bb"}, "def" "bar"}} | |
:query [{[:things/by-iden [1 2]] [:a]}] | |
:expected {[:things/by-iden [1 2]] {:a "aa"}}} | |
{:name "don't do this" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb"}, "def" "bar"}} | |
;; if you want to sub-select (join) some portion of the results, | |
;; don't do this! | |
;; this asks for the thing [:things/by-iden "abc"], and also | |
;; the thing [:a] (whatever that is). | |
;; the example above is the correct syntax. | |
:query [[:things/by-iden "abc"] [:a]] | |
:expected {[:things/by-iden "abc"] {:a "aa" :b "bb"}}} | |
{:name "by ident, don't yet nested join" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" "bar"}} | |
;; our item [:things/by-iden "abc"] now contains a reference | |
;; to [:things/by-iden "def"], but it doesn't resolve this item. | |
;; the reference remains as-is. | |
:query [[:things/by-iden "abc"]] | |
:expected {[:things/by-iden "abc"] {:a "aa" :b "bb" :c [:things/by-iden "def"]}}} | |
{:name "by ident, direct join, no nested join" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" "bar"}} | |
;; we can join some of the immediate props (:a and :c), but don't yet | |
;; follow the link that :c contains. | |
:query [{[:things/by-iden "abc"] [:a :c]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :c [:things/by-iden "def"]}}} | |
{:name "by ident, nested join" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" {:d "bar" :e "baz"}}} | |
;; now, we want to follow the link in :c. | |
;; we use join syntax ( { ), with the key being the prop name | |
;; of [:things/by-iden "abc"] that contains the link. | |
;; of course, maps must have an even number of entries, so the value | |
;; is the list of things we want from the target item. | |
:query [{[:things/by-iden "abc"] [:a {:c [:d]}]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :c {:d "bar"}}}} | |
{:name "by ident, nested join, two props" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" {:d "bar" :e "baz"}}} | |
;; get two things from the linked item (:d and :e). | |
:query [{[:things/by-iden "abc"] [:a {:c [:d :e]}]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :c {:d "bar" :e "baz"}}}} | |
{:name "by ident, nested join, all props" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" {:d "bar" :e "baz"}}} | |
;; use the special term '[*] that denotes "fetch the entire item". | |
:query [{[:things/by-iden "abc"] [:a {:c '[*]}]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :c {:d "bar" :e "baz"}}}} | |
{:name "by ident, nested join, all props, with dups" | |
:disabled "not supported by om/db->tree" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" {:d "bar" :e "baz"}}} | |
;; this syntax is not supported by om/db->tree | |
;; the * must be found in exactly '[*] | |
:query [{[:things/by-iden "abc"] [:a {:c ['* :d]}]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :c {:d "bar" :e "baz"}}}} | |
{:name "by ident, all props, with link" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb" :c [:things/by-iden "def"],} | |
"def" {:d "bar" :e "baz"}}} | |
;; although we are fetching the entire item, we don't expect the link | |
;; to be resolved. | |
:query [{[:things/by-iden "abc"] '[*]}] | |
:expected {[:things/by-iden "abc"] {:a "aa" :b "bb" :c [:things/by-iden "def"]}}} | |
{:name "list of links" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb"} | |
"def" {:a "AA" :b "AA"}} | |
:the-things [[:things/by-iden "abc"] | |
[:things/by-iden "def"]]} | |
:query [:the-things] | |
:expected {:the-things [[:things/by-iden "abc"] | |
[:things/by-iden "def"]]}} | |
{:name "join list of links" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb"} | |
"def" {:a "AA" :b "BB"}} | |
:the-things [[:things/by-iden "abc"] | |
[:things/by-iden "def"]]} | |
;; here we have a list of links to other things. | |
;; we want to traverse into those things. | |
:query [{:the-things [:a :b]}] | |
:expected {:the-things [{:a "aa" :b "bb"} | |
{:a "AA" :b "BB"}]}} | |
{:name "join list of links with star" | |
:model {:things/by-iden {"abc" {:a "aa" :b "bb"} | |
"def" {:a "AA" :b "BB"}} | |
:the-things [[:things/by-iden "abc"] | |
[:things/by-iden "def"]]} | |
;; here we have a list of links to other things. | |
;; we want to traverse into those things. | |
:query [{:the-things '[*]}] | |
:expected {:the-things [{:a "aa" :b "bb"} | |
{:a "AA" :b "BB"}]}} | |
{:name "missing iden" | |
:model {:things/by-iden {"abc" "foo", "def" "bar"}} | |
;; note that we use double-[ | |
;; the first level is because the query is a list of things. | |
;; the second level is the ident [:things/by-iden "abc"] | |
:query [[:things/by-iden "xyz"]] | |
:expected {} | |
:missing-idents #{[:things/by-iden "xyz"]}} | |
{:name "union" | |
:via "https://github.com/omcljs/om/wiki/Queries-With-Unions" | |
:model {:dashboard/items | |
[[:dashboard/post 0] | |
[:dashboard/photo 1] | |
[:dashboard/post 2] | |
[:dashboard/graphic 3] | |
[:dashboard/post 4]], | |
:dashboard/post | |
{0 | |
{:id 0, | |
:type :dashboard/post, | |
:title "A Post!", | |
:author "Laura Smith", | |
:content "Lorem ipsum dolor sit amet, quem atomorum te quo", | |
:favorites 0}, | |
2 | |
{:id 2, | |
:type :dashboard/post, | |
:title "Another Post!", | |
:author "Jim Jacobs", | |
:content "Lorem ipsum dolor sit amet, quem atomorum te quo", | |
:favorites 0}, | |
4 | |
{:id 4, | |
:type :dashboard/post, | |
:title "Yet Another Post!", | |
:author "May Fields", | |
:content "Lorem ipsum dolor sit amet, quem atomorum te quo", | |
:favorites 0}}, | |
:dashboard/photo | |
{1 | |
{:id 1, | |
:type :dashboard/photo, | |
:title "A Photo!", | |
:image "photo.jpg", | |
:caption "Lorem ipsum", | |
:favorites 0}}, | |
:dashboard/graphic | |
{3 | |
{:id 3, | |
:type :dashboard/graphic, | |
:title "Charts and Stufff!", | |
:image "chart.jpg", | |
:favorites 0}}} | |
;; :dashboard/items is a list that contains idents of different types. | |
;; we use a union query to map the ident type to the data we want for some ident type. | |
;; so, if the ident type is :dashboard/post, then we want six props, including :content. | |
;; but not including :image. | |
:query [{:dashboard/items | |
{:dashboard/post [:id :type :title :author :content :favorites], | |
:dashboard/photo [:id :type :title :image :caption :favorites], | |
:dashboard/graphic [:id :type :title :image :favorites]}}] | |
:expected {:dashboard/items | |
[{:id 0, | |
:type :dashboard/post, | |
:title "A Post!", | |
:author "Laura Smith", | |
:content "Lorem ipsum dolor sit amet, quem atomorum te quo", | |
:favorites 0} | |
{:id 1, | |
:type :dashboard/photo, | |
:title "A Photo!", | |
:image "photo.jpg", | |
:caption "Lorem ipsum", | |
:favorites 0} | |
{:id 2, | |
:type :dashboard/post, | |
:title "Another Post!", | |
:author "Jim Jacobs", | |
:content "Lorem ipsum dolor sit amet, quem atomorum te quo", | |
:favorites 0} | |
{:id 3, | |
:type :dashboard/graphic, | |
:title "Charts and Stufff!", | |
:image "chart.jpg", | |
:favorites 0} | |
{:id 4, | |
:type :dashboard/post, | |
:title "Yet Another Post!", | |
:author "May Fields", | |
:content "Lorem ipsum dolor sit amet, quem atomorum te quo", | |
:favorites 0}]}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment