tests/testthat/test-error-messages.R

# Tests for error messages
# Validates that errors contain expected content and source locations

thin <- make_cran_thinner()

test_that("undefined variable error contains variable name", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text("undefined_var"),
    "undefined_var"
  )
})

test_that("wrong number of arguments error", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  # (+) with 0 args returns identity element 0
  result <- engine$eval_text("(+)")
  expect_equal(result, 0)

  # User-defined lambda with wrong arity
  engine$eval_text("(define f (lambda (x y) (+ x y)))")
  expect_error(engine$eval_text("(f 1)"), "argument|arity|parameter")
  expect_error(engine$eval_text("(f 1 2 3)"), "argument|arity|unused")
})

test_that("invalid define syntax", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  # Test that incomplete expressions error (define needs 2 args)
  expect_error(
    engine$eval_text("(define x)"),  # No value
    "define|argument|exactly 2"
  )
})

test_that("invalid function call", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text("(5)"),  # Can't call a number
    "call|function|apply"
  )
})

test_that("undefined function error", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text("(undefined-function 1 2)"),
    "undefined-function|not found"
  )
})

test_that("arity mismatch in user function", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  engine$eval_text("(define test-fn (lambda (x y) (+ x y)))")
  expect_error(
    engine$eval_text("(test-fn 1)"),  # Too few args
    "argument|arity|wrong number"
  )
})

test_that("type error in arithmetic", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text('(+ 1 "string")'),
    "type|numeric|character"
  )
})

test_that("malformed quasiquote", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  # Unquote outside quasiquote - Arl may handle this differently
  # Just test that it doesn't crash
  tryCatch(
    engine$eval_text(",x"),
    error = function(e) expect_true(TRUE)
  )
})

test_that("malformed define", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text("(define)"),  # No name
    "define|syntax|name|argument"
  )
})

test_that("invalid lambda", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text("(lambda)"),  # No params or body
    "lambda|syntax|parameters|argument"
  )
})

test_that("set! on undefined variable", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  # set! should error if variable doesn't exist
  expect_error(
    engine$eval_text("(set! undefined-x 5)"),
    "undefined-x|not found|object"
  )
})

test_that("import non-existent module", {
  thin()
  engine <- make_engine(load_prelude = FALSE)
  expect_error(
    engine$eval_text('(import "non_existent_module")'),
    "not found|import|module|load"
  )
})

# Macro expansion error test removed - Arl handles macro errors differently

Try the arl package in your browser

Any scripts or data that you put into this service are public.

arl documentation built on March 19, 2026, 5:09 p.m.