test_that("pipe-continuation correctly handles stand-alone expressions", { linter <- pipe_continuation_linter() lint_msg <- rex::rex("`%>%` should always have a space before it and a new line after it,") # Expressions without pipes are ignored expect_lint("blah", NULL, linter) # Pipe expressions on a single line are ignored expect_lint("foo %>% bar() %>% baz()", NULL, linter) # Pipe expressions spanning multiple lines with each expression on a line are ignored expect_lint( trim_some(" foo %>% bar() %>% baz() "), NULL, linter ) # Pipe expressions with multiple expression on a line are linted expect_lint( trim_some(" foo %>% bar() %>% baz() "), lint_msg, linter ) expect_lint( trim_some(" foo %>% bar() %>% baz() %>% qux() "), lint_msg, linter ) }) test_that("pipe-continuation linter correctly handles nesting", { linter <- pipe_continuation_linter() lint_msg <- rex::rex("`%>%` should always have a space before it and a new line after it,") expect_lint( trim_some(" my_fun <- function(){ a %>% b() %>% c() } "), list(list(message = lint_msg, line_number = 2L)), linter ) expect_lint( trim_some(" my_fun <- function(){ a %>% b() %>% c() } "), list(list(message = lint_msg, line_number = 3L)), linter ) # but no lints here expect_lint( trim_some(" 1:4 %>% { (.) %>% sum() } "), NULL, linter ) }) test_that("pipe-continuation linter handles native pipe", { skip_if_not_r_version("4.1.0") linter <- pipe_continuation_linter() lint_msg_native <- rex::rex("`|>` should always have a space before it and a new line after it,") lint_msg_magrittr <- rex::rex("`%>%` should always have a space before it and a new line after it,") expect_lint("foo |> bar() |> baz()", NULL, linter) expect_lint( trim_some(" foo |> bar() |> baz() "), NULL, linter ) expect_lint( trim_some(" foo |> bar() |> baz() "), lint_msg_native, linter ) # mixing pipes expect_lint( trim_some(" foo %>% bar() |> baz() "), lint_msg_native, linter ) expect_lint( trim_some(" foo |> bar() %>% baz() "), lint_msg_magrittr, linter ) expect_lint( trim_some(" list( foo |> bar() |> baz(), foo %>% bar() %>% baz() ) "), list( lint_msg_native, lint_msg_magrittr ), linter ) }) local({ linter <- pipe_continuation_linter() valid_code <- c( # all on one line trim_some(" my_fun <- function() { a %>% b() } "), trim_some(" my_fun <- function() { a %>% b() %>% c() } "), trim_some(" with( diamonds, x %>% head(10) %>% tail(5) ) "), trim_some(" test_that('blah', { test_data <- diamonds %>% head(10) %>% tail(5) }) "), # two different single-line pipelines trim_some(" { x <- a %>% b %>% c y <- c %>% b %>% a } "), # at most one pipe-character per line trim_some(" my_fun <- function() { a %>% b() %>% c() } ") ) patrick::with_parameters_test_that( "valid nesting is handled", { expect_lint(code_string, NULL, linter) }, .test_name = valid_code, code_string = valid_code ) }) local({ linter <- pipe_continuation_linter() pipes <- pipes() cases <- expand.grid(pipe1 = pipes, pipe2 = pipes, stringsAsFactors = FALSE) cases <- within(cases, { .test_name <- sprintf("(%s, %s)", pipe1, pipe2) }) patrick::with_parameters_test_that( "Various pipes are linted correctly", expect_lint( sprintf("a %s b() %s\n c()", pipe1, pipe2), rex::rex(sprintf("`%s` should always have a space before it", pipe2)), linter ), .cases = cases ) })