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 ToJSON Linter #6379
Add ToJSON Linter #6379
Conversation
d74163a
to
2ab1725
Compare
lib/rubocop/cop/lint/to_json.rb
Outdated
M_JSON | ||
|
||
def on_def(node) | ||
return if node.method_name != :to_json |
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.
Think these guard clauses would be clearer if combined:
return unless node.method?(:to_json) && node.arguments.empty?
This reads exactly as the condition you laid out in the description. 🙂
lib/rubocop/cop/lint/to_json.rb
Outdated
|
||
def autocorrect(node) | ||
lambda do |corrector| | ||
corrector.insert_after(node.loc.name, '(_opts = {})') |
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.
Think this will raise a RuboCop offense in Style/OptionHash
. We should probably look at adding a whitelist entry to that cop to account for this.
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.
@Drenmi thanks for calling this out - where exactly would I add the whitelist?
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.
@Drenmi can you point me in the right direction?
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.
@allcentury: The changes need to be made in Style/OptionHash
. For an example of a method whitelist, check e.g. Rails/DynamicFindBy
.
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.
@allcentury: The changes need to be made in Style/OptionHash
. For an example of a method whitelist, check e.g. Rails/DynamicFindBy
.
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.
@allcentury: The changes need to be made in Style/OptionHash
. For an example of a method whitelist, check e.g. Rails/DynamicFindBy
.
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.
@allcentury: The changes need to be made in Style/OptionHash
. For an example of a method whitelist, check e.g. Rails/DynamicFindBy
.
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.
@allcentury: The changes need to be made in Style/OptionHash
. For an example of a method whitelist, check e.g. Rails/DynamicFindBy
.
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.
@allcentury: The changes need to be made in Style/OptionHash
. For an example of a method whitelist, check e.g. Rails/DynamicFindBy
. 🙂
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.
@Drenmi thank you! I think I've implemented your suggestion, please take a look when you have a sec
7177f8a
to
6662c89
Compare
899c9a7
to
28a443d
Compare
@Drenmi is this ready to merge? |
lib/rubocop/cop/lint/to_json.rb
Outdated
# end | ||
# | ||
class ToJSON < Cop | ||
MSG = <<-M_JSON.strip_indent.chomp.freeze |
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.
Let's change the identifier from M_JSON
(makes me think of the late king of pop 😅) to MESSAGE
. 🙂
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.
No need for a heredoc here:
MSG = '`#to_json` requires an optional hash argument to be parsable ' \
'via JSON.generate(obj).'
|
||
it 'does not register an offense when using `#to_json` with arguments' do | ||
expect_no_offenses(<<-RUBY.strip_indent) | ||
def to_json(opts = {}) |
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.
Let's indent the contents of the heredoc one more level for this and the next example. 🙂
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.
Some small nits, but looks good to me. 🚀
Ping @bbatsov.
lib/rubocop/cop/lint/to_json.rb
Outdated
# end | ||
# | ||
# # good | ||
# def to_json(opts = {}) |
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.
As mentioned in #6378 (comment) I am not sure the argument is always a Hash
require 'json'
class MyClass
def to_json(*args)
p args
""
end
end
JSON.generate(MyClass.new)
#=> [#<JSON::Ext::Generator::State:0x00007faacb155a40>]
In the JSON documentation I see a few different signatures for #to_json
:
…maybe we can only say that to_json
should have arity 1?
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 @bquorning - I'll make that change
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.
On second thought, *
and *args
aren’t arity 1…
This fixes issue rubocop#6378 classes that override to_json need to ensure an optional argument is available. class MyClass def to_json end end While calling MyClass.new.to_json works, calling JSON.generate(MyClass.new) results in an ArgumentError.
28a443d
to
8fd679e
Compare
@allcentury Sorry for dropping the ball on this. Please rebase your branch on current |
This fixes issue #6378
classes that override to_json need to ensure an optional parameter is
available.
While calling
MyClass.new.to_json
works, callingJSON.generate(MyClass.new)
results in anArgumentError
.0.59.2 (using Parser 2.5.1.2, running on ruby 2.5.1 x86_64-linux)
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.
rake default
. It executes all tests and RuboCop for itself, and generates the documentation.