Skip to content

Commit

Permalink
Merge pull request #153 from CFiggers/data
Browse files Browse the repository at this point in the history
Code quality improvements, bugfixes, additional tests for `spork/data`
  • Loading branch information
bakpakin authored Sep 3, 2023
2 parents e48eaf4 + 0c0a897 commit 707e9bc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 35 deletions.
54 changes: 21 additions & 33 deletions spork/data.janet
Original file line number Diff line number Diff line change
Expand Up @@ -34,52 +34,40 @@
(let [va (safe-in a k)
vb (safe-in b k)
[a* b* ab] (diff va vb)
in-a (in? k (keys a))
in-b (in? k (keys b))
same (and in-a in-b
same (and (in? k (keys a)) (in? k (keys b))
(or (not (nil? ab))
(and (nil? va) (nil? vb))))]
[(when (and in-a (or (not (nil? a*)) (not same))) {k a*})
(when (and in-b (or (not (nil? b*)) (not same))) {k b*})
[(when (and (in? k (keys a)) (or (not (nil? a*)) (not same))) {k a*})
(when (and (in? k (keys b)) (or (not (nil? b*)) (not same))) {k b*})
(when same {k ab})]))

(defn- diff-associative [a b ks]
(reduce
(fn [diff1 diff2]
(map |(if (empty? $) nil $)
(map |(merge (or $0 {}) (or $1 {})) diff1 diff2)))
[nil nil nil]
(map
(partial diff-associative-key a b)
ks)))
(defn- diff-associative [a b &opt ks]
(default ks (distinct (array/concat (keys a) (keys b))))
(let [reduced (reduce
(fn [diff1 diff2]
(map |(if (empty? $) nil $)
(map |(merge (or $0 @{}) (or $1 @{})) diff1 diff2)))
[nil nil nil]
(map (partial diff-associative-key a b) ks))]
reduced))

(defn- diff-sequential [a b]
(map vectorize (diff-associative
(if (array? a) a (array ;a))
(if (array? b) b (array ;b))
(range (max (length a) (length b))))))

(defn- diff-similar [kind a b]
(cond
(in? kind [:array :tuple]) (diff-sequential a b)
(in? kind [:table :struct]) (diff-associative a b (distinct (array/concat (keys a) (keys b))))
(atom-diff a b)))

(defn- categorize [x]
(cond
(in? (type x) [:array :tuple]) :sequence
(in? (type x) [:table :struct]) :associative
:atom))

(varfn diff
```
Compares a and b recursively. Returns an array of
[things-only-in-a things-only-in-b things-in-both].
@[things-only-in-a things-only-in-b things-in-both].
```
[a b]
(if (= a b)
@[nil nil (cond (tuple? a) (array ;a)
(struct? a) (struct/to-table a) a)]
(if (= (categorize a) (categorize b))
(diff-similar (type a) a b)
(atom-diff a b))))
(if (deep= a b)
@[nil nil (postwalk |(cond (tuple? $) (array ;$)
(struct? $) (struct/to-table $) $) a)]
(do
(cond
(all indexed? [a b]) (diff-sequential a b)
(all dictionary? [a b]) (diff-associative a b)
(atom-diff a b)))))
34 changes: 32 additions & 2 deletions test/suite0021.janet
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(use ../spork/test)
(import ../spork/data :as d)

(start-suite)
(start-suite 21)

(assert-docs "/spork/data")

Expand Down Expand Up @@ -51,7 +51,37 @@
[{:a 1 :b 2} @{:a 1 :b 2 :c 4 :d 5} @[nil @{:c 4 :d 5} @{:a 1 :b 2}] "Should be: Struct and Table, different"]

[@[1 2 3] [1 2 3] @[nil nil @[1 2 3]] "Should be: Array and Tuple, same"]
[@[1 2 3] [1 2 3 4 5] @[nil @[nil nil nil 4 5] @[1 2 3]] "Should be: Array and Tuple, different"]])
[@[1 2 3] [1 2 3 4 5] @[nil @[nil nil nil 4 5] @[1 2 3]] "Should be: Array and Tuple, different"]

[@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@[nil nil @{6 @{7 @{:f "test" :g @{8 @[9 10 11] :h 12}}} :a @[1 2 @{:b @{:c 3}}] 5 @[:d :e 4]}]
"Should be: Nested Complex Data Structures, same"]

[@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 {:z 100} 11] :h 12}}}}
@[@{6 @{7 @{:g @{8 @[nil nil 11]}}}} @{6 @{7 @{:g @{8 @[nil nil {:z 100} 11]}}}} @{5 @[:d :e 4] 6 @{7 @{:f "test" :g @{8 @[9 10] :h 12}}} :a @[1 2 @{:b @{:c 3}}]}]
"Should be: Nested Complex Data Structures, deep insertion"]

[@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11]}}}}
@[@{6 @{7 @{:g @{:h 12}}}} nil @{6 @{7 @{:g @{8 @[9 10 11]} :f "test"}} 5 @[:d :e 4] :a @[1 2 @{:b @{:c 3}}]}]
"Should be: Nested Complex Data Structures, deep delete"]

[@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [:z 10 11] :h 12}}}}
@[@{6 @{7 @{:g @{8 @[9]}}}} @{6 @{7 @{:g @{8 @[:z]}}}} @{6 @{7 @{:f "test" :g @{8 @[nil 10 11] :h 12}}} 5 @[:d :e 4] :a @[1 2 @{:b @{:c 3}}]}]
"Should be: Nested Complex Data Structures, deep update"]

[@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 {:z 100 :x 10000 :y 100000} :h 12}}}}
@[@{6 @{7 @{:g @{8 [9 10 11]}}}} @{6 @{7 @{:g @{8 {:x 10000 :y 100000 :z 100}}}}} @{:a @[1 2 @{:b @{:c 3}}] 5 @[:d :e 4] 6 @{7 @{:f "test" :g @{:h 12}}}}]
"Should be: Nested Complex Data Structures, deep update of a whole structure"]

[@{:a [1 2 {:b {:c 3}}] 5 @[:d :e 4] 6 @{7 {:f "test" :g {8 [9 10 11] :h 12}}}}
@{:zz [1 10000 {:b {:c 3}}] 5 @[:d :e 1000] 6 @{7 {:f "test" :g {8 [9 10 11 {:z 10}] :h 12}}}}
@[@{5 @[nil nil 4] :a [1 2 {:b {:c 3}}]} @{5 @[nil nil 1000] 6 @{7 @{:g @{8 @[nil nil nil {:z 10}]}}} :zz [1 10000 {:b {:c 3}}]} @{5 @[:d :e] 6 @{7 @{:f "test" :g @{8 @[9 10 11] :h 12}}}}]
"Should be: Nested Complex Data Structures, multiple deep updates"]])

(map |(diff-assert ;$) cases)

Expand Down

0 comments on commit 707e9bc

Please sign in to comment.