All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m49s
Three-layer architecture:
spec/ — Core language (19 files): evaluator, parser, primitives,
CEK machine, types, continuations. Host-independent.
web/ — Web framework (20 files): signals, adapters, engine,
orchestration, boot, router, CSSX. Built on core spec.
sx/ — Application (sx-docs website). Built on web framework.
Split boundary.sx into boundary-core.sx (type-of, make-env, identical?)
and boundary-web.sx (IO primitives, signals, spreads, page helpers).
Bootstrappers search spec/ → web/ → shared/sx/ref/ for .sx files.
Original files remain in shared/sx/ref/ as fallback during transition.
All 63 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
87 lines
3.0 KiB
Plaintext
87 lines
3.0 KiB
Plaintext
;; ==========================================================================
|
|
;; test-framework.sx — Reusable test macros and assertion helpers
|
|
;;
|
|
;; Loaded first by all test runners. Provides deftest, defsuite, and
|
|
;; assertion helpers. Requires 5 platform functions from the host:
|
|
;;
|
|
;; try-call (thunk) -> {:ok true} | {:ok false :error "msg"}
|
|
;; report-pass (name) -> platform-specific pass output
|
|
;; report-fail (name error) -> platform-specific fail output
|
|
;; push-suite (name) -> push suite name onto context stack
|
|
;; pop-suite () -> pop suite name from context stack
|
|
;;
|
|
;; Any host that provides these 5 functions can run any test spec.
|
|
;; ==========================================================================
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; 1. Test framework macros
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(defmacro deftest (name &rest body)
|
|
`(let ((result (try-call (fn () ,@body))))
|
|
(if (get result "ok")
|
|
(report-pass ,name)
|
|
(report-fail ,name (get result "error")))))
|
|
|
|
(defmacro defsuite (name &rest items)
|
|
`(do (push-suite ,name)
|
|
,@items
|
|
(pop-suite)))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; 2. Assertion helpers — defined in SX, available in test bodies
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(define assert-equal
|
|
(fn (expected actual)
|
|
(assert (equal? expected actual)
|
|
(str "Expected " (str expected) " but got " (str actual)))))
|
|
|
|
(define assert-not-equal
|
|
(fn (a b)
|
|
(assert (not (equal? a b))
|
|
(str "Expected values to differ but both are " (str a)))))
|
|
|
|
(define assert-true
|
|
(fn (val)
|
|
(assert val (str "Expected truthy but got " (str val)))))
|
|
|
|
(define assert-false
|
|
(fn (val)
|
|
(assert (not val) (str "Expected falsy but got " (str val)))))
|
|
|
|
(define assert-nil
|
|
(fn (val)
|
|
(assert (nil? val) (str "Expected nil but got " (str val)))))
|
|
|
|
(define assert-type
|
|
(fn ((expected-type :as string) val)
|
|
(let ((actual-type
|
|
(if (nil? val) "nil"
|
|
(if (boolean? val) "boolean"
|
|
(if (number? val) "number"
|
|
(if (string? val) "string"
|
|
(if (list? val) "list"
|
|
(if (dict? val) "dict"
|
|
"unknown"))))))))
|
|
(assert (= expected-type actual-type)
|
|
(str "Expected type " expected-type " but got " actual-type)))))
|
|
|
|
(define assert-length
|
|
(fn ((expected-len :as number) (col :as list))
|
|
(assert (= (len col) expected-len)
|
|
(str "Expected length " expected-len " but got " (len col)))))
|
|
|
|
(define assert-contains
|
|
(fn (item (col :as list))
|
|
(assert (some (fn (x) (equal? x item)) col)
|
|
(str "Expected collection to contain " (str item)))))
|
|
|
|
(define assert-throws
|
|
(fn ((thunk :as lambda))
|
|
(let ((result (try-call thunk)))
|
|
(assert (not (get result "ok"))
|
|
"Expected an error to be thrown but none was"))))
|