core: close surfaced gaps — first-class sorted colls, with-out-str, rand arity, deref reduced
jolt-ti9: sorted-map/sorted-set are now first-class across the collection fns — get/assoc/dissoc/conj/contains?/keys/vals/disj and call-as-fn all operate on the wrapper and preserve sort order. The by-comparator constructors (sorted-map-by/ sorted-set-by) now thread the user comparator (numeric or boolean-predicate) through all derived colls. Sorted predicates/ctors/ops moved above core-conj so the collection fns can branch on them; jolt-invoke (interpreter) gets inline branches. jolt-rfw: add with-out-str (binds output to a string buffer) + the macro. jolt-ek3: (rand n) arity and deref-of-reduced (uuid? still deferred). Specs: new io-spec.janet; sorted-spec expanded to pin the now-working map/set ops and by-comparator ordering; predicate/number spec restorations.
This commit is contained in:
parent
ae8b635602
commit
afef55704c
7 changed files with 174 additions and 30 deletions
26
test/spec/io-spec.janet
Normal file
26
test/spec/io-spec.janet
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Specification: printing / output (print/println/pr/prn, *-str, format, str).
|
||||
# Output is captured with with-out-str (jolt-rfw); the *-str fns return strings.
|
||||
(use ../support/harness)
|
||||
|
||||
(defspec "io / with-out-str captures"
|
||||
["println" "\"hi\\n\"" "(with-out-str (println \"hi\"))"]
|
||||
["print spaces" "\"a b\"" "(with-out-str (print \"a\" \"b\"))"]
|
||||
["prn quotes" "\"[1 2]\\n\"" "(with-out-str (prn [1 2]))"]
|
||||
["pr no newline" "\"5\"" "(with-out-str (pr 5))"]
|
||||
["multiple writes" "\"12\"" "(with-out-str (print 1) (print 2))"]
|
||||
["no output" "\"\"" "(with-out-str 42)"]
|
||||
["println no args" "\"\\n\"" "(with-out-str (println))"])
|
||||
|
||||
(defspec "io / *-str builders"
|
||||
["print-str" "\"a b\"" "(print-str \"a\" \"b\")"]
|
||||
["println-str" "\"x\\n\"" "(println-str \"x\")"]
|
||||
["prn-str" "\"[1 2]\\n\"" "(prn-str [1 2])"]
|
||||
["pr-str quotes" "\"\\\"s\\\"\"" "(pr-str \"s\")"]
|
||||
["pr-str keyword" "\":a\"" "(pr-str :a)"])
|
||||
|
||||
(defspec "io / str & format"
|
||||
["str concat" "\"1:ab\"" "(str 1 :a \"b\")"]
|
||||
["str nil" "\"\"" "(str nil)"]
|
||||
["str of coll" "\"[1 2]\"" "(str [1 2])"]
|
||||
["format d/s" "\"5-x\"" "(format \"%d-%s\" 5 \"x\")"]
|
||||
["format float" "\"3.14\"" "(format \"%.2f\" 3.14159)"])
|
||||
|
|
@ -131,5 +131,6 @@
|
|||
["rand-int in range" "true" "(let [r (rand-int 5)] (and (integer? r) (>= r 0) (< r 5)))"]
|
||||
["rand-int zero" "0" "(rand-int 1)"]
|
||||
["rand in [0,1)" "true" "(let [r (rand)] (and (>= r 0) (< r 1)))"]
|
||||
["rand n in [0,n)" "true" "(let [r (rand 10)] (and (>= r 0) (< r 10)))"]
|
||||
["rand-nth member" "true" "(contains? #{:a :b :c} (rand-nth [:a :b :c]))"]
|
||||
["rand-nth single" ":x" "(rand-nth [:x])"])
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@
|
|||
["integer? fraction" "false" "(integer? 5.5)"]
|
||||
["reduced? wrapped" "true" "(reduced? (reduced 1))"]
|
||||
["reduced? plain" "false" "(reduced? 1)"]
|
||||
["deref reduced" "9" "(deref (reduced 9))"]
|
||||
["unreduced wrapped" "9" "(unreduced (reduced 9))"]
|
||||
["unreduced plain" "9" "(unreduced 9)"]
|
||||
["not-empty full" "[1]" "(not-empty [1])"]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
# Specification: sorted collections (sorted-map / sorted-set, subseq/rsubseq).
|
||||
#
|
||||
# NOTE: sorted collections are only partially first-class in Jolt — get/conj/assoc/
|
||||
# contains?/keys/vals on a sorted coll, and the by-comparator constructors, are NOT
|
||||
# yet wired up (jolt-ti9). This spec pins the behavior that DOES work (construction,
|
||||
# SEQ ordering, subseq/rsubseq, sorted?, first) so it can't regress; the broken ops
|
||||
# are tracked in jolt-ti9. (vec coerces the seq to a vector so expecteds are vector
|
||||
# literals rather than quoted lists.)
|
||||
# sorted collections are first-class for the core ops (jolt-ti9): get/assoc/dissoc/
|
||||
# conj/contains?/keys/vals/disj all work and preserve sort order, and a sorted coll
|
||||
# is callable as a key-lookup fn. STILL TODO: the by-comparator constructors
|
||||
# (sorted-map-by / sorted-set-by) ignore the supplied comparator (jolt-ti9). (vec
|
||||
# coerces a seq to a vector so expecteds are vector literals, not quoted lists.)
|
||||
(use ../support/harness)
|
||||
|
||||
(defspec "sorted / construction & ordering"
|
||||
|
|
@ -22,6 +21,37 @@
|
|||
["plain map" "false" "(sorted? {:a 1})"]
|
||||
["vector" "false" "(sorted? [1 2])"])
|
||||
|
||||
(defspec "sorted / map ops"
|
||||
["get hit" "2" "(get (sorted-map :a 1 :b 2) :b)"]
|
||||
["get miss default" ":none" "(get (sorted-map :a 1) :z :none)"]
|
||||
["contains? yes" "true" "(contains? (sorted-map :a 1) :a)"]
|
||||
["contains? no" "false" "(contains? (sorted-map :a 1) :z)"]
|
||||
["assoc keeps order" "[[:a 1] [:b 2] [:c 3]]" "(vec (seq (assoc (sorted-map :c 3 :a 1) :b 2)))"]
|
||||
["dissoc" "[[:a 1] [:c 3]]" "(vec (seq (dissoc (sorted-map :a 1 :b 2 :c 3) :b)))"]
|
||||
["conj entry" "[[:a 1] [:z 9]]" "(vec (seq (conj (sorted-map :a 1) [:z 9])))"]
|
||||
["keys sorted" "[:a :b :c]" "(vec (keys (sorted-map :c 3 :a 1 :b 2)))"]
|
||||
["vals by key" "[1 2 3]" "(vec (vals (sorted-map :c 3 :a 1 :b 2)))"]
|
||||
["map as fn" "2" "((sorted-map :a 1 :b 2) :b)"]
|
||||
["map as fn miss" ":d" "((sorted-map :a 1) :z :d)"])
|
||||
|
||||
(defspec "sorted / set ops"
|
||||
["get present" "2" "(get (sorted-set 1 2 3) 2)"]
|
||||
["get absent" ":none" "(get (sorted-set 1 2 3) 9 :none)"]
|
||||
["contains? yes" "true" "(contains? (sorted-set 1 2 3) 2)"]
|
||||
["contains? no" "false" "(contains? (sorted-set 1 2 3) 9)"]
|
||||
["conj keeps order" "[0 1 2 3 5]" "(vec (seq (conj (sorted-set 1 2 3) 5 0)))"]
|
||||
["disj" "[1 3]" "(vec (seq (disj (sorted-set 1 2 3) 2)))"]
|
||||
["set as fn" "3" "((sorted-set 1 2 3) 3)"]
|
||||
["set as fn miss" "nil" "((sorted-set 1 2 3) 9)"])
|
||||
|
||||
(defspec "sorted / by comparator"
|
||||
["sorted-set-by desc" "[10 3 2 1]" "(vec (seq (sorted-set-by > 1 3 2 10)))"]
|
||||
["sorted-map-by desc" "[[3 :c] [2 :b] [1 :a]]" "(vec (seq (sorted-map-by > 1 :a 3 :c 2 :b)))"]
|
||||
["conj keeps comparator" "[5 3 2 1 0]" "(vec (seq (conj (sorted-set-by > 1 3 2) 5 0)))"]
|
||||
["assoc keeps comparator" "[3 2 1]" "(vec (keys (assoc (sorted-map-by > 1 :a 3 :c) 2 :b)))"]
|
||||
["disj keeps comparator" "[3 1]" "(vec (seq (disj (sorted-set-by > 1 2 3) 2)))"]
|
||||
["by-comparator is sorted?" "true" "(sorted? (sorted-set-by > 1 2))"])
|
||||
|
||||
(defspec "sorted / subseq & rsubseq"
|
||||
["subseq >=" "[3 4 5]" "(vec (subseq (sorted-set 1 2 3 4 5) >= 3))"]
|
||||
["subseq <" "[1 2]" "(vec (subseq (sorted-set 1 2 3 4 5) < 3))"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue