#lang racket/base (require rackunit racket/port racket/system unstable/debug racket/match (for-syntax racket/base syntax/parse)) ;; {{ Shelly ;; This macro is intended to make Eli proud. ;; Wow, RackUnit really sucks that test-begin/case don't work inside ;; each other like this already (define (wrapping-test-case-around thunk) (with-handlers ([exn:test:check? (λ (e) (raise (struct-copy exn:test:check e [stack (list* (make-check-name (current-test-name)) (exn:test:check-stack e))])))]) (thunk))) (define-syntax-rule (check-begin e ...) (parameterize ([current-test-case-around wrapping-test-case-around]) (test-begin e ...))) (define-syntax-rule (check-case m e ...) (parameterize ([current-test-case-around wrapping-test-case-around]) (test-case m e ...))) (define-syntax-rule (check-similar? act exp name) (let () (define exp-v exp) (define act-v act) (if (regexp? exp-v) (check-regexp-match exp-v act-v name) (check-equal? act-v exp-v name)))) (define (exn:input-port-closed? x) (and (exn:fail? x) (regexp-match #rx"input port is closed" (exn-message x)))) (begin-for-syntax (define-splicing-syntax-class shelly-case #:attributes (code) (pattern (~seq (~datum $) command-line:expr (~optional (~seq (~datum =exit>) exit-cond:expr) #:defaults ([exit-cond #'0])) (~optional (~seq (~datum =stdout>) output-str:expr) #:defaults ([output-str #'#f])) (~optional (~seq (~datum =stderr>) error-str:expr) #:defaults ([error-str #'#f])) (~optional (~seq (~datum