test_that("missing values in input are missing in output", { df <- tibble(x = c(NA, "a b")) out <- separate(df, x, c("x", "y")) expect_equal(out$x, c(NA, "a")) expect_equal(out$y, c(NA, "b")) }) test_that("positive integer values specific position between characters", { df <- tibble(x = c(NA, "ab", "cd")) out <- separate(df, x, c("x", "y"), 1) expect_equal(out$x, c(NA, "a", "c")) expect_equal(out$y, c(NA, "b", "d")) }) test_that("negative integer values specific position between characters", { df <- tibble(x = c(NA, "ab", "cd")) out <- separate(df, x, c("x", "y"), -1) expect_equal(out$x, c(NA, "a", "c")) expect_equal(out$y, c(NA, "b", "d")) }) test_that("extreme integer values handled sensibly", { df <- tibble(x = c(NA, "a", "bc", "def")) out <- separate(df, x, c("x", "y"), 3) expect_equal(out$x, c(NA, "a", "bc", "def")) expect_equal(out$y, c(NA, "", "", "")) out <- separate(df, x, c("x", "y"), -3) expect_equal(out$x, c(NA, "", "", "")) expect_equal(out$y, c(NA, "a", "bc", "def")) }) test_that("convert produces integers etc", { df <- tibble(x = "1-1.5-FALSE") out <- separate(df, x, c("x", "y", "z"), "-", convert = TRUE) expect_equal(out$x, 1L) expect_equal(out$y, 1.5) expect_equal(out$z, FALSE) }) test_that("convert keeps characters as character", { df <- tibble(x = "X-1") out <- separate(df, x, c("x", "y"), "-", convert = TRUE) expect_equal(out$x, "X") expect_equal(out$y, 1L) }) test_that("too many pieces dealt with as requested", { df <- tibble(x = c("a b", "a b c")) expect_snapshot(separate(df, x, c("x", "y"))) merge <- separate(df, x, c("x", "y"), extra = "merge") expect_equal(merge[[1]], c("a", "a")) expect_equal(merge[[2]], c("b", "b c")) drop <- separate(df, x, c("x", "y"), extra = "drop") expect_equal(drop[[1]], c("a", "a")) expect_equal(drop[[2]], c("b", "b")) expect_snapshot(separate(df, x, c("x", "y"), extra = "error")) }) test_that("too few pieces dealt with as requested", { df <- tibble(x = c("a b", "a b c")) expect_snapshot(separate(df, x, c("x", "y", "z"))) left <- separate(df, x, c("x", "y", "z"), fill = "left") expect_equal(left$x, c(NA, "a")) expect_equal(left$y, c("a", "b")) expect_equal(left$z, c("b", "c")) right <- separate(df, x, c("x", "y", "z"), fill = "right") expect_equal(right$z, c(NA, "c")) }) test_that("preserves grouping", { df <- tibble(g = 1, x = "a:b") %>% dplyr::group_by(g) rs <- df %>% separate(x, c("a", "b")) expect_equal(class(df), class(rs)) expect_equal(dplyr::group_vars(df), dplyr::group_vars(rs)) }) test_that("drops grouping when needed", { df <- tibble(x = "a:b") %>% dplyr::group_by(x) rs <- df %>% separate(x, c("a", "b")) expect_equal(rs$a, "a") expect_equal(dplyr::group_vars(rs), character()) }) test_that("overwrites existing columns", { df <- tibble(x = "a:b") rs <- df %>% separate(x, c("x", "y")) expect_named(rs, c("x", "y")) expect_equal(rs$x, "a") }) test_that("drops NA columns", { df <- tibble(x = c(NA, "ab", "cd")) out <- separate(df, x, c(NA, "y"), 1) expect_equal(names(out), "y") expect_equal(out$y, c(NA, "b", "d")) }) test_that("validates inputs", { df <- tibble(x = "a:b") expect_snapshot(error = TRUE, { separate(df) separate(df, x, into = 1) separate(df, x, into = "x", sep = c("a", "b")) separate(df, x, into = "x", remove = 1) separate(df, x, into = "x", convert = 1) }) }) test_that("informative error if using stringr modifier functions (#693)", { df <- tibble(x = "a") sep <- structure("a", class = "pattern") expect_snapshot((expect_error(separate(df, x, "x", sep = sep)))) }) # helpers ----------------------------------------------------------------- test_that("str_split_n can cap number of splits", { expect_equal(str_split_n(c("x,x"), ",", 1), list("x,x")) expect_equal(str_split_n(c("x,x"), ",", 2), list(c("x", "x"))) expect_equal(str_split_n(c("x,x"), ",", 3), list(c("x", "x"))) }) test_that("str_split_n handles edge cases", { expect_equal(str_split_n(character(), ",", 1), list()) expect_equal(str_split_n(NA, ",", 1), list(NA_character_)) }) test_that("str_split_n handles factors", { expect_equal(str_split_n(factor(), ",", 1), list()) expect_equal(str_split_n(factor("x,x"), ",", 2), list(c("x", "x"))) }) test_that("list_indices truncates long warnings", { expect_equal(list_indices(letters, max = 3), "a, b, c, ...") })