Skip to content

Commit 6ddbc50

Browse files
committed
Make tests green and get rid of warnings
This also unifies clj/cljs code in some places, like using an `array?` check instead of relying on object type. Also clean up use of extend/extend-protocol. The original version used `extend` for nil and Object out of a mistaken belief that `extend-protocol` wouldn't work for these cases, but it works fine. For ClojureScript the default value is not `Object` or `js/Object` but `default`. - Fix diffing of records - Make sure type-name always returns a symbol - Fix printing of time values - Make the registry feature availabe cross platform by using an atom instead of vars
1 parent f5e19f9 commit 6ddbc50

File tree

2 files changed

+187
-185
lines changed

2 files changed

+187
-185
lines changed

src/lambdaisland/deep_diff/diff.cljc

Lines changed: 137 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313

1414
;; For property based testing
1515
(defprotocol Undiff
16-
(-left-undiff [x])
17-
(-right-undiff [x]))
16+
(left-undiff [x])
17+
(right-undiff [x]))
1818

19-
(defn- shift-insertions [ins]
19+
(defn shift-insertions [ins]
2020
(reduce (fn [res idx]
2121
(let [offset (apply + (map count (vals res)))]
2222
(assoc res (+ idx offset) (get ins idx))))
2323
{}
2424
(sort (keys ins))))
2525

26-
(defn- replacements
26+
(defn replacements
2727
"Given a set of deletion indexes and a map of insertion index to value sequence,
2828
match up deletions and insertions into replacements, returning a map of
2929
replacements, a set of deletions, and a map of insertions."
@@ -58,23 +58,23 @@
5858
(remove (comp nil? val))
5959
(shift-insertions ins))])))
6060

61-
(defn- del+ins
61+
(defn del+ins
6262
"Wrapper around clj-diff that returns deletions and insertions as a set and map
6363
respectively."
6464
[exp act]
6565
(let [{del :- ins :+} (seq-diff/diff exp act)]
6666
[(into #{} del)
6767
(into {} (map (fn [[k & vs]] [k (vec vs)])) ins)]))
6868

69-
(defn- diff-seq-replacements [replacements s]
69+
(defn diff-seq-replacements [replacements s]
7070
(map-indexed
7171
(fn [idx v]
7272
(if (contains? replacements idx)
7373
(diff v (get replacements idx))
7474
v))
7575
s))
7676

77-
(defn- diff-seq-deletions [del s]
77+
(defn diff-seq-deletions [del s]
7878
(map
7979
(fn [v idx]
8080
(if (contains? del idx)
@@ -83,27 +83,21 @@
8383
s
8484
(range)))
8585

86-
(defn- diff-seq-insertions [ins s]
86+
(defn diff-seq-insertions [ins s]
8787
(reduce (fn [res [idx vs]]
8888
(concat (take (inc idx) res) (map ->Insertion vs) (drop (inc idx) res)))
8989
s
9090
ins))
9191

92-
(defn- diff-seq [exp act]
92+
(defn diff-seq [exp act]
9393
(let [[rep del ins] (replacements (del+ins exp act))]
9494
(->> exp
9595
(diff-seq-replacements rep)
9696
(diff-seq-deletions del)
9797
(diff-seq-insertions ins)
9898
(into []))))
9999

100-
#?(:clj (defn- val-type [val]
101-
(let [t (type val)]
102-
(if (class? t)
103-
(symbol (.getName ^Class t))
104-
t))))
105-
106-
(defn- diff-map [exp act]
100+
(defn diff-map [exp act]
107101
(first
108102
(let [exp-ks (keys exp)
109103
act-ks (concat (filter (set (keys act)) exp-ks)
@@ -126,65 +120,60 @@
126120
{}) 0]
127121
exp-ks))))
128122

129-
(defn- primitive? [x]
123+
(defn primitive? [x]
130124
(or (number? x) (string? x) (boolean? x) (inst? x) (keyword? x) (symbol? x)))
131125

132-
(defn- diff-atom [exp act]
126+
(defn diff-atom [exp act]
133127
(if (= exp act)
134128
exp
135129
(->Mismatch exp act)))
136130

137-
(defn- diff-similar [x y]
138-
#?(:clj (-diff-similar x y)
139-
:cljs
140-
(if (primitive? x)
141-
(diff-atom x y)
142-
(-diff-similar x y))))
143-
144-
(defn- left-undiff [m]
145-
#?(:clj (-left-undiff m)
146-
:cljs
147-
(if (primitive? m)
148-
m
149-
(-left-undiff m))))
150-
151-
(defn- right-undiff [m]
152-
#?(:clj (-right-undiff m)
153-
:cljs
154-
(if (primitive? m)
155-
m
156-
(-right-undiff m))))
131+
(defn diff-similar [x y]
132+
(if (primitive? x)
133+
(diff-atom x y)
134+
(-diff-similar x y)))
135+
136+
(defn diffable? [exp]
137+
(or (implements? Diff exp)
138+
(satisfies? Diff exp)))
157139

158140
(defn diff [exp act]
159-
(if (= (data/equality-partition exp) (data/equality-partition act))
141+
(cond
142+
(nil? exp)
143+
(diff-atom exp act)
144+
145+
(and (diffable? exp)
146+
(= (data/equality-partition exp) (data/equality-partition act)))
160147
(diff-similar exp act)
161-
(diff-atom exp act)))
162148

163-
#?(:clj (extend nil
164-
Diff
165-
{:-diff-similar diff-atom})
166-
:cljs (extend-type nil
167-
Diff
168-
(-diff-similar [x y] (diff-atom x y))))
149+
(array? exp)
150+
(diff-seq exp act)
169151

170-
#?(:cljs (extend-type js/Object
171-
Diff
172-
(-diff-similar [x y] (diff-atom (js->clj x) (js->clj y)))))
152+
(record? exp)
153+
(diff-map exp act)
173154

174-
#?(:clj (extend Object
175-
Diff
176-
{:-diff-similar (fn [exp act]
177-
(if (.isArray (.getClass ^Object exp))
178-
(diff-seq exp act)
179-
(diff-atom exp act)))}))
155+
:else
156+
(diff-atom exp act)))
180157

