Fix general gaps the hiccup suite shook out

Six correctness fixes, each a general gap (not hiccup-specific):

- deftype is not a map. jolt treated every deftype instance as a map
  (map?/record?/seqable over its fields); in Clojure only a defrecord is
  map-like, a bare deftype is an opaque object. defrecord now marks its type;
  map?/record?/coll?/seq/empty? gate on it, while a deftype implementing a
  collection interface still dispatches through its methods.

- cross-ns extend-protocol on an imported deftype. register-method built the
  type tag from the *calling* ns + bare name, so (extend-protocol P Raw …) in
  one ns missed a Raw value defined in another. A simple-name index resolves
  the bare name to the type's real tag (local ns still wins).

- str vs print. str of a collection is its readable form (nested strings
  quoted: (str ["x"]) => ["x"]); print leaves them raw. jolt defined print
  as str, conflating the two. Split via a __print1 seam.

- clojure.test thrown? now honors the exception hierarchy (instance?), so
  (thrown? IllegalArgumentException …) matches an ArityException subclass.

- java.net.URI is value-equal (= and hash by string form).

- clojure.walk/macroexpand-all was missing; an unresolved qualified var made
  the analyzer report "Unknown class walk".

deftype/defrecord + print are seed sources, re-minted. hiccup 365->381 of its
own suite; the rest are charset-encoding / var-meta niches.
This commit is contained in:
Yogthos 2026-06-26 20:15:39 -04:00
parent 448611a5df
commit 3d80bdc10b
12 changed files with 823 additions and 724 deletions

View file

@ -3269,4 +3269,12 @@
{:suite "seqs / laziness" :label "distinct over a rest-derived seq does not overrun" :expected "2" :actual "(count (distinct (map inc (rest [10 20 30]))))"}
{:suite "transducers / map multi-input" :label "the map transducer applies f across all inputs" :expected "[6]" :actual "(((map +) conj) [] 1 2 3)"}
{:suite "transducers / map multi-input" :label "single input is unchanged" :expected "[3]" :actual "(((map +) conj) [] 3)"}
{:suite "records / deftype is not a map" :label "a bare deftype is neither map? nor record?, a defrecord is both" :expected "[false false true true]" :actual "(do (deftype DT [a]) (defrecord DR [a]) [(map? (->DT 1)) (record? (->DT 1)) (map? (->DR 1)) (record? (->DR 1))])"}
{:suite "printer / str vs print" :label "str of a vector quotes nested strings" :expected "true" :actual "(= \"[\\\"x\\\"]\" (str [\"x\"]))"}
{:suite "printer / str vs print" :label "print-str of a vector leaves strings raw" :expected "true" :actual "(= \"[x]\" (print-str [\"x\"]))"}
{:suite "printer / str vs print" :label "str of a map quotes nested strings" :expected "true" :actual "(= \"{\\\"a\\\" \\\"b\\\"}\" (str {\"a\" \"b\"}))"}
{:suite "printer / str vs print" :label "print-str of a map leaves strings raw" :expected "true" :actual "(= \"{:a x}\" (print-str {:a \"x\"}))"}
{:suite "printer / str vs print" :label "infinity inside a collection prints readably in str" :expected "true" :actual "(= \"[##Inf]\" (str [##Inf]))"}
{:suite "interop / uri equality" :label "URIs are value-equal and usable as set members" :expected "[true true]" :actual "[(= (java.net.URI. \"/\") (java.net.URI. \"/\")) (= #{(java.net.URI. \"/\")} #{(java.net.URI. \"/\")})]"}
{:suite "stdlib / clojure.walk" :label "macroexpand-all expands a form" :expected "true" :actual "(do (require (quote clojure.walk)) (seq? (clojure.walk/macroexpand-all (quote (when true 1)))))"}
]