test_that("other : expressions are fine", { linter <- seq_linter() expect_lint("1:10", NULL, linter) expect_lint("2:length(x)", NULL, linter) expect_lint("1:(length(x) || 1)", NULL, linter) }) test_that("seq_len(...) or seq_along(...) expressions are fine", { linter <- seq_linter() expect_lint("seq_len(x)", NULL, linter) expect_lint("seq_along(x)", NULL, linter) expect_lint("seq(2, length(x))", NULL, linter) expect_lint("seq(length(x), 2)", NULL, linter) }) test_that("finds seq(...) expressions", { linter <- seq_linter() lint_msg <- function(want, got) rex::rex("Use ", want, " instead of ", got) expect_lint( "seq(length(x))", lint_msg("seq_along(...)", "seq(length(...))"), linter ) expect_lint( "seq(nrow(x))", lint_msg("seq_len(nrow(...))", "seq(nrow(...))"), linter ) expect_lint( "rev(seq(length(x)))", lint_msg("seq_along(...)", "seq(length(...))"), linter ) expect_lint( "rev(seq(nrow(x)))", lint_msg("seq_len(nrow(...))", "seq(nrow(...))"), linter ) }) test_that("finds 1:length(...) expressions", { linter <- seq_linter() lint_msg <- function(want, got) rex::rex("Use ", want, " instead of ", got) expect_lint( "1:length(x)", lint_msg("seq_along(...)", "1:length(...)"), linter ) expect_lint( "1:nrow(x)", lint_msg("seq_len(nrow(...))", "1:nrow(...)"), linter ) expect_lint( "1:ncol(x)", lint_msg("seq_len(ncol(...))", "1:ncol(...)"), linter ) expect_lint( "1:NROW(x)", lint_msg("seq_len(NROW(...))", "1:NROW(...)"), linter ) expect_lint( "1:NCOL(x)", lint_msg("seq_len(NCOL(...))", "1:NCOL(...)"), linter ) expect_lint( "1:dim(x)[1L]", lint_msg("seq_len(dim(...)[1L])", "1:dim(...)[1L]"), linter ) expect_lint( "1L:dim(x)[[1]]", rex::rex("Use seq_len", anything, "dim(...)"), linter ) expect_lint( "mutate(x, .id = 1:n())", lint_msg("seq_len(n())", "1:n(),"), linter ) expect_lint( "x[, .id := 1:.N]", lint_msg("seq_len(.N)", "1:.N,"), linter ) }) test_that("1L is also bad", { expect_lint( "1L:length(x)", rex::rex("seq_along", anything, "1L:length(...)"), seq_linter() ) }) test_that("reverse seq is ok", { linter <- seq_linter() expect_lint("rev(seq_along(x))", NULL, linter) expect_lint("rev(seq_len(nrow(x)))", NULL, linter) expect_lint( "length(x):1", rex::rex("rev(seq_along(...))", anything, "length(...):1"), linter ) }) test_that("Message vectorization works for multiple lints", { linter <- seq_linter() expect_lint( trim_some("{ 1:length(x) 1:nrow(y) }"), list( list(rex::rex("seq_along(...)", anything, "1:length(...)"), line_number = 2L), list(rex::rex("seq_len(nrow(...))", anything, "1:nrow(...)"), line_number = 3L) ), linter ) expect_lint( trim_some("{ seq(length(x)) 1:nrow(y) }"), list( list(rex::rex("seq_along(...)", anything, "seq(length(...))"), line_number = 2L), list(rex::rex("seq_len(nrow(...))", anything, "1:nrow(...)"), line_number = 3L) ), linter ) expect_lint( trim_some("{ seq(length(x)) seq(nrow(y)) }"), list( list(rex::rex("seq_along(...)", anything, "seq(length(...))"), line_number = 2L), list(rex::rex("seq_len(nrow(...))", anything, "seq(nrow(...))"), line_number = 3L) ), linter ) expect_lint( trim_some("{ 1:NROW(x) seq(NCOL(y)) }"), list( list(rex::rex("seq_len(NROW(...))", anything, "1:NROW(...)"), line_number = 2L), list(rex::rex("seq_len(NCOL(...))", anything, "seq(NCOL(...))"), line_number = 3L) ), linter ) }) test_that("Message recommends rev() correctly", { linter <- seq_linter() expect_lint(".N:1", rex::rex("Use rev(seq_len(.N))"), linter) expect_lint("n():1", rex::rex("Use rev(seq_len(n()))"), linter) expect_lint("nrow(x):1", rex::rex("Use rev(seq_len(nrow(...)))"), linter) expect_lint("length(x):1", rex::rex("Use rev(seq_along(...))"), linter) })