I looked through all of my R7RS tests and I don't think I have any that
matter if interaction-environment is different on each call or different
than load. I have some where I test import and define-library that do
matter, but I don't think those tests are portable anyway.
In Foment, you can define a library using eval: (eval '(define-library
(foo bar) ...)) and (foo bar) will be available for importing. That
means as you are developing a program and libraries, you can just put
them all into the same file to begin with and use load to try it out.
Does chibi do something similar?
;;;
;;; Put all the code into a single file, for example, program.scm
;;; foment -i -l program.scm
;;; will define the library, run the program, and leave you at a repl.
;;;
(define-library (hello)
(import (scheme base))
(import (scheme write))
(export hello)
(begin
(define (hello) (write '|hello, world!|))))
(import (scheme write))
(import (hello))
(hello) (newline)
On 10/24/2013 9:09 PM, Michael Montague wrote:
I used a different approach. I use a procedure very like load, but
that handles (must-equal <result> <expr>) and (must-raise <exception>
<expr>) specially. Using this approach, I could start testing before I
had syntax-rules working, and even before I had all that much of a
scheme system working.
Right now, that procedure is written in C, but I am in the process of
making it a scheme program, and making my tests compatible with (chibi
test).
The specification for (interaction-environment) says that it "returns
a specifier for a mutable environment..." Does it return the same
environment every time that it is called? Does it return the same
environment as
that used by load? must-raise can easily be transformed to (test-error
(eval '(lambda () expr) (interaction-environment))) but the following
example will not work if interaction-environment does not return the
same environment as load -- assuming the tests are run by load. And I
don't think the following example will work at all if the tests are
run as a program, assuming the must-raise to test-error transformation.
(define (l x y) x)
(must-raise (assertion-violation l) (l 3))
(must-raise (assertion-violation l) (l 3 4 5))
Here is an R7RS program which will handle testing with must-equal and
must-raise. It does not check for a specific exception being raised
because that is implementation specific.
;;
;; A program to run the tests.
;;
;; <scheme> runtests.scm <test> ...
;;
(import (scheme base))
(import (scheme cxr))
(import (scheme eval))
(import (scheme file))
(import (scheme process-context))
(import (scheme read))
(import (scheme repl))
(import (scheme write))
(define pass-count 0)
(define fail-count 0)
(define (run-tests lst)
(define (fail obj ret)
(set! fail-count (+ fail-count 1))
(display "failed: ")
(write obj)
(display ": ")
(write ret)
(newline))
(let ((env (interaction-environment)))
(define (test-must-equal obj)
(let ((ret (eval (caddr obj) env)))
(if (equal? (cadr obj) ret)
(set! pass-count (+ pass-count 1))
(fail obj ret))))
(define (test-must-raise obj)
(guard (exc
((error-object? exc) (set! pass-count (+ pass-count 1)))
(else (fail obj exc)))
(eval (caddr obj) env)
(fail obj "no exception raised")))
(define (test port)
(let ((obj (read port)))
(if (not (eof-object? obj))
(begin
(cond
((and (pair? obj) (eq? (car obj) 'must-equal))
(test-must-equal obj))
((and (pair? obj) (eq? (car obj) 'must-raise))
(test-must-raise obj))
(else (eval obj env)))
(test port)))))
(if (not (null? lst))
(begin
(display (car lst))
(newline)
(call-with-port (open-input-file (car lst)) test)
(run-tests (cdr lst))))))
(run-tests (cdr (command-line)))
(display "pass: ") (display pass-count) (display " fail: ") (display
fail-count) (newline)
On 10/24/2013 5:48 PM, Alex Shinn wrote:
On Fri, Oct 25, 2013 at 12:53 AM, Michael Montague <[email protected]
<mailto:[email protected]>> wrote:
My reader includes location information when it reads identifiers and
quote strips all that out. I want that to be part of the tests and I
want to be able to test for specific errors. I will put more thought
into it and figure out a way to make my tests work in (chibi test).
It's not really possible without implementation-specific
extensions, because the error is happening at compile
time, and there's no standard way to catch compile-time
errors.
You could write a low-level macro that evaluates it's body:
(define-syntax test-syntax
(er-macro-transformer
(lambda (expr rename compare)
(guard (else (exn '(test-assert "syntax bad" #f)))
(eval expr)
'(test-assert "syntax ok" #t)))))
and maybe preserve the source info there, but it's still
just falling back on eval.
As an implementation-specific extension you could provide
a syntax-guard form which can catch macro errors, which
would be a cleaner solution.
--
Alex
_______________________________________________
Scheme-reports mailing list
[email protected]
http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports