From 8c23c509c8b141a6db67728aa5a9631ebb54cc25 Mon Sep 17 00:00:00 2001 From: Yauheni Dakuka Date: Sun, 26 Jan 2025 20:48:04 +0400 Subject: [PATCH] Add more tests for Rails/FilePath --- spec/rubocop/cop/rails/file_path_spec.rb | 257 +++++++++++++++++++++-- 1 file changed, 239 insertions(+), 18 deletions(-) diff --git a/spec/rubocop/cop/rails/file_path_spec.rb b/spec/rubocop/cop/rails/file_path_spec.rb index 6f26d1df44..7b9b362f23 100644 --- a/spec/rubocop/cop/rails/file_path_spec.rb +++ b/spec/rubocop/cop/rails/file_path_spec.rb @@ -4,41 +4,66 @@ context 'when EnforcedStyle is `slashes`' do let(:cop_config) { { 'EnforcedStyle' => 'slashes' } } - context 'when using Rails.root.join with some path strings' do + context 'when using Rails.root.parent' do it 'registers an offense' do expect_offense(<<~RUBY) - Rails.root.join('app', 'models', 'user.rb') - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. + Rails.root.parent.join("app", "models") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. RUBY expect_correction(<<~RUBY) - Rails.root.join("app/models/user.rb") + Rails.root.parent.join("app/models") RUBY end end - context 'when using File.join with Rails.root and path starting with `/`' do + context 'when using Rails.root.dirname' do it 'registers an offense' do expect_offense(<<~RUBY) - File.join(Rails.root, '/app/models', '/user.rb') - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`. + Rails.root.dirname.join("config", "initializers") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. RUBY expect_correction(<<~RUBY) - Rails.root.join("app/models/user.rb").to_s + Rails.root.dirname.join("config/initializers") RUBY end end - context 'when using ::Rails.root.join with some path strings' do + context 'when using Rails.root.basename' do it 'registers an offense' do expect_offense(<<~RUBY) - ::Rails.root.join('app', 'models', 'user.rb') - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. + Rails.root.basename.join("config", "initializers") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. RUBY expect_correction(<<~RUBY) - ::Rails.root.join("app/models/user.rb") + Rails.root.basename.join("config/initializers") + RUBY + end + end + + context 'when using Rails.application.config.root' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + File.join(Rails.application.config.root, "app", "models") + RUBY + + expect_no_offenses(<<~RUBY) + File.join(Rails.application.config.root, "app/models") + RUBY + end + end + + context 'when using Rails.root.join with some path strings' do + it 'registers an offense' do + expect_offense(<<~RUBY) + Rails.root.join('app', 'models', 'user.rb') + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join("app/models/user.rb") RUBY end end @@ -56,6 +81,32 @@ end end + context 'when using File.join with Rails.root and path starting with `/`' do + it 'registers an offense' do + expect_offense(<<~RUBY) + File.join(Rails.root, '/app/models', '/user.rb') + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to').to_s`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join("app/models/user.rb").to_s + RUBY + end + end + + context 'when using ::Rails.root.join with some path strings' do + it 'registers an offense' do + expect_offense(<<~RUBY) + ::Rails.root.join('app', 'models', 'user.rb') + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path/to')`. + RUBY + + expect_correction(<<~RUBY) + ::Rails.root.join("app/models/user.rb") + RUBY + end + end + context 'when using Rails.root.join in string interpolation with nothing after it' do it 'does not register an offense' do expect_no_offenses(<<~'RUBY') @@ -136,7 +187,9 @@ context 'when using Rails.root.join with slash separated path string' do it 'does not register an offense' do - expect_no_offenses("Rails.root.join('app/models/goober')") + expect_no_offenses(<<~RUBY) + Rails.root.join('app/models/goober') + RUBY end end @@ -237,6 +290,32 @@ end end + context 'when interpolation with `Rails.root` contains other operations' do + it 'does not register an offense for boolean method' do + expect_no_offenses(<<~'RUBY') + "#{Rails.root || '.'}/config" + RUBY + end + + it 'does not register an offense for `rescue`' do + expect_no_offenses(<<~'RUBY') + "#{Rails.root rescue '.'}/config" + RUBY + end + + it 'does not register an offense for if condition' do + expect_no_offenses(<<~'RUBY') + "#{Rails.root if flag}/app/models" + RUBY + end + + it 'does not register an offense for a ternary operator' do + expect_no_offenses(<<~'RUBY') + "#{some_condition ? Rails.root : '/tmp'}/app/models" + RUBY + end + end + context 'with `join` method with implicit receiver' do it 'does not register an offense' do expect_no_offenses(<<~RUBY) @@ -566,16 +645,92 @@ context 'when EnforcedStyle is `arguments`' do let(:cop_config) { { 'EnforcedStyle' => 'arguments' } } - context 'when using Rails.root.join with some path strings' do + context 'when using Rails.root.parent' do + it 'registers an offense' do + expect_offense(<<~RUBY) + Rails.root.parent.join("app/models") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.parent.join("app", "models") + RUBY + end + end + + context 'when using Rails.root.dirname' do + it 'registers an offense' do + expect_offense(<<~RUBY) + Rails.root.dirname.join("config/initializers") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.dirname.join("config", "initializers") + RUBY + end + end + + context 'when using Rails.root.basename' do + it 'registers an offense' do + expect_offense(<<~RUBY) + Rails.root.basename.join("config/initializers") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.basename.join("config", "initializers") + RUBY + end + end + + context 'when using Rails.application.config.root' do it 'does not register an offense' do - expect_no_offenses("Rails.root.join('app', 'models', 'user.rb')") + expect_no_offenses(<<~RUBY) + File.join(Rails.application.config.root, "app", "models") + RUBY + + expect_no_offenses(<<~RUBY) + File.join(Rails.application.config.root, "app/models") + RUBY + end + end + + context 'when using Rails.root.join with some path strings' do + it 'registers an offense' do + expect_offense(<<~RUBY) + Rails.root.join('app/models/user.rb') + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~RUBY) + Rails.root.join('app', "models", "user.rb") + RUBY end end context 'when using Rails.root.join in string interpolation of argument' do - it 'does not register an offense' do - expect_no_offenses(<<~'RUBY') - 'system "rm -rf #{Rails.root.join(\'a\', \'b.png\')}"' + it 'registers an offense' do + expect_offense(<<~'RUBY') + system "rm -rf #{Rails.root.join("a/b.png")}" + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~'RUBY') + system "rm -rf #{Rails.root.join("a", "b.png")}" + RUBY + end + end + + context 'when using ::Rails.root.join with some path strings' do + it 'registers an offense' do + expect_offense(<<~RUBY) + ::Rails.root.join("app/models/user.rb") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~RUBY) + ::Rails.root.join("app", "models", "user.rb") RUBY end end @@ -588,6 +743,14 @@ end end + context 'when string interpolated `Rails.root` is followed by a message starting with `.`' do + it 'does not register an offense' do + expect_no_offenses(<<~'RUBY') + "#{Rails.root}. a message" + RUBY + end + end + context 'when using string interpolation without Rails.root' do it 'does not register an offense' do expect_no_offenses(<<~'RUBY') @@ -630,6 +793,39 @@ end end + context 'when using ::File.join with Rails.root' do + it 'registers an offense' 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 'when using File.join with an array' do + it 'registers an offense' do + expect_offense(<<~RUBY) + File.join([Rails.root, 'foo']) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`. + RUBY + + expect_no_corrections + end + + it 'registers an offense for nested arrays' do + expect_offense(<<~RUBY) + File.join([Rails.root, 'foo', ['bar']]) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to').to_s`. + RUBY + + expect_no_corrections + end + end + context 'when using Rails.root.join with slash separated path string' do it 'registers an offense' do expect_offense(<<~RUBY) @@ -656,6 +852,19 @@ end end + context 'when using Rails.root called by double quoted string that ends with string interpolation' do + it 'registers an offense' do + expect_offense(<<~'RUBY') + "#{Rails.root}/a/#{b}" + ^^^^^^^^^^^^^^^^^^^^^^ Prefer `Rails.root.join('path', 'to')`. + RUBY + + expect_correction(<<~'RUBY') + "#{Rails.root.join("a/#{b}")}" + RUBY + end + end + context 'when concat Rails.root and file separator using string interpolation' do it 'registers an offense' do expect_offense(<<~'RUBY') @@ -744,6 +953,18 @@ "#{Rails.root rescue '.'}/config" RUBY end + + it 'does not register an offense for if condition' do + expect_no_offenses(<<~'RUBY') + "#{Rails.root if flag}/app/models" + RUBY + end + + it 'does not register an offense for a ternary operator' do + expect_no_offenses(<<~'RUBY') + "#{some_condition ? Rails.root : '/tmp'}/app/models" + RUBY + end end context 'with `join` method with implicit receiver' do