-
-
Notifications
You must be signed in to change notification settings - Fork 44
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
Add new Minitest/AssertWithExpectedArgument
cop
#120
Conversation
end | ||
end | ||
RUBY | ||
end |
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.
Can you add the following test cases?
def test_does_not_register_offense_when_second_argument_is_an_interpolated_string
assert_no_offenses(<<~'RUBY')
class FooTest < Minitest::Test
def test_do_something
assert([], "empty array should be truthy #{additional_message}")
end
end
RUBY
end
def test_does_not_register_offense_when_using_assert_equal_with_two_arguments
assert_no_offenses(<<~'RUBY')
class FooTest < Minitest::Test
def test_do_something
assert_equal([], actual)
end
end
RUBY
end
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.
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.
assert_equal([], actual)
should suggest assert_empty?
The role of each cop force should be simple, so let Minitest/AssertEmptyLiteral
cop make suggestions for assert_empty?
. So the cop is up to the suggestion to assert_equal
:-)
|
||
def on_send(node) | ||
assert_with_two_arguments?(node) do |_expected, message| | ||
return if message.str_type? |
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.
Can you add the condition?
return if message.str_type? | |
return if message.str_type? || message.dstr_type? |
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.
Fixed in 6917350
# | ||
class AssertWithTwoArguments < Cop | ||
MSG = 'Did you mean to use `assert_equal(%<arguments>s)`?' | ||
|
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.
Can you add RESTRICT_ON_SEND
?
diff --git a/lib/rubocop/cop/minitest/assert_with_two_arguments.rb b/lib/rubocop/cop/minitest/assert_with_two_arguments.rb
index 4ba7bd9..a3b81ff 100644
--- a/lib/rubocop/cop/minitest/assert_with_two_arguments.rb
+++ b/lib/rubocop/cop/minitest/assert_with_two_arguments.rb
@@ -19,6 +19,8 @@ module RuboCop
class AssertWithTwoArguments < Cop
MSG = 'Did you mean to use `assert_equal(%<arguments>s)`?'
+ RESTRICT_ON_SEND = %i[assert].freeze
+
def_node_matcher :assert_with_two_arguments?, <<~PATTERN
(send nil? :assert $_ $_)
PATTERN
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.
Fixed in 0db8efb
I think the name of this cop could be clearer, how about |
module Cop | ||
module Minitest | ||
# This cop tries to detect when a user accidentally used | ||
# `assert` when they meant to use `assert_equal` |
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.
Can you add the period at the end of the sentence?
# `assert` when they meant to use `assert_equal` | |
# `assert` when they meant to use `assert_equal`. |
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.
Fixed in 4b0e9ea
I'm worried that the term |
|
4b0e9ea
to
c11c324
Compare
I pushed a bunch of fixup commits in response to code review. Let me know when things look good and I'll squash them (along with the changelog commit), rebase onto master, and resolve the merge conflict.
Yeah, I'm not in love with the current name either. Naming things is hard. Personally I think |
Thank you for the idea of the cop name. I think this cop is essentially checking that # bad
assert(expected, actual) # `assert` method never accepts `expected` argument.
# good
assert(test, message)
assert_equal(expected, actual) |
I'm not sure what you mean by this. As I understand it, |
end | ||
end | ||
RUBY | ||
end |
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.
Can you add the testcase?
def test_registers_offense_when_second_argument_is_a_variable
assert_offense(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
my_list = [1, 2, 3].length
assert(3, my_list_length)
^^^^^^^^^^^^^^^^^^^^^^^^^ Did you mean to use `assert_equal(3, my_list_length)`?
end
end
RUBY
end
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.
Added in d8e98bf
Let's take The user should write The following is an updated offense message with this comment added.
This is the reason for the naming that meant the violation And I'm worried about Of course, I think there are more better names I haven't come up with. Naming is difficult 😅 |
df48d62
to
d8e98bf
Compare
OK, I think I understand what you meant. I guess my issue with calling the cop The reason why I personally prefer I guess a better MSG = 'The `msg` argument to `assert` is not a `String`. Did you mean to use assert_equal(%<arguments>s)?' It's worth mentioning that I'm not fundamentally opposed to either. I just thought I'd explain my preference. Ultimately it's your call to make. |
Sorry for my late reply. For example, in future it may be possible to detect cases that do not use string literals in messages, such as: # I hope that these variable message and constant message can be detected as strings in future :-)
message ="#{variable} phrase"
assert(test, message)
MESSAGE ='fixed phrase'
assert(test, MESSAGE) Unfortunately, that experimentation haven't caught up yet, so current implementation have to rely on literal types 😅 |
d8e98bf
to
2d5c3e7
Compare
That's a good point. I went ahead and changed the cop name to |
Perhaps change the PR title to match the new name to avoid confusion, and make it easier to search for? |
Minitest/AssertWithTwoArguments
copMinitest/AssertWithExpectedArgument
cop
Done! Good catch! |
CHANGELOG.md
Outdated
@@ -6,6 +6,9 @@ | |||
|
|||
* [#118](https://github.com/rubocop/rubocop-minitest/pull/118): **(BREAKING)** Fix `Minitest/AssertEmptyLiteral` by making it check for `assert_equal([], array)` instead of `assert([], array)`. ([@cstyles][]) | |||
* [#122](https://github.com/rubocop/rubocop-minitest/pull/122): Fix `Minitest/TestMethodName` for tests with multiple assertions. ([@ghiculescu][]) | |||
### New features | |||
|
|||
* [#117](https://github.com/rubocop/rubocop-minitest/issues/117): Add new cop `Minitest/AssertWithExpectedArgument` to check for unintended usages of `assert` instead of `assert_equal`. ([@cstyles][]) |
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.
Can you move this New features
section to above the Bug fixes
section and squash your commits into one?
## master (unreleased)
+
+### New features
+
+* [#117](https://github.com/rubocop/rubocop-minitest/issues/117): Add new cop `Minitest/AssertWithExpectedArgument` to check for unintended usages of `assert` instead of `assert_equal`. ([@cstyles][])
### Bug fixes
* [#118](https://github.com/rubocop/rubocop-minitest/pull/118): **(BREAKING)** Fix `Minitest/AssertEmptyLiteral` by making it check for `assert_equal([], array)` instead of `assert([], array)`. ([@cstyles][])
* [#122](https://github.com/rubocop/rubocop-minitest/pull/122): Fix `Minitest/TestMethodName` for tests with multiple assertions. ([@ghiculescu][])
-### New features
-
-* [#117](https://github.com/rubocop/rubocop-minitest/issues/117): Add new cop `Minitest/AssertWithExpectedArgument` to check for unintended usages of `assert` instead of `assert_equal`. ([@cstyles][])
## 0.10.3 (2021-01-12)
It is a common mistake to use `assert` instead of `assert_equal`. This is dangerous because minitest will treat the second argument to `assert` as the `msg` parameter and, as long as the first argument is truthy, the test will always pass. This false negative gives the user a sense of security even though they're not actually testing what they think they are. This commit introduces a new cop which will register a violation if `assert` is called with two arguments and the second argument isn't a `String`. If the second argument *is* a `String`, then the user is likely using `assert` as intended. If it's not, most of the time it means a mistake has been made.
2d5c3e7
to
2dea4e6
Compare
Thanks! |
Fixes #117
It is a common mistake to use
assert
instead ofassert_equal
. Thisis dangerous because minitest will treat the second argument to
assert
as the
msg
parameter and, as long as the first argument is truthy, thetest will always pass. This false negative gives the user a sense of
security even though they're not actually testing what they think they
are.
This PR introduces a new cop which will register a violation if
assert
is called with two arguments and the second argument isn't aString
. If the second argument is aString
, then the user islikely using
assert
as intended. If it's not, most of the time itmeans a mistake has been made.
Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).and description in grammatically correct, complete sentences.
bundle exec rake default
. It executes all tests and RuboCop for itself, and generates the documentation.