#lang racket
(require
rackunit
rackunit/gui
racket/sandbox
racket/require
(path-up "self/require.rkt")
(cce-in main))
(provide test-private)
(define define-below-require
'(require (lib "do-check.rkt" "dracula" "lang")))
(define (eval/module code)
((make-trusted-evaluator 'racket)
`(module temp racket (#%module-begin ,define-below-require ,@code))))
(define (eval/internal code)
(eval/module `[(let () ,@code (void))]))
(define (sexps->string first . rest)
(apply format
(apply string-append "~s" (map (lambda args "\n~s") rest))
first rest))
(define-syntax (test-eval/success stx)
(syntax-case stx ()
[(te/s code)
(syntax/loc stx
(let ([c code])
(test-suite (apply sexps->string c)
(test-not-exn "module" (lambda () (eval/module c)))
(test-not-exn "internal" (lambda () (eval/internal c))))))]))
(define-syntax (test-eval/failure stx)
(syntax-case stx ()
[(te/f pred code)
(syntax/loc stx
(let ([c code]
[p pred])
(test-suite (apply sexps->string c)
(test-exn "module" p (lambda () (eval/module c)))
(test-exn "internal" p (lambda () (eval/internal c))))))]))
(define test-private
(test-suite "private"
(test-suite "define-below"
(test-eval/success
'[(begin-below
(define-below (f x) (+ 1 x))
(define-below (g x) (+ 1 (f x))))
(list (f 1))
(list (g 1))])
(test-eval/success
'[(begin-below
(define-values-below (evenp oddp)
(values (lambda (x) (if (zero? x) #t (oddp (- x 1))))
(lambda (x) (if (zero? x) #f (evenp (- x 1)))))))
(list (evenp 4))
(list (oddp 4))])
(test-eval/success
'[(lambda () (begin-below (define-below (f x) 1)) (list (f 2)))])
(test-eval/failure
exn:fail:syntax?
'[(define-below x 1)])
(test-eval/failure
exn:fail:syntax?
'[(begin-below
(define-below (j x) (+ 1 (h x)))
(define-below (h x) (+ 1 x)))])
(test-eval/failure
exn:fail:syntax?
'[(list (k 1))
(begin-below
(define-below k (lambda (x) (+ 1 x))))]))))