Skip to content

Commit

Permalink
box function import count linter
Browse files Browse the repository at this point in the history
  • Loading branch information
radbasa committed Jan 11, 2024
1 parent de3f082 commit caced92
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
66 changes: 66 additions & 0 deletions R/linter_box_function_import_count_linter.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#' Box library function import count linter
#'
#' Checks that function imports do not exceed the defined `max`. Defaults to 5.
#'
#' @param max Maximum function imports allowed between `[` and `]`. Defaults to 5.
#'
#' @examples
#' # will produce lints
#' lintr::lint(
#' text = "box::use(package[one, two, three, four, five, six, ])",
#' linters = box_func_import_count_linter()
#' )
#'
#' lintr::lint(
#' text = "box::use(package[one, two, three, four, ])",
#' linters = box_func_import_count_linter(3)
#' )
#'
#' # okay
#' lintr::lint(
#' text = "box::use(package[one, two, three, four, five, ])",
#' linters = box_func_import_count_linter()
#' )
#'
#' lintr::lint(
#' text = "box::use(package[one, two, three, ])",
#' linters = box_func_import_count_linter(3)
#' )
#'
#' @export
box_func_import_count_linter <- function(max = 5L) {
xpath <- glue::glue("//SYMBOL_PACKAGE[
(text() = 'box' and
following-sibling::SYMBOL_FUNCTION_CALL[text() = 'use'])
]
/parent::expr
/parent::expr
/descendant::OP-LEFT-BRACKET[
count(
following-sibling::expr[
count(. | ..//OP-RIGHT-BRACKET/preceding-sibling::expr) =
count(../OP-RIGHT-BRACKET/preceding-sibling::expr)
]
) > {max}
]
/parent::expr")

lint_message <- glue::glue("Limit the function imports to a max of {max}.")

lintr::Linter(function(source_expression) {
if (!lintr::is_lint_level(source_expression, "file")) {
return(list())
}

xml <- source_expression$full_xml_parsed_content

bad_expr <- xml2::xml_find_all(xml, xpath)

lintr::xml_nodes_to_lints(
bad_expr,
source_expression = source_expression,
lint_message = lint_message,
type = "style"
)
})
}
67 changes: 67 additions & 0 deletions tests/testthat/test-linter_box_function_import_count_linter.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
five_function_imports <- "box::use(
dplyr[
arrange,
select,
mutate,
distinct,
filter,
],
)"

five_function_imports_inline <- "box::use(
dplyr[arrange, select, mutate, distinct, filter, ],
)"

six_function_imports <- "box::use(
dplyr[
arrange,
select,
mutate,
distinct,
filter,
slice,
],
)"

six_function_imports_inline <- "box::use(
dplyr[arrange, select, mutate, distinct, filter, slice, ],
)"

three_function_imports <- "box::use(
dplyr[
arrange,
select,
mutate,
],
)"

three_function_imports_inline <- "box::use(
dplyr[arrange, select, mutate, ],
)"

lint_message <- function(max = 5L) {
rex::rex(glue::glue("Limit the function imports to a max of {max}."))
}

test_that("box_func_import_count_linter skips allowed function count.", {
linter <- box_func_import_count_linter()

lintr::expect_lint(five_function_imports, NULL, )
lintr::expect_lint(five_function_imports_inline, NULL, linter)
})

test_that("box_func_import_count_linter skips allowed function count supplied max", {
linter <- box_func_import_count_linter(max = 3)

lintr::expect_lint(three_function_imports, NULL, )
lintr::expect_lint(three_function_imports_inline, NULL, linter)
})

test_that("box_func_import_count_linter blocks function imports more than max", {
max <- 5
linter <- box_func_import_count_linter(max = max)
lint_msg <- lint_message(max)

lintr::expect_lint(six_function_imports, list(message = lint_msg), linter)
lintr::expect_lint(six_function_imports_inline, list(message = lint_msg), linter)
})

0 comments on commit caced92

Please sign in to comment.