sema-test
0.1.0Test framework for Sema — define, run, and report test results
sema-test
Test framework for Sema — define, run, and report test results.
Install
sema pkg add sema-test
Quick start
Tests are plain named functions containing assertions. Pass them to
(test/run! ...), which prints a report and exits with code 1 if any fail —
so sema tests.sema works directly in CI.
(import "sema-test")
(define (addition)
(test/assert-equal 4 (+ 2 2))
(test/assert-equal 0 (+ -1 1)))
(define (strings)
(test/assert-contains "hello world" "lo wo")
(test/assert-true (string/starts-with? "hello" "hel")))
(test/run! addition strings)
;
; ✓ addition
; ✓ strings
;
; All 2 tests passed ✓
API
Every assertion returns #t on success and raises a descriptive error on
failure; the runner catches those errors and reports them per test.
| Function | Description |
|---|---|
(test/assert-equal expected actual) |
Assert deep equality |
(test/assert-true value) |
Assert value is truthy |
(test/assert-false value) |
Assert value is falsy |
(test/assert-throws thunk) |
Assert (thunk) raises an error |
(test/assert-near expected actual tolerance) |
Assert numbers differ by at most tolerance |
(test/assert-contains haystack needle) |
Assert a list contains an element or a string a substring |
(test/run . test-fns) |
Run tests, print a report, return {:passed :failed :total} |
(test/run! . test-fns) |
Like test/run, but exit with code 1 if any test fails |
test/assert-equal
(test/assert-equal 4 (+ 2 2)) ; => #t
(test/assert-equal (list 1 2) (list 1 2)) ; => #t
(test/assert-equal {:a 1} {:a 1}) ; => #t
(test/assert-equal 1 2) ; error: expected 1, got 2
Deep structural equality (equal?) — works on numbers, strings, lists, and
maps. expected comes first and is named in the failure message.
test/assert-true
(test/assert-true (string? "x")) ; => #t
(test/assert-true nil) ; error: expected truthy value, got falsy
Passes for any truthy value (everything except #f and nil — including 0
and "").
test/assert-false
(test/assert-false (string? 42)) ; => #t
(test/assert-false 1) ; error: expected falsy value, got 1
Passes only for #f and nil.
test/assert-throws
(test/assert-throws (fn () (error "boom"))) ; => #t
(test/assert-throws (fn () (+ 1 1))) ; error: expected an error to be
; thrown, but none was
Takes a zero-argument function (thunk) and calls it. Use it to test that your code rejects bad input.
test/assert-near
(test/assert-near 1.0 1.1 0.2) ; => #t
(test/assert-near 1.0 1.25 0.25) ; => #t (diff equal to tolerance passes)
(test/assert-near 1.0 1.5 0.25) ; error: expected 1.0 ≈ 1.5 (tolerance
; 0.25), diff was 0.5
Asserts |expected - actual| <= tolerance; the order of expected and
actual doesn't matter. Note the usual floating-point caveat: a difference
that is exactly the tolerance only passes when both are binary-exact (e.g.
0.25, not 0.05) — give yourself a little headroom otherwise.
test/assert-contains
(test/assert-contains "hello world" "lo wo") ; => #t
(test/assert-contains (list 1 2 3) 2) ; => #t
(test/assert-contains (list "a" (list 1 2)) (list 1 2)) ; => #t (deep equality)
(test/assert-contains (list 1 2 3) 4) ; error: expected (1 2 3) to contain 4
Strings check for a substring; lists check for an element using deep equality. Any other haystack type raises an error.
test/run
(define (passing) (test/assert-true #t))
(define (failing) (test/assert-equal 1 2))
(test/run passing failing)
;
; ✓ passing
; ✗ failing — expected 1, got 2
;
; 1/2 tests failed ✗
; => {:failed 1 :passed 1 :total 2}
Runs each test function, printing ✓/✗ per test with the failure message,
and returns a summary map with :passed, :failed, and :total counts. It
never exits the process — use it when you want the counts.
test/run!
(test/run! passing)
;
; ✓ passing
;
; All 1 tests passed ✓
; => {:failed 0 :passed 1 :total 1}
Same report and return value as test/run, but exits the process with code 1
if any test failed. Put it at the bottom of your tests.sema and run
sema tests.sema in CI.
Testing
The framework tests itself:
sema tests.sema
(The output includes a few nested reports — the suite runs test/run on
deliberately failing tests to check the summary counts.)
License
MIT
| Version | Size | Published |
|---|---|---|
| 0.1.0 | 4 KB | 2026-07-07 21:28:18 |