123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- ; <PLAINTEXT>
- ; Copyright (c) 2005-2006 Sebastian Egner.
- ;
- ; Permission is hereby granted, free of charge, to any person obtaining
- ; a copy of this software and associated documentation files (the
- ; ``Software''), to deal in the Software without restriction, including
- ; without limitation the rights to use, copy, modify, merge, publish,
- ; distribute, sublicense, and/or sell copies of the Software, and to
- ; permit persons to whom the Software is furnished to do so, subject to
- ; the following conditions:
- ;
- ; The above copyright notice and this permission notice shall be
- ; included in all copies or substantial portions of the Software.
- ;
- ; THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- ; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- ; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- ; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- ; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- ;
- ; -----------------------------------------------------------------------
- ;
- ; Lightweight testing (reference implementation)
- ; ==============================================
- ;
- ; Sebastian.Egner@philips.com
- ; in R5RS + SRFI 23 (error) + SRFI 42 (comprehensions)
- ;
- ; history of this file:
- ; SE, 25-Oct-2004: first version based on code used in SRFIs 42 and 67
- ; SE, 19-Jan-2006: (arg ...) made optional in check-ec
- ;
- ; Naming convention "check:<identifier>" is used only internally.
- ; -- portability --
- ; PLT: (require (lib "23.ss" "srfi") (lib "42.ss" "srfi"))
- ; Scheme48: ,open srfi-23 srfi-42
- ; -- utilities --
- (define check:write write)
- ; You can also use a pretty printer if you have one.
- ; However, the output might not improve for most cases
- ; because the pretty printers usually output a trailing
- ; newline.
- ; PLT: (require (lib "pretty.ss")) (define check:write pretty-print)
- ; Scheme48: ,open pp (define check:write p)
- ; -- mode --
- (define check:mode #f)
- (define (check-set-mode! mode)
- (set! check:mode
- (case mode
- ((off) 0)
- ((summary) 1)
- ((report-failed) 10)
- ((report) 100)
- (else (error "unrecognized mode" mode)))))
- (check-set-mode! 'report)
- ; -- state --
- (define check:correct #f)
- (define check:failed #f)
- (define (check-reset!)
- (set! check:correct 0)
- (set! check:failed '()))
- (define (check:add-correct!)
- (set! check:correct (+ check:correct 1)))
- (define (check:add-failed! expression actual-result expected-result)
- (set! check:failed
- (cons (list expression actual-result expected-result)
- check:failed)))
- (check-reset!)
- ; -- reporting --
- (define (check:report-expression expression)
- (newline)
- (check:write expression)
- (display " => "))
- (define (check:report-actual-result actual-result)
- (check:write actual-result)
- (display " ; "))
- (define (check:report-correct cases)
- (display "correct")
- (if (not (= cases 1))
- (begin (display " (")
- (display cases)
- (display " cases checked)")))
- (newline))
- (define (check:report-failed expected-result)
- (display "*** failed ***")
- (newline)
- (display " ; expected result: ")
- (check:write expected-result)
- (newline))
- (define (check-report)
- (if (>= check:mode 1)
- (begin
- (newline)
- (display "; *** checks *** : ")
- (display check:correct)
- (display " correct, ")
- (display (length check:failed))
- (display " failed.")
- (if (or (null? check:failed) (<= check:mode 1))
- (newline)
- (let* ((w (car (reverse check:failed)))
- (expression (car w))
- (actual-result (cadr w))
- (expected-result (caddr w)))
- (display " First failed example:")
- (newline)
- (check:report-expression expression)
- (check:report-actual-result actual-result)
- (check:report-failed expected-result))))))
- (define (check-passed? expected-total-count)
- (and (= (length check:failed) 0)
- (= check:correct expected-total-count)))
-
- ; -- simple checks --
- (define (check:proc expression thunk equal expected-result)
- (case check:mode
- ((0) #f)
- ((1)
- (let ((actual-result (thunk)))
- (if (equal actual-result expected-result)
- (check:add-correct!)
- (check:add-failed! expression actual-result expected-result))))
- ((10)
- (let ((actual-result (thunk)))
- (if (equal actual-result expected-result)
- (check:add-correct!)
- (begin
- (check:report-expression expression)
- (check:report-actual-result actual-result)
- (check:report-failed expected-result)
- (check:add-failed! expression actual-result expected-result)))))
- ((100)
- (check:report-expression expression)
- (let ((actual-result (thunk)))
- (check:report-actual-result actual-result)
- (if (equal actual-result expected-result)
- (begin (check:report-correct 1)
- (check:add-correct!))
- (begin (check:report-failed expected-result)
- (check:add-failed! expression
- actual-result
- expected-result)))))
- (else (error "unrecognized check:mode" check:mode)))
- (if #f #f))
- (define-syntax check
- (syntax-rules (=>)
- ((check expr => expected)
- (check expr (=> equal?) expected))
- ((check expr (=> equal) expected)
- (if (>= check:mode 1)
- (check:proc 'expr (lambda () expr) equal expected)))))
- ; -- parametric checks --
- (define (check:proc-ec w)
- (let ((correct? (car w))
- (expression (cadr w))
- (actual-result (caddr w))
- (expected-result (cadddr w))
- (cases (car (cddddr w))))
- (if correct?
- (begin (if (>= check:mode 100)
- (begin (check:report-expression expression)
- (check:report-actual-result actual-result)
- (check:report-correct cases)))
- (check:add-correct!))
- (begin (if (>= check:mode 10)
- (begin (check:report-expression expression)
- (check:report-actual-result actual-result)
- (check:report-failed expected-result)))
- (check:add-failed! expression
- actual-result
- expected-result)))))
- (define-syntax check-ec:make
- (syntax-rules (=>)
- ((check-ec:make qualifiers expr (=> equal) expected (arg ...))
- (if (>= check:mode 1)
- (check:proc-ec
- (let ((cases 0))
- (let ((w (first-ec
- #f
- qualifiers
- (:let equal-pred equal)
- (:let expected-result expected)
- (:let actual-result
- (let ((arg arg) ...) ; (*)
- expr))
- (begin (set! cases (+ cases 1)))
- (if (not (equal-pred actual-result expected-result)))
- (list (list 'let (list (list 'arg arg) ...) 'expr)
- actual-result
- expected-result
- cases))))
- (if w
- (cons #f w)
- (list #t
- '(check-ec qualifiers
- expr (=> equal)
- expected (arg ...))
- (if #f #f)
- (if #f #f)
- cases)))))))))
- ; (*) is a compile-time check that (arg ...) is a list
- ; of pairwise disjoint bound variables at this point.
- (define-syntax check-ec
- (syntax-rules (nested =>)
- ((check-ec expr => expected)
- (check-ec:make (nested) expr (=> equal?) expected ()))
- ((check-ec expr (=> equal) expected)
- (check-ec:make (nested) expr (=> equal) expected ()))
- ((check-ec expr => expected (arg ...))
- (check-ec:make (nested) expr (=> equal?) expected (arg ...)))
- ((check-ec expr (=> equal) expected (arg ...))
- (check-ec:make (nested) expr (=> equal) expected (arg ...)))
- ((check-ec qualifiers expr => expected)
- (check-ec:make qualifiers expr (=> equal?) expected ()))
- ((check-ec qualifiers expr (=> equal) expected)
- (check-ec:make qualifiers expr (=> equal) expected ()))
- ((check-ec qualifiers expr => expected (arg ...))
- (check-ec:make qualifiers expr (=> equal?) expected (arg ...)))
- ((check-ec qualifiers expr (=> equal) expected (arg ...))
- (check-ec:make qualifiers expr (=> equal) expected (arg ...)))
- ((check-ec (nested q1 ...) q etc ...)
- (check-ec (nested q1 ... q) etc ...))
- ((check-ec q1 q2 etc ...)
- (check-ec (nested q1 q2) etc ...))))
|