From f644b4b719adf0dc855da5e766bc4e43abe7dcaf Mon Sep 17 00:00:00 2001 From: Yogthos Date: Fri, 5 Jun 2026 13:57:05 -0400 Subject: [PATCH] feat(strictness): merge rejects atomic/wrong-shape args into a map merge now throws when a non-first arg is a scalar, a set, a list, or a wrong-length vector (a length-2 vector or a map still merge). Other map-like tables (records/sorted-maps/host tables, e.g. SCI's namespaces) keep the lenient conj path so the SCI bootstrap still loads. merge 29/11/2 -> 35/3/4. clojure-test-suite pass 3874->3880. spec: 5 merge strictness cases. jpm test green. --- src/jolt/core.janet | 7 +++++++ test/integration/clojure-test-suite-test.janet | 2 +- test/spec/maps-spec.janet | 7 ++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/jolt/core.janet b/src/jolt/core.janet index 0f04153..64dd89d 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -632,6 +632,13 @@ (and (or (pvec? m) (tuple? m) (array? m)) (= 2 (if (pvec? m) (pv-count m) (length m)))) (set result (core-assoc result (vnth m 0) (vnth m 1))) + # scalars, sets, and wrong-length sequentials can't merge into a map + # (a length-2 vector was handled above; anything else here is bad) + (or (number? m) (string? m) (buffer? m) (keyword? m) (boolean? m) + (set? m) (plist? m) (pvec? m) (tuple? m) (array? m) + (and (struct? m) (get m :jolt/type))) + (error (string "Can't merge " (type m) " into a map")) + # other map-like tables (records, sorted-maps, host tables): lenient conj (set result (core-conj result m)))) (++ i)) result))) diff --git a/test/integration/clojure-test-suite-test.janet b/test/integration/clojure-test-suite-test.janet index 1c79296..4d8b7e3 100644 --- a/test/integration/clojure-test-suite-test.janet +++ b/test/integration/clojure-test-suite-test.janet @@ -18,7 +18,7 @@ # Baseline: assertions Jolt currently passes across the suite. Raise as Jolt # improves so a regression (previously-passing assertion breaking) is caught. -(def baseline-pass 3870) +(def baseline-pass 3875) # A file is "clean" when it ran with zero failures AND zero errors. (def baseline-clean-files 45) # Per-file wall-clock budget (seconds). Normal files finish in well under 1s; diff --git a/test/spec/maps-spec.janet b/test/spec/maps-spec.janet index c24dc3c..7f3ded5 100644 --- a/test/spec/maps-spec.janet +++ b/test/spec/maps-spec.janet @@ -90,4 +90,9 @@ ["subvec out of range" :throws "(subvec [0 1 2 3] 1 5)"] ["subvec start>end" :throws "(subvec [0 1 2 3] 3 2)"] ["subvec ok" "[1 2]" "(subvec [0 1 2 3] 1 3)"] - ["min-key empty" :throws "(apply min-key identity [])"]) + ["min-key empty" :throws "(apply min-key identity [])"] + ["merge empty vector" :throws "(merge {} [])"] + ["merge 1-elem vector" :throws "(merge {} [:foo])"] + ["merge atomic arg" :throws "(merge {} :foo)"] + ["merge [k v] ok" "{:foo 1}" "(merge {} [:foo 1])"] + ["merge maps ok" "{:a 1, :b 2}" "(merge {:a 1} {:b 2})"])