"import non-existent module fails gracefully"
"same file imported with different path strings uses one module (absolute path alias)"
"load can access previously defined symbols"
"circular import dependency produces clear error"

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_return_module.arl

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_runtime_error.arl

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_multiple_load.arl

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_access_symbols.arl

load can access previously defined symbols

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_module_a.arl

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_empty.arl

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_comments_only.arl

<arl_error/error/condition>
Error: File not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm/test_macro_module.arl

<arl_error/error/condition>
Error: Module not found: D:	emp\2026_02_23_11_20_16_15377\Rtmp4WUrHm\filee1823812341/testmod.arl

# Tests for selective imports with :refer, :as, :rename modifiers
# Helper: create a temp module file with known exports
make_temp_module <- function(name = "testmod", exports = c("square", "cube", "helper-val"),
sprintf("  (export %s)", paste(exports, collapse = " ")),
"  (define square (lambda (x) (* x x)))",
"  (define cube (lambda (x) (* x x x)))",
module_file <- file.path(tmp_dir, paste0(name, ".arl"))
list(dir = tmp_dir, file = module_file, name = name)
test_that("import with no modifiers imports all exports", {
on.exit(unlink(m$dir, recursive = TRUE), add = TRUE)
test_that("import :refer imports only specified symbols", {
expect_error(engine$eval_text("(cube 3)"), "not found|could not find|object .* not found")
expect_error(engine$eval_text("helper-val"), "not found|could not find|object .* not found")
test_that("import :refer errors on names not in module exports", {
test_that("import :refer :all imports all exports", {
test_that("import :as aliases the module binding", {
m <- make_temp_module(exports = c("square", "cube"))
# Unqualified names not imported (no :refer)
expect_error(engine$eval_text("(square 5)"), "not found|could not find|object .* not found")
test_that("import :as with :refer combines correctly", {
engine$eval_text("(import testmod :as m :refer (square))")
test_that("import :rename renames specified symbols", {
engine$eval_text("(import testmod :rename ((square sq)))")
test_that("import :rename errors on names not in module exports", {
engine$eval_text("(import testmod :rename ((nonexistent foo)))"),
test_that("import :refer + :rename composes correctly", {
engine$eval_text("(import testmod :refer (square cube) :rename ((square sq)))")
test_that("import :refer works with macros", {
m <- make_temp_module(name = "macmod", exports = c("my-when", "my-unless"), body = c(
"  (defmacro my-when (test . body) `(if ,test (begin ,@body) #nil))",
"  (defmacro my-unless (test . body) `(if ,test #nil (begin ,@body))))"
# my-unless was not referred — not visible as a macro
expect_error(engine$eval_text("(my-unless #f 42)"), "not found|could not find")
m <- make_temp_module(name = "macmod2", exports = c("mw"), body = c(
"  (defmacro mw (test . body) `(if ,test (begin ,@body) #nil)))"
test_that("import :rename works with macros", {
m <- make_temp_module(name = "macmod3", exports = c("mw3"), body = c(
"  (defmacro mw3 (test . body) `(if ,test (begin ,@body) #nil)))"
engine$eval_text("(import macmod3 :rename ((mw3 my-when3)))")
expect_error(engine$eval_text("(mw3 #t 42)"), "not found|could not find")
test_that("import with empty :refer imports nothing unqualified", {
test_that("import with path string supports modifiers", {
engine$eval_text(sprintf('(import "%s" :refer (square))', m$file))
test_that("proxy-based imports are accessible via scoping but not in ls(env)", {
# Proxy-based imports live in parent chain, not in the env itself
# (but the module binding "testmod" IS in env)
expect_false("square" %in% ls(env, all.names = FALSE))
# But they're accessible via get with inherits
expect_equal(get("square", envir = env)(5L), 25L)
test_that("reference semantics: module bindings are locked", {
test_that("import with unknown modifier errors", {
test_that("import :as rejects non-symbol alias", {
# a/b is parsed as (module-ref a b), not a symbol
# Qualified access via / syntax and module-ref
test_that("parser: math/inc produces (module-ref math inc)", {
test_that("parser: a/b/c produces nested module-ref", {
test_that("parser: bare / stays as division symbol", {
test_that("parser: round-trip math/inc -> write -> math/inc", {
test_that("parser: round-trip a/b/c -> write -> a/b/c", {
test_that("parser: R infix operators %/% are not split", {
test_that("qualified access: import :refer then mod/sym resolves", {
test_that("qualified access: import :as then alias/sym resolves", {