test_that("array() supports reshaping non-scalar data", { fn <- function(x) { declare(type(x = integer(2L, 3L, 4L))) array(as.double(x), dim = c(2L, 3L, 4L)) } set.seed(1) x <- array(sample(1:10, 24, replace = TRUE), dim = c(2L, 3L, 4L)) expect_quick_identical(fn, list(x)) }) test_that("array() reshape accepts numeric dim vectors", { fn <- function(x) { declare(type(x = integer(2L, 3L, 4L))) array(as.double(x), dim = c(2, 3, 4)) } set.seed(1) x <- array(sample(1:10, 24, replace = TRUE), dim = c(2L, 3L, 4L)) expect_quick_identical(fn, list(x)) }) test_that("array() reshape accepts scalar dims", { fn <- function(x) { declare(type(x = integer(24L))) # Rank-1 arrays carry a `dim` attribute in base R, but quickr treats them as # plain vectors; wrap in `c()` so both sides compare identically while still # exercising the `array(dim=scalar)` lowering. c(array(as.double(x), dim = 24)) } set.seed(1) x <- sample(1:10, 24, replace = TRUE) expect_quick_identical(fn, list(x)) }) test_that("array() reshape works when data is scalar-emitted (e.g. integer(n))", { fn <- function() { # `integer(3)` currently lowers to scalar `0` with a non-scalar value shape. # The array() reshape path must produce valid Fortran anyway. array(integer(3L), dim = c(1L, 3L)) } expect_quick_identical(fn, list()) }) test_that("array() reshape accepts literal dim vectors in the AST", { dim_const <- c(2L, 3L, 4L) fn <- eval(bquote(function(x) { declare(type(x = integer(2L, 3L, 4L))) array(as.double(x), dim = .(dim_const)) })) set.seed(1) x <- array(sample(1:10, 24, replace = TRUE), dim = c(2L, 3L, 4L)) expect_quick_identical(fn, list(x)) }) test_that("array() reshape accepts dim as a literal sequence (2:4)", { fn <- function(x) { declare(type(x = integer(2L, 3L, 4L))) array(as.double(x), dim = 2:4) } set.seed(1) x <- array(sample(1:10, 24, replace = TRUE), dim = c(2L, 3L, 4L)) expect_quick_identical(fn, list(x)) }) test_that("array() reshape accepts dim passed as a variable bound to a literal sequence", { fn <- function(x) { declare(type(x = integer(2L, 3L, 4L))) d <- 2:4 array(as.double(x), dim = d) } set.seed(1) x <- array(sample(1:10, 24, replace = TRUE), dim = c(2L, 3L, 4L)) expect_quick_identical(fn, list(x)) }) test_that("array() reshape fails early when recycling would be required", { fn <- function() { array(c(1L, 2L, 3L), dim = c(2L, 2L)) } # Fortran `reshape()` errors when the source is too short; quickr should stop # before generating uncompilable code. expect_error(quick(fn), "does not support recycling") }) test_that("array() fill reshape handles dim expressions that lower to comma-containing Fortran", { fn <- function(y, x) { declare(type(y = double(NA, NA)), type(x = double(nrow(y), ncol(y)))) # `dim(x)` uses the dims declared above, which dims2f() lowers to # `size(y, 1), size(y, 2)` (commas inside expressions). Codegen must not # split on commas in Fortran output. array(integer(nrow(y) * ncol(y)), dim = dim(x)) } set.seed(1) y <- matrix(runif(6), 2, 3) x <- y expect_quick_identical(fn, list(y, x)) }) test_that("array() reshape supports dim = 1 for non-scalar data", { fn <- function(x) { declare(type(x = integer(2L, 3L, 4L))) # Rank-1 length-1 arrays are scalar-like in quickr; index the first element # to compare against base R without relying on `dim` attributes. array(as.double(x), dim = 1L)[1] } set.seed(1) x <- array(sample(1:10, 24, replace = TRUE), dim = c(2L, 3L, 4L)) expect_quick_identical(fn, list(x)) }) test_that("array() forwards hoist when data needs hoisted temporaries", { fn <- function(x, y) { declare(type(x = double(2L, 2L)), type(y = double(2L, 2L))) array((x + y)[, 1], dim = c(2L, 1L)) } set.seed(1) x <- matrix(runif(4), 2, 2) y <- matrix(runif(4), 2, 2) expect_quick_identical(fn, list(x, y)) }) test_that("array() rejects empty dim vectors (dim=c())", { fn <- function(x) { declare(type(x = double(2L, 2L))) array(as.double(x), dim = c()) } # Base R errors here ("'dims' cannot be of length 0"); quickr should fail # early too, rather than emitting rank-mismatched Fortran. expect_error(quick(fn), "dim") })