sigildocs

(sigil test)

(sigil test) - Test Framework for Sigil

Provides a simple but powerful test framework with support for test groups, assertions, and structured results for CLI integration.

Usage: (import (sigil test))

(test-group "Arithmetic" (test "addition" (assert-equal 3 (+ 1 2))) (test "multiplication" (assert-equal 12 (* 3 4))))

(run-tests)

Exports

A test descriptor holds metadata about a registered test

Test if a value is a test-descriptor struct.

Get the name field of a test-descriptor struct.

Get the group field of a test-descriptor struct.

Get the thunk field of a test-descriptor struct.

Get the file field of a test-descriptor struct.

Get the line field of a test-descriptor struct.

Get the line field of a test-descriptor struct.

test-resultprocedure

A test result holds the outcome of running a test

test-result?procedure

Test if a value is a test-result struct.

Get the name field of a test-result struct.

Get the group field of a test-result struct.

Get the passed? field of a test-result struct.

Get the message field of a test-result struct.

Get the expected field of a test-result struct.

Get the actual field of a test-result struct.

Get the duration-ms field of a test-result struct.

Get the file field of a test-result struct.

Get the line field of a test-result struct.

Get the line field of a test-result struct.

test-summaryprocedure

Construct a test-summary struct.

test-summary?procedure

Test if a value is a test-summary struct.

Get the total field of a test-summary struct.

Get the passed field of a test-summary struct.

Get the failed field of a test-summary struct.

Get the skipped field of a test-summary struct.

Get the duration-ms field of a test-summary struct.

Get the results field of a test-summary struct.

*tests*variable

Global list of registered tests

Current test group (set by test-group)

Current source file (set before loading test file)

Runner mode flag - when #t, run-tests-exit doesn't print or exit This allows the CLI runner to handle output formatting

Set the default group for tests (used by runner for filename-based grouping)

current-groupprocedure

Get the current test group name.

push-group!procedure

Push a new group onto the group stack.

Returns the previous group for later restoration with pop-group!. Used internally by test-group.

pop-group!procedure

Pop back to a previous group.

Restores the group saved by push-group!.

get-testsprocedure

Get all registered tests as a list of test descriptors.

clear-tests!procedure

Clear all registered tests.

Resets the test registry and current group. Useful when running multiple test files in sequence.

Current assertion failure info

Signal assertion failure

Reset assertion state

assert-equalprocedure

Assert two values are equal using deep equality.

Uses equal? for comparison, which recursively compares lists, vectors, and strings by content.

(assert-equal 3 (+ 1 2))           ; passes
(assert-equal '(1 2) '(1 2))       ; passes (deep equality)
(assert-equal "hello" "hello")     ; passes
(assert-equal 5 6)                 ; fails: expected 5 but got 6
assert-eqvprocedure

Assert two values are equivalent using eqv?.

Uses eqv? which compares numbers by value and characters, but not lists or strings by content.

(assert-eqv 42 42)       ; passes
(assert-eqv #\a #\a)     ; passes
(assert-eqv 3.14 3.14)   ; passes
assert-eqprocedure

Assert two values are the same object using eq?.

Uses eq? which tests object identity. Useful for symbols and checking if two variables reference the same object.

(assert-eq 'foo 'foo)       ; passes (symbols are interned)
(let ((x '(1 2)))
  (assert-eq x x))          ; passes (same object)
(assert-eq '(1) '(1))       ; fails (different list objects)
assert-trueprocedure

Assert a value is truthy (not #f).

Any value except #f is considered truthy in Scheme.

(assert-true #t)           ; passes
(assert-true 42)           ; passes (non-#f is truthy)
(assert-true '())          ; passes (empty list is truthy)
(assert-true #f)           ; fails
assert-falseprocedure

Assert a value is #f.

(assert-false #f)                ; passes
(assert-false (member 'x '()))   ; passes (member returns #f)
(assert-false #t)                ; fails
assert-nullprocedure

Assert a value is the empty list ().

(assert-null '())              ; passes
(assert-null (cdr '(1)))       ; passes
(assert-null '(1 2))           ; fails

Assert a value is not the empty list.

(assert-not-null '(1 2 3))     ; passes
(assert-not-null "hello")      ; passes
(assert-not-null '())          ; fails
assert-failprocedure

Fail unconditionally with a message.

Use this to mark code paths that should not be reached.

(test "unreachable"
  (if (some-condition)
      (assert-equal ...)
      (assert-fail "should not reach here")))

Assert that an expression raises an error.

The test passes if the expression raises any error, and fails if it completes normally.

(assert-error (error "boom"))      ; passes
(assert-error (car '()))           ; passes (error on empty list)
(assert-error (+ 1 2))             ; fails (no error raised)

A TRAPPED EXIT IS NOT AN ERROR, AND MUST NOT SATISFY THIS ASSERTION.

The runtime's exit trap (%set-exit-trap!) turns an exit under the test runner into an ordinary VM error, so one test file can no longer terminate the whole suite. That is a large improvement and it creates one new hazard, here: before the trap existed, (assert-error <something-that-exits>) KILLED the run — loud, and impossible to miss. Afterwards the trap converts it to an error and this guard accepts it, so the assertion turns GREEN.

A green assertion that is green because the code under test tried to terminate the process is exactly the class of lie the exit trap was built to remove; introducing a fresh instance of it while removing the old ones would be a poor trade. So this is a defect, not a footnote, and it is caught rather than documented.

The message prefix below is a CONTRACT with native_exit in packages/sigil-lib/src/process.c, which is the only producer of this text. It is asserted from both ends: change one and packages/sigil-test-runner/test/test-exit-trap.sgl goes red. Spelled with core string operations rather than string-starts-with? so this library does not have to grow a (sigil string) import.

Run a single test and return its result.

Takes a test descriptor and returns a test-result struct with pass/fail status and any failure details.

run-testsprocedure

Run all registered tests and report results.

In standalone mode, prints results and exits with code 1 if any tests fail. In runner mode (set by CLI), returns a summary struct for the test runner to process.

(test "example" (assert-true #t))
(run-tests)  ; runs test and prints result

Run tests matching a predicate and return a summary.

The predicate receives each test descriptor and should return #t for tests to include.

(run-tests-filtered
  (lambda (td)
    (string-contains? (test-descriptor-name td) "math")))

Run tests and print results (legacy)

countprocedure

Count items matching predicate

value->stringprocedure

Convert value to string for display

pair->stringprocedure

Convert pair/list to string

Convert vector to string

join-stringsprocedure

Join strings with separator

list?procedure

Check if something is a proper list

testvariable

(No description)

test-groupvariable

(No description)

test-skipvariable

(No description)

test-pendingvariable

(No description)

assert-errorvariable

(No description)

(No description)

(No description)