Skip to content

Commit

Permalink
revamp merge-by-id to retain type; merge-by-id test
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew committed Jun 14, 2016
1 parent 7e14b60 commit f0967b8
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
23 changes: 15 additions & 8 deletions src/cljs/ulysses/utils.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
(defn boolean? [x]
(or (true? x) (false? x)))

(defn lazy-seq? [x]
(instance? LazySeq x))

(defn ptr
"print x, then return it. useful for
debugging inside threading macros or map"
Expand Down Expand Up @@ -120,14 +123,18 @@
seqable)))

(defn merge-by-id
"merge multiple seqables of maps by :id; the rightmost having the highest preference"
([a b]
(let [new-ids (map :id b)]
(concat
(remove #(-> % :id hash-set (some new-ids)) a)
b)))
([& seqables]
(reduce merge-by-id seqables)))
"merge multiple seqables of maps by :id;
the rightmost having the highest preference;
the result taking on the type of the first"
[a & more]
(let [list-or-lzs? ((some-fn list? lazy-seq?) a)
into-maybe (if list-or-lzs? identity (partial into (empty a)))
all (apply (partial concat a) more)]
(->> all
(group-by :id)
(vals)
(map last)
(into-maybe))))

(defn remove-by-id
"remove a map by :id within a seqable (of maps)"
Expand Down
46 changes: 34 additions & 12 deletions test/cljs/ulysses/utils_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
(:require [cljs.test :refer-macros [deftest testing are is]]
[ulysses.utils :as utils]))

(deftest test-noop
(deftest noop
(are [x] (nil? (apply utils/noop x))
[] [1] [1 2]))

(deftest test-boolean?
(deftest boolean?
(are [x y] (= x (utils/boolean? y))
true true
true false
Expand All @@ -18,13 +18,13 @@

; missing: ptr-first

(deftest test-metas-equal?
(deftest metas-equal?
(is (utils/metas-equal? [(with-meta {:a 1} {:key 1})]
[(with-meta {:a 2} {:key 1})]))
(is (not (utils/metas-equal? [(with-meta {:a 1} {:key 1})]
[(with-meta {:a 2} {:key 2})]))))

(deftest test-remap-and-variations
(deftest remap-and-variations
(let [from {:a 1 :b 2 :c 3}]
(testing "remap"
(is (= {:a 2 :b 4 :c 6}
Expand All @@ -40,10 +40,10 @@
(fn [k v] (keyword (str (name k) v)))
from))))))

(deftest test-hyphenate-keys
(deftest hyphenate-keys
(is (= {:a-b 1 :c-d 2} (utils/hyphenate-keys {:a_b 1 :c_d 2}))))

(deftest test-map-subels
(deftest map-subels
(testing "when values have ids"
(let [in [{:id 23 :value 3} {:id 95 :value 4}]
out (utils/map-subels :div in)
Expand All @@ -66,7 +66,7 @@
(is (= out expected))
(is (utils/metas-equal? out expected)))))

(deftest test-str->int
(deftest str->int
(testing "successful cases"
(are [x y] (= x (utils/str->int y))
0 "0"
Expand All @@ -83,15 +83,15 @@
"garbage" "12moregarbage12"
123.123 nil)))

(deftest test-clj->json
(deftest clj->json
(are [x y] (= x (utils/clj->json y))
"null" nil
"true" true
"-3" -3
"[1,2,3]" [1 2 3]
"[\"one\",\"three\",\"two\"]" (sorted-set :one :two :three)))

(deftest test-json->clj
(deftest json->clj
(testing "basic values"
(are [x y] (= x (utils/json->clj y))
nil "null"
Expand All @@ -107,19 +107,19 @@
(are [x] (thrown? js/SyntaxError (utils/json->clj x))
"asdf" "[1,2")))

(deftest test-url-encode-component
(deftest url-encode-component
(are [x y] (= x (utils/url-encode-component y))
"foo" "foo"
"foo%20bar" "foo bar"
"%3F%26%3F%26" "?&?&"))

(deftest test-truncate-with-ellipsis
(deftest truncate-with-ellipsis
(testing "normal"
(is (= "foo..." (utils/truncate-with-ellipsis "foo bar" 3))))
(testing "custom ellipsis"
(is (= "foo[..]" (utils/truncate-with-ellipsis "foo bar" 3 "[..]")))))

(deftest test-find-by-id
(deftest find-by-id
(let [ms [{:id 1} {:id 2} {:id 94}]]
(testing "found (type int)"
(are [pf y] (= (pf ms) (utils/find-by-id y ms))
Expand All @@ -134,3 +134,25 @@
(testing "not found"
(are [x] (nil? (utils/find-by-id x ms))
33 "33" "1.0" nil))))

(deftest merge-by-id
;; ih test util, ex: (ih [1 2 3]) => [{:id 1} {:id 2} {:id 3}]
(let [ih (fn [coll]
((if (list? coll) identity (partial into (empty coll)))
(map #(if (map? %) % (hash-map :id %)) coll)))]
(testing "two seq args"
(are [x a b] (= x (utils/merge-by-id (ih a) (ih b)))
[] [] []
[] [] (list)
[{:id 0} {:id 1} {:id 2}] [0] [1 2]
#{{:id 0} {:id 1} {:id 2}} #{0} #{1 2}
#{{:id 0} {:id 1} {:id 2}} #{0} [1 2]
(list {:id 0} {:id 1 :a true} {:id 2} {:id 3}) (list 0 {:id 1 :a false} 2) [{:id 1 :a true} 2 3]))
(testing "many seq args"
(are [x many] (= x (apply utils/merge-by-id (map ih many)))
[] [[] [] []]
[] [[] (list) (list)]
[{:id 0}] [[] [0] [] [0]]
#{{:id 0} {:id 1} {:id 2}} [#{0} #{1 2} #{0 2 1}]
#{{:id 0} {:id 1} {:id 2 :a true}} [#{0} [1 2] #{{:id 2 :a true}}]
(list {:id 0} {:id 1} {:id 2 :a true} {:id 3}) [(list 0 1 2) [1 {:id 2 :a true} 3] []]))))

0 comments on commit f0967b8

Please sign in to comment.