Skip to content

Commit cf07d8a

Browse files
Added ability to specify additional functions considered as assertions
1 parent 2c0d46d commit cf07d8a

File tree

7 files changed

+58
-14
lines changed

7 files changed

+58
-14
lines changed

R/coverage.R

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ logger::log_formatter(logger::formatter_sprintf, namespace = "slicingCoverage")
77
#' @param test_files Character vector of test files with code to test the functions
88
#' @param line_exclusions Currently unsupported
99
#' @param function_exclusions Currently unsupported
10+
#' @param additional_functions Character vector of regular expressions that match
11+
#' functions that should additionally be considered as assertions
1012
#'
1113
#' @export
1214
file_coverage <- function(
1315
source_files,
1416
test_files,
1517
line_exclusions = NULL,
16-
function_exclusions = NULL) {
18+
function_exclusions = NULL,
19+
additional_functions = c()) {
1720
stopifnot(missing(line_exclusions), missing(function_exclusions))
1821

1922
logger::log_trace("Tracing coverage", namespace = "slicingCoverage")
@@ -22,22 +25,24 @@ file_coverage <- function(
2225
test_files = test_files,
2326
))
2427

25-
return(give_me_covr_and_i_do_the_rest(covr_measure, source_files, test_files))
28+
return(give_me_covr_and_i_do_the_rest(covr_measure, source_files, test_files, additional_functions))
2629
}
2730

2831
#' Calculate slicing coverage for a package
2932
#'
3033
#' @param path Path to the package
34+
#' @param additional_functions Character vector of regular expressions that match
35+
#' functions that should additionally be considered as assertions
3136
#'
3237
#' @export
33-
package_coverage <- function(path = ".") {
38+
package_coverage <- function(path = ".", additional_functions = c()) {
3439
sources <- get_pkg_source_files(path)
3540
tests <- get_pkg_test_files(path)
3641

3742
logger::log_trace("Tracing coverage", namespace = "slicingCoverage")
3843
covr_measure <- measure(covr::package_coverage(path = path))
3944

40-
return(give_me_covr_and_i_do_the_rest(covr_measure, sources$files, tests$files))
45+
return(give_me_covr_and_i_do_the_rest(covr_measure, sources$files, tests$files, additional_functions))
4146
}
4247

4348
#' Calculate the maximum possible slicing coverage with the current assertions.

R/flowr_utils.R

+6-6
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ analysis_info_funs <- make_analysis_info_funs()
7777
init_analysis <- analysis_info_funs$init_analysis
7878
get_filetoken <- analysis_info_funs$get_filetoken
7979

80-
retrieve_slice <- function(file_filter = NULL) {
81-
slicing_points_measure <- measure(gather_slicing_points(file_filter))
80+
retrieve_slice <- function(file_filter = NULL, additional_functions = c()) {
81+
slicing_points_measure <- measure(gather_slicing_points(file_filter, additional_functions))
8282
query_time <- slicing_points_measure$elapsed_time
8383
slicing_points <- slicing_points_measure$result
8484
criteria <- slicing_points$criteria
@@ -127,7 +127,7 @@ retrieve_slice <- function(file_filter = NULL) {
127127
))
128128
}
129129

130-
get_check_function_ids <- function(file_filter = NULL) {
130+
get_check_function_ids <- function(file_filter = NULL, additional_functions = c()) {
131131
if (!is.null(file_filter)) {
132132
logger::log_debug("Only searching for assertions in %s", file_filter, namespace = "slicingCoverage")
133133
}
@@ -144,7 +144,7 @@ get_check_function_ids <- function(file_filter = NULL) {
144144
includeUndefinedFiles = TRUE
145145
))
146146
}),
147-
arguments = get_all_groups() |> combine_groups()
147+
arguments = get_all_groups() |> combine_groups() |> with_user_functions(additional_functions)
148148
))
149149

150150
res <- flowr::request_query(con, get_filetoken(), query) |> verify_flowr_response()
@@ -159,9 +159,9 @@ get_check_function_ids <- function(file_filter = NULL) {
159159
})
160160
}
161161

162-
gather_slicing_points <- function(file_filter = NULL) {
162+
gather_slicing_points <- function(file_filter = NULL, additional_functions = c()) {
163163
logger::log_trace("Searching for slicing points", namespace = "slicingCoverage")
164-
check_function_ids <- get_check_function_ids(file_filter)
164+
check_function_ids <- get_check_function_ids(file_filter, additional_functions)
165165
logger::log_debug("Found %d slicing points", length(check_function_ids), namespace = "slicingCoverage")
166166
criteria <- lapply(check_function_ids, function(id) sprintf("$%s", id))
167167
return(list(

R/queries.R

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ combine_groups <- function(names) {
2222
return(groups |> lapply(normalize_group) |> unlist(recursive = FALSE))
2323
}
2424

25+
with_user_functions <- function(query, regexes) {
26+
q <- lapply(regexes, function(r) list(callName = r, kind = "user", includeAliases = TRUE))
27+
return(c(query, q))
28+
}
29+
2530
get_all_groups <- function() {
2631
return(list.files(system.file("queries", package = "slicingCoverage")))
2732
}

R/utils.R

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@ get_coverered_and_sliced_srcrefs <- function(slc_coverage) { # nolint: object_le
249249
))
250250
}
251251

252-
give_me_covr_and_i_do_the_rest <- function(covr_measure, sources, tests) { # nolint: object_length_linter, line_length_linter.
252+
give_me_covr_and_i_do_the_rest <- function(covr_measure, sources, tests, additional_functions = c()) { # nolint: object_length_linter, line_length_linter.
253253
covr_time <- covr_measure$elapsed_time
254254
covr <- covr_measure$result
255255

256256
ana_time <- measure(init_analysis(c(sources, tests)), only_time = TRUE)
257257

258258
filter <- sprintf("(%s)", paste(stringr::str_escape(tests), collapse = "|"))
259-
slicing_measure <- retrieve_slice(filter)
259+
slicing_measure <- retrieve_slice(filter, additional_functions)
260260
slicing_points <- slicing_measure$slicing_points
261261
slicing_time <- slicing_measure$slicing_time
262262
query_time <- slicing_measure$query_time

man/file_coverage.Rd

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/package_coverage.Rd

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-coverage.R

+27
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,33 @@ test_that("We can find all assertions", {
301301
}
302302
})
303303

304+
test_that("We can find all user defined assertions", {
305+
file <- file_with_content("")
306+
test <- file_with_content("
307+
my_assertion <- function(a,b) {}
308+
my_assertion(1 + 2, 3)
309+
")
310+
311+
slicing_points <- file_coverage(file, test, additional_functions = c("^my_assertion$"))$slicing_points
312+
expect_length(slicing_points, 1)
313+
314+
test <- file_with_content("
315+
disguised_assertion <- function(a,b) {}
316+
my_cool_assertion <- function(a,b) {}
317+
my_uncool_assertion <- function(a,b) {}
318+
319+
disguised_assertion(1 + 2, 3)
320+
321+
my_cool_assertion(1 + 2, 3)
322+
my_uncool_assertion(1 + 2, 3)
323+
")
324+
325+
slicing_points <- file_coverage(file, test,
326+
additional_functions = c("^disguised_assertion$", "^my_(un)?cool_assertion$")
327+
)$slicing_points
328+
expect_length(slicing_points, 3)
329+
})
330+
304331
test_that("code that's called by eval or do.call is not in the slice", {
305332
file <- file_with_content("
306333
do_the_add <- function(a,b) a+b

0 commit comments

Comments
 (0)