1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
test_that("function_argument_linter skips allowed usages", {
linter <- function_argument_linter()
expect_lint("function(x, y = 1, z = 2) {}", NULL, linter)
expect_lint("function(x, y, z = 1) {}", NULL, linter)
# ... handled correctly
expect_lint("function(x, y, z = 1, ...) {}", NULL, linter)
expect_lint("function(x, y, ..., z = 1) {}", NULL, linter)
})
test_that("function_argument_linter blocks disallowed usages", {
linter <- function_argument_linter()
lint_msg <- rex::rex("Arguments without defaults should come before arguments with defaults.")
expect_lint("function(x, y = 1, z) {}", list(message = lint_msg, column_number = 20L), linter)
expect_lint("function(x, y = 1, z, w = 2) {}", list(message = lint_msg, column_number = 20L), linter)
expect_lint("function(x, y, z = 1, ..., w) {}", list(message = lint_msg, column_number = 28L), linter)
# Multi-line also works
expect_lint(
trim_some("
function(x,
y = 1,
z) {
}
"),
list(message = lint_msg, line_number = 3L),
linter
)
expect_lint(
trim_some("
function(x,
y # comment for distraction
= 1,
z,
w = 2) {
}
"),
list(message = lint_msg, line_number = 4L),
linter
)
expect_lint(
trim_some("
function(x,
y = 1,
z = 2) {
}
"),
NULL,
linter
)
})
test_that("function_argument_linter also lints lambda expressions", {
skip_if_not_r_version("4.1.0")
linter <- function_argument_linter()
lint_msg <- rex::rex("Arguments without defaults should come before arguments with defaults.")
expect_lint("\\(x, y = 1, z) {}", list(message = lint_msg, column_number = 13L), linter)
expect_lint("\\(x, y = 1, z, w = 2) {}", list(message = lint_msg, column_number = 13L), linter)
expect_lint("\\(x, y = 1, z = 2) {}", NULL, linter)
expect_lint("\\(x, y, z = 1) {}", NULL, linter)
})
test_that("Use of missing() is reported in the lint message", {
linter <- function_argument_linter()
simple_msg <- "Arguments without defaults should come before arguments with defaults."
expect_lint(
trim_some("
function(x, y = 1, z) {
if (missing(z)) {
z <- 2
}
}
"),
rex::rex(simple_msg, anything, "missing()"),
linter
)
expect_lint(
trim_some("
function(x, y = 1, z) {
if (y > 1) {
if (missing(z)) {
z <- 2
}
}
}
"),
rex::rex(simple_msg, anything, "missing()"),
linter
)
# inline function
expect_lint(
"function(x = 2, y) if (missing(y)) x else y",
rex::rex(simple_msg, anything, "missing()"),
linter
)
# missing() used for a different argument
expect_lint(
trim_some("
function(x, y = 1, z) {
if (missing(x)) {
z <- 2
}
}
"),
rex::rex(simple_msg, end),
linter
)
# missing() used in the signature (not quite the same, and easier to spot)
expect_lint(
trim_some("
function(x = 1, y, z = missing(y)) {
x
}
"),
rex::rex(simple_msg, end),
linter
)
})
test_that("multiple lints give correct message", {
simple_msg <- "Arguments without defaults should come before arguments with defaults."
expect_lint(
trim_some("{
function(x, y = 1, z) {
x
}
function(x, y = 1, z) {
if (missing(z)) {
z <- 2
}
}
function(x, y = 1, z, w) {
if (missing(z)) {
z <- 2
}
}
}"),
list(
list(rex::rex(simple_msg, end), line_number = 2L),
list(rex::rex(simple_msg, anything, "missing()"), line_number = 5L),
list(rex::rex(simple_msg, anything, "missing()"), line_number = 10L, column_number = 22L),
list(rex::rex(simple_msg, end), line_number = 10L, column_number = 25L)
),
function_argument_linter()
)
})
|