From 334e5cc394afdac3bc36ad24ceac577fbbe557c2 Mon Sep 17 00:00:00 2001 From: Yauheni Dakuka Date: Sat, 18 Jan 2025 17:04:16 +0400 Subject: [PATCH] [Fix rubocop#1389] Handle TypeError caused by an array in Rails/RootPathname cop --- ...to_handle_type_error_caused_by_an_array.md | 1 + .../cop/rails/root_pathname_methods.rb | 7 +- .../cop/rails/root_pathname_methods_spec.rb | 66 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_rails_root_pathname_to_handle_type_error_caused_by_an_array.md diff --git a/changelog/fix_rails_root_pathname_to_handle_type_error_caused_by_an_array.md b/changelog/fix_rails_root_pathname_to_handle_type_error_caused_by_an_array.md new file mode 100644 index 0000000000..8c77d4b0b3 --- /dev/null +++ b/changelog/fix_rails_root_pathname_to_handle_type_error_caused_by_an_array.md @@ -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/RootPathnameMethods` cop. ([@ydakuka][]) diff --git a/lib/rubocop/cop/rails/root_pathname_methods.rb b/lib/rubocop/cop/rails/root_pathname_methods.rb index 5898d0b421..1678d51c47 100644 --- a/lib/rubocop/cop/rails/root_pathname_methods.rb +++ b/lib/rubocop/cop/rails/root_pathname_methods.rb @@ -237,7 +237,12 @@ def build_path_replacement(path, method, args) end replacement = "#{path_replacement}.#{method}" - replacement += "(#{args.map(&:source).join(', ')})" unless args.empty? + + if args.any? + formatted_args = args.map { |arg| arg.array_type? ? "*#{arg.source}" : arg.source } + replacement += "(#{formatted_args.join(', ')})" + end + replacement end diff --git a/spec/rubocop/cop/rails/root_pathname_methods_spec.rb b/spec/rubocop/cop/rails/root_pathname_methods_spec.rb index 82f00ea5da..77cb1b1218 100644 --- a/spec/rubocop/cop/rails/root_pathname_methods_spec.rb +++ b/spec/rubocop/cop/rails/root_pathname_methods_spec.rb @@ -210,4 +210,70 @@ file = Rails.root.join('docs', 'invoice.pdf').open RUBY end + + it 'registers an offense when using only [] syntax' do + expect_offense(<<~RUBY) + File.join(Rails.root, ['app', 'models']) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join(*['app', 'models'])`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join(*['app', 'models']) + RUBY + end + + it 'registers an offense when using a leading string and an array using [] syntax' do + expect_offense(<<~RUBY) + File.join(Rails.root, "app", ["models", "goober"]) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join("app", *["models", "goober"])`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join("app", *["models", "goober"]) + RUBY + end + + it 'registers an offense when using an array using [] syntax and a trailing string' do + expect_offense(<<~RUBY) + File.join(Rails.root, ["app", "models"], "goober") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join(*["app", "models"], "goober")`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join(*["app", "models"], "goober") + RUBY + end + + it 'registers an offense when using only %w[] syntax' do + expect_offense(<<~RUBY) + File.join(Rails.root, %w[app models]) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join(*%w[app models])`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join(*%w[app models]) + RUBY + end + + it 'registers an offense when using a leading string and an array using %w[] syntax' do + expect_offense(<<~RUBY) + File.join(Rails.root, "app", %w[models goober]) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join("app", *%w[models goober])`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join("app", *%w[models goober]) + RUBY + end + + it 'registers an offense when using an array using %w[] syntax and a trailing string' do + expect_offense(<<~RUBY) + File.join(Rails.root, %w[app models], "goober") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join(*%w[app models], "goober")`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join(*%w[app models], "goober") + RUBY + end end