test.check generators: rand-double, take +Inf, UUID/Long/shiftLeft, transient
More general fixes from clojure.test.check's own suite. - *unchecked-math* on doubles: unchecked-* only wrap integer math; on a flonum operand they're an ordinary float op (Clojure: (unchecked-multiply 1.5 2.0) => 3.0). test.check's rand-double is (* double-unit shifted) under *unchecked-math* and was truncating to a long 0, so every distribution-driven generator (choose, vector, …) collapsed to its lower bound. - (take Double/POSITIVE_INFINITY coll) takes the whole coll instead of throwing on the infinite count coercion (rose-tree unchunk relies on it). - (java.util.UUID. msb lsb) 2-long constructor (the uuid generator), formatted as the canonical lowercase 8-4-4-4-12 string; (Long. n) constructor; BigInteger .shiftLeft / .shiftRight (size-bounded-bigint); number methods now receive args. - A transient (ITransientSet) responds to .contains / .valAt / .count (distinct-collection generators). make test green (+3 corpus rows, 0 new divergences), runtime only (no re-mint).
This commit is contained in:
parent
992fc0af34
commit
f32bd335e3
5 changed files with 59 additions and 15 deletions
|
|
@ -96,6 +96,15 @@
|
|||
;; (.getClass x) universal — the class token for any value, before the
|
||||
;; collection/map field-lookup arms below would read it as a missing key.
|
||||
((string=? method-name "getClass") (jolt-class obj))
|
||||
;; a transient (ITransientCollection/Set/Map): .contains / .valAt / .count —
|
||||
;; test.check's distinct-collection gen uses (.contains transient-set k).
|
||||
((jolt-transient? obj)
|
||||
(cond
|
||||
((string=? mname "contains") (if (jolt-truthy? (t-contains? obj (car rest))) #t #f))
|
||||
((or (string=? mname "valAt") (string=? mname "get"))
|
||||
(t-get obj (car rest) (if (null? (cdr rest)) jolt-nil (cadr rest))))
|
||||
((string=? mname "count") (t-count obj))
|
||||
(else (%dot-rmd obj method-name rest-args))))
|
||||
;; a deftype/record's OWN declared method (matched by name AND arity) wins
|
||||
;; over the generic collection interop below — e.g. data.priority-map
|
||||
;; declares both seq[this] (Seqable) and seq[this ascending] (Sorted), and
|
||||
|
|
|
|||
|
|
@ -103,13 +103,13 @@
|
|||
(if f
|
||||
(apply f obj (if (jolt-nil? rest-args) '() (seq->list rest-args)))
|
||||
(error #f (string-append "No method " method-name " on host " (jhost-tag obj)))))))
|
||||
((number? obj) (number-method method-name obj))
|
||||
((number? obj) (apply number-method method-name obj (if (jolt-nil? rest-args) '() (seq->list rest-args))))
|
||||
(else (%hs-record-method-dispatch obj method-name rest-args)))))
|
||||
|
||||
;; java.lang.Number method surface (the boxed-number methods cljc code calls). The
|
||||
;; integer projections wrap modulo their width (ring-codec relies on byteValue
|
||||
;; overflow: (.byteValue 255) => -1); the float projections are identity flonums.
|
||||
(define (number-method method n)
|
||||
(define (number-method method n . args)
|
||||
(cond
|
||||
((string=? method "byteValue") (let ((b (modulo (jnum->exact n) 256))) (->num (if (>= b 128) (- b 256) b))))
|
||||
((string=? method "shortValue") (let ((b (modulo (jnum->exact n) 65536))) (->num (if (>= b 32768) (- b 65536) b))))
|
||||
|
|
@ -129,6 +129,10 @@
|
|||
((string=? method "abs") (->num (abs (jnum->exact n))))
|
||||
((string=? method "bitLength") (->num (integer-length (jnum->exact n))))
|
||||
((string=? method "signum") (->num (let ((e (jnum->exact n))) (cond ((> e 0) 1) ((< e 0) -1) (else 0)))))
|
||||
;; BigInteger.shiftLeft/shiftRight (test.check's size-bounded-bigint): arbitrary
|
||||
;; precision, so an arithmetic shift by the (positive) amount.
|
||||
((string=? method "shiftLeft") (->num (bitwise-arithmetic-shift-left (jnum->exact n) (jnum->exact (car args)))))
|
||||
((string=? method "shiftRight") (->num (bitwise-arithmetic-shift-right (jnum->exact n) (jnum->exact (car args)))))
|
||||
(else (error #f (string-append "No method " method " for number")))))
|
||||
|
||||
;; Mutable static fields: "Class" -> (member -> 1-vector cell). A library that
|
||||
|
|
|
|||
|
|
@ -536,7 +536,26 @@
|
|||
(register-class-statics! "java.util.UUID"
|
||||
(list (cons "randomUUID" (lambda () (jolt-random-uuid)))
|
||||
(cons "fromString" (lambda (s) (jolt-parse-uuid (jolt-str-render-one s))))))
|
||||
(register-class-ctor! "UUID" (lambda (s) (jolt-parse-uuid (jolt-str-render-one s))))
|
||||
;; (UUID. msb lsb): build from the most/least-significant 64-bit halves (the JVM's
|
||||
;; 2-long ctor), the form test.check's uuid generator uses. (UUID. s) parses a
|
||||
;; string. The 128 bits format as the canonical 8-4-4-4-12 lowercase hex string.
|
||||
(define (uuid-long->hex16 n)
|
||||
(let* ((u (bitwise-and (jnum->exact n) #xFFFFFFFFFFFFFFFF))
|
||||
(s (string-downcase (number->string u 16)))) ; JVM UUIDs are lowercase
|
||||
(string-append (make-string (- 16 (string-length s)) #\0) s)))
|
||||
(define (uuid-from-halves msb lsb)
|
||||
(let ((h (uuid-long->hex16 msb)) (l (uuid-long->hex16 lsb)))
|
||||
(make-juuid (string-append (substring h 0 8) "-" (substring h 8 12) "-" (substring h 12 16)
|
||||
"-" (substring l 0 4) "-" (substring l 4 16)))))
|
||||
(define (uuid-ctor . args)
|
||||
(if (= (length args) 2)
|
||||
(uuid-from-halves (car args) (cadr args))
|
||||
(jolt-parse-uuid (jolt-str-render-one (car args)))))
|
||||
(register-class-ctor! "UUID" uuid-ctor)
|
||||
(register-class-ctor! "java.util.UUID" uuid-ctor)
|
||||
;; (Long. n) / (Long. "n"): a Long is just jolt's integer; return it (parse a string).
|
||||
(register-class-ctor! "Long" (lambda (x) (if (string? x) (parse-int-or-throw x 10 "Long") (->num (jnum->exact x)))))
|
||||
(register-class-ctor! "java.lang.Long" (lambda (x) (if (string? x) (parse-int-or-throw x 10 "Long") (->num (jnum->exact x)))))
|
||||
|
||||
;; --- java.net.URI -----------------------------------------------------------
|
||||
;; A minimal RFC-3986 split into scheme/authority/host/port/path/query/fragment,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue