Skip to content

Commit d04362c

Browse files
committed
filter_desc supports selecting describe(desc0, { it(desc1) {...} }by desc0&&&desc1
1 parent 30f5b11 commit d04362c

File tree

2 files changed

+64
-27
lines changed

2 files changed

+64
-27
lines changed

R/source.R

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,39 +61,56 @@ source_file <- function(path,
6161
}
6262

6363
filter_desc <- function(exprs, desc = NULL, error_call = caller_env()) {
64-
if (is.null(desc)) {
65-
return(exprs)
66-
}
67-
68-
found <- FALSE
69-
include <- rep(FALSE, length(exprs))
70-
71-
for (i in seq_along(exprs)) {
72-
expr <- exprs[[i]]
73-
74-
if (!is_call(expr, c("test_that", "describe"), n = 2)) {
75-
if (!found) {
76-
include[[i]] <- TRUE
64+
if (is.null(desc)) return(exprs)
65+
66+
desc_levels <- strsplit(desc, "&&&", fixed = TRUE)[[1]]
67+
match_count <- 0
68+
include <- logical(length(exprs))
69+
70+
find_matching_expr <- function(current_exprs, remaining_levels) {
71+
for (i in seq_along(current_exprs)) {
72+
current_expr <- current_exprs[[i]]
73+
74+
if (is_call(current_expr, c("test_that", "describe", "it"), n = 2)) {
75+
expr_desc <- as.character(current_expr[[2]])
76+
77+
if (expr_desc == remaining_levels[1]) {
78+
if (length(remaining_levels) == 1) {
79+
match_count <<- match_count + 1
80+
include[i] <<- TRUE
81+
} else if (is_call(current_expr, "describe", n = 2)) {
82+
body_of_expr <- as.list(current_expr[[3]])[-1]
83+
84+
previous_include <- include
85+
previous_match_count <- match_count
86+
87+
include <<- logical(length(body_of_expr))
88+
find_matching_expr(body_of_expr, remaining_levels[-1])
89+
90+
if (match_count > previous_match_count) {
91+
current_expr[[3]][-1] <- body_of_expr[include]
92+
current_exprs[[i]] <<- current_expr
93+
include <<- previous_include
94+
include[i] <<- TRUE
95+
} else {
96+
include <<- previous_include
97+
}
98+
}
99+
}
100+
} else if (match_count == 0 && !is_call(current_expr, c("test_that", "describe"))) {
101+
include[i] <<- TRUE
77102
}
78-
} else {
79-
if (!is_string(expr[[2]]))
80-
next
81-
82-
test_desc <- as.character(expr[[2]])
83-
if (test_desc != desc)
84-
next
85-
86-
if (found) {
87-
abort("Found multiple tests with specified description", call = error_call)
88-
}
89-
include[[i]] <- TRUE
90-
found <- TRUE
91103
}
92104
}
93105

94-
if (!found) {
106+
find_matching_expr(exprs, desc_levels)
107+
108+
if (match_count == 0) {
95109
abort("Failed to find test with specified description", call = error_call)
96110
}
111+
if (match_count > 1) {
112+
abort("Found multiple tests with specified description", call = error_call)
113+
}
97114

98115
exprs[include]
99116
}

tests/testthat/test-source.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,23 @@ test_that("errors if duplicate labels", {
8282

8383
expect_snapshot(filter_desc(code, "baz"), error = TRUE)
8484
})
85+
86+
test_that("filters nested tests with '&&&' syntax correctly", {
87+
code <- exprs(
88+
f(),
89+
describe("level 0", {
90+
it("level 1 A", {}),
91+
it("level 1 B", {})
92+
}),
93+
g()
94+
)
95+
96+
expected <- exprs(
97+
f(),
98+
describe("level 0", {
99+
it("level 1 A", {})
100+
})
101+
)
102+
103+
expect_equal(filter_desc(code, "level 0&&&level 1 A"), expected)
104+
})

0 commit comments

Comments
 (0)