181158
(extend-protocol Diff
182-
#?(:clj java.util.List
183-
:cljs cljs.core/List)
184-
(-diff-similar [exp act] (diff-seq exp act))
159+
#?(:clj java.util.Set :cljs cljs.core/PersistentHashSet)
160+
(-diff-similar [exp act]
161+
(let [exp-seq (seq exp)
162+
act-seq (seq act)]
163+
(set (diff-seq exp-seq (concat (filter act exp-seq)
164+
(remove exp act-seq))))))
165+
#?@(:clj
166+
[java.util.List
167+
(-diff-similar [exp act] (diff-seq exp act))
168+
169+
java.util.Map
170+
(-diff-similar [exp act] (diff-map exp act))]
171+
172+
:cljs
173+
[cljs.core/List
174+
(-diff-similar [exp act] (diff-seq exp act))
185175

186-
#?@(:cljs
187-
[cljs.core/PersistentVector
176+
cljs.core/PersistentVector
188177
(-diff-similar [exp act] (diff-seq exp act))
189178

190179
cljs.core/EmptyList
@@ -193,91 +182,98 @@
193182
cljs.core/PersistentHashMap
194183
(-diff-similar [exp act] (diff-map exp act))
195184

196-
array
197-
(-diff-similar [exp act] (diff-seq exp act))])
198-
199-
#?(:clj java.util.Set
200-
:cljs cljs.core/PersistentHashSet)
201-
(-diff-similar [exp act]
202-
(let [exp-seq (seq exp)
203-
act-seq (seq act)]
204-
(set (diff-seq exp-seq (concat (filter act exp-seq)
205-
(remove exp act-seq))))))
206-
207-
#?(:clj java.util.Map
208-
:cljs cljs.core/PersistentArrayMap)
209-
(-diff-similar [exp act] (diff-map exp act)))
185+
cljs.core/PersistentArrayMap
186+
(-diff-similar [exp act] (diff-map exp act))]))
210187

211188
(extend-protocol Undiff
212-
#?(:clj java.util.List
213-
:cljs cljs.core/List)
214-
(-left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s)))
215-
(-right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s)))
216-
217-
#?(:cljs cljs.core/EmptyList)
218-
#?(:cljs (-left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s))))
219-
#?(:cljs (-right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s))))
220-
221-
#?(:cljs cljs.core/PersistentVector)
222-
#?(:cljs (-left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s))))
223-
#?(:cljs (-right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s))))
224-
225-
#?(:clj java.util.Set
226-
:cljs cljs.core/PersistentHashSet)
227-
(-left-undiff [s] (set (left-undiff (seq s))))
228-
(-right-undiff [s] (set (right-undiff (seq s))))
229-
230-
#?(:cljs cljs.core/KeySeq)
231-
#?(:cljs (-left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s))))
232-
#?(:cljs (-right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s))))
233-
234-
#?(:clj java.util.Map
235-
:cljs cljs.core/PersistentArrayMap)
236-
(-left-undiff [m]
237-
(into {}
238-
(comp (remove #(instance? Insertion (key %)))
239-
(map (juxt (comp left-undiff key) (comp left-undiff val))))
240-
m))
241-
(-right-undiff [m]
242-
(into {}
243-
(comp (remove #(instance? Deletion (key %)))
244-
(map (juxt (comp right-undiff key) (comp right-undiff val))))
245-
m))
246-
247-
#?(:cljs cljs.core/PersistentHashMap)
248-
#?(:cljs (-left-undiff [m]
249-
(into {}
250-
(comp (remove #(instance? Insertion (key %)))
251-
(map (juxt (comp left-undiff key) (comp left-undiff val))))
252-
m)))
253-
#?(:cljs (-right-undiff [m]
254-
(into {}
255-
(comp (remove #(instance? Deletion (key %)))
256-
(map (juxt (comp right-undiff key) (comp right-undiff val))))
257-
m)))
258-
259189
Mismatch
260-
(-left-undiff [m] (get m :-))
261-
(-right-undiff [m] (get m :+))
190+
(left-undiff [m] (get m :-))
191+
(right-undiff [m] (get m :+))
262192

