Skip to content

Commit 84dc618

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

File tree

2 files changed

+62
-28
lines changed

2 files changed

+62
-28
lines changed

R/source.R

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,41 +61,55 @@ 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
77-
}
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)
64+
if (is.null(desc)) return(exprs)
65+
66+
desc_levels <- strsplit(desc, "&&&", fixed = TRUE)[[1]]
67+
68+
find_matching_expr <- function(current_exprs, remaining_levels) {
69+
match_count <- 0
70+
include <- logical(length(current_exprs))
71+
72+
for (i in seq_along(current_exprs)) {
73+
current_expr <- current_exprs[[i]]
74+
75+
if (is_call(current_expr, c("test_that", "describe", "it"), n = 2)) {
76+
expr_desc <- as.character(current_expr[[2]])
77+
78+
if (expr_desc == remaining_levels[1]) {
79+
if (length(remaining_levels) == 1) {
80+
match_count <- match_count + 1
81+
include[i] <- TRUE
82+
} else if (is_call(current_expr, "describe", n = 2)) {
83+
body_of_expr <- as.list(current_expr[[3]])[-1]
84+
nested_result <- find_matching_expr(body_of_expr, remaining_levels[-1])
85+
86+
if (nested_result$match_count > 0) {
87+
new_body <- as.call(c(quote(`{`), nested_result$current_exprs[nested_result$include]))
88+
current_expr[[3]] <- new_body
89+
current_exprs[[i]] <- current_expr
90+
match_count <- match_count + nested_result$match_count
91+
include[i] <- TRUE
92+
}
93+
}
94+
}
95+
} else if (match_count == 0 && !is_call(current_expr, c("test_that", "describe"))) {
96+
include[i] <- TRUE
8897
}
89-
include[[i]] <- TRUE
90-
found <- TRUE
9198
}
99+
100+
list(current_exprs = current_exprs, include = include, match_count = match_count)
92101
}
93102

94-
if (!found) {
103+
result <- find_matching_expr(exprs, desc_levels)
104+
105+
if (result$match_count == 0) {
95106
abort("Failed to find test with specified description", call = error_call)
96107
}
108+
if (result$match_count > 1) {
109+
abort("Found multiple tests with specified description", call = error_call)
110+
}
97111

98-
exprs[include]
112+
result$current_exprs[result$include]
99113
}
100114

101115
#' @rdname source_file

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)