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:
parent
448611a5df
commit
3d80bdc10b
12 changed files with 823 additions and 724 deletions
|
|
@ -33,11 +33,26 @@
|
||||||
((null? rs) (jolt-pr-str v))
|
((null? rs) (jolt-pr-str v))
|
||||||
(((caar rs) v) ((cdar rs) v))
|
(((caar rs) v) ((cdar rs) v))
|
||||||
(else (loop (cdr rs))))))))
|
(else (loop (cdr rs))))))))
|
||||||
|
;; print/println render non-readably: a nested string is raw. jolt-str-render-one
|
||||||
|
;; is exactly that (collections fall through to jolt-pr-str). The print family
|
||||||
|
;; uses this seam, NOT the str fn — which renders readably (below). A top-level nil
|
||||||
|
;; prints "nil" (str renders it ""), so the seam special-cases it.
|
||||||
|
(define (jolt-print-one v) (if (jolt-nil? v) "nil" (jolt-str-render-one v)))
|
||||||
|
(def-var! "clojure.core" "__print1" jolt-print-one)
|
||||||
|
|
||||||
|
;; str: a top-level string/scalar renders as jolt-str-render-one (raw string,
|
||||||
|
;; "Infinity"…), but a COLLECTION renders as its readable form — nested strings
|
||||||
|
;; are QUOTED ((str ["x"]) => "[\"x\"]"), matching the JVM (a collection's
|
||||||
|
;; toString is readable). jolt-pr-readable resolves at call time.
|
||||||
|
(define (jolt-str-one v)
|
||||||
|
(if (or (pvec? v) (pmap? v) (pset? v) (cseq? v) (empty-list-t? v) (jolt-lazyseq? v))
|
||||||
|
(jolt-pr-readable v)
|
||||||
|
(jolt-str-render-one v)))
|
||||||
(define (jolt-str . xs)
|
(define (jolt-str . xs)
|
||||||
(let loop ((xs xs) (acc '()))
|
(let loop ((xs xs) (acc '()))
|
||||||
(if (null? xs)
|
(if (null? xs)
|
||||||
(apply string-append (reverse acc))
|
(apply string-append (reverse acc))
|
||||||
(loop (cdr xs) (cons (jolt-str-render-one (car xs)) acc)))))
|
(loop (cdr xs) (cons (jolt-str-one (car xs)) acc)))))
|
||||||
|
|
||||||
;; jolt indices are flonums; substring etc. need exact ints.
|
;; jolt indices are flonums; substring etc. need exact ints.
|
||||||
(define (jolt->idx n) (exact (truncate n)))
|
(define (jolt->idx n) (exact (truncate n)))
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@
|
||||||
(define %h-set? jolt-set?)
|
(define %h-set? jolt-set?)
|
||||||
(set! jolt-set? (lambda (x) (or (htable-sorted-set? x) (%h-set? x))))
|
(set! jolt-set? (lambda (x) (or (htable-sorted-set? x) (%h-set? x))))
|
||||||
(def-var! "clojure.core" "set?" jolt-set?)
|
(def-var! "clojure.core" "set?" jolt-set?)
|
||||||
(def-var! "clojure.core" "coll?" (lambda (x) (or (htable-sorted? x) (jrec? x) (jolt-coll-pred? x))))
|
(def-var! "clojure.core" "coll?" (lambda (x) (or (htable-sorted? x) (jrec-collection? x) (jolt-coll-pred? x))))
|
||||||
|
|
||||||
;; --- equality / hash ---------------------------------------------------------
|
;; --- equality / hash ---------------------------------------------------------
|
||||||
;; A sorted coll canonicalizes like its unordered counterpart:
|
;; A sorted coll canonicalizes like its unordered counterpart:
|
||||||
|
|
|
||||||
|
|
@ -605,6 +605,14 @@
|
||||||
(cons "hashCode" (lambda (u) (string-hash (uri-field u 'string))))
|
(cons "hashCode" (lambda (u) (string-hash (uri-field u 'string))))
|
||||||
(cons "equals" (lambda (u o) (and (jhost? o) (string=? (jhost-tag o) "uri")
|
(cons "equals" (lambda (u o) (and (jhost? o) (string=? (jhost-tag o) "uri")
|
||||||
(string=? (uri-field u 'string) (uri-field o 'string)))))))
|
(string=? (uri-field u 'string) (uri-field o 'string)))))))
|
||||||
|
;; (= u1 u2) is value equality by string form (the .equals method above only
|
||||||
|
;; serves explicit (.equals …)); hash matches so a URI works as a map key / set
|
||||||
|
;; member (ring/hiccup compare (URI. "/") values).
|
||||||
|
(define (uri-jhost? x) (and (jhost? x) (string=? (jhost-tag x) "uri")))
|
||||||
|
(register-eq-arm! (lambda (a b) (or (uri-jhost? a) (uri-jhost? b)))
|
||||||
|
(lambda (a b) (and (uri-jhost? a) (uri-jhost? b)
|
||||||
|
(string=? (uri-field a 'string) (uri-field b 'string)))))
|
||||||
|
(register-hash-arm! uri-jhost? (lambda (x) (string-hash (uri-field x 'string))))
|
||||||
;; str / pr-str of a uri -> its string form.
|
;; str / pr-str of a uri -> its string form.
|
||||||
(register-str-render! (lambda (x) (and (jhost? x) (string=? (jhost-tag x) "uri")))
|
(register-str-render! (lambda (x) (and (jhost? x) (string=? (jhost-tag x) "uri")))
|
||||||
(lambda (x) (uri-field x 'string)))
|
(lambda (x) (uri-field x 'string)))
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,10 @@
|
||||||
;; chunked-seq? is true for a vector's seq (a real chunked-seq); the overlay's
|
;; chunked-seq? is true for a vector's seq (a real chunked-seq); the overlay's
|
||||||
;; always-false stub loaded over the host fn, so re-assert it.
|
;; always-false stub loaded over the host fn, so re-assert it.
|
||||||
(def-var! "clojure.core" "chunked-seq?" na-chunked-seq?)
|
(def-var! "clojure.core" "chunked-seq?" na-chunked-seq?)
|
||||||
;; record? is a host type check (jrec?), not the overlay's (some? (get x
|
;; record? is a host type check — true only for a defrecord, not a bare deftype
|
||||||
;; :jolt/deftype)) — the get-trick invokes a sorted-map's comparator on
|
;; (jrec-record?), matching the JVM (instance? IRecord). The overlay's
|
||||||
;; :jolt/deftype and throws. Matches the JVM (instance? IRecord).
|
;; (some? (get x :jolt/deftype)) get-trick would invoke a sorted-map comparator.
|
||||||
(def-var! "clojure.core" "record?" (lambda (x) (jrec? x)))
|
(def-var! "clojure.core" "record?" (lambda (x) (jrec-record? x)))
|
||||||
|
|
||||||
;; read / read+string over a HOST reader jhost (java.io StringReader/PushbackReader):
|
;; read / read+string over a HOST reader jhost (java.io StringReader/PushbackReader):
|
||||||
;; the overlay's IReader protocol only covers the reify map-reader, so a (read
|
;; the overlay's IReader protocol only covers the reify map-reader, so a (read
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,33 @@
|
||||||
;; map (jolt-nil unless non-field keys have been assoc'd on).
|
;; map (jolt-nil unless non-field keys have been assoc'd on).
|
||||||
(define-record-type (jrec make-jrec jrec?) (fields desc vals ext) (nongenerative chez-jrec-v2))
|
(define-record-type (jrec make-jrec jrec?) (fields desc vals ext) (nongenerative chez-jrec-v2))
|
||||||
(define (jrec-tag r) (jrdesc-tag (jrec-desc r)))
|
(define (jrec-tag r) (jrdesc-tag (jrec-desc r)))
|
||||||
|
|
||||||
|
;; defrecord vs deftype: a defrecord IS a map (map?/seq/keys/assoc over its
|
||||||
|
;; fields); a bare deftype is an opaque object with only its declared interfaces,
|
||||||
|
;; never a map (Clojure semantics). defrecord registers its type tag here; the
|
||||||
|
;; default jrec-as-map behaviour (map?/record?/field-seq) is gated on it, while
|
||||||
|
;; method dispatch (a deftype implementing ISeq/Counted/…) stays open to any jrec.
|
||||||
|
(define chez-record-type-tbl (make-hashtable string-hash string=?))
|
||||||
|
(define (jrec-record? x) (and (jrec? x) (hashtable-ref chez-record-type-tbl (jrec-tag x) #f) #t))
|
||||||
|
;; every deftype/defrecord tag, and a simple-name -> tag index. An extend-protocol
|
||||||
|
;; in a DIFFERENT ns names the type bare (it is :import-ed), so register-method
|
||||||
|
;; resolves "Raw" to its real tag "a.util.Raw" here instead of prepending the
|
||||||
|
;; calling ns. The local ns is preferred, so a same-named local type still wins.
|
||||||
|
(define chez-deftype-tag-set (make-hashtable string-hash string=?))
|
||||||
|
(define chez-simple-name-tag (make-hashtable string-hash string=?))
|
||||||
|
;; a jrec that is coll? — a record, or a deftype implementing a collection
|
||||||
|
;; interface (its seq/count/nth/valAt/cons method is registered). find-method-any-
|
||||||
|
;; protocol is defined later; resolved at call time. An opaque deftype is not coll?.
|
||||||
|
(define (jrec-collection? x)
|
||||||
|
(and (jrec? x)
|
||||||
|
(or (jrec-record? x)
|
||||||
|
(let ((tag (jrec-tag x)))
|
||||||
|
(or (find-method-any-protocol tag "seq")
|
||||||
|
(find-method-any-protocol tag "count")
|
||||||
|
(find-method-any-protocol tag "nth")
|
||||||
|
(find-method-any-protocol tag "valAt")
|
||||||
|
(find-method-any-protocol tag "cons"))))
|
||||||
|
#t))
|
||||||
(define jolt-deftype-kw (keyword "jolt" "deftype"))
|
(define jolt-deftype-kw (keyword "jolt" "deftype"))
|
||||||
;; unique present-vs-absent sentinel for extension-map lookups (so a present nil
|
;; unique present-vs-absent sentinel for extension-map lookups (so a present nil
|
||||||
;; in the extension map is distinguished from a genuine miss).
|
;; in the extension map is distinguished from a genuine miss).
|
||||||
|
|
@ -338,7 +365,9 @@
|
||||||
(define %r-jolt-seq jolt-seq)
|
(define %r-jolt-seq jolt-seq)
|
||||||
(set! jolt-seq (lambda (x)
|
(set! jolt-seq (lambda (x)
|
||||||
(cond ((jrec-cl x "seq") => (lambda (m) (jolt-seq (jolt-invoke m x))))
|
(cond ((jrec-cl x "seq") => (lambda (m) (jolt-seq (jolt-invoke m x))))
|
||||||
((jrec? x) (list->cseq (jrec-entry-list x)))
|
;; a record seqs its fields; a bare deftype is not seqable (falls through
|
||||||
|
;; to %r-jolt-seq, which errors like the JVM).
|
||||||
|
((jrec-record? x) (list->cseq (jrec-entry-list x)))
|
||||||
(else (%r-jolt-seq x)))))
|
(else (%r-jolt-seq x)))))
|
||||||
(define %r-jolt-conj1 jolt-conj1)
|
(define %r-jolt-conj1 jolt-conj1)
|
||||||
(set! jolt-conj1 (lambda (coll x)
|
(set! jolt-conj1 (lambda (coll x)
|
||||||
|
|
@ -350,7 +379,8 @@
|
||||||
;; empty? over a jrec: a map-like deftype is empty iff its entry seq is (data
|
;; empty? over a jrec: a map-like deftype is empty iff its entry seq is (data
|
||||||
;; .priority-map's peek calls (.isEmpty this) -> empty?). jolt-seq is method-first.
|
;; .priority-map's peek calls (.isEmpty this) -> empty?). jolt-seq is method-first.
|
||||||
(define %r-jolt-empty? jolt-empty?)
|
(define %r-jolt-empty? jolt-empty?)
|
||||||
(set! jolt-empty? (lambda (coll) (if (jrec? coll) (jolt-nil? (jolt-seq coll)) (%r-jolt-empty? coll))))
|
(set! jolt-empty? (lambda (coll)
|
||||||
|
(if (jrec-collection? coll) (jolt-nil? (jolt-seq coll)) (%r-jolt-empty? coll))))
|
||||||
(define %r-jolt-peek jolt-peek)
|
(define %r-jolt-peek jolt-peek)
|
||||||
(set! jolt-peek (lambda (coll)
|
(set! jolt-peek (lambda (coll)
|
||||||
(cond ((jrec-cl coll "peek") => (lambda (m) (jolt-invoke m coll)))
|
(cond ((jrec-cl coll "peek") => (lambda (m) (jolt-invoke m coll)))
|
||||||
|
|
@ -365,10 +395,13 @@
|
||||||
;; predicates.ss vars hold a snapshot, so re-def-var! after extending. record? is
|
;; predicates.ss vars hold a snapshot, so re-def-var! after extending. record? is
|
||||||
;; the overlay's (some? (get x :jolt/deftype)) — works for free since the get
|
;; the overlay's (some? (get x :jolt/deftype)) — works for free since the get
|
||||||
;; override returns the tag for that key.
|
;; override returns the tag for that key.
|
||||||
|
;; only a defrecord is a map (Clojure: a record IS an associative map); a bare
|
||||||
|
;; deftype is not. coll? additionally covers a deftype implementing a collection
|
||||||
|
;; interface. predicates.ss vars hold a snapshot, so re-def-var! after extending.
|
||||||
(define %r-jolt-map? jolt-map?)
|
(define %r-jolt-map? jolt-map?)
|
||||||
(set! jolt-map? (lambda (x) (or (jrec? x) (%r-jolt-map? x))))
|
(set! jolt-map? (lambda (x) (or (jrec-record? x) (%r-jolt-map? x))))
|
||||||
(def-var! "clojure.core" "map?" jolt-map?)
|
(def-var! "clojure.core" "map?" jolt-map?)
|
||||||
(def-var! "clojure.core" "coll?" (lambda (x) (or (jrec? x) (jolt-coll-pred? x))))
|
(def-var! "clojure.core" "coll?" (lambda (x) (or (jrec-collection? x) (jolt-coll-pred? x))))
|
||||||
|
|
||||||
;; ---- protocol registry ------------------------------------------------------
|
;; ---- protocol registry ------------------------------------------------------
|
||||||
;; type-tag -> (proto-name -> (method-name -> fn))
|
;; type-tag -> (proto-name -> (method-name -> fn))
|
||||||
|
|
@ -483,6 +516,9 @@
|
||||||
;; even when the runtime current ns is the caller's, not the defining ns
|
;; even when the runtime current ns is the caller's, not the defining ns
|
||||||
;; (host-new checks class-ctors-tbl before the current-ns var fallback).
|
;; (host-new checks class-ctors-tbl before the current-ns var fallback).
|
||||||
(register-class-ctor! (symbol-t-name name-sym) ctor)
|
(register-class-ctor! (symbol-t-name name-sym) ctor)
|
||||||
|
;; index the tag so a cross-ns extend-protocol resolves the bare type name.
|
||||||
|
(hashtable-set! chez-deftype-tag-set tag #t)
|
||||||
|
(hashtable-set! chez-simple-name-tag (symbol-t-name name-sym) tag)
|
||||||
;; record the shape for whole-program inference, keyed by the positional
|
;; record the shape for whole-program inference, keyed by the positional
|
||||||
;; ctor var "ns/->Name" the analyzer resolves a (->Name …) call to.
|
;; ctor var "ns/->Name" the analyzer resolves a (->Name …) call to.
|
||||||
(register-record-shape! (string-append (chez-current-ns) "/->" (symbol-t-name name-sym))
|
(register-record-shape! (string-append (chez-current-ns) "/->" (symbol-t-name name-sym))
|
||||||
|
|
@ -559,7 +595,14 @@
|
||||||
(when pi (hashtable-set! pi extend-mark #t))))))
|
(when pi (hashtable-set! pi extend-mark #t))))))
|
||||||
(define (register-method type-name proto-name method-name fn)
|
(define (register-method type-name proto-name method-name fn)
|
||||||
(let* ((host (canonical-host-tag type-name))
|
(let* ((host (canonical-host-tag type-name))
|
||||||
(tag (or host (string-append (chez-current-ns) "." type-name))))
|
(local (string-append (chez-current-ns) "." type-name))
|
||||||
|
;; a host class -> its canonical tag; a deftype defined in THIS ns -> the
|
||||||
|
;; local tag; an :import-ed deftype from another ns -> its real tag via the
|
||||||
|
;; simple-name index; otherwise the local tag (a forward extend).
|
||||||
|
(tag (cond (host host)
|
||||||
|
((hashtable-ref chez-deftype-tag-set local #f) local)
|
||||||
|
((hashtable-ref chez-simple-name-tag type-name #f))
|
||||||
|
(else local))))
|
||||||
(register-protocol-method tag proto-name method-name fn)
|
(register-protocol-method tag proto-name method-name fn)
|
||||||
(mark-extend! tag proto-name)
|
(mark-extend! tag proto-name)
|
||||||
jolt-nil))
|
jolt-nil))
|
||||||
|
|
@ -830,6 +873,14 @@
|
||||||
;; yields (jolt-symbol #f (jrec-tag x)), the ns.Name class-name symbol.
|
;; yields (jolt-symbol #f (jrec-tag x)), the ns.Name class-name symbol.
|
||||||
|
|
||||||
(def-var! "clojure.core" "make-deftype-ctor" make-deftype-ctor)
|
(def-var! "clojure.core" "make-deftype-ctor" make-deftype-ctor)
|
||||||
|
|
||||||
|
;; defrecord marks its type a record (deftype does not), keyed by the same
|
||||||
|
;; "ns.Name" tag make-deftype-ctor bakes — so jrec-record? distinguishes the two.
|
||||||
|
(define (register-record-type! name-sym)
|
||||||
|
(hashtable-set! chez-record-type-tbl
|
||||||
|
(string-append (chez-current-ns) "." (symbol-t-name name-sym)) #t)
|
||||||
|
jolt-nil)
|
||||||
|
(def-var! "clojure.core" "register-record-type!" register-record-type!)
|
||||||
(def-var! "clojure.core" "make-protocol" make-protocol)
|
(def-var! "clojure.core" "make-protocol" make-protocol)
|
||||||
(def-var! "clojure.core" "register-protocol-methods!" register-protocol-methods!)
|
(def-var! "clojure.core" "register-protocol-methods!" register-protocol-methods!)
|
||||||
(def-var! "clojure.core" "register-method" register-method)
|
(def-var! "clojure.core" "register-method" register-method)
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -59,11 +59,13 @@
|
||||||
;; nil, which prints as "nil" (str yields ""). Only the top-level arg needs the
|
;; nil, which prints as "nil" (str yields ""). Only the top-level arg needs the
|
||||||
;; guard; nil nested in a collection already renders as "nil" via the collection
|
;; guard; nil nested in a collection already renders as "nil" via the collection
|
||||||
;; printer.
|
;; printer.
|
||||||
|
;; print renders non-readably (__print1): a nested string is raw, unlike str/pr
|
||||||
|
;; which quote it. (print ["x"]) => [x], (str ["x"]) => ["x"].
|
||||||
(defn print [& xs]
|
(defn print [& xs]
|
||||||
(__write (loop [out "" s (seq xs) first? true]
|
(__write (loop [out "" s (seq xs) first? true]
|
||||||
(if s
|
(if s
|
||||||
(let [x (first s)
|
(let [x (first s)
|
||||||
r (if (nil? x) "nil" (str x))]
|
r (__print1 x)]
|
||||||
(recur (str out (if first? "" " ") r) (next s) false))
|
(recur (str out (if first? "" " ") r) (next s) false))
|
||||||
out)))
|
out)))
|
||||||
nil)
|
nil)
|
||||||
|
|
|
||||||
|
|
@ -613,6 +613,8 @@
|
||||||
;; deftype already defines ->name (= the ctor); no (name. …) interop needed,
|
;; deftype already defines ->name (= the ctor); no (name. …) interop needed,
|
||||||
;; so defrecord compiles too. map->name builds via that ctor.
|
;; so defrecord compiles too. map->name builds via that ctor.
|
||||||
(deftype ~name-sym ~fields)
|
(deftype ~name-sym ~fields)
|
||||||
|
;; mark the type a record (map?/record?/field-seq); a bare deftype is not.
|
||||||
|
(register-record-type! (quote ~name-sym))
|
||||||
;; build via the positional ctor for declared fields, then carry any
|
;; build via the positional ctor for declared fields, then carry any
|
||||||
;; remaining keys as extension fields (JVM keeps them on the record).
|
;; remaining keys as extension fields (JVM keeps them on the record).
|
||||||
(def ~mapf (fn* [~m]
|
(def ~mapf (fn* [~m]
|
||||||
|
|
|
||||||
|
|
@ -89,13 +89,19 @@
|
||||||
(cond
|
(cond
|
||||||
;; (is (thrown? Class body...))
|
;; (is (thrown? Class body...))
|
||||||
(thrown-form? form "thrown?")
|
(thrown-form? form "thrown?")
|
||||||
(let [klass (name (second form))
|
(let [klass-sym (second form)
|
||||||
|
klass (name klass-sym)
|
||||||
body (nthrest form 2)]
|
body (nthrest form 2)]
|
||||||
`(try
|
`(try
|
||||||
~@body
|
~@body
|
||||||
(clojure.test/fail! (str "expected " '~form " to throw" (when ~msg (str " — " ~msg))))
|
(clojure.test/fail! (str "expected " '~form " to throw" (when ~msg (str " — " ~msg))))
|
||||||
(catch Throwable e#
|
(catch Throwable e#
|
||||||
(if (clojure.test/class-match? e# ~klass)
|
;; instance? honors the exception hierarchy (a literal class symbol), so
|
||||||
|
;; (thrown? IllegalArgumentException …) matches an ArityException subclass
|
||||||
|
;; like the JVM; class-match? is the simple-name fallback for a class jolt
|
||||||
|
;; models only by name.
|
||||||
|
(if (or (clojure.core/instance? ~klass-sym e#)
|
||||||
|
(clojure.test/class-match? e# ~klass))
|
||||||
(clojure.test/inc-pass!)
|
(clojure.test/inc-pass!)
|
||||||
(clojure.test/fail! (str "expected throw of " ~klass " but got " (clojure.core/class e#)))))))
|
(clojure.test/fail! (str "expected throw of " ~klass " but got " (clojure.core/class e#)))))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,11 @@
|
||||||
[smap form]
|
[smap form]
|
||||||
(prewalk (fn [x] (if (contains? smap x) (get smap x) x)) form))
|
(prewalk (fn [x] (if (contains? smap x) (get smap x) x)) form))
|
||||||
|
|
||||||
|
(defn macroexpand-all
|
||||||
|
"Recursively performs all possible macroexpansions in form."
|
||||||
|
[form]
|
||||||
|
(prewalk (fn [x] (if (seq? x) (macroexpand x) x)) form))
|
||||||
|
|
||||||
(defn keywordize-keys
|
(defn keywordize-keys
|
||||||
[m]
|
[m]
|
||||||
(let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
|
(let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
|
||||||
|
|
|
||||||
|
|
@ -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 "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 "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 "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)))))"}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue