-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make scalar_in_linter()
configurable
#2574
Changes from 5 commits
60869ce
b38f100
39a9c02
ae58e20
7bd8324
b756379
3f5eb7c
04881ef
49c453e
1aa6491
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,28 +3,48 @@ test_that("scalar_in_linter skips allowed usages", { | |
|
||
expect_lint("x %in% y", NULL, linter) | ||
expect_lint("y %in% c('a', 'b')", NULL, linter) | ||
expect_lint("c('a', 'b') %chin% x", NULL, linter) | ||
expect_lint("c('a', 'b') %in% x", NULL, linter) | ||
expect_lint("z %in% 1:3", NULL, linter) | ||
# scalars on LHS are fine (often used as `"col" %in% names(DF)`) | ||
expect_lint("3L %in% x", NULL, linter) | ||
|
||
# this should be is.na(x), but it more directly uses the "always TRUE/FALSE, _not_ NA" | ||
# aspect of %in%, so we delegate linting here to equals_na_linter() | ||
expect_lint("x %in% NA", NULL, linter) | ||
expect_lint("x %in% NA_character_", NULL, linter) | ||
}) | ||
|
||
test_that("scalar_in_linter blocks simple disallowed usages", { | ||
linter <- scalar_in_linter() | ||
lint_in_msg <- rex::rex("Use == to match length-1 scalars, not %in%.") | ||
lint_chin_msg <- rex::rex("Use == to match length-1 scalars, not %chin%.") | ||
linter <- scalar_in_linter(in_operators = c("%chin%", "%notin%")) | ||
|
||
lint_in_msg <- rex::rex("Use == to match length-1 scalars instead of %in%.") | ||
F-Noelle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
lint_chin_msg <- rex::rex("%chin% behaves similar to %in%.") | ||
lint_notin_msg <- rex::rex("%notin% behaves similar to %in%.") | ||
|
||
expect_lint("x %in% 1", lint_in_msg, linter) | ||
expect_lint("x %chin% 'a'", lint_chin_msg, linter) | ||
expect_lint("x %notin% 1", lint_notin_msg, linter) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a negative test case (no lints) here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a test where I add negative test cases based on configuration and negative test cases for the additional in operators in general. Is there by the way an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great idea! #2580 |
||
}) | ||
|
||
test_that("scalar_in_linter blocks or skips based on configuration", { | ||
linter_default <- scalar_in_linter() | ||
linter_config <- scalar_in_linter(in_operators = "%notin%") | ||
|
||
lint_in_msg <- rex::rex("Use == to match length-1 scalars instead of %in%.") | ||
lint_notin_msg <- rex::rex("%notin% behaves similar to %in%.") | ||
|
||
# default | ||
expect_lint("x %in% 1", lint_in_msg, linter_default) | ||
expect_lint("x %notin% 1", NULL, linter_default) | ||
expect_lint("x %notin% y", NULL, linter_default) | ||
|
||
# configured | ||
expect_lint("x %in% 1", lint_in_msg, linter_config) | ||
expect_lint("x %notin% 1", lint_notin_msg, linter_config) | ||
expect_lint("x %notin% y", NULL, linter_config) | ||
}) | ||
|
||
test_that("multiple lints are generated correctly", { | ||
linter <- scalar_in_linter() | ||
linter <- scalar_in_linter(in_operators = "%chin%") | ||
|
||
expect_lint( | ||
trim_some('{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the default argument is
NULL
for this parameter, the second sentence is no longer needed here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linter previously did lint the
%chin%
in its unconfigurable state. As this is no longer the case due to the default changing to NULL this is a notable change. If there is a better way to phrase that I am all ears.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The larger point of the change you are making is allowing to configure this linter.
%chin%
was just your use case, and the developers who are reading this NEWS item don't need to know that. For users of some other package, it would have been a different operator (say%nin%
).I personally don't use
{data.table}
much, so I wasn't even aware of this infix operator; as a result, this part of the NEWS item was confusing for me because I thought this was an operator in base that I didn't know about.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you might misunderstand something here.
%chin%
was never my use case. I know of{data.tables}
, but never used it in any of my projects. I just through it would be easy to make this linter configurable to work with my use cases, hence the pull request.Previously the linter in its unconfigurable form linted
%in%
and%chin%
, nothing else. When I made the update I wanted to make it backwards compatible to its original use case, so I opted to make%chin%
the default for the new parameter.@MichaelChirico then suggested to demote
%chin%
from its special status making this PR a breaking change, which I am completely on board with. But having a breaking change is NEWS worthy in my opinion, because people might have relied on the old behaviour aka%chin%
being linted.As this is no longer the case I want to highlight that simple fact as part of the NEWS. Just because I don't rely on it doesn't mean that nobody else did. If there is a better way of phrasing this I am all ears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have nothing more to add here over my previous reply.
I will let @MichaelChirico decide the best phrasing for this news item, if he thinks it merits being phrased differently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do make a breaking change, the corresponding bullet should be in its own section to highlight the change more clearly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @F-Noelle about the NEWS item, it looks good to me. Maybe we can emphasize better that it's a {data.table} operator.
@IndrajeetPatil see here, I'm not quite sure your point:
lintr/R/scalar_in_linter.R
Line 35 in fc2268f
main
,x %chin% 'a'
will lintx %chin% 'a'
will only lint underscalar_in_linter("%chin%")
or similar.