diff --git a/htdp-doc/scribblings/htdp-langs/prim-ops.rkt b/htdp-doc/scribblings/htdp-langs/prim-ops.rkt index f8b7b9a7..49843876 100644 --- a/htdp-doc/scribblings/htdp-langs/prim-ops.rkt +++ b/htdp-doc/scribblings/htdp-langs/prim-ops.rkt @@ -564,7 +564,9 @@ In contrast, when @racket[delta] is small, the test fails: random computation produces inexact numbers, which @racket[check-random] refuses to compare. - If @racket[delta] is not a number, @check-random-within-elem reports an error.} + If @racket[delta] is not a number, @check-random-within-elem reports an error. + + @history[#:added "1.9"]} @defform*[#:id [check-error check-error-id] [(check-error expression expected-error-message) diff --git a/htdp-doc/test-engine/test-engine.scrbl b/htdp-doc/test-engine/test-engine.scrbl index d6dcffa7..bb7c370b 100644 --- a/htdp-doc/test-engine/test-engine.scrbl +++ b/htdp-doc/test-engine/test-engine.scrbl @@ -101,6 +101,26 @@ corresponding number in the second expression. It is an error for @racket[expr] or @racket[expected] to produce a function value.} +@defform[(check-random-within expr expected-expr delta-expr) + #:contracts ([delta-expr number?])]{ +Combines @racket[check-random] and @racket[check-within]. The +@racket[expr] and @racket[expected-expr] expressions are evaluated with +the same random-number sequence. Their values must be structurally equal, +with every number in the first value within @racket[delta-expr] of the +corresponding number in the second value. Inexact numbers are allowed. + +@examples[#:eval (mk-eval (require test-engine/racket-tests)) +(check-random-within (exact->inexact (random 100)) + (+ 0.01 (random 100)) + 0.1) +(test) +] + +It is an error for @racket[expr] or @racket[expected-expr] to produce a +function value. + +@history[#:added "1.9"]} + @defform*[ [(check-error expr) (check-error expr msg-expr)] #:contracts ([msg-expr string?]) ]{ diff --git a/htdp-lib/info.rkt b/htdp-lib/info.rkt index ce94567f..edd687db 100644 --- a/htdp-lib/info.rkt +++ b/htdp-lib/info.rkt @@ -38,7 +38,7 @@ (define pkg-authors '(matthias mflatt robby "sperber@deinprogramm.de")) -(define version "1.8") +(define version "1.9") (define license '(Apache-2.0 OR MIT)) diff --git a/htdp-lib/test-engine/racket-tests.rkt b/htdp-lib/test-engine/racket-tests.rkt index 5f82f2a2..588fb913 100644 --- a/htdp-lib/test-engine/racket-tests.rkt +++ b/htdp-lib/test-engine/racket-tests.rkt @@ -43,6 +43,10 @@ "check-within: expects an inexact number for the range. ~s is not inexact.") (define CHECK-WITHIN-FUNCTION-FMT "check-within cannot compare functions, but the second argument is ~a.") +(define CHECK-RANDOM-WITHIN-NUMBER-FMT + "check-random-within: expects a number for the range. ~s is not a number.") +(define CHECK-RANDOM-WITHIN-FUNCTION-FMT + "check-random-within cannot compare functions, but the second argument is ~a.") (define LIST-FMT "check-member-of: expects a list for the second argument (the possible outcomes). Given ~s") (define CHECK-MEMBER-OF-FUNCTION-FMT @@ -249,13 +253,13 @@ ;; with the same freshly-seeded pseudo-random generator; like check-within, ;; the two results are compared up to the `within` tolerance. (define (do-check-random-within test expected-thunk within src) - (error-check number? within CHECK-WITHIN-INEXACT-FMT #t) + (error-check number? within CHECK-RANDOM-WITHIN-NUMBER-FMT #t) (let ((rng (make-pseudo-random-generator)) (k (modulo (current-milliseconds) (sub1 (expt 2 31))))) (let ((expected (parameterize ([current-pseudo-random-generator rng]) (random-seed k) (expected-thunk)))) - (error-check (lambda (v) (not (procedure? v))) expected CHECK-WITHIN-FUNCTION-FMT #t) + (error-check (lambda (v) (not (procedure? v))) expected CHECK-RANDOM-WITHIN-FUNCTION-FMT #t) (execute-test src (lambda () @@ -266,7 +270,7 @@ #t (not-within src actual expected within)))) (lambda (exn) - (unexpected-error/check-* src expected exn (exn->markup exn) 'check-random)))))) + (unexpected-error/check-* src expected exn (exn->markup exn) 'check-random-within)))))) (define-syntax (check-error stx) (check-context! 'check-error CHECK-ERROR-DEFN-STR stx) diff --git a/htdp-test/tests/test-engine/racket-tests.rkt b/htdp-test/tests/test-engine/racket-tests.rkt index ea79c66c..1375c3ee 100644 --- a/htdp-test/tests/test-engine/racket-tests.rkt +++ b/htdp-test/tests/test-engine/racket-tests.rkt @@ -400,10 +400,25 @@ (lambda (e) (initialize-test-object!) (and (exn:fail:contract? e) - (regexp-match? #rx"\"0[.]1\" is not inexact" (exn-message e)))) + (regexp-match? #rx"^check-random-within:.*\"0[.]1\" is not a number" (exn-message e)))) (lambda () (run-tests!))) +;; A function in the expected position names the correct check form. +(check-random-within 1.0 (lambda (x) x) 0.1) +(check-exn + (lambda (e) + (initialize-test-object!) + (and (exn:fail:contract? e) + (regexp-match? #rx"^check-random-within cannot compare functions" + (exn-message e)))) + (lambda () (run-tests!))) + +;; An exception in the tested expression also names the correct check form. +(check-random-within (error 'random-test "failed") 1.0 0.1) +(check-failure unexpected-error/check-*? + unexpected-error/check-*-form-name 'check-random-within) + (check-property (for-all ((a Integer) (b Integer))