test_that("spaces_left_parentheses_linter skips allowed usages", {
linter <- spaces_left_parentheses_linter()
expect_lint("blah", NULL, linter)
expect_lint("print(blah)", NULL, linter)
expect_lint("base::print(blah)", NULL, linter)
expect_lint("base::print(blah, fun(1))", NULL, linter)
expect_lint("blah <- function(blah) { }", NULL, linter)
expect_lint("(1 + 1)", NULL, linter)
expect_lint("(1 + 1)", NULL, linter)
expect_lint("( (1 + 1) )", NULL, linter)
expect_lint("if (blah) { }", NULL, linter)
expect_lint("for (i in j) { }", NULL, linter)
expect_lint("1 * (1 + 1)", NULL, linter)
expect_lint("!(1 == 1)", NULL, linter)
expect_lint("(2 - 1):(3 - 1)", NULL, linter)
expect_lint("c(1, 2, 3)[(2 - 1)]", NULL, linter)
expect_lint("list(1, 2, 3)[[(2 - 1)]]", NULL, linter)
expect_lint("range(10)[(2 - 1):(10 - 1)]", NULL, linter)
expect_lint("function(){function(){}}()()", NULL, linter)
expect_lint("c(function(){})[1]()", NULL, linter)
expect_lint("\"test <- function(x) { if(1 + 1) 'hi' }\"", NULL, linter)
expect_lint("res <- c((mat - 1L) %*% combs + 1L)", NULL, linter)
expect_lint("if (!(foo && bar || baz)) { foo }", NULL, linter)
expect_lint("x^(y + z)", NULL, linter)
expect_lint("x**(y + z)", NULL, linter)
expect_lint("a <- -(b)", NULL, linter)
expect_lint("(3^(3 + 2))", NULL, linter)
expect_lint("-(!!!symb)", NULL, linter)
expect_lint("'[[<-.data.frame'(object, y)", NULL, linter)
expect_lint("object@data@get('input')", NULL, linter)
expect_lint("x <- ~(. + y)", NULL, linter)
# the internal newline is required to trigger the lint
expect_lint("if (x > 1)\n x <- x[-(i)]", NULL, linter)
# these don't violate the linter, even if they are strange coding practice
expect_lint("for (ii in 1:10) next()", NULL, linter)
expect_lint("for (ii in 1:10) break()", NULL, linter)
})
test_that("spaces_left_parentheses_linter blocks disallowed usages", {
linter <- spaces_left_parentheses_linter()
lint_msg <- rex::rex("Place a space before left parenthesis, except in a function call.")
expect_lint("if(blah) { }", lint_msg, linter)
expect_lint("for(i in j) { }", lint_msg, linter)
expect_lint("1*(1 + 1)", lint_msg, linter)
expect_lint("test <- function(x) { if(1 + 1) 'hi' }", lint_msg, linter)
expect_lint("test <- function(x) { if(`+`(1, 1)) 'hi' }", lint_msg, linter)
# more complicated cases for parse tree
expect_lint("y1<-(abs(yn)>90)*1", lint_msg, linter)
expect_lint("c(a,(a+b))", lint_msg, linter)
expect_lint("if (x>y) 1 else(2)", lint_msg, linter)
expect_lint("y~(x+z)", lint_msg, linter)
expect_lint("if (x>y) {(x+y) / (x-y)}", lint_msg, linter)
expect_lint("for (ii in(1:10)) { }", lint_msg, linter)
expect_lint("x = 1;(x + 2)*3", lint_msg, linter)
expect_lint("foo <- function(x=(1+2)) { }", lint_msg, linter)
})
test_that("doesn't produce a warning", {
# this contains a function with nested if-statements where the conditional includes a unary minus.
# This specific constellation with another if-statement at the same nesting level on the other enclosing if-branch
# caused a warning in spaces_left_parentheses_linter (e.g. 84bc3a is broken)
complex_lines <- trim_some("
complexity <- function(x) {
if (x > 0.0) {
if (x > 10.0) {
if (x > 20.0) {
x <- x / 2.0
} else {
return(x)
}
} else {
return(x)
}
} else {
if (x < -10.0) {
if (x < -20.0) {
x <- x * 2.0
} else {
return(x)
}
} else {
return(x)
}
}
x
}
")
expect_no_warning(lint(text = complex_lines, linters = spaces_left_parentheses_linter()))
})
test_that("lints vectorize", {
lint_msg <- rex::rex("Place a space before left parenthesis, except in a function call.")
expect_lint(
trim_some("{
y1<-(abs(yn)>90)*1
for(i in j) { }
}"),
list(
list(lint_msg, line_number = 2L),
list(lint_msg, line_number = 3L)
),
spaces_left_parentheses_linter()
)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.