skip_on_cran() test_that("stop propagates errors from quickr functions", { stop_fn <- function(x) { declare(type(x = double(1))) if (x < 0) { stop("x must be nonnegative") } x + 1 } q_stop <- quick(stop_fn) expect_error(q_stop(-1), "x must be nonnegative", fixed = TRUE) expect_equal(q_stop(1), 2) }) test_that("stop with empty message still signals an error", { stop_empty <- function(x) { declare(type(x = double(1))) if (x < 0) { stop("") } x + 1 } expect_error(quick(stop_empty)(-1), "quickr error", fixed = TRUE) }) test_that("stop with one-character message propagates", { stop_one <- function(x) { declare(type(x = double(1))) if (x < 0) { stop("x") } x + 1 } expect_error(quick(stop_one)(-1), "x", fixed = TRUE) }) test_that("stop with newline escapes in error message", { stop_newline <- function(x) { declare(type(x = double(1))) if (x < 0) { stop("a\nb") } x + 1 } err <- tryCatch(quick(stop_newline)(-1), error = identity) expect_true(inherits(err, "error")) expect_equal(conditionMessage(err), "a\\nb") }) test_that("long stop messages are truncated", { # Include spaces so Fortran line continuations can split the literal. long_msg <- paste(rep("abcdefghij", 30), collapse = " ") stop_long <- eval(bquote(function(x) { declare(type(x = double(1))) if (x < 0) { stop(.(long_msg)) } x + 1 })) err <- tryCatch(quick(stop_long)(-1), error = identity) expect_true(inherits(err, "error")) msg <- conditionMessage(err) expect_equal(nchar(msg), 255L) expect_equal(msg, substr(long_msg, 1, 255L)) }) test_that("long stop messages without spaces are rejected", { long_msg <- paste(rep("abcdefghij", 30), collapse = "") stop_long <- eval(bquote(function(x) { declare(type(x = double(1))) if (x < 0) { stop(.(long_msg)) } x + 1 })) expect_error( quick(stop_long), "Error message is too long to fit in a single Fortran line without spaces.", fixed = TRUE ) }) test_that("lapack rank deficiency errors surface in quickr", { solve_singular <- function(A, b) { declare(type(A = double(2, 2)), type(b = double(2))) solve(A, b) } qr_singular <- function(A, b) { declare(type(A = double(2, 2)), type(b = double(2))) qr.solve(A, b) } A <- matrix(c(1, 2, 2, 4), nrow = 2) b <- c(1, 2) expect_error(quick(solve_singular)(A, b), "dgesv", fixed = TRUE) expect_error(quick(qr_singular)(A, b), "rank deficient", fixed = TRUE) }) test_that("stop() translation includes error plumbing", { stop_fn <- function(x) { declare(type(x = double(1))) if (x < 0) { stop("x must be nonnegative") } x + 1 } expect_translation_snapshots( stop_fn, note = "stop() should emit error message and C bridge checks" ) }) test_that("stop() translation wraps long error messages", { long_msg <- paste(rep("abcdefghij", 15), collapse = " ") stop_fn <- eval(bquote(function(x) { declare(type(x = double(1))) if (x < 0) { stop(.(long_msg)) } x + 1 })) expect_translation_snapshots(stop_fn) })