Safsaf is a Guile web framework, written using Claude Code running Claude Opus 4.6, based off of the Guix Data Service, Nar Herder and Guix Build Coordinator codebases.
This commit is contained in:
commit
5b0e6397dc
53 changed files with 7427 additions and 0 deletions
73
tests/CLAUDE.md
Normal file
73
tests/CLAUDE.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# Testing
|
||||
|
||||
## Framework
|
||||
|
||||
Tests use a minimal SRFI-269 implementation in `(tests support)`. Three
|
||||
primitives — `is`, `test`, `suite` — build first-class test entities and
|
||||
deliver them to a pluggable runner. Definition is separated from execution.
|
||||
|
||||
## Running tests
|
||||
|
||||
All tests (via Automake):
|
||||
|
||||
make check
|
||||
|
||||
Single file:
|
||||
|
||||
./pre-inst-env guile tests/test-router.scm
|
||||
|
||||
## Writing tests
|
||||
|
||||
```scheme
|
||||
(use-modules (tests support)
|
||||
(safsaf router)) ; module under test
|
||||
|
||||
(define-suite router-tests
|
||||
(suite "route construction"
|
||||
(test "creates route with method and pattern"
|
||||
(let ((r (route 'GET '("users") identity)))
|
||||
(is (route? r))
|
||||
(is (eq? 'GET (route-method r))))))
|
||||
|
||||
(suite "matching"
|
||||
(test "exact path match"
|
||||
...)))
|
||||
|
||||
(run-tests router-tests)
|
||||
```
|
||||
|
||||
Key points:
|
||||
|
||||
- `(is expr)` — assert expr is truthy. Returns the value on success.
|
||||
- `(is (pred arg ...))` — predicate form; on failure shows evaluated args.
|
||||
- `(test "desc" body ...)` — a single test case with one or more assertions.
|
||||
- `(suite "desc" body ...)` — group tests and nested suites.
|
||||
- `(define-suite name body ...)` — bind a suite-thunk to a variable.
|
||||
- `(run-tests thunk)` — run with the simple runner, print summary, exit.
|
||||
- Tests should be self-contained: don't depend on ordering or side effects
|
||||
from other tests.
|
||||
- Use `define` inside `test` bodies for local setup.
|
||||
|
||||
## Synthetic requests
|
||||
|
||||
Many tests need Guile `<request>` objects without a real HTTP server.
|
||||
Build them with `build-request` from `(web request)`:
|
||||
|
||||
```scheme
|
||||
(use-modules (web request) (web uri))
|
||||
|
||||
(define* (make-request method path #:optional (headers '()))
|
||||
(build-request (build-uri 'http #:host "localhost" #:path path)
|
||||
#:method method
|
||||
#:headers headers))
|
||||
```
|
||||
|
||||
Handler signature is `(request body-port) → (values response body)`. When
|
||||
calling handlers or wrapped handlers in tests, pass `#f` as the body-port:
|
||||
|
||||
```scheme
|
||||
(let ((resp body (wrapped (make-request 'GET "/" '()) #f)))
|
||||
(is (= 200 (response-code resp))))
|
||||
```
|
||||
|
||||
For handlers that read `current-route-params`, `parameterize` it directly.
|
||||
Loading…
Add table
Add a link
Reference in a new issue