# =========================================================================== # as_mapper # =========================================================================== test_that("as_mapper returns function unchanged", { f <- function(x) x + 1 expect_identical(as_mapper(f), f) }) test_that("as_mapper converts formula to function", { f <- as_mapper(~ .x + 1) expect_true(is.function(f)) expect_equal(f(10), 11) }) test_that("as_mapper formula supports .x and .y", { f <- as_mapper(~ .x + .y) expect_equal(f(2, 3), 5) }) test_that("as_mapper formula supports .z", { f <- as_mapper(~ .x + .y + .z) expect_equal(f(1, 2, 3), 6) }) test_that("as_mapper formula supports ..1 ..2 ..3 placeholders", { f <- as_mapper(~ ..1 * ..2 + ..3) expect_equal(f(2, 3, 4), 10) }) test_that("as_mapper converts string/integer to extractor function", { f_int <- as_mapper(1L) expect_true(is.function(f_int)) expect_equal(f_int(list("x", "y")), "x") f_chr <- as_mapper("a") expect_true(is.function(f_chr)) expect_equal(f_chr(list(a = 10, b = 20)), 10) }) # =========================================================================== # map family # =========================================================================== test_that("map returns a list", { result <- map(1:3, ~ .x * 2) expect_equal(result, list(2, 4, 6)) }) test_that("map passes extra args", { result <- map(1:3, function(x, y) x + y, y = 10) expect_equal(result, list(11, 12, 13)) }) test_that("map_chr returns character vector", { result <- map_chr(1:3, ~ paste0("x", .x)) expect_equal(result, c("x1", "x2", "x3")) }) test_that("map_dbl returns numeric vector", { result <- map_dbl(1:3, ~ .x^2) expect_equal(result, c(1, 4, 9)) }) test_that("map_int returns integer vector", { result <- map_int(1:3, ~ as.integer(.x * 10L)) expect_equal(result, c(10L, 20L, 30L)) }) test_that("map_lgl returns logical vector", { result <- map_lgl(1:3, ~ .x > 1) expect_equal(result, c(FALSE, TRUE, TRUE)) }) test_that("map_dfr row-binds data.frames", { result <- map_dfr(1:3, ~ data.frame(a = .x, b = .x * 2)) expect_true(is.data.frame(result)) expect_equal(nrow(result), 3) expect_equal(result$a, 1:3) }) test_that("map_dfc column-binds data.frames", { result <- map_dfc(1:2, ~ { df <- data.frame(v = .x) names(df) <- paste0("col", .x) df }) expect_true(is.data.frame(result)) expect_equal(ncol(result), 2) }) # =========================================================================== # map2 family # =========================================================================== test_that("map2 returns a list", { result <- map2(1:3, 4:6, ~ .x + .y) expect_equal(result, list(5, 7, 9)) }) test_that("map2 passes extra args", { result <- map2(1:2, 3:4, function(x, y, z) x + y + z, z = 100) expect_equal(result, list(104, 106)) }) test_that("map2_chr returns character vector", { result <- map2_chr(1:2, c("a", "b"), ~ paste0(.y, .x)) expect_equal(result, c("a1", "b2")) }) test_that("map2_dbl returns numeric vector", { result <- map2_dbl(1:3, 4:6, `+`) expect_equal(result, c(5, 7, 9)) }) test_that("map2_int returns integer vector", { result <- map2_int(1:2, 3:4, ~ as.integer(.x + .y)) expect_equal(result, c(4L, 6L)) }) test_that("map2_lgl returns logical vector", { result <- map2_lgl(1:3, 3:1, ~ .x > .y) expect_equal(result, c(FALSE, FALSE, TRUE)) }) test_that("map2_dfr row-binds data.frames", { result <- map2_dfr(1:2, c("a", "b"), ~ data.frame(n = .x, l = .y)) expect_true(is.data.frame(result)) expect_equal(nrow(result), 2) }) test_that("map2_dfc column-binds data.frames", { result <- map2_dfc(1:2, c("a", "b"), ~ { df <- data.frame(v = paste0(.y, .x)) names(df) <- paste0("c", .x) df }) expect_true(is.data.frame(result)) expect_equal(ncol(result), 2) }) # =========================================================================== # pmap family # =========================================================================== test_that("pmap returns a list", { result <- pmap(list(1:3, 4:6, 7:9), ~ ..1 + ..2 + ..3) expect_equal(result, list(12, 15, 18)) }) test_that("pmap with named args matches formals", { result <- pmap(list(a = 1:2, b = 3:4), function(a, b) a * b) expect_equal(result, list(3, 8)) }) test_that("pmap_chr returns character vector", { result <- pmap_chr(list(1:2, c("a", "b")), function(n, l) paste0(l, n)) expect_equal(result, c("a1", "b2")) }) test_that("pmap_dbl returns numeric vector", { result <- pmap_dbl(list(a = 1:3, b = 4:6), function(a, b) a * b) expect_equal(result, c(4, 10, 18)) }) test_that("pmap_int returns integer vector", { result <- pmap_int(list(1:2, 3:4), function(x, y) as.integer(x + y)) expect_equal(result, c(4L, 6L)) }) test_that("pmap_lgl returns logical vector", { result <- pmap_lgl(list(1:3, 3:1), function(x, y) x > y) expect_equal(result, c(FALSE, FALSE, TRUE)) }) test_that("pmap_dfr row-binds data.frames", { result <- pmap_dfr(list(1:2, c("a", "b")), function(n, l) data.frame(n = n, l = l)) expect_true(is.data.frame(result)) expect_equal(nrow(result), 2) }) test_that("pmap_dfc column-binds data.frames", { result <- pmap_dfc(list(1:2, c("a", "b")), function(n, l) { df <- data.frame(v = paste0(l, n)) names(df) <- paste0("c", n) df }) expect_true(is.data.frame(result)) expect_equal(ncol(result), 2) }) # =========================================================================== # walk family # =========================================================================== test_that("walk returns .x invisibly", { out <- walk(1:3, identity) expect_equal(out, 1:3) }) test_that("walk calls function for side effect", { acc <- c() walk(1:3, function(x) acc <<- c(acc, x)) expect_equal(acc, 1:3) }) test_that("walk2 returns .x invisibly", { out <- walk2(1:2, 3:4, function(x, y) NULL) expect_equal(out, 1:2) }) test_that("walk2 calls function for side effect", { acc <- c() walk2(1:2, 3:4, function(x, y) acc <<- c(acc, x + y)) expect_equal(acc, c(4, 6)) }) test_that("pwalk returns .l invisibly", { l <- list(1:2, 3:4) out <- pwalk(l, function(x, y) NULL) expect_equal(out, l) }) test_that("pwalk calls function for side effect", { acc <- c() pwalk(list(1:2, 3:4), function(x, y) acc <<- c(acc, x * y)) expect_equal(acc, c(3, 8)) }) # =========================================================================== # imap family # =========================================================================== test_that("imap uses names when available", { result <- imap(c(a = 1, b = 2), ~ paste(.y, .x)) expect_equal(result, list(a = "a 1", b = "b 2")) }) test_that("imap uses integer index when unnamed", { result <- imap(c(10, 20), ~ .x + .y) expect_equal(result, list(11, 22)) }) test_that("imap_chr returns character vector", { result <- imap_chr(c(a = 1, b = 2), ~ paste(.y, "=", .x)) expect_equal(unname(result), c("a = 1", "b = 2")) }) test_that("imap_chr with unnamed input uses indices", { result <- imap_chr(c(10, 20), ~ paste0(.x, "@", .y)) expect_equal(result, c("10@1", "20@2")) }) test_that("imap_dbl returns numeric vector", { result <- imap_dbl(10:12, ~ .x + .y) expect_equal(result, c(11, 13, 15)) }) test_that("imap_dfr row-binds data.frames", { result <- imap_dfr(c(a = 1, b = 2), ~ data.frame(name = .y, val = .x)) expect_true(is.data.frame(result)) expect_equal(nrow(result), 2) expect_equal(result$name, c("a", "b")) }) # =========================================================================== # pluck # =========================================================================== test_that("pluck with no accessors returns .x", { x <- list(a = 1) expect_identical(pluck(x), x) }) test_that("pluck accesses by name", { x <- list(a = list(b = 42)) expect_equal(pluck(x, "a", "b"), 42) }) test_that("pluck accesses by position", { x <- list(10, 20, 30) expect_equal(pluck(x, 2), 20) }) test_that("pluck returns .default for missing name", { x <- list(a = 1) expect_equal(pluck(x, "z", .default = NA), NA) }) test_that("pluck returns .default for out-of-range index", { x <- list(10, 20) expect_equal(pluck(x, 5, .default = -1), -1) }) test_that("pluck returns .default for NULL intermediate", { x <- list(a = NULL) expect_equal(pluck(x, "a", "b", .default = "nope"), "nope") }) test_that("pluck supports function accessor", { x <- list(a = list(b = 9)) expect_equal(pluck(x, "a", "b", sqrt), 3) }) test_that("pluck errors on unsupported accessor type", { expect_error(pluck(list(1), TRUE), "Accessor must be") }) test_that("pluck returns .default when result is NULL", { x <- list(a = NULL) expect_equal(pluck(x, "a", .default = "fallback"), "fallback") }) test_that("pluck returns .default for index < 1", { x <- list(10, 20) expect_equal(pluck(x, 0, .default = "oob"), "oob") })