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")
)