racket/collects/tests/drscheme/module-lang-test-utils.ss
2008-10-25 20:35:09 +00:00

132 lines
5.8 KiB
Scheme

#lang scheme/gui
(require "drscheme-test-util.ss" mzlib/etc framework scheme/string)
(provide test t rx run-test in-here write-test-modules)
;; utilities to use with scribble/reader
(define t string-append)
(define (rx . strs)
(regexp (regexp-replace* #rx" *\n *" (string-append* strs) ".*")))
(define-struct test (definitions ; string
interactions ; (union #f string)
result ; string
all? ; boolean (#t => compare all of the text between the 3rd and n-1-st line)
error-ranges ; (or/c 'dont-test
; (-> (is-a?/c text)
; (is-a?/c text)
; (or/c #f (listof ...))))
; fn => called with defs & ints, result must match get-error-ranges method's result
line) ; number or #f: the line number of the test case
#:omit-define-syntaxes)
(define in-here
(let ([here (this-expression-source-directory)])
(lambda (file) (format "~s" (path->string (build-path here file))))))
(define tests '())
(define-syntax (test stx)
(syntax-case stx ()
[(_ args ...)
(with-syntax ([line (syntax-line stx)])
#'(test/proc line args ...))]))
(define (test/proc line definitions interactions results [all? #f] #:error-ranges [error-ranges 'dont-test])
(set! tests (cons (make-test (if (string? definitions)
definitions
(format "~s" definitions))
interactions
results
all?
error-ranges
line)
tests)))
(define temp-files '())
(define (write-test-modules* name code)
(let ([file (build-path (this-expression-source-directory) (format "~a.ss" name))])
(set! temp-files (cons file temp-files))
(with-output-to-file file #:exists 'truncate
(lambda () (printf "~s\n" code)))))
(define-syntax write-test-modules
(syntax-rules (module)
[(_ (module name lang x ...) ...)
(begin (write-test-modules* 'name '(module name lang x ...)) ...)]))
(define drs (wait-for-drscheme-frame))
(define interactions-text (send drs get-interactions-text))
(define definitions-text (send drs get-definitions-text))
(define (single-test test)
(let/ec k
(clear-definitions drs)
(insert-in-definitions drs (test-definitions test))
(do-execute drs)
(let ([ints (test-interactions test)])
(when ints
(let ([after-execute-output
(send interactions-text
get-text
(send interactions-text paragraph-start-position 2)
(send interactions-text paragraph-end-position 2))])
(unless (or (test-all? test) (string=? "> " after-execute-output))
(printf "FAILED (line ~a): ~a\n ~a\n expected no output after execution, got: ~s\n"
(test-line test)
(test-definitions test)
(or (test-interactions test) 'no-interactions)
after-execute-output)
(k (void)))
(type-in-interactions drs ints)
(test:keystroke #\return)
(wait-for-computation drs)))
(let* ([text
(if (test-all? test)
(let* ([para (- (send interactions-text position-paragraph
(send interactions-text last-position))
1)])
(send interactions-text
get-text
(send interactions-text paragraph-start-position 2)
(send interactions-text paragraph-end-position para)))
(let* ([para (- (send interactions-text position-paragraph
(send interactions-text last-position))
1)])
(send interactions-text
get-text
(send interactions-text paragraph-start-position para)
(send interactions-text paragraph-end-position para))))]
[output-passed? (let ([r (test-result test)])
((cond [(string? r) string=?]
[(regexp? r) regexp-match?]
[else 'module-lang-test "bad test value: ~e" r])
r text))])
(unless output-passed?
(printf "FAILED (line ~a): ~a\n ~a\n expected: ~s\n got: ~s\n"
(test-line test)
(test-definitions test)
(or (test-interactions test) 'no-interactions)
(test-result test)
text))
(cond
[(eq? (test-error-ranges test) 'dont-test)
(void)]
[else
(let ([error-ranges-expected
((test-error-ranges test) definitions-text interactions-text)])
(unless (equal? error-ranges-expected (send interactions-text get-error-ranges))
(printf "FAILED (line ~a; ranges): ~a\n expected: ~s\n got: ~s\n"
(test-line test)
(test-definitions test)
error-ranges-expected
(send interactions-text get-error-ranges))))])))))
(define (run-test)
(set-language-level! '("Module") #t)
(for-each single-test (reverse tests))
(clear-definitions drs)
(send (send drs get-definitions-text) set-modified #f)
(for ([file temp-files]) (when (file-exists? file) (delete-file file))))