263193
Insertion
264-
(-right-undiff [m] (get m :+))
194+
(right-undiff [m] (get m :+))
265195

266196
Deletion
267-
(-left-undiff [m] (get m :-)))
268-
269-
(extend-type nil
270-
Undiff
271-
(-left-undiff [m] m)
272-
(-right-undiff [m] m))
273-
274-
#?(:clj (extend Object Undiff {:-left-undiff identity :-right-undiff identity}))
275-
#?(:cljs (extend-type cljs.core/UUID
276-
Undiff
277-
(-left-undiff [m] m)
278-
(-right-undiff [m] m)))
279-
280-
#?(:cljs (extend-type js/Object
281-
Undiff
282-
(-left-undiff [m] m)
283-
(-right-undiff [m] m)))
197+
(left-undiff [m] (get m :-))
198+
199+
nil
200+
(left-undiff [m] m)
201+
(right-undiff [m] m)
202+
203+
#?(:clj Object :cljs default)
204+
(left-undiff [m] m)
205+
(right-undiff [m] m)
206+
207+
#?@(:clj
208+
[java.util.List
209+
(left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s)))
210+
(right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s)))
211+
212+
java.util.Set
213+
(left-undiff [s] (set (left-undiff (seq s))))
214+
(right-undiff [s] (set (right-undiff (seq s))))
215+
216+
java.util.Map
217+
(left-undiff [m]
218+
(into {}
219+
(comp (remove #(instance? Insertion (key %)))
220+
(map (juxt (comp left-undiff key) (comp left-undiff val))))
221+
m))
222+
(right-undiff [m]
223+
(into {}
224+
(comp (remove #(instance? Deletion (key %)))
225+
(map (juxt (comp right-undiff key) (comp right-undiff val))))
226+
m))]
227+
228+
:cljs
229+
[cljs.core/List
230+
(left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s)))
231+
(right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s)))
232+
233+
cljs.core/EmptyList
234+
(left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s)))
235+
(right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s)))
236+
237+
cljs.core/PersistentHashSet
238+
(left-undiff [s] (set (left-undiff (seq s))))
239+
(right-undiff [s] (set (right-undiff (seq s))))
240+
241+
cljs.core/PersistentTreeSet
242+
(left-undiff [s] (set (left-undiff (seq s))))
243+
(right-undiff [s] (set (right-undiff (seq s))))
244+
245+
cljs.core/PersistentVector
246+
(left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s)))
247+
(right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s)))
248+
249+
cljs.core/KeySeq
250+
(left-undiff [s] (map left-undiff (remove #(instance? Insertion %) s)))
251+
(right-undiff [s] (map right-undiff (remove #(instance? Deletion %) s)))
252+
253+
cljs.core/PersistentArrayMap
254+
(left-undiff [m]
255+
(into {}
256+
(comp (remove #(instance? Insertion (key %)))
257+
(map (juxt (comp left-undiff key) (comp left-undiff val))))
258+
m))
259+
(right-undiff [m]
260+
(into {}
261+
(comp (remove #(instance? Deletion (key %)))
262+
(map (juxt (comp right-undiff key) (comp right-undiff val))))
263+
m))
264+
265+
cljs.core/PersistentHashMap
266+
(left-undiff [m]
267+
(into {}
268+
(comp (remove #(instance? Insertion (key %)))
269+
(map (juxt (comp left-undiff key) (comp left-undiff val))))
270+
m))
271+
(right-undiff [m]
272+
(into {}
273+
(comp (remove #(instance? Deletion (key %)))
274+
(map (juxt (comp right-undiff key) (comp right-undiff val))))
275+
m))
276+
277+
cljs.core/UUID
278+
(left-undiff [m] m)
279+
(right-undiff [m] m)]))

0 commit comments

Comments
 (0)