;; Tests for define-library, import, and the import suspension mechanism ;; ============================================================ ;; Basic define-library + import ;; ============================================================ (define-library (test basic-lib) (export double greet) (begin (define double (fn (x) (* x 2))) (define greet "hello"))) (import (test basic-lib)) (deftest "import binds exported functions" (assert= (double 5) 10)) (deftest "import binds exported values" (assert= greet "hello")) (deftest "library-loaded? returns true after define-library" (assert= (library-loaded? (quote (test basic-lib))) true)) (deftest "library-loaded? returns false for unknown library" (assert= (library-loaded? (quote (test nonexistent))) false)) ;; ============================================================ ;; define-library with (import ...) clause ;; ============================================================ (define-library (test dep-a) (export triple) (begin (define triple (fn (x) (* x 3))))) (define-library (test dep-b) (export six-times) (import (test dep-a)) (begin (define six-times (fn (x) (triple (* x 2)))))) (import (test dep-b)) (deftest "define-library import clause makes dep symbols available" (assert= (six-times 3) 18)) ;; ============================================================ ;; Nested transitive imports (A → B → C) ;; ============================================================ (define-library (test chain-c) (export c-val) (begin (define c-val 100))) (define-library (test chain-b) (export b-fn) (import (test chain-c)) (begin (define b-fn (fn () (+ c-val 50))))) (define-library (test chain-a) (export a-fn) (import (test chain-b)) (begin (define a-fn (fn () (+ (b-fn) 25))))) (import (test chain-a)) (deftest "three-level transitive import chain works" (assert= (a-fn) 175)) ;; ============================================================ ;; Import does not leak private symbols ;; ============================================================ (define-library (test private) (export public-fn) (begin (define secret 42) (define public-fn (fn () secret)))) (import (test private)) (deftest "exported function is available" (assert= (public-fn) 42)) (deftest "non-exported symbol is not imported" (assert= (cek-try (fn () secret) (fn (e) "not-found")) "not-found")) ;; ============================================================ ;; Re-import of already-loaded library ;; ============================================================ (define-library (test reimport) (export val99) (begin (define val99 99))) (import (test reimport)) (import (test reimport)) (deftest "re-import of loaded library still binds exports" (assert= val99 99)) ;; ============================================================ ;; Import with perform/suspension path ;; (Tests that cek_run handles import suspensions correctly) ;; ============================================================ (define-library (test suspend-target) (export suspended-val) (begin (define suspended-val "resolved"))) ;; This import goes through step_sf_import → library_loaded_p check. ;; If the library was just registered above, it's already loaded. ;; The test verifies the import → bind path works end-to-end. (import (test suspend-target)) (deftest "import resolves without IO suspension error" (assert= suspended-val "resolved")) ;; ============================================================ ;; define-library body can reference imports ;; ============================================================ (define-library (test math-base) (export square) (begin (define square (fn (x) (* x x))))) (define-library (test math-ext) (export sum-of-squares) (import (test math-base)) (begin (define sum-of-squares (fn (a b) (+ (square a) (square b)))))) (import (test math-ext)) (deftest "library body uses imported function" (assert= (sum-of-squares 3 4) 25)) ;; ============================================================ ;; Multiple imports in one define-library ;; ============================================================ (define-library (test multi-a) (export a-val) (begin (define a-val 1))) (define-library (test multi-b) (export b-val) (begin (define b-val 2))) (define-library (test multi-consumer) (export total) (import (test multi-a)) (import (test multi-b)) (begin (define total (fn () (+ a-val b-val))))) (import (test multi-consumer)) (deftest "multiple import clauses in one define-library" (assert= (total) 3)) ;; ============================================================ ;; Import inside define-library doesn't pollute outer env ;; ============================================================ (define-library (test scoped-import-dep) (export inner-secret) (begin (define inner-secret "inside"))) (define-library (test scoped-import-user) (export get-secret) (import (test scoped-import-dep)) (begin (define get-secret (fn () inner-secret)))) (import (test scoped-import-user)) (deftest "imported function from library works" (assert= (get-secret) "inside")) (deftest "library's imported dep not in outer scope" (assert= (cek-try (fn () inner-secret) (fn (e) "not-found")) "not-found"))