Nothing
# Tests for re-export functionality
write_module <- function(path, name, body) {
lines <- c(
sprintf("(module %s", name),
body,
")"
)
writeLines(lines, path)
}
thin <- make_cran_thinner()
test_that("explicit re-export: imported symbol available to consumers", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
# Module B exports foo
write_module(file.path(tmp_dir, "b.arl"), "b", c(
" (export foo bar)",
" (define foo 42)",
" (define bar 99)"
))
# Module A imports from B, re-exports foo along with own binding
write_module(file.path(tmp_dir, "a.arl"), "a", c(
" (export foo baz)",
' (import "b.arl" :refer :all)',
" (define baz 7)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "a.arl"))
# Module C imports from A
eng$eval_text('(import a :refer :all)')
expect_equal(eng$eval_text("foo"), 42)
expect_equal(eng$eval_text("baz"), 7)
})
test_that("export-all :re-export includes imported symbols", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "provider.arl"), "provider", c(
" (export val)",
" (define val 100)"
))
# Facade module re-exports everything
write_module(file.path(tmp_dir, "facade.arl"), "facade", c(
" (export-all :re-export)",
' (import "provider.arl" :refer :all)',
" (define own-val 200)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "facade.arl"))
entry <- engine_field(eng, "env")$module_registry$get("facade")
expect_true("val" %in% entry$exports)
expect_true("own-val" %in% entry$exports)
eng$eval_text('(import facade :refer :all)')
expect_equal(eng$eval_text("val"), 100)
expect_equal(eng$eval_text("own-val"), 200)
})
test_that("export-all without :re-export excludes imports (unchanged behavior)", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "src.arl"), "src", c(
" (export x)",
" (define x 1)"
))
write_module(file.path(tmp_dir, "consumer.arl"), "consumer", c(
" (export-all)",
' (import "src.arl" :refer :all)',
" (define own 2)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "consumer.arl"))
entry <- engine_field(eng, "env")$module_registry$get("consumer")
expect_true("own" %in% entry$exports)
expect_false("x" %in% entry$exports)
})
test_that("re-export with :only modifier", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "b.arl"), "b", c(
" (export x y)",
" (define x 10)",
" (define y 20)"
))
write_module(file.path(tmp_dir, "a.arl"), "a", c(
" (export x y own)",
' (import "b.arl" :refer :all)',
" (define own 30)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "a.arl"))
# Import only x from facade a
eng$eval_text('(import a :refer (x))')
expect_equal(eng$eval_text("x"), 10)
expect_error(eng$eval_text("y"))
})
test_that("re-export with :as modifier for qualified access", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "b.arl"), "b", c(
" (export val)",
" (define val 42)"
))
write_module(file.path(tmp_dir, "a.arl"), "a", c(
" (export val)",
' (import "b.arl" :refer :all)'
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "a.arl"))
eng$eval_text('(import a :as aa)')
expect_equal(eng$eval_text("aa/val"), 42)
})
test_that("re-export with :rename modifier", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "b.arl"), "b", c(
" (export val)",
" (define val 42)"
))
write_module(file.path(tmp_dir, "a.arl"), "a", c(
" (export val)",
' (import "b.arl" :refer :all)'
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "a.arl"))
eng$eval_text('(import a :rename ((val renamed-val)))')
expect_equal(eng$eval_text("renamed-val"), 42)
})
test_that("macro re-export: consumer can use macro from transitive module", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
# Module B defines a macro
write_module(file.path(tmp_dir, "b.arl"), "b", c(
" (export my-when)",
" (defmacro my-when (test . body)",
" `(if ,test (begin ,@body) #f))"
))
# Module A re-exports macro from B
write_module(file.path(tmp_dir, "a.arl"), "a", c(
" (export my-when)",
' (import "b.arl" :refer :all)'
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "a.arl"))
eng$eval_text('(import a :refer :all)')
expect_equal(eng$eval_text("(my-when #t 42)"), 42)
expect_equal(eng$eval_text("(my-when #f 42)"), FALSE)
})
test_that("transitive re-export: A -> B -> C -> D", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "d.arl"), "d", c(
" (export deep-val)",
" (define deep-val 999)"
))
write_module(file.path(tmp_dir, "c.arl"), "c", c(
" (export deep-val)",
' (import "d.arl" :refer :all)'
))
write_module(file.path(tmp_dir, "b.arl"), "b", c(
" (export deep-val)",
' (import "c.arl" :refer :all)'
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "b.arl"))
eng$eval_text('(import b :refer :all)')
expect_equal(eng$eval_text("deep-val"), 999)
})
test_that("reload value change reflected through re-export (live forwarding)", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "src.arl"), "src", c(
" (export val)",
" (define val 1)"
))
write_module(file.path(tmp_dir, "facade.arl"), "facade", c(
" (export val)",
' (import "src.arl" :refer :all)'
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "facade.arl"))
eng$eval_text('(import facade :refer :all)')
expect_equal(eng$eval_text("val"), 1)
# Change the source module's value and reload
write_module(file.path(tmp_dir, "src.arl"), "src", c(
" (export val)",
" (define val 999)"
))
src_path <- normalizePath(file.path(tmp_dir, "src.arl"), winslash = "/")
eng$eval_text(sprintf('(import "%s" :reload)', src_path))
# Re-export forwarding should reflect new value
expect_equal(eng$eval_text("val"), 999)
})
test_that("reload does not cascade: facade export set unchanged after source reload", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "src.arl"), "src", c(
" (export x)",
" (define x 1)"
))
write_module(file.path(tmp_dir, "facade.arl"), "facade", c(
" (export-all :re-export)",
' (import "src.arl" :refer :all)'
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "facade.arl"))
entry_before <- engine_field(eng, "env")$module_registry$get("facade")
exports_before <- sort(entry_before$exports)
# Reload source with a new export added
write_module(file.path(tmp_dir, "src.arl"), "src", c(
" (export x y)",
" (define x 1)",
" (define y 2)"
))
src_path <- normalizePath(file.path(tmp_dir, "src.arl"), winslash = "/")
eng$eval_text(sprintf('(import "%s" :reload)', src_path))
# Facade's export set should NOT have changed (no cascade)
entry_after <- engine_field(eng, "env")$module_registry$get("facade")
exports_after <- sort(entry_after$exports)
expect_equal(exports_before, exports_after)
})
test_that("error: exporting undefined/unimported name", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "bad.arl"), "bad", c(
" (export nonexistent)",
" (define something-else 1)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
expect_error(
eng$load_file_in_env(file.path(tmp_dir, "bad.arl")),
"not defined or imported"
)
})
test_that("export-all excludes _-prefixed names (private convention)", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "mod.arl"), "mod", c(
" (export-all)",
" (define public-fn 1)",
" (define _private-helper 2)",
" (define __also-private 3)",
" (define _another 4)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "mod.arl"))
entry <- engine_field(eng, "env")$module_registry$get("mod")
expect_true("public-fn" %in% entry$exports)
expect_false("_private-helper" %in% entry$exports)
expect_false("__also-private" %in% entry$exports)
expect_false("_another" %in% entry$exports)
})
test_that("export-all :re-export still excludes _-prefixed own bindings", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "provider.arl"), "provider", c(
" (export val)",
" (define val 100)"
))
write_module(file.path(tmp_dir, "facade.arl"), "facade", c(
" (export-all :re-export)",
' (import "provider.arl" :refer :all)',
" (define own-public 200)",
" (define _own-private 300)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "facade.arl"))
entry <- engine_field(eng, "env")$module_registry$get("facade")
expect_true("val" %in% entry$exports)
expect_true("own-public" %in% entry$exports)
expect_false("_own-private" %in% entry$exports)
})
test_that("explicit export of _-prefixed name still works", {
thin()
eng <- make_engine()
tmp_dir <- tempfile()
dir.create(tmp_dir)
on.exit(unlink(tmp_dir, recursive = TRUE), add = TRUE)
write_module(file.path(tmp_dir, "mod.arl"), "mod", c(
" (export _intentionally-public helper)",
" (define _intentionally-public 1)",
" (define helper 2)"
))
old_wd <- getwd()
setwd(tmp_dir)
on.exit(setwd(old_wd), add = TRUE)
eng$load_file_in_env(file.path(tmp_dir, "mod.arl"))
eng$eval_text('(import mod :refer :all)')
expect_equal(eng$eval_text("_intentionally-public"), 1)
expect_equal(eng$eval_text("helper"), 2)
})
test_that("compile error: export-all with bad modifier", {
thin()
eng <- make_engine()
expect_error(
eng$eval_text("(module bad (export-all :bad-modifier) (define x 1))"),
"only accepts :re-export"
)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.