stdlib: port clojure.data, rewrite clojure.zip; fix with-meta nil; add battery
clojure.data: ported from the ClojureScript impl (jolt-native equality-partition fn instead of host-type protocol dispatch). Verified against Clojure's own data-test (12/13 canonical; the 13th needs nil-valued-map support, jolt-c7h). Used mapv over the reference's (doall (map …)) — jolt's lazy multi-coll map + doall don't force as a reduce accumulator (jolt-dzh). clojure.zip: jolt's was a broken custom reimplementation; replaced with a port of real clojure.zip (metadata-based locs). Uses (nth loc …) instead of (loc …) because meta-bearing vectors aren't invocable as fns (jolt-vh5). core: with-meta now accepts nil metadata (Clojure allows (with-meta x nil)); it crashed calling keys on nil. This is what unblocked zip's make-node. New vendored battery (test/clojure-stdlib/, from clojurust's suite with fixtures corrected to match real Clojure): walk 34, zip 33, data 61 all clean; edn guarded at 43 (still a stub — jolt-b7y). Conformance 218/218 all modes; full suite green.
This commit is contained in:
parent
c975f5d1c3
commit
e623968b45
8 changed files with 812 additions and 95 deletions
149
test/clojure-stdlib/clojure/data_test/diff.cljc
Normal file
149
test/clojure-stdlib/clojure/data_test/diff.cljc
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
(ns clojure.data-test.diff
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
;; NOTE (jolt): sequential-diff expectations corrected to match real Clojure —
|
||||
;; clojure.data pads only to the max differing index (e.g. (diff [1 2 3] [1 9 3])
|
||||
;; -> a=[nil 2], not [nil 2 nil]). The upstream clojurust fixtures had this wrong.
|
||||
[clojure.data :refer [diff]]))
|
||||
|
||||
;; ── Atoms ────────────────────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-equal-atoms
|
||||
(testing "equal atoms"
|
||||
(is (= [nil nil :a] (diff :a :a)))
|
||||
(is (= [nil nil 1] (diff 1 1)))
|
||||
(is (= [nil nil "hello"] (diff "hello" "hello")))
|
||||
(is (= [nil nil nil] (diff nil nil)))
|
||||
(is (= [nil nil true] (diff true true)))))
|
||||
|
||||
(deftest test-diff-unequal-atoms
|
||||
(testing "unequal atoms"
|
||||
(is (= [:a :b nil] (diff :a :b)))
|
||||
(is (= [1 2 nil] (diff 1 2)))
|
||||
(is (= ["a" "b" nil] (diff "a" "b")))
|
||||
(is (= [nil 1 nil] (diff nil 1)))
|
||||
(is (= [true false nil] (diff true false)))))
|
||||
|
||||
;; ── Maps ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-equal-maps
|
||||
(testing "equal maps"
|
||||
(is (= [nil nil {:a 1 :b 2}] (diff {:a 1 :b 2} {:a 1 :b 2})))
|
||||
(is (= [nil nil {}] (diff {} {})))))
|
||||
|
||||
(deftest test-diff-maps-only-in-a
|
||||
(testing "keys only in a"
|
||||
(let [[a b both] (diff {:a 1 :b 2} {:a 1})]
|
||||
(is (= {:b 2} a))
|
||||
(is (nil? b))
|
||||
(is (= {:a 1} both)))))
|
||||
|
||||
(deftest test-diff-maps-only-in-b
|
||||
(testing "keys only in b"
|
||||
(let [[a b both] (diff {:a 1} {:a 1 :b 2})]
|
||||
(is (nil? a))
|
||||
(is (= {:b 2} b))
|
||||
(is (= {:a 1} both)))))
|
||||
|
||||
(deftest test-diff-maps-different-values
|
||||
(testing "same keys, different values"
|
||||
(let [[a b both] (diff {:a 1 :b 2} {:a 1 :b 9})]
|
||||
(is (= {:b 2} a))
|
||||
(is (= {:b 9} b))
|
||||
(is (= {:a 1} both)))))
|
||||
|
||||
(deftest test-diff-maps-nested
|
||||
(testing "nested maps"
|
||||
(let [[a b both] (diff {:a {:x 1 :y 2}} {:a {:x 1 :z 3}})]
|
||||
(is (= {:a {:y 2}} a))
|
||||
(is (= {:a {:z 3}} b))
|
||||
(is (= {:a {:x 1}} both)))))
|
||||
|
||||
(deftest test-diff-maps-disjoint
|
||||
(testing "completely disjoint maps"
|
||||
(let [[a b both] (diff {:a 1} {:b 2})]
|
||||
(is (= {:a 1} a))
|
||||
(is (= {:b 2} b))
|
||||
(is (nil? both)))))
|
||||
|
||||
;; ── Sets ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-equal-sets
|
||||
(testing "equal sets"
|
||||
(is (= [nil nil #{1 2 3}] (diff #{1 2 3} #{1 2 3})))
|
||||
(is (= [nil nil #{}] (diff #{} #{})))))
|
||||
|
||||
(deftest test-diff-sets
|
||||
(testing "overlapping sets"
|
||||
(let [[a b both] (diff #{1 2 3} #{2 3 4})]
|
||||
(is (= #{1} a))
|
||||
(is (= #{4} b))
|
||||
(is (= #{2 3} both)))))
|
||||
|
||||
(deftest test-diff-disjoint-sets
|
||||
(testing "disjoint sets"
|
||||
(let [[a b both] (diff #{1 2} #{3 4})]
|
||||
(is (= #{1 2} a))
|
||||
(is (= #{3 4} b))
|
||||
(is (nil? both)))))
|
||||
|
||||
;; ── Vectors / Sequential ────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-equal-vectors
|
||||
(testing "equal vectors"
|
||||
(is (= [nil nil [1 2 3]] (diff [1 2 3] [1 2 3])))
|
||||
(is (= [nil nil []] (diff [] [])))))
|
||||
|
||||
(deftest test-diff-vectors-same-length
|
||||
(testing "same length, different elements"
|
||||
(let [[a b both] (diff [1 2 3] [1 9 3])]
|
||||
(is (= [nil 2] a))
|
||||
(is (= [nil 9] b))
|
||||
(is (= [1 nil 3] both)))))
|
||||
|
||||
(deftest test-diff-vectors-different-length
|
||||
(testing "different lengths"
|
||||
(let [[a b both] (diff [1 2 3] [1 2])]
|
||||
(is (= [nil nil 3] a))
|
||||
(is (nil? b))
|
||||
(is (= [1 2] both)))
|
||||
(let [[a b both] (diff [1] [1 2 3])]
|
||||
(is (nil? a))
|
||||
(is (= [nil 2 3] b))
|
||||
(is (= [1] both)))))
|
||||
|
||||
(deftest test-diff-lists
|
||||
(testing "lists treated as sequential"
|
||||
(let [[a b both] (diff '(1 2 3) '(1 9 3))]
|
||||
(is (= [nil 2] a))
|
||||
(is (= [nil 9] b))
|
||||
(is (= [1 nil 3] both)))))
|
||||
|
||||
;; ── Mixed types ─────────────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-mixed-types
|
||||
(testing "different partition types treated as atoms"
|
||||
(is (= [{:a 1} [1 2] nil] (diff {:a 1} [1 2])))
|
||||
(is (= [#{1} [1] nil] (diff #{1} [1])))
|
||||
(is (= [1 :a nil] (diff 1 :a)))))
|
||||
|
||||
;; ── Nil handling ────────────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-nil
|
||||
(testing "nil vs non-nil"
|
||||
(is (= [nil 1 nil] (diff nil 1)))
|
||||
(is (= [1 nil nil] (diff 1 nil)))
|
||||
(is (= [nil {:a 1} nil] (diff nil {:a 1})))))
|
||||
|
||||
;; ── Deeply nested ───────────────────────────────────────────────────────────
|
||||
|
||||
(deftest test-diff-deeply-nested
|
||||
(testing "deeply nested structures"
|
||||
(let [[a b both] (diff {:a {:b {:c 1}}} {:a {:b {:c 2}}})]
|
||||
(is (= {:a {:b {:c 1}}} a))
|
||||
(is (= {:a {:b {:c 2}}} b))
|
||||
(is (nil? both))))
|
||||
(testing "deeply nested with shared keys"
|
||||
(let [[a b both] (diff {:a {:b 1 :c 2}} {:a {:b 1 :c 9}})]
|
||||
(is (= {:a {:c 2}} a))
|
||||
(is (= {:a {:c 9}} b))
|
||||
(is (= {:a {:b 1}} both)))))
|
||||
107
test/clojure-stdlib/clojure/edn_test/read_string.cljc
Normal file
107
test/clojure-stdlib/clojure/edn_test/read_string.cljc
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
(ns clojure.edn-test.read-string
|
||||
(:require [clojure.edn :as edn]
|
||||
[clojure.test :refer [are deftest is testing]]))
|
||||
|
||||
(deftest test-read-string-scalars
|
||||
(testing "nil, booleans"
|
||||
(is (nil? (edn/read-string "nil")))
|
||||
(is (true? (edn/read-string "true")))
|
||||
(is (false? (edn/read-string "false"))))
|
||||
|
||||
(testing "integers"
|
||||
(is (= 0 (edn/read-string "0")))
|
||||
(is (= 42 (edn/read-string "42")))
|
||||
(is (= -1 (edn/read-string "-1")))
|
||||
(is (= 1000000000000 (edn/read-string "1000000000000"))))
|
||||
|
||||
(testing "floats"
|
||||
(is (= 3.14 (edn/read-string "3.14")))
|
||||
(is (= -0.5 (edn/read-string "-0.5")))
|
||||
(is (= 1.0 (edn/read-string "1.0"))))
|
||||
|
||||
(testing "bigints"
|
||||
(is (= 42N (edn/read-string "42N"))))
|
||||
|
||||
(testing "bigdecimals"
|
||||
(is (= 3.14M (edn/read-string "3.14M"))))
|
||||
|
||||
(testing "strings"
|
||||
(is (= "" (edn/read-string "\"\"")))
|
||||
(is (= "hello" (edn/read-string "\"hello\"")))
|
||||
(is (= "line1\nline2" (edn/read-string "\"line1\\nline2\"")))
|
||||
(is (= "tab\there" (edn/read-string "\"tab\\there\""))))
|
||||
|
||||
(testing "characters"
|
||||
(is (= \a (edn/read-string "\\a")))
|
||||
(is (= \newline (edn/read-string "\\newline")))
|
||||
(is (= \space (edn/read-string "\\space")))
|
||||
(is (= \tab (edn/read-string "\\tab"))))
|
||||
|
||||
(testing "keywords"
|
||||
(is (= :foo (edn/read-string ":foo")))
|
||||
(is (= :bar/baz (edn/read-string ":bar/baz"))))
|
||||
|
||||
(testing "symbols"
|
||||
(is (= 'foo (edn/read-string "foo")))
|
||||
(is (= 'bar/baz (edn/read-string "bar/baz")))))
|
||||
|
||||
(deftest test-read-string-collections
|
||||
(testing "vectors"
|
||||
(is (= [] (edn/read-string "[]")))
|
||||
(is (= [1 2 3] (edn/read-string "[1 2 3]")))
|
||||
(is (= [1 [2 3] 4] (edn/read-string "[1 [2 3] 4]"))))
|
||||
|
||||
(testing "lists"
|
||||
(is (= '() (edn/read-string "()")))
|
||||
(is (= '(1 2 3) (edn/read-string "(1 2 3)")))
|
||||
(is (= '(+ 1 2) (edn/read-string "(+ 1 2)"))))
|
||||
|
||||
(testing "maps"
|
||||
(is (= {} (edn/read-string "{}")))
|
||||
(is (= {:a 1} (edn/read-string "{:a 1}")))
|
||||
(is (= {:a 1 :b 2} (edn/read-string "{:a 1 :b 2}")))
|
||||
(is (= {:nested {:deep true}} (edn/read-string "{:nested {:deep true}}"))))
|
||||
|
||||
(testing "sets"
|
||||
(is (= #{} (edn/read-string "#{}")))
|
||||
(is (= #{1 2 3} (edn/read-string "#{1 2 3}"))))
|
||||
|
||||
(testing "mixed nested"
|
||||
(is (= {:users [{:name "Alice" :age 30}
|
||||
{:name "Bob" :age 25}]}
|
||||
(edn/read-string "{:users [{:name \"Alice\" :age 30} {:name \"Bob\" :age 25}]}")))))
|
||||
|
||||
(deftest test-read-string-tagged-literals
|
||||
(testing "#uuid"
|
||||
(let [u (edn/read-string "#uuid \"f81d4fae-7dec-11d0-a765-00a0c91e6bf6\"")]
|
||||
(is (uuid? u))
|
||||
(is (= u (edn/read-string "#uuid \"f81d4fae-7dec-11d0-a765-00a0c91e6bf6\""))))))
|
||||
|
||||
(deftest test-read-string-eof
|
||||
(testing "empty string with :eof option"
|
||||
(is (= :eof (edn/read-string {:eof :eof} "")))
|
||||
(is (= nil (edn/read-string {:eof nil} "")))
|
||||
(is (= 42 (edn/read-string {:eof 42} ""))))
|
||||
|
||||
(testing "whitespace-only with :eof option"
|
||||
(is (= :done (edn/read-string {:eof :done} " "))))
|
||||
|
||||
(testing "nil input returns nil"
|
||||
(is (nil? (edn/read-string nil)))))
|
||||
|
||||
(deftest test-read-string-comments
|
||||
(testing "comments are skipped"
|
||||
(is (= 42 (edn/read-string "; this is a comment\n42"))))
|
||||
|
||||
(testing "discard reader macro"
|
||||
(is (= 2 (edn/read-string "#_ 1 2")))))
|
||||
|
||||
(deftest test-read-string-only-first-form
|
||||
(testing "reads only the first form"
|
||||
(is (= 1 (edn/read-string "1 2 3")))
|
||||
(is (= :a (edn/read-string ":a :b :c")))))
|
||||
|
||||
(deftest test-read-string-ratios
|
||||
(testing "ratios"
|
||||
(is (= 1/2 (edn/read-string "1/2")))
|
||||
(is (= 3/4 (edn/read-string "3/4")))))
|
||||
101
test/clojure-stdlib/clojure/walk_test/walk.cljc
Normal file
101
test/clojure-stdlib/clojure/walk_test/walk.cljc
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
(ns clojure.walk-test.walk
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[clojure.walk :as w]))
|
||||
|
||||
(deftest test-walk
|
||||
(testing "walk with identity"
|
||||
(is (= [1 2 3] (w/walk identity identity [1 2 3])))
|
||||
(is (= '(1 2 3) (w/walk identity identity '(1 2 3))))
|
||||
(is (= #{1 2 3} (w/walk identity identity #{1 2 3}))))
|
||||
|
||||
(testing "walk with inner transform"
|
||||
(is (= [2 3 4] (w/walk inc identity [1 2 3])))
|
||||
(is (= [2 3 4] (w/walk inc vec [1 2 3]))))
|
||||
|
||||
(testing "walk with outer transform"
|
||||
(is (= [1 2 3] (w/walk identity vec '(1 2 3))))))
|
||||
|
||||
(deftest test-postwalk
|
||||
(testing "postwalk with numbers"
|
||||
(is (= [2 3 4] (w/postwalk #(if (number? %) (inc %) %) [1 2 3]))))
|
||||
|
||||
(testing "postwalk with nested structures"
|
||||
(is (= [2 [3 4] 5]
|
||||
(w/postwalk #(if (number? %) (inc %) %) [1 [2 3] 4]))))
|
||||
|
||||
(testing "postwalk preserves types"
|
||||
(is (vector? (w/postwalk identity [1 2 3])))
|
||||
(is (list? (w/postwalk identity '(1 2 3))))
|
||||
(is (set? (w/postwalk identity #{1 2 3})))
|
||||
(is (map? (w/postwalk identity {:a 1 :b 2}))))
|
||||
|
||||
(testing "postwalk on maps"
|
||||
(is (= {:a 2 :b 3}
|
||||
(w/postwalk #(if (number? %) (inc %) %) {:a 1 :b 2}))))
|
||||
|
||||
(testing "postwalk on empty collections"
|
||||
(is (= [] (w/postwalk identity [])))
|
||||
(is (= {} (w/postwalk identity {})))
|
||||
(is (= #{} (w/postwalk identity #{})))
|
||||
(is (= '() (w/postwalk identity '())))))
|
||||
|
||||
(deftest test-prewalk
|
||||
(testing "prewalk with numbers"
|
||||
(is (= [2 3 4] (w/prewalk #(if (number? %) (inc %) %) [1 2 3]))))
|
||||
|
||||
(testing "prewalk with nested structures"
|
||||
(is (= [2 [3 4] 5]
|
||||
(w/prewalk #(if (number? %) (inc %) %) [1 [2 3] 4]))))
|
||||
|
||||
(testing "prewalk transforms before descending"
|
||||
;; prewalk applies f to the outer form first, so we can replace
|
||||
;; entire subtrees before they are walked
|
||||
(is (= [:replaced]
|
||||
(w/prewalk #(if (= % [1 2 3]) [:replaced] %) [1 2 3])))))
|
||||
|
||||
(deftest test-keywordize-keys
|
||||
(testing "basic keywordize"
|
||||
(is (= {:a 1 :b 2} (w/keywordize-keys {"a" 1 "b" 2}))))
|
||||
|
||||
(testing "nested keywordize"
|
||||
(is (= {:a {:b 2}} (w/keywordize-keys {"a" {"b" 2}}))))
|
||||
|
||||
(testing "non-string keys unchanged"
|
||||
(is (= {:a 1 42 2} (w/keywordize-keys {"a" 1 42 2}))))
|
||||
|
||||
(testing "already keyword keys unchanged"
|
||||
(is (= {:a 1} (w/keywordize-keys {:a 1})))))
|
||||
|
||||
(deftest test-stringify-keys
|
||||
(testing "basic stringify"
|
||||
(is (= {"a" 1 "b" 2} (w/stringify-keys {:a 1 :b 2}))))
|
||||
|
||||
(testing "nested stringify"
|
||||
(is (= {"a" {"b" 2}} (w/stringify-keys {:a {:b 2}}))))
|
||||
|
||||
(testing "non-keyword keys unchanged"
|
||||
(is (= {"a" 1 42 2} (w/stringify-keys {:a 1 42 2})))))
|
||||
|
||||
(deftest test-postwalk-replace
|
||||
(testing "basic replacement"
|
||||
(is (= [:x :y :c] (w/postwalk-replace {:a :x :b :y} [:a :b :c]))))
|
||||
|
||||
(testing "nested replacement"
|
||||
(is (= [:x [:y :c]] (w/postwalk-replace {:a :x :b :y} [:a [:b :c]]))))
|
||||
|
||||
(testing "no matches"
|
||||
(is (= [1 2 3] (w/postwalk-replace {:a :x} [1 2 3]))))
|
||||
|
||||
(testing "empty smap"
|
||||
(is (= [1 2 3] (w/postwalk-replace {} [1 2 3])))))
|
||||
|
||||
(deftest test-prewalk-replace
|
||||
(testing "basic replacement"
|
||||
(is (= [:x :y :c] (w/prewalk-replace {:a :x :b :y} [:a :b :c]))))
|
||||
|
||||
(testing "nested replacement"
|
||||
(is (= [:x [:y :c]] (w/prewalk-replace {:a :x :b :y} [:a [:b :c]]))))
|
||||
|
||||
(testing "replaces before descending"
|
||||
;; prewalk-replace replaces the whole form first, then walks children
|
||||
(is (= :replaced (w/prewalk-replace {[:a :b] :replaced} [:a :b])))))
|
||||
122
test/clojure-stdlib/clojure/zip_test/zip.cljc
Normal file
122
test/clojure-stdlib/clojure/zip_test/zip.cljc
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
(ns clojure.zip-test.zip
|
||||
(:require [clojure.test :refer [deftest is testing run-tests]]
|
||||
[clojure.zip :as zip]))
|
||||
|
||||
(deftest test-vector-zip-navigation
|
||||
(let [data [[1 2] [3 [4 5]]]
|
||||
z (zip/vector-zip data)]
|
||||
(testing "root node"
|
||||
(is (= (zip/node z) [[1 2] [3 [4 5]]]))
|
||||
(is (zip/branch? z)))
|
||||
(testing "down"
|
||||
(is (= (zip/node (zip/down z)) [1 2])))
|
||||
(testing "right"
|
||||
(is (= (zip/node (zip/right (zip/down z))) [3 [4 5]])))
|
||||
(testing "down into nested"
|
||||
(is (= (zip/node (zip/down (zip/right (zip/down z)))) 3)))
|
||||
(testing "up returns parent"
|
||||
(is (= (zip/node (zip/up (zip/down z))) [[1 2] [3 [4 5]]])))
|
||||
(testing "rights"
|
||||
(is (= (zip/rights (zip/down z)) '([3 [4 5]]))))
|
||||
(testing "lefts"
|
||||
(is (= (zip/lefts (zip/right (zip/down z))) [[1 2]])))))
|
||||
|
||||
(deftest test-vector-zip-rightmost-leftmost
|
||||
(let [z (zip/vector-zip [1 2 3])]
|
||||
(testing "rightmost"
|
||||
(is (= (zip/node (zip/rightmost (zip/down z))) 3)))
|
||||
(testing "leftmost"
|
||||
(is (= (zip/node (zip/leftmost (zip/rightmost (zip/down z)))) 1)))))
|
||||
|
||||
(deftest test-seq-zip-navigation
|
||||
(let [z (zip/seq-zip '(1 (2 3) 4))]
|
||||
(testing "root"
|
||||
(is (= (zip/node z) '(1 (2 3) 4))))
|
||||
(testing "down"
|
||||
(is (= (zip/node (zip/down z)) 1)))
|
||||
(testing "right"
|
||||
(is (= (zip/node (zip/right (zip/down z))) '(2 3))))
|
||||
(testing "down into nested list"
|
||||
(is (= (zip/node (zip/down (zip/right (zip/down z)))) 2)))))
|
||||
|
||||
(deftest test-path
|
||||
(let [z (zip/vector-zip [[1 2] [3 4]])]
|
||||
(testing "path at root is nil"
|
||||
(is (nil? (zip/path z))))
|
||||
(testing "path one level down"
|
||||
(is (= (zip/path (zip/down z)) [[[1 2] [3 4]]])))
|
||||
(testing "path two levels down"
|
||||
(is (= (zip/path (zip/down (zip/down z)))
|
||||
[[[1 2] [3 4]] [1 2]])))))
|
||||
|
||||
(deftest test-edit
|
||||
(let [z (zip/vector-zip [1 [2 3] [4 5]])]
|
||||
(testing "edit a leaf"
|
||||
(let [loc (-> z zip/down zip/right zip/down)
|
||||
edited (zip/edit loc inc)]
|
||||
(is (= (zip/root edited) [1 [3 3] [4 5]]))))
|
||||
(testing "edit a branch"
|
||||
(let [loc (-> z zip/down zip/right)
|
||||
edited (zip/edit loc (fn [x] (vec (map inc x))))]
|
||||
(is (= (zip/root edited) [1 [3 4] [4 5]]))))))
|
||||
|
||||
(deftest test-replace
|
||||
(let [z (zip/vector-zip '[a b c])]
|
||||
(is (= (zip/root (zip/replace (zip/down z) 'x))
|
||||
'[x b c]))))
|
||||
|
||||
(deftest test-insert-left-right
|
||||
(let [z (zip/vector-zip [1 2 3])
|
||||
loc (-> z zip/down zip/right)]
|
||||
(testing "insert-left"
|
||||
(is (= (zip/root (zip/insert-left loc 'x)) [1 'x 2 3])))
|
||||
(testing "insert-right"
|
||||
(is (= (zip/root (zip/insert-right loc 'y)) [1 2 'y 3])))))
|
||||
|
||||
(deftest test-insert-child-append-child
|
||||
(let [z (zip/vector-zip [1 2 3])]
|
||||
(testing "insert-child"
|
||||
(is (= (zip/root (zip/insert-child z 0)) [0 1 2 3])))
|
||||
(testing "append-child"
|
||||
(is (= (zip/root (zip/append-child z 4)) [1 2 3 4])))))
|
||||
|
||||
(deftest test-remove
|
||||
(let [z (zip/vector-zip [1 2 3])
|
||||
loc (-> z zip/down zip/right)]
|
||||
(is (= (zip/root (zip/remove loc)) [1 3]))))
|
||||
|
||||
(deftest test-next-traversal
|
||||
(let [z (zip/vector-zip [1 [2 3]])]
|
||||
(testing "next enumerates depth-first"
|
||||
(is (= (loop [loc z, acc []]
|
||||
(if (zip/end? loc)
|
||||
acc
|
||||
(recur (zip/next loc) (conj acc (zip/node loc)))))
|
||||
[[1 [2 3]] 1 [2 3] 2 3])))))
|
||||
|
||||
(deftest test-end?
|
||||
(let [z (zip/vector-zip [1 2])]
|
||||
(testing "not end at start"
|
||||
(is (not (zip/end? z))))
|
||||
(testing "end after full traversal"
|
||||
(is (zip/end? (-> z zip/next zip/next zip/next))))))
|
||||
|
||||
(deftest test-prev
|
||||
(let [z (zip/vector-zip [1 [2 3]])]
|
||||
(testing "prev from second child"
|
||||
(let [loc (-> z zip/next zip/next)]
|
||||
(is (= (zip/node loc) [2 3]))
|
||||
(is (= (zip/node (zip/prev loc)) 1))))
|
||||
(testing "prev from leaf inside nested"
|
||||
(let [loc (-> z zip/next zip/next zip/next)]
|
||||
(is (= (zip/node loc) 2))
|
||||
(is (= (zip/node (zip/prev loc)) [2 3]))))))
|
||||
|
||||
(deftest test-root-after-edits
|
||||
(testing "root unwinds all the way after deep edits"
|
||||
(let [z (zip/vector-zip [[1 2] [3 [4 5]]])
|
||||
loc (-> z zip/down zip/right zip/down zip/right zip/down)
|
||||
edited (zip/edit loc inc)]
|
||||
(is (= (zip/root edited) [[1 2] [3 [5 5]]])))))
|
||||
|
||||
(run-tests)
|
||||
Loading…
Add table
Add a link
Reference in a new issue