From 676a35eb97f472a878c3fdaf1e393b8eab10ec5a Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 20:36:11 +0200 Subject: [PATCH 01/16] Add `repeat_linter` --- DESCRIPTION | 1 + NAMESPACE | 1 + R/repeat_linter.R | 46 +++++++++++++++++++++++++++++ inst/lintr/linters.csv | 1 + man/linters.Rd | 5 ++-- man/readability_linters.Rd | 1 + man/repeat_linter.Rd | 33 +++++++++++++++++++++ man/style_linters.Rd | 1 + tests/testthat/test-repeat_linter.R | 13 ++++++++ 9 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 R/repeat_linter.R create mode 100644 man/repeat_linter.Rd create mode 100644 tests/testthat/test-repeat_linter.R diff --git a/DESCRIPTION b/DESCRIPTION index cbc7a1937f..80f541da6c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -149,6 +149,7 @@ Collate: 'redundant_equals_linter.R' 'redundant_ifelse_linter.R' 'regex_subset_linter.R' + 'repeat_linter.R' 'routine_registration_linter.R' 'semicolon_linter.R' 'seq_linter.R' diff --git a/NAMESPACE b/NAMESPACE index 75cba1df05..e529025f8a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -113,6 +113,7 @@ export(quotes_linter) export(redundant_equals_linter) export(redundant_ifelse_linter) export(regex_subset_linter) +export(repeat_linter) export(routine_registration_linter) export(sarif_output) export(semicolon_linter) diff --git a/R/repeat_linter.R b/R/repeat_linter.R new file mode 100644 index 0000000000..ec606d0884 --- /dev/null +++ b/R/repeat_linter.R @@ -0,0 +1,46 @@ +#' Repeat linter +#' +#' Check that `while` is not used for infinite loops. +#' +#' @examples +#' # will produce lints +#' lint( +#' text = "while (TRUE) { }", +#' linters = repeat_linter() +#' ) +#' +#' +#' # okay +#' lint( +#' text = "repeat { }", +#' linters = repeat_linter() +#' ) +#' +#' +#' @evalRd rd_tags("repeat_linter") +#' @seealso [linters] for a complete list of linters available in lintr. +#' @export +repeat_linter <- function() { + xpath <- " + //WHILE[following-sibling::*[1][self::OP-LEFT-PAREN] and + following-sibling::*[2][self::expr[NUM_CONST[text()='TRUE'] and count(*)=1]] + and following-sibling::*[3][self::OP-RIGHT-PAREN]]" + + Linter(function(source_expression) { + if (!is_lint_level(source_expression, "expression")) { + return(list()) + } + xml <- source_expression$xml_parsed_content + + + lints <- xml_nodes_to_lints( + xml_find_all(xml, xpath), + source_expression = source_expression, + lint_message = "'while (TRUE)' is not recommended for infinite loops. Use 'repeat' instead.", + range_start_xpath = "number(./@col1)", + range_end_xpath = "number(./following-sibling::*[3]/@col2)" + ) + + lints + }) +} diff --git a/inst/lintr/linters.csv b/inst/lintr/linters.csv index 263c0d345f..520699254e 100644 --- a/inst/lintr/linters.csv +++ b/inst/lintr/linters.csv @@ -71,6 +71,7 @@ quotes_linter,style consistency readability default configurable redundant_equals_linter,best_practices readability efficiency common_mistakes redundant_ifelse_linter,best_practices efficiency consistency configurable regex_subset_linter,best_practices efficiency +repeat_linter,style readability routine_registration_linter,best_practices efficiency robustness semicolon_linter,style readability default configurable semicolon_terminator_linter,style readability deprecated configurable diff --git a/man/linters.Rd b/man/linters.Rd index bf56015070..b9421f90e7 100644 --- a/man/linters.Rd +++ b/man/linters.Rd @@ -28,9 +28,9 @@ The following tags exist: \item{\link[=executing_linters]{executing} (5 linters)} \item{\link[=package_development_linters]{package_development} (14 linters)} \item{\link[=pkg_testthat_linters]{pkg_testthat} (12 linters)} -\item{\link[=readability_linters]{readability} (51 linters)} +\item{\link[=readability_linters]{readability} (52 linters)} \item{\link[=robustness_linters]{robustness} (14 linters)} -\item{\link[=style_linters]{style} (36 linters)} +\item{\link[=style_linters]{style} (37 linters)} } } \section{Linters}{ @@ -103,6 +103,7 @@ The following linters exist: \item{\code{\link{redundant_equals_linter}} (tags: best_practices, common_mistakes, efficiency, readability)} \item{\code{\link{redundant_ifelse_linter}} (tags: best_practices, configurable, consistency, efficiency)} \item{\code{\link{regex_subset_linter}} (tags: best_practices, efficiency)} +\item{\code{\link{repeat_linter}} (tags: readability, style)} \item{\code{\link{routine_registration_linter}} (tags: best_practices, efficiency, robustness)} \item{\code{\link{semicolon_linter}} (tags: configurable, default, readability, style)} \item{\code{\link{seq_linter}} (tags: best_practices, consistency, default, efficiency, robustness)} diff --git a/man/readability_linters.Rd b/man/readability_linters.Rd index ddc74a30bb..2469a5a29a 100644 --- a/man/readability_linters.Rd +++ b/man/readability_linters.Rd @@ -50,6 +50,7 @@ The following linters are tagged with 'readability': \item{\code{\link{pipe_continuation_linter}}} \item{\code{\link{quotes_linter}}} \item{\code{\link{redundant_equals_linter}}} +\item{\code{\link{repeat_linter}}} \item{\code{\link{semicolon_linter}}} \item{\code{\link{sort_linter}}} \item{\code{\link{spaces_inside_linter}}} diff --git a/man/repeat_linter.Rd b/man/repeat_linter.Rd new file mode 100644 index 0000000000..9dba4d9284 --- /dev/null +++ b/man/repeat_linter.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/repeat_linter.R +\name{repeat_linter} +\alias{repeat_linter} +\title{Repeat linter} +\usage{ +repeat_linter() +} +\description{ +Check that \code{while} is not used for infinite loops. +} +\examples{ +# will produce lints +lint( + text = "while (TRUE) { }", + linters = repeat_linter() +) + + +# okay +lint( + text = "repeat { }", + linters = repeat_linter() +) + + +} +\seealso{ +\link{linters} for a complete list of linters available in lintr. +} +\section{Tags}{ +\link[=readability_linters]{readability}, \link[=style_linters]{style} +} diff --git a/man/style_linters.Rd b/man/style_linters.Rd index 1c8337301c..fba8f2799a 100644 --- a/man/style_linters.Rd +++ b/man/style_linters.Rd @@ -37,6 +37,7 @@ The following linters are tagged with 'style': \item{\code{\link{pipe_call_linter}}} \item{\code{\link{pipe_continuation_linter}}} \item{\code{\link{quotes_linter}}} +\item{\code{\link{repeat_linter}}} \item{\code{\link{semicolon_linter}}} \item{\code{\link{spaces_inside_linter}}} \item{\code{\link{spaces_left_parentheses_linter}}} diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R new file mode 100644 index 0000000000..5774559e4b --- /dev/null +++ b/tests/testthat/test-repeat_linter.R @@ -0,0 +1,13 @@ +library(testthat) +test_that("test repeat_linter", { + linter <- repeat_linter() + msg <- rex::rex("'while (TRUE)' is not recommended for infinite loops. Use 'repeat' instead.") + + expect_lint("repeat { }", NULL, linter) + expect_lint("while (FALSE) { }", NULL, linter) + expect_lint("while (i < 5) { }", NULL, linter) + + expect_lint("while (TRUE) { }", msg, linter) + expect_lint("for (i in 1:10) { while (TRUE) { if (i == 5) { break } } }", msg, linter) + expect_lint("while (TRUE) { while (TRUE) { } }", list(msg, msg), linter) +}) From 6bc66afbd9a17a413edd7069c5e7b858e4d6367f Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 20:43:54 +0200 Subject: [PATCH 02/16] Add `repeat_linter` to NEWS --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index c2a2fbf11d..fec4399dcd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -40,6 +40,7 @@ * `keyword_quote_linter()` for finding unnecessary or discouraged quoting of symbols in assignment, function arguments, or extraction (part of #884, @MichaelChirico). Quoting is unnecessary when the target is a valid R name, e.g. `c("a" = 1)` can be `c(a = 1)`. The same goes to assignment (`"a" <- 1`) and extraction (`x$"a"`). Where quoting is necessary, the linter encourages doing so with backticks (e.g. `` x$`a b` `` instead of `x$"a b"`). * `length_levels_linter()` for using the specific function `nlevels()` instead of checking `length(levels(x))` (part of #884, @MichaelChirico). * `if_not_else_linter()` for encouraging `if` statements to be structured as `if (A) x else y` instead of `if (!A) y else x` (part of #884, @MichaelChirico). +* `repeat_linter()` for encouraging `repeat` for infinite loops instead of `while (TRUE)` (#2106, @MEO265). ## Changes to defaults From 296793e1358b22406784c5924de01029387a39ab Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 21:56:02 +0200 Subject: [PATCH 03/16] Update description --- R/repeat_linter.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index ec606d0884..dbd43a6bd4 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -1,6 +1,6 @@ #' Repeat linter #' -#' Check that `while` is not used for infinite loops. +#' Check that `while (TRUE)` is not used for infinite loops. #' #' @examples #' # will produce lints From 22072a2d397993b64bd42e94f41763db3892008f Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 21:56:28 +0200 Subject: [PATCH 04/16] Update lint_message --- R/repeat_linter.R | 2 +- tests/testthat/test-repeat_linter.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index dbd43a6bd4..8da28cb94f 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -36,7 +36,7 @@ repeat_linter <- function() { lints <- xml_nodes_to_lints( xml_find_all(xml, xpath), source_expression = source_expression, - lint_message = "'while (TRUE)' is not recommended for infinite loops. Use 'repeat' instead.", + lint_message = "Use 'repeat' instead of 'while (TRUE)' for infinite loops.", range_start_xpath = "number(./@col1)", range_end_xpath = "number(./following-sibling::*[3]/@col2)" ) diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R index 5774559e4b..d39871e223 100644 --- a/tests/testthat/test-repeat_linter.R +++ b/tests/testthat/test-repeat_linter.R @@ -1,7 +1,7 @@ library(testthat) test_that("test repeat_linter", { linter <- repeat_linter() - msg <- rex::rex("'while (TRUE)' is not recommended for infinite loops. Use 'repeat' instead.") + msg <- rex::rex("Use 'repeat' instead of 'while (TRUE)' for infinite loops.") expect_lint("repeat { }", NULL, linter) expect_lint("while (FALSE) { }", NULL, linter) From d112eec2ff01b63cc51611ccdd44c5d8b86de598 Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 21:56:46 +0200 Subject: [PATCH 05/16] Add more tests --- tests/testthat/test-repeat_linter.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R index d39871e223..5ddc87f90c 100644 --- a/tests/testthat/test-repeat_linter.R +++ b/tests/testthat/test-repeat_linter.R @@ -6,8 +6,11 @@ test_that("test repeat_linter", { expect_lint("repeat { }", NULL, linter) expect_lint("while (FALSE) { }", NULL, linter) expect_lint("while (i < 5) { }", NULL, linter) + expect_lint("while (j < 5) TRUE", NULL, linter) + expect_lint("while (TRUE && j < 5) { ... }", NULL, linter) expect_lint("while (TRUE) { }", msg, linter) + expect_lint("`while`(TRUE)", msg, linter) expect_lint("for (i in 1:10) { while (TRUE) { if (i == 5) { break } } }", msg, linter) expect_lint("while (TRUE) { while (TRUE) { } }", list(msg, msg), linter) }) From 3836d7fda33dcb6c45c51b259629f14191f958a4 Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 21:58:14 +0200 Subject: [PATCH 06/16] Simplify and enhance the XPath expression --- R/repeat_linter.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index 8da28cb94f..3ceccc6dea 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -22,9 +22,9 @@ #' @export repeat_linter <- function() { xpath <- " - //WHILE[following-sibling::*[1][self::OP-LEFT-PAREN] and - following-sibling::*[2][self::expr[NUM_CONST[text()='TRUE'] and count(*)=1]] - and following-sibling::*[3][self::OP-RIGHT-PAREN]]" + //*[(self::WHILE or self::expr[SYMBOL_FUNCTION_CALL[.='while']]) + and following-sibling::expr + and following-sibling::expr[1]/NUM_CONST[.='TRUE']]" Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) { From dfc807ed5f02deba56379c019feefff7bbad7fe1 Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 21:58:50 +0200 Subject: [PATCH 07/16] Update doc --- man/repeat_linter.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/repeat_linter.Rd b/man/repeat_linter.Rd index 9dba4d9284..dd31001155 100644 --- a/man/repeat_linter.Rd +++ b/man/repeat_linter.Rd @@ -7,7 +7,7 @@ repeat_linter() } \description{ -Check that \code{while} is not used for infinite loops. +Check that \verb{while (TRUE)} is not used for infinite loops. } \examples{ # will produce lints From 17e15d5093b4b3b106aac64f451a3bdb7846bcbd Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 22:19:04 +0200 Subject: [PATCH 08/16] Fix XPath expression --- R/repeat_linter.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index 3ceccc6dea..82a40b06b0 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -22,7 +22,7 @@ #' @export repeat_linter <- function() { xpath <- " - //*[(self::WHILE or self::expr[SYMBOL_FUNCTION_CALL[.='while']]) + //*[(self::WHILE or self::expr[SYMBOL_FUNCTION_CALL[.='`while`']]) and following-sibling::expr and following-sibling::expr[1]/NUM_CONST[.='TRUE']]" From 1a7f510e11110d82e78b41283b2698ad89a2984e Mon Sep 17 00:00:00 2001 From: Matthias Ollech Date: Tue, 5 Sep 2023 22:27:35 +0200 Subject: [PATCH 09/16] Add multiline test --- tests/testthat/test-repeat_linter.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R index 5ddc87f90c..1f87ae483f 100644 --- a/tests/testthat/test-repeat_linter.R +++ b/tests/testthat/test-repeat_linter.R @@ -13,4 +13,10 @@ test_that("test repeat_linter", { expect_lint("`while`(TRUE)", msg, linter) expect_lint("for (i in 1:10) { while (TRUE) { if (i == 5) { break } } }", msg, linter) expect_lint("while (TRUE) { while (TRUE) { } }", list(msg, msg), linter) + expect_lint("{ \nwhile (TRUE) { \n} \nwhile (TRUE) { \n} \n}", + list( + list(message = msg, line_number = 2L, column_number = 1L, ranges = list(c(1L, 12L))), + list(message = msg, line_number = 4L, column_number = 1L, ranges = list(c(1L, 12L))) + ), + linter) }) From 3ec302f420644ac3ba52d2f4e6a64d5bf1f71eac Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 5 Sep 2023 14:28:09 -0700 Subject: [PATCH 10/16] extra newline --- NEWS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index f1aa4e12f7..e872085b1d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -43,7 +43,6 @@ * `if_not_else_linter()` for encouraging `if` statements to be structured as `if (A) x else y` instead of `if (!A) y else x` (part of #884, @MichaelChirico). * `repeat_linter()` for encouraging `repeat` for infinite loops instead of `while (TRUE)` (#2106, @MEO265). - ## Changes to defaults * `assignment_linter()` lints the {magrittr} assignment pipe `%<>%` (#2008, @MichaelChirico). This can be deactivated by setting the new argument `allow_pipe_assign` to `TRUE`. From 1d6d1c49b57768c556dced276f32701c0732de23 Mon Sep 17 00:00:00 2001 From: Matthias Ollech <99362508+MEO265@users.noreply.github.com> Date: Wed, 6 Sep 2023 21:50:51 +0200 Subject: [PATCH 11/16] Ignore `` `while` (TRUE) `` --- R/repeat_linter.R | 5 +---- tests/testthat/test-repeat_linter.R | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index 82a40b06b0..12ee70b934 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -21,10 +21,7 @@ #' @seealso [linters] for a complete list of linters available in lintr. #' @export repeat_linter <- function() { - xpath <- " - //*[(self::WHILE or self::expr[SYMBOL_FUNCTION_CALL[.='`while`']]) - and following-sibling::expr - and following-sibling::expr[1]/NUM_CONST[.='TRUE']]" + xpath <- "//WHILE[following-sibling::expr and following-sibling::expr[1]/NUM_CONST[text()='TRUE']]" Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) { diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R index 1f87ae483f..47831e13fb 100644 --- a/tests/testthat/test-repeat_linter.R +++ b/tests/testthat/test-repeat_linter.R @@ -10,7 +10,6 @@ test_that("test repeat_linter", { expect_lint("while (TRUE && j < 5) { ... }", NULL, linter) expect_lint("while (TRUE) { }", msg, linter) - expect_lint("`while`(TRUE)", msg, linter) expect_lint("for (i in 1:10) { while (TRUE) { if (i == 5) { break } } }", msg, linter) expect_lint("while (TRUE) { while (TRUE) { } }", list(msg, msg), linter) expect_lint("{ \nwhile (TRUE) { \n} \nwhile (TRUE) { \n} \n}", From 4fac026aef066fd83c60f47dba24ff19d0866025 Mon Sep 17 00:00:00 2001 From: Matthias Ollech <99362508+MEO265@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:16:40 +0200 Subject: [PATCH 12/16] Fix merge fails --- man/conjunct_test_linter.Rd | 10 ++-------- man/linters.Rd | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/man/conjunct_test_linter.Rd b/man/conjunct_test_linter.Rd index 308e11b648..dd24799f2c 100644 --- a/man/conjunct_test_linter.Rd +++ b/man/conjunct_test_linter.Rd @@ -44,10 +44,7 @@ lint( ) lint( - text = "dplyr::filter( - mtcars, - mpg > 20 & vs == 0 - )", + text = "dplyr::filter(mtcars, mpg > 20 & vs == 0)", linters = conjunct_test_linter() ) @@ -63,10 +60,7 @@ lint( ) lint( - text = "dplyr::filter( - mtcars, - mpg > 20 & vs == 0 - )", + text = "dplyr::filter(mtcars, mpg > 20 & vs == 0)", linters = conjunct_test_linter(allow_filter = TRUE) ) diff --git a/man/linters.Rd b/man/linters.Rd index 35842a1f2f..e5bcd6aede 100644 --- a/man/linters.Rd +++ b/man/linters.Rd @@ -28,7 +28,7 @@ The following tags exist: \item{\link[=executing_linters]{executing} (5 linters)} \item{\link[=package_development_linters]{package_development} (14 linters)} \item{\link[=pkg_testthat_linters]{pkg_testthat} (12 linters)} -\item{\link[=readability_linters]{readability} (52 linters)} +\item{\link[=readability_linters]{readability} (53 linters)} \item{\link[=robustness_linters]{robustness} (14 linters)} \item{\link[=style_linters]{style} (37 linters)} } From f6915df70ab834a2ca9b4eb57a56210dc6ecc803 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Thu, 7 Sep 2023 09:21:23 -0700 Subject: [PATCH 13/16] redundant condition --- R/repeat_linter.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index 12ee70b934..4e654be43e 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -21,7 +21,7 @@ #' @seealso [linters] for a complete list of linters available in lintr. #' @export repeat_linter <- function() { - xpath <- "//WHILE[following-sibling::expr and following-sibling::expr[1]/NUM_CONST[text()='TRUE']]" + xpath <- "//WHILE[following-sibling::expr[1]/NUM_CONST[text() = 'TRUE']]" Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) { From e8887e499b36ce5e514a3810433581a340c4399f Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Thu, 7 Sep 2023 09:22:55 -0700 Subject: [PATCH 14/16] use intermediate variable for easier debugging --- R/repeat_linter.R | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/R/repeat_linter.R b/R/repeat_linter.R index 4e654be43e..fd10d5cbca 100644 --- a/R/repeat_linter.R +++ b/R/repeat_linter.R @@ -28,16 +28,14 @@ repeat_linter <- function() { return(list()) } xml <- source_expression$xml_parsed_content + lints <- xml_find_all(xml, xpath) - - lints <- xml_nodes_to_lints( - xml_find_all(xml, xpath), + xml_nodes_to_lints( + lints, source_expression = source_expression, lint_message = "Use 'repeat' instead of 'while (TRUE)' for infinite loops.", range_start_xpath = "number(./@col1)", range_end_xpath = "number(./following-sibling::*[3]/@col2)" ) - - lints }) } From 44a1f7d653c80d3cc39fb0dfbb0f871df0f3ecf0 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Thu, 7 Sep 2023 09:25:48 -0700 Subject: [PATCH 15/16] style --- tests/testthat/test-repeat_linter.R | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R index 47831e13fb..43fce30056 100644 --- a/tests/testthat/test-repeat_linter.R +++ b/tests/testthat/test-repeat_linter.R @@ -1,4 +1,3 @@ -library(testthat) test_that("test repeat_linter", { linter <- repeat_linter() msg <- rex::rex("Use 'repeat' instead of 'while (TRUE)' for infinite loops.") @@ -12,10 +11,17 @@ test_that("test repeat_linter", { expect_lint("while (TRUE) { }", msg, linter) expect_lint("for (i in 1:10) { while (TRUE) { if (i == 5) { break } } }", msg, linter) expect_lint("while (TRUE) { while (TRUE) { } }", list(msg, msg), linter) - expect_lint("{ \nwhile (TRUE) { \n} \nwhile (TRUE) { \n} \n}", - list( - list(message = msg, line_number = 2L, column_number = 1L, ranges = list(c(1L, 12L))), - list(message = msg, line_number = 4L, column_number = 1L, ranges = list(c(1L, 12L))) - ), - linter) + expect_lint( + trim_some("{ + while (TRUE) { + } + while (TRUE) { + } + }"), + list( + list(message = msg, line_number = 2L, column_number = 1L, ranges = list(c(1L, 12L))), + list(message = msg, line_number = 4L, column_number = 1L, ranges = list(c(1L, 12L))) + ), + linter + ) }) From 5d95612af6b26e3a524b1e643e41c35e2043ec94 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Thu, 7 Sep 2023 09:53:11 -0700 Subject: [PATCH 16/16] update test metadata --- tests/testthat/test-repeat_linter.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-repeat_linter.R b/tests/testthat/test-repeat_linter.R index 43fce30056..9c3cb16eec 100644 --- a/tests/testthat/test-repeat_linter.R +++ b/tests/testthat/test-repeat_linter.R @@ -19,8 +19,8 @@ test_that("test repeat_linter", { } }"), list( - list(message = msg, line_number = 2L, column_number = 1L, ranges = list(c(1L, 12L))), - list(message = msg, line_number = 4L, column_number = 1L, ranges = list(c(1L, 12L))) + list(message = msg, line_number = 2L, column_number = 3L, ranges = list(c(3L, 14L))), + list(message = msg, line_number = 4L, column_number = 3L, ranges = list(c(3L, 14L))) ), linter )