On this page:
expect
expect/  print
expect/  pretty
expect-file
expect-exn
expect-unreachable
capture-output
capture-output/  split
expectation
commit-expectation!
reset-expectation!
skip-expectation!
with-expectation
run-expect
run-expect-exn
update-file-entire

6 Reference🔗ℹ

syntax

(expect expr expected-str ...
        [#:strict? strict?-expr #f]
        [#:port port-expr (quotestdout)]
        [#:match match-expr (quoteequal)])
Evaluates expr and checks that the captured output is equal to the concatenation of expected-strs.

#:strict? controls whitespace comparison. When false, comparison ignores surrounding whitespace and common indentation. When true, comparison uses exact string equality. #:port accepts (quote stdout), (quote stderr), or (quote both). #:match accepts (quote equal), (quote contains), or (quote regexp).

If the expectation differs and RECSPECS_UPDATE is set, the expectation string in the source file is replaced with the new value. Otherwise the test case fails. Update mode is skipped for (quote contains) and (quote regexp) because recspecs cannot infer the intended substring or regular expression from the actual output.

(expect (display "hello world") "hello" #:match (quotecontains))
(expect (display "value: 42") "value: [0-9]+" #:match (quoteregexp))
(require recspecs)
(expect (displayln "hello") "hello\n")

It can be convenient to use at-exp for multi-line expectations:

#:lang at-exp racket
(require recspecs)
 
(expect (begin (displayln "hello") (displayln (+ 1 2)))
"hello""\n"
"3")

syntax

(expect/print expr expected-str ...
              [#:strict? strict?-expr #f]
              [#:port port-expr (quotestdout)]
              [#:match match-expr (quoteequal)])
Like expect, but the result of expr is printed with print before comparison. This is shorthand for (expect (print expr) expected-str ...). It accepts the same #:strict?, #:port, and #:match keywords as expect, with defaults shown in the form above.

syntax

(expect/pretty expr expected-str ...
               [#:strict? strict?-expr #f]
               [#:port port-expr (quotestdout)]
               [#:match match-expr (quoteequal)])
Like expect/print, but uses pretty-print to output the result. The newline produced by pretty-print is included in the expectation. It accepts the same #:strict?, #:port, and #:match keywords as expect, with defaults shown in the form above.

syntax

(expect-file expr path-str
              [#:strict? strict?-expr #f]
              [#:port port-expr (quotestdout)])
Reads the expectation from path-str instead of embedding it in the source. The file is replaced with new output when RECSPECS_UPDATE is set. #:port accepts (quote stdout), (quote stderr), or (quote both).
(expect-file
  (begin
    (displayln "hello")
    (displayln "world"))
  "expected.txt")

syntax

(expect-exn expr expected-str ...
             [#:strict? strict?-expr #f]
             [#:port port-expr (quotestdout)])
Checks that expr raises an exception whose message matches the concatenation of expected-strs. The message is updated when update mode is enabled. #:port is accepted for consistency with the other expectation forms; expect-exn compares the exception message rather than captured output.
(expect-exn (raise-user-error "bad")
            "bad")

syntax

(expect-unreachable expr)

Fails the enclosing test if expr evaluates. When update mode is enabled, the form is replaced with expr in the source instead of failing.
(when #f
  (expect-unreachable (displayln "never")))

procedure

(capture-output thunk [#:port port])  string?

  thunk : (-> any/c)
  port : (symbols 'stdout 'stderr 'both) = 'stdout
Runs thunk and returns everything printed to the selected port(s). When port is 'stderr, the current error port is captured instead of the output port. Pass 'both to capture from both ports. When recspecs-verbose? is true, the output is also echoed to the original port(s).

(capture-output (lambda () (display "hi")))

(capture-output (lambda () (display "err" (current-error-port)))
#:port 'stderr)
(capture-output (lambda ()
 (display "warn" (current-error-port))
 (display "out"))
#:port 'both)

procedure

(capture-output/split thunk)  
string? string?
  thunk : (-> any/c)
Runs thunk and returns two values: the stdout output and the stderr output as separate strings. When recspecs-verbose? is true, both streams are echoed to their original ports.

(define-values (out err)
  (capture-output/split
    (lambda ()
      (display "normal output")
      (display "error output" (current-error-port)))))
out
err

struct

(struct expectation (out committed? skip?)
    #:extra-constructor-name make-expectation)
  out : string?
  committed? : boolean?
  skip? : boolean?
Represents recorded output that can be committed or skipped. The structure is mutable so repeated with-expectation blocks can append to out.

procedure

(commit-expectation! e)  void?

  e : expectation?
Mark e as committed.

procedure

(reset-expectation! e)  void?

  e : expectation?
Reset the output and flags of e.

procedure

(skip-expectation! e)  void?

  e : expectation?
Mark e as skipped.

syntax

(with-expectation e [#:port port-expr (quotestdout)]expr ...)

Evaluates the exprs and appends anything printed to e’s out field. #:port accepts (quote stdout), (quote stderr), or (quote both).

The recorded output is available with expectation-out:

(define log (make-expectation))
(with-expectation log
  (display "hi"))
(commit-expectation! log)
(displayln (expectation-out log))

procedure

(run-expect thunk    
  expected    
  path    
  pos    
  span    
  [#:strict strict?    
  #:port port    
  #:status status    
  #:match match-mode])  void?
  thunk : (-> any/c)
  expected : string?
  path : (or/c path-string? #f)
  pos : exact-nonnegative-integer?
  span : exact-nonnegative-integer?
  strict? : boolean? = #f
  port : (symbols 'stdout 'stderr 'both) = 'stdout
  status : (or/c #f exact-integer?) = #f
  match-mode : (symbols 'equal 'contains 'regexp) = 'equal
Runs thunk and checks that the captured output matches expected. The path, pos and span identify the source location used when updating.

When status is not #f, the return value of thunk is also checked against status using check-equal?.

The match-mode controls how the comparison is performed:
  • 'equal (default) — exact string equality (modulo whitespace normalization when not strict)

  • 'contains — passes when the actual output contains expected as a substring

  • 'regexp — passes when expected matches the actual output as a regular expression

Update mode is skipped for non-'equal match modes since substring and regexp patterns cannot be auto-derived from output.

procedure

(run-expect-exn thunk    
  expected    
  path    
  pos    
  span    
  [#:strict strict?    
  #:port port])  void?
  thunk : (-> any/c)
  expected : string?
  path : (or/c path-string? #f)
  pos : exact-nonnegative-integer?
  span : exact-nonnegative-integer?
  strict? : boolean? = #f
  port : (symbols 'stdout 'stderr 'both) = 'stdout
Like run-expect but expects thunk to raise an exception whose message matches expected. The #:port keyword is accepted for consistency with expectation forms, but the comparison is against the exception message.

procedure

(update-file-entire path pos span new-str)  void?

  path : path-string?
  pos : exact-nonnegative-integer?
  span : exact-nonnegative-integer?
  new-str : string?
Replace the entire file at path with new-str.