# --- rename --- test_that("rename changes column names", { df <- data.frame(a = 1:3, b = 4:6) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> rename(alpha = a, beta = b) |> collect() expect_equal(names(result), c("alpha", "beta")) expect_equal(result$alpha, c(1, 2, 3)) expect_equal(result$beta, c(4, 5, 6)) }) test_that("rename errors on missing column", { df <- data.frame(a = 1:3) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) expect_error(tbl(f) |> rename(x = nonexistent)) }) # --- relocate --- test_that("relocate moves columns to front by default", { df <- data.frame(a = 1, b = 2, c = 3) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> relocate(c) |> collect() expect_equal(names(result), c("c", "a", "b")) }) test_that("relocate with .before", { df <- data.frame(a = 1, b = 2, c = 3, d = 4) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> relocate(d, .before = b) |> collect() expect_equal(names(result), c("a", "d", "b", "c")) }) test_that("relocate with .after", { df <- data.frame(a = 1, b = 2, c = 3, d = 4) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> relocate(a, .after = c) |> collect() expect_equal(names(result), c("b", "c", "a", "d")) }) test_that("relocate with .after last column", { df <- data.frame(a = 1, b = 2, c = 3) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> relocate(a, .after = c) |> collect() expect_equal(names(result), c("b", "c", "a")) }) # --- transmute --- test_that("transmute keeps only computed columns", { df <- data.frame(x = c(1.0, 2.0, 3.0), y = c(10.0, 20.0, 30.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> transmute(total = x + y) |> collect() expect_equal(names(result), "total") expect_equal(result$total, c(11, 22, 33)) }) # --- distinct --- test_that("distinct removes duplicate rows", { df <- data.frame(a = c("x", "x", "y", "y"), b = c(1.0, 1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> distinct() |> collect() expect_equal(nrow(result), 3) }) test_that("distinct on specific columns", { df <- data.frame(g = c("a", "a", "b"), x = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> distinct(g) |> collect() expect_equal(nrow(result), 2) expect_equal(sort(result$g), c("a", "b")) }) # --- ungroup --- test_that("ungroup removes grouping", { df <- data.frame(g = c("a", "b"), x = 1:2) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(g) expect_equal(node$.groups, "g") node2 <- ungroup(node) expect_null(node2$.groups) }) # --- group preservation --- test_that("filter preserves groups", { df <- data.frame(g = c("a", "a", "b"), x = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(g) |> filter(x > 1) expect_equal(node$.groups, "g") }) test_that("select preserves groups", { df <- data.frame(g = c("a", "b"), x = 1:2, y = 3:4) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(g) |> select(g, x) expect_equal(node$.groups, "g") }) test_that("select drops groups for removed group columns", { df <- data.frame(g = c("a", "b"), x = 1:2, y = 3:4, stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) # Selecting without the group column drops the group node <- tbl(f) |> group_by(g) |> select(x, y) expect_null(node$.groups) }) test_that("select with multi-group drops only removed groups", { df <- data.frame(a = c("x", "x", "y"), b = c("p", "q", "p"), v = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(a, b) |> select(a, v) expect_equal(node$.groups, "a") }) test_that("rename preserves and updates groups", { df <- data.frame(g = c("a", "b"), x = 1:2) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(g) |> rename(group = g) expect_equal(node$.groups, "group") }) test_that("relocate preserves groups", { df <- data.frame(g = c("a", "b"), x = 1:2, y = 3:4) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(g) |> relocate(y, .before = g) expect_equal(node$.groups, "g") }) test_that("arrange preserves groups", { df <- data.frame(g = c("b", "a"), x = c(2.0, 1.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) node <- tbl(f) |> group_by(g) |> arrange(x) expect_equal(node$.groups, "g") }) # --- count --- test_that("count counts by group", { df <- data.frame(g = c("a", "a", "b"), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> count(g) |> collect() expect_equal(result$n[result$g == "a"], 2) expect_equal(result$n[result$g == "b"], 1) }) test_that("count with custom name", { df <- data.frame(g = c("a", "a", "b"), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> count(g, name = "cnt") |> collect() expect_true("cnt" %in% names(result)) }) # --- tally --- test_that("tally counts rows in grouped data", { df <- data.frame(g = c("a", "a", "b"), x = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> group_by(g) |> tally() |> collect() expect_equal(result$n[result$g == "a"], 2) expect_equal(result$n[result$g == "b"], 1) }) # --- pull --- test_that("pull extracts a column as vector", { df <- data.frame(x = c(1.0, 2.0, 3.0), y = c(4.0, 5.0, 6.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> pull(x) expect_equal(result, c(1, 2, 3)) }) test_that("pull with negative index gets last column", { df <- data.frame(x = c(1.0, 2.0), y = c(3.0, 4.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> pull(-1) expect_equal(result, c(3, 4)) }) # --- head --- test_that("head returns first n rows", { df <- data.frame(x = 1:10 + 0.0) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- head(tbl(f), 3) expect_equal(nrow(result), 3) expect_equal(result$x, c(1, 2, 3)) }) # --- arrange --- test_that("arrange sorts ascending by default", { df <- data.frame(x = c(3.0, 1.0, 2.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> arrange(x) |> collect() expect_equal(result$x, c(1, 2, 3)) }) test_that("arrange desc() sorts descending", { df <- data.frame(x = c(3.0, 1.0, 2.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> arrange(desc(x)) |> collect() expect_equal(result$x, c(3, 2, 1)) }) test_that("arrange by multiple columns", { df <- data.frame(g = c("a", "b", "a", "b"), x = c(2.0, 1.0, 1.0, 2.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> arrange(g, x) |> collect() expect_equal(result$g, c("a", "a", "b", "b")) expect_equal(result$x, c(1, 2, 1, 2)) }) test_that("arrange puts NA last in ascending order", { df <- data.frame(x = c(2.0, NA, 1.0, 3.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> arrange(x) |> collect() expect_equal(result$x[1:3], c(1, 2, 3)) expect_true(is.na(result$x[4])) }) test_that("arrange with strings", { df <- data.frame(s = c("banana", "apple", "cherry"), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> arrange(s) |> collect() expect_equal(result$s, c("apple", "banana", "cherry")) }) # --- slice_head / slice_tail --- test_that("slice_head returns first n rows", { df <- data.frame(x = c(10.0, 20.0, 30.0, 40.0, 50.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> slice_head(n = 3) |> collect() expect_equal(result$x, c(10, 20, 30)) }) test_that("slice_tail returns last n rows", { df <- data.frame(x = c(10.0, 20.0, 30.0, 40.0, 50.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> slice_tail(n = 2) expect_equal(result$x, c(40, 50)) }) # --- slice_min / slice_max --- test_that("slice_min returns rows with smallest values", { df <- data.frame(x = c(5.0, 1.0, 3.0, 2.0, 4.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> slice_min(order_by = x, n = 2) |> collect() expect_equal(result$x, c(1, 2)) }) test_that("slice_max returns rows with largest values", { df <- data.frame(x = c(5.0, 1.0, 3.0, 2.0, 4.0)) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> slice_max(order_by = x, n = 2) |> collect() expect_equal(result$x, c(5, 4)) }) # --- .groups argument in summarise --- test_that("summarise with .groups = 'drop' drops all groups", { df <- data.frame(g1 = c("a", "a", "b"), g2 = c("x", "y", "x"), v = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> group_by(g1, g2) |> summarise(s = sum(v), .groups = "drop") expect_null(result$.groups) }) test_that("summarise with .groups = 'keep' preserves groups", { df <- data.frame(g1 = c("a", "a", "b"), g2 = c("x", "y", "x"), v = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> group_by(g1, g2) |> summarise(s = sum(v), .groups = "keep") expect_equal(result$.groups, c("g1", "g2")) }) test_that("summarise default .groups = 'drop_last' drops last group", { df <- data.frame(g1 = c("a", "a", "b"), g2 = c("x", "y", "x"), v = c(1.0, 2.0, 3.0), stringsAsFactors = FALSE) f <- tempfile(fileext = ".vtr") on.exit(unlink(f)) write_vtr(df, f) result <- tbl(f) |> group_by(g1, g2) |> summarise(s = sum(v)) expect_equal(result$.groups, "g1") })