r2evans · GitHub

Related to my comment #2275 (comment), I thought I'd go with exhaustive testing of all combinations of number and type of selectors. Currently it looks like this (rather verbose):

  cn <- setNames(colnames(mtcars), nm = colnames(mtcars))
  ### Single Column Selected
  # single columns (present), explicit
  expect_equal(select_vars(cn, mpg), cn["mpg"])
  expect_equal(select_vars(cn, -mpg), cn[ cn != "mpg" ])
  # single columns (present), matched
  expect_equal(select_vars(cn, contains("mpg")), cn["mpg"])
  expect_equal(select_vars(cn, -contains("mpg")), cn[ cn != "mpg" ])
  # single columns (not present), explicit
  expect_error(select_vars(cn, foo), "object 'foo' not found")
  expect_error(select_vars(cn, -foo), "object 'foo' not found")
  # single columns (not present), matched
  expect_named(res <- select_vars(cn, contains("foo")))
  expect_length(res, 0)
  expect_equal(select_vars(cn, -contains("foo")), cn)
  ### Multiple Columns Selected
  # explicit(present) + matched(present)
  expect_equal(select_vars(cn, mpg, contains("vs")), cn[c("mpg", "vs")])
  expect_equal(select_vars(cn, mpg, -contains("vs")), cn["mpg"])
  expect_equal(select_vars(cn, -mpg, contains("vs")), cn[ cn != "mpg" ])
  expect_equal(select_vars(cn, -mpg, -contains("vs")), cn[ ! cn %in% c("mpg", "vs") ])
  # explicit(present) + matched(not present)
  expect_equal(select_vars(cn, mpg, contains("foo")), cn["mpg"])
  expect_equal(select_vars(cn, mpg, -contains("foo")), cn["mpg"])
  expect_equal(select_vars(cn, -mpg, contains("foo")), cn[ cn != "mpg" ])
  expect_equal(select_vars(cn, -mpg, -contains("foo")), cn[ cn != "mpg" ])
  # matched(present) + explicit(present)
  expect_equal(select_vars(cn, contains("vs"), mpg), cn[c("vs", "mpg")])
  expect_equal(select_vars(cn, contains("vs"), -mpg), cn["vs"])
  expect_equal(select_vars(cn, -contains("vs"), mpg), cn[cn != "vs"])
  expect_equal(select_vars(cn, -contains("vs"), -mpg), cn[ ! cn %in% c("mpg", "vs") ])
  # matched(not present) + explicit(not present)
  expect_error(select_vars(cn, contains("foo"), bar), "object 'bar' not found")
  expect_error(select_vars(cn, contains("foo"), -bar), "object 'bar' not found")
  expect_error(select_vars(cn, -contains("foo"), bar), "object 'bar' not found")
  expect_error(select_vars(cn, -contains("foo"), -bar), "object 'bar' not found")
  # matched(present) + matched(present)
  expect_equal(select_vars(cn, contains("vs"), contains("mpg")), cn[c("vs", "mpg")])
  expect_equal(select_vars(cn, contains("vs"), -contains("mpg")), cn["vs"])
  expect_equal(select_vars(cn, -contains("vs"), contains("mpg")), cn[cn != "vs"])
  expect_equal(select_vars(cn, -contains("vs"), -contains("mpg")), cn[! cn %in% c("vs", "mpg")])
  # matched(present) + matched(not present)
  expect_equal(select_vars(cn, contains("vs"), contains("foo")), cn["vs"])
  expect_equal(select_vars(cn, contains("vs"), -contains("foo")), cn["vs"])
  expect_equal(select_vars(cn, -contains("vs"), contains("foo")), cn[cn != "vs"])
  expect_equal(select_vars(cn, -contains("vs"), -contains("foo")), cn[cn != "vs"])
  # matched(not present) + matched(present)
  expect_equal(select_vars(cn, contains("foo"), contains("mpg")), cn["mpg"])
  expect_named(res <- select_vars(cn, contains("foo"), -contains("mpg")))
  expect_length(res, 0)
  expect_equal(select_vars(cn, -contains("foo"), contains("mpg")), cn)
  expect_equal(select_vars(cn, -contains("foo"), -contains("mpg")), cn[cn != "mpg"])
  # matched(not present) + matched(not present)
  expect_named(res <- select_vars(cn, contains("foo"), contains("bar")))
  expect_length(res, 0)
  expect_named(res <- select_vars(cn, contains("foo"), -contains("bar")))
  expect_length(res, 0)
  expect_equal(select_vars(cn, -contains("foo"), contains("bar")), cn)
  expect_equal(select_vars(cn, -contains("foo"), -contains("bar")), cn)

This is rather busy/loud, but it definitely encapsulates all of the problems in both #1176 and #2275. Though some of them are relatively identical to some in test-select.r, I suggest keeping these here and together helps contrast the different expectations.

Is this too much? I can remove the "obvious" ones if need be, though there are varying levels of "obvious".

I also have a three-selector to ensure the first (match) isn't removed by the second (no match).

  expect_equal(
    select_vars(colnames(mtcars), contains("am"), contains("FOO"), contains("vs")),
    c(am = "am", vs = "vs")
  )

Read the original on github.com ↗