Skip to content

Commit 560dd01

Browse files
committed
WIP
1 parent c04eb3d commit 560dd01

File tree

3 files changed

+58
-54
lines changed

3 files changed

+58
-54
lines changed

R/source.R

Lines changed: 33 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ source_file <- function(
2121
) {
2222
stopifnot(file.exists(path))
2323
stopifnot(is.environment(env))
24+
check_character(desc, allow_null = TRUE)
2425

2526
lines <- brio::read_lines(path)
2627
srcfile <- srcfilecopy(
@@ -35,7 +36,7 @@ source_file <- function(
3536
con <- textConnection(lines, encoding = "UTF-8")
3637
on.exit(try(close(con), silent = TRUE), add = TRUE)
3738
exprs <- parse(con, n = -1, srcfile = srcfile, encoding = "UTF-8")
38-
exprs <- filter_desc(exprs, desc, error_call = error_call)
39+
exprs <- filter_subtests(exprs, desc, error_call = error_call)
3940

4041
n <- length(exprs)
4142
if (n == 0L) {
@@ -69,63 +70,45 @@ source_file <- function(
6970
}
7071
}
7172

72-
filter_desc <- function(exprs, desc = NULL, error_call = caller_env()) {
73-
if (is.null(desc)) {
73+
filter_subtests <- function(exprs, descs, error_call = caller_env()) {
74+
if (length(descs) == 0) {
7475
return(exprs)
7576
}
76-
desc_levels <- if (is.list(desc)) {
77-
desc
78-
} else {
79-
as.list(desc)
80-
}
8177

82-
find_matching_expr <- function(exprs, queue) {
83-
if (length(queue) == 0) {
84-
exprs
85-
} else {
86-
found <- FALSE
87-
include <- rep(FALSE, length(exprs))
88-
desc <- queue[[1]]
89-
90-
for (i in seq_along(exprs)) {
91-
expr <- exprs[[i]]
92-
93-
if (!is_call(expr, c("test_that", "describe", "it"), n = 2)) {
94-
if (!found) {
95-
include[[i]] <- TRUE
96-
}
97-
} else {
98-
if (!is_string(expr[[2]])) {
99-
next
100-
}
101-
102-
test_desc <- as.character(expr[[2]])
103-
if (test_desc != desc) {
104-
next
105-
}
106-
107-
if (found) {
108-
abort(
109-
"Found multiple tests with specified description",
110-
call = error_call
111-
)
112-
}
113-
include[[i]] <- TRUE
114-
found <- TRUE
115-
exprs[[i]][[3]] <- find_matching_expr(expr[[3]], queue[-1])
116-
}
117-
}
78+
is_subtest <- unname(map_lgl(exprs, is_subtest))
11879

119-
if (!found) {
120-
abort("Failed to find test with specified description", call = error_call)
121-
}
80+
subtest_idx <- which(is_subtest)
81+
code_idx <- which(!is_subtest)
82+
matching_idx <- keep(subtest_idx, \(idx) {
83+
exprs[[idx]][[2]] == descs[[1]]
84+
})
12285

123-
exprs[include]
124-
}
86+
if (length(matching_idx) == 0) {
87+
cli::cli_abort(
88+
"Failed to find test with specified description",
89+
call = error_call
90+
)
91+
} else if (length(matching_idx) > 1) {
92+
cli::cli_abort(
93+
"Found multiple tests with specified description",
94+
call = error_call
95+
)
12596
}
126-
find_matching_expr(exprs, desc_levels)
97+
98+
keep_idx <- intersect(seq_along(exprs), c(matching_idx, code_idx))
99+
exprs[[matching_idx]] <- filter_subtests(
100+
exprs[[matching_idx]],
101+
descs[-1],
102+
error_call = error_call
103+
)
104+
exprs[keep_idx]
127105
}
128106

107+
is_subtest <- function(expr) {
108+
is_call(expr, c("test_that", "describe", "it"), n = 2) && is_string(expr[[2]])
109+
}
110+
111+
129112
#' @rdname source_file
130113
#' @export
131114
source_dir <- function(
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# source_file wraps error
2+
3+
Code
4+
source_file(test_path("reporters/error-setup.R"), wrap = FALSE)
5+
Condition
6+
Error:
7+
! In path: "reporters/error-setup.R"
8+
Caused by error in `h()`:
9+
! !
10+
11+
# errors if duplicate labels
12+
13+
Code
14+
filter_desc(code, "baz")
15+
Condition
16+
Error in `filter_desc()`:
17+
! could not find function "filter_desc"
18+

tests/testthat/test-source.R

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ test_that("can find only matching test", {
8585
describe("bar", {}),
8686
h()
8787
)
88-
expect_equal(filter_desc(code, "foo"), code[c(1, 2)])
89-
expect_equal(filter_desc(code, "bar"), code[c(1, 3, 4)])
90-
expect_snapshot(filter_desc(code, "baz"), error = TRUE)
88+
expect_equal(filter_subtests(code, "foo"), code[c(1, 2)])
89+
expect_equal(filter_subtests(code, "bar"), code[c(1, 3, 4)])
90+
expect_snapshot(filter_subtests(code, "baz"), error = TRUE)
9191
})
9292

9393
test_that("preserve srcrefs", {
@@ -205,5 +205,8 @@ test_that("you can select deeply nested describe(...)", {
205205
})
206206
)
207207

208-
expect_equal(filter_desc(code, c("level 0", "level 1 A", "level 2 B", "level 3 C")), expected)
208+
expect_equal(
209+
filter_subtests(code, c("level 0", "level 1 A", "level 2 B", "level 3 C")),
210+
expected
211+
)
209212
})

0 commit comments

Comments
 (0)