Skip to content

Commit

Permalink
Merge pull request #1415 from ydakuka/fix/typeerror_in_the_file_path_cop
Browse files Browse the repository at this point in the history
[Fix #1389] Handle `TypeError` caused by passing array literals as arguments to `File` methods in `Rails/FilePath` cop
  • Loading branch information
koic authored Jan 20, 2025
2 parents 158cd38 + 3677f7b commit 7024ab5
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ InternalAffairs/NodeDestructuring:
# Offense count: 10
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
Max: 163
Max: 179

# Offense count: 41
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#1389](https://github.com/rubocop/rubocop-rails/issues/1389): Handle `TypeError` caused by passing array literals as arguments to `File` methods in `Rails/FilePath` cop. ([@ydakuka][])
24 changes: 22 additions & 2 deletions lib/rubocop/cop/rails/file_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,17 @@ def autocorrect_extension_after_rails_root_join_in_dstr(corrector, node, rails_r
end

def autocorrect_file_join(corrector, node)
replace_receiver_with_rails_root(corrector, node)
remove_first_argument_with_comma(corrector, node)
process_arguments(corrector, node.arguments)
append_to_string_conversion(corrector, node)
end

def replace_receiver_with_rails_root(corrector, node)
corrector.replace(node.receiver, 'Rails.root')
end

def remove_first_argument_with_comma(corrector, node)
corrector.remove(
range_with_surrounding_space(
range_with_surrounding_comma(
Expand All @@ -183,9 +193,19 @@ def autocorrect_file_join(corrector, node)
side: :right
)
)
node.arguments.filter(&:str_type?).each do |argument|
corrector.replace(argument, argument.value.delete_prefix('/').inspect)
end

def process_arguments(corrector, arguments)
arguments.each do |argument|
if argument.str_type?
corrector.replace(argument, argument.value.delete_prefix('/').inspect)
elsif argument.array_type?
corrector.replace(argument, "*#{argument.source}")
end
end
end

def append_to_string_conversion(corrector, node)
corrector.insert_after(node, '.to_s')
end

Expand Down
156 changes: 156 additions & 0 deletions spec/rubocop/cop/rails/file_path_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,84 @@
RUBY
end
end

context 'when using only [] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, ['app', 'models'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*['app', 'models']).to_s
RUBY
end
end

context 'with a leading string and an array using [] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, "app", ["models", "goober"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join("app", *["models", "goober"]).to_s
RUBY
end
end

context 'with an array using [] syntax and a trailing string' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, ["app", "models"], "goober")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*["app", "models"], "goober").to_s
RUBY
end
end

context 'when using only %w[] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, %w[app models])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*%w[app models]).to_s
RUBY
end
end

context 'with a leading string and an array using %w[] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, "app", %w[models goober])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join("app", *%w[models goober]).to_s
RUBY
end
end

context 'with an array using %w[] syntax and a trailing string' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, %w[app models], "goober")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*%w[app models], "goober").to_s
RUBY
end
end
end

context 'when EnforcedStyle is `arguments`' do
Expand Down Expand Up @@ -436,5 +514,83 @@
RUBY
end
end

context 'when using only [] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, ['app', 'models'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*['app', 'models']).to_s
RUBY
end
end

context 'with a leading string and an array using [] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, "app", ["models", "goober"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join("app", *["models", "goober"]).to_s
RUBY
end
end

context 'with an array using [] syntax and a trailing string' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, ["app", "models"], "goober")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*["app", "models"], "goober").to_s
RUBY
end
end

context 'when using only %w[] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, %w[app models])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*%w[app models]).to_s
RUBY
end
end

context 'with a leading string and an array using %w[] syntax' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, "app", %w[models goober])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join("app", *%w[models goober]).to_s
RUBY
end
end

context 'with an array using %w[] syntax and a trailing string' do
it 'registers an offense once' do
expect_offense(<<~RUBY)
File.join(Rails.root, %w[app models], "goober")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`.
RUBY

expect_correction(<<~RUBY)
Rails.root.join(*%w[app models], "goober").to_s
RUBY
end
end
end
end

0 comments on commit 7024ab5

Please sign in to comment.