#lang scheme/base
(require scheme/contract
scheme/match
"../base.ss"
"annotation.ss"
"result.ss"
(only-in "result-internal.ss" annotations/c))
(define (check-pass [message "Okay"])
(list (make-check-success message)))
(define (check-warn message)
(list (make-check-warning message)))
(define (check-fail message)
(list (make-check-failure message)))
(define check-all append)
(define (check-problems . args)
(filter check-problem? (apply check-all args)))
(define (check-errors . args)
(filter check-error? (apply check-all args)))
(define (check-warnings+failures+fatals . args)
(let loop ([results (apply check-all args)] [warnings null] [failures null] [fatals null])
(match results
[(list)
(values (reverse warnings)
(reverse failures)
(reverse fatals))]
[(list-rest (? check-result? result) other)
(cond [(check-success? result) (loop other warnings failures fatals)]
[(check-warning? result) (loop other (cons result warnings) failures fatals)]
[(check-failure? result) (loop other warnings (cons result failures) fatals)]
[(check-fatal? result) (loop other warnings failures (cons result fatals))])])))
(define (check-with-handlers thunk)
(with-handlers ([exn? (lambda (exn)
(list (make-check-fatal "Exception raised" exn)))])
(thunk)))
(define (check-with-annotations annotations+values thunk)
(map (lambda (result)
(foldl (match-lambda*
[(list (list-rest ann val) result)
(check-result-annotation-set result ann val)])
result
annotations+values))
(check-with-handlers thunk)))
(define check-until-problems
(match-lambda*
[(list) null]
[(list-rest head tail)
(define results
(head))
(define problems?
(and (ormap check-problem? results) #t))
(if problems?
results
(apply check-until-problems tail))]))
(provide/contract
[check-pass (->* () (string?) (list/c check-success?))]
[check-warn (-> string? (list/c check-warning?))]
[check-fail (-> string? (list/c check-failure?))]
[check-all (->* () () #:rest (listof (listof check-result?)) (listof check-result?))]
[check-problems (->* () () #:rest (listof (listof check-result?)) (listof check-result?))]
[check-errors (->* () () #:rest (listof (listof check-result?)) (listof check-result?))]
[check-warnings+failures+fatals (->* () () #:rest (listof (listof check-result?))
(values (listof check-warning?)
(listof check-failure?)
(listof check-fatal?)))]
[check-with-handlers (-> (-> (listof check-result?)) (listof check-result?))]
[check-with-annotations (-> (listof (cons/c annotation? any/c)) (-> (listof check-result?)) (listof check-result?))]
[check-until-problems (->* () () #:rest (listof procedure?) (listof check-problem?))])