diff --git a/.rubocop.yml b/.rubocop.yml index 43ee5e077b..dc83f549fc 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -19,10 +19,6 @@ AllCops: InternalAffairs/NodeMatcherDirective: Enabled: false -# FIXME: Workaround for a false positive caused by this cop when using `bundle exec rake`. -InternalAffairs/UndefinedConfig: - Enabled: false - Naming/InclusiveLanguage: Enabled: true CheckStrings: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 8671e1bf72..ae1c5d800e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,18 @@ ## master (unreleased) +## 2.26.1 (2024-09-07) + +### Bug fixes + +* [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) +* [#1340](https://github.com/rubocop/rubocop-rails/issues/1340): Fix a false positive for `Rails/WhereEquals`, `Rails/WhereNot`, and `Rails/WhereRange` when qualifying the database name. ([@earlopain][]) + +### Changes + +* [#1342](https://github.com/rubocop/rubocop-rails/issues/1342): Change `Rails/ApplicationRecord` to ignore migrations. ([@fatkodima][]) +* [#1350](https://github.com/rubocop/rubocop-rails/pull/1350): Change `Rails/EnumSyntax` to autocorrect underscored options. ([@fatkodima][]) + ## 2.26.0 (2024-08-24) ### New features diff --git a/config/default.yml b/config/default.yml index 97b01498b0..b59db897c5 100644 --- a/config/default.yml +++ b/config/default.yml @@ -212,7 +212,9 @@ Rails/ApplicationRecord: Enabled: true SafeAutoCorrect: false VersionAdded: '0.49' - VersionChanged: '2.5' + VersionChanged: '2.26' + Exclude: + - db/**/*.rb Rails/ArelStar: Description: 'Enforces `Arel.star` instead of `"*"` for expanded columns.' diff --git a/docs/modules/ROOT/pages/cops_rails.adoc b/docs/modules/ROOT/pages/cops_rails.adoc index b946879608..ad89ca7c52 100644 --- a/docs/modules/ROOT/pages/cops_rails.adoc +++ b/docs/modules/ROOT/pages/cops_rails.adoc @@ -612,11 +612,15 @@ end | Yes | Always (Unsafe) | 0.49 -| 2.5 +| 2.26 |=== Checks that models subclass `ApplicationRecord` with Rails 5.0. +It is a common practice to define models inside migrations in order to retain forward +compatibility by avoiding loading any application code. And so migration files are excluded +by default for this cop. + === Safety This cop's autocorrection is unsafe because it may let the logic from `ApplicationRecord` @@ -638,6 +642,16 @@ class Rails4Model < ActiveRecord::Base end ---- +=== Configurable attributes + +|=== +| Name | Default value | Configurable values + +| Exclude +| `+db/**/*.rb+` +| Array +|=== + == Rails/ArelStar |=== @@ -4178,7 +4192,7 @@ core extensions to the numeric classes. 3.day.ago 1.months.ago 5.megabyte -1.gigabyte +1.gigabytes # good 3.days.ago @@ -5458,6 +5472,8 @@ File.read(Rails.root.join('db', 'schema.rb')) File.binread(Rails.root.join('db', 'schema.rb')) File.write(Rails.root.join('db', 'schema.rb'), content) File.binwrite(Rails.root.join('db', 'schema.rb'), content) +Dir.glob(Rails.root.join('db', 'schema.rb')) +Dir[Rails.root.join('db', 'schema.rb')] # good Rails.root.join('db', 'schema.rb').open @@ -5466,6 +5482,7 @@ Rails.root.join('db', 'schema.rb').read Rails.root.join('db', 'schema.rb').binread Rails.root.join('db', 'schema.rb').write(content) Rails.root.join('db', 'schema.rb').binwrite(content) +Rails.root.glob("db/schema.rb") ---- == Rails/RootPublicPath diff --git a/lib/rubocop/cop/rails/action_order.rb b/lib/rubocop/cop/rails/action_order.rb index a2bcd3b462..954c1ae2fd 100644 --- a/lib/rubocop/cop/rails/action_order.rb +++ b/lib/rubocop/cop/rails/action_order.rb @@ -92,11 +92,7 @@ def add_range(range1, range2) end def range_with_comments(node) - # rubocop:todo InternalAffairs/LocationExpression - # Using `RuboCop::Ext::Comment#source_range` requires RuboCop > 1.46, - # which introduces https://github.com/rubocop/rubocop/pull/11630. - ranges = [node, *processed_source.ast_with_comments[node]].map { |comment| comment.loc.expression } - # rubocop:enable InternalAffairs/LocationExpression + ranges = [node, *processed_source.ast_with_comments[node]].map(&:source_range) ranges.reduce do |result, range| add_range(result, range) end diff --git a/lib/rubocop/cop/rails/active_record_callbacks_order.rb b/lib/rubocop/cop/rails/active_record_callbacks_order.rb index 8742e76338..cb544234f6 100644 --- a/lib/rubocop/cop/rails/active_record_callbacks_order.rb +++ b/lib/rubocop/cop/rails/active_record_callbacks_order.rb @@ -123,11 +123,7 @@ def begin_pos_with_comment(node) end def inline_comment?(comment) - # rubocop:todo InternalAffairs/LocationExpression - # Using `RuboCop::Ext::Comment#source_range` requires RuboCop > 1.46, - # which introduces https://github.com/rubocop/rubocop/pull/11630. - !comment_line?(comment.loc.expression.source_line) - # rubocop:enable InternalAffairs/LocationExpression + !comment_line?(comment.source_range.source_line) end def start_line_position(node) diff --git a/lib/rubocop/cop/rails/application_record.rb b/lib/rubocop/cop/rails/application_record.rb index 91ee5e2aaf..f5f40bcdc2 100644 --- a/lib/rubocop/cop/rails/application_record.rb +++ b/lib/rubocop/cop/rails/application_record.rb @@ -5,6 +5,10 @@ module Cop module Rails # Checks that models subclass `ApplicationRecord` with Rails 5.0. # + # It is a common practice to define models inside migrations in order to retain forward + # compatibility by avoiding loading any application code. And so migration files are excluded + # by default for this cop. + # # @safety # This cop's autocorrection is unsafe because it may let the logic from `ApplicationRecord` # sneak into an Active Record model that is not purposed to inherit logic common among other diff --git a/lib/rubocop/cop/rails/enum_syntax.rb b/lib/rubocop/cop/rails/enum_syntax.rb index 39501c4331..a3d650440a 100644 --- a/lib/rubocop/cop/rails/enum_syntax.rb +++ b/lib/rubocop/cop/rails/enum_syntax.rb @@ -24,7 +24,10 @@ class EnumSyntax < Base MSG = 'Enum defined with keyword arguments in `%s` enum declaration. Use positional arguments instead.' MSG_OPTIONS = 'Enum defined with deprecated options in `%s` enum declaration. Remove the `_` prefix.' RESTRICT_ON_SEND = %i[enum].freeze - OPTION_NAMES = %w[prefix suffix scopes default].freeze + + # From https://github.com/rails/rails/blob/v7.2.1/activerecord/lib/active_record/enum.rb#L231 + OPTION_NAMES = %w[prefix suffix scopes default instance_methods].freeze + UNDERSCORED_OPTION_NAMES = OPTION_NAMES.map { |option| "_#{option}" }.freeze def_node_matcher :enum?, <<~PATTERN (send nil? :enum (hash $...)) @@ -34,14 +37,6 @@ class EnumSyntax < Base (send nil? :enum $_ ${array hash} $_) PATTERN - def_node_matcher :enum_values, <<~PATTERN - (pair $_ ${array hash}) - PATTERN - - def_node_matcher :enum_options, <<~PATTERN - (pair $_ $_) - PATTERN - def on_send(node) check_and_correct_keyword_args(node) check_enum_options(node) @@ -52,10 +47,9 @@ def on_send(node) def check_and_correct_keyword_args(node) enum?(node) do |pairs| pairs.each do |pair| - key, values = enum_values(pair) - next unless key + next if option_key?(pair) - correct_keyword_args(node, key, values, pairs[1..]) + correct_keyword_args(node, pair.key, pair.value, pairs[1..]) end end end @@ -63,9 +57,11 @@ def check_and_correct_keyword_args(node) def check_enum_options(node) enum_with_options?(node) do |key, _, options| options.children.each do |option| - name, = enum_options(option) + next unless option_key?(option) - add_offense(name, message: format(MSG_OPTIONS, enum: enum_name_value(key))) if name.source[0] == '_' + add_offense(option.key, message: format(MSG_OPTIONS, enum: enum_name_value(key))) do |corrector| + corrector.replace(option.key, option.key.source.delete_prefix('_')) + end end end end @@ -107,6 +103,10 @@ def enum_name(elem) end end + def option_key?(pair) + UNDERSCORED_OPTION_NAMES.include?(pair.key.source) + end + def correct_options(options) corrected_options = options.map do |pair| name = if pair.key.source[0] == '_' diff --git a/lib/rubocop/cop/rails/pluralization_grammar.rb b/lib/rubocop/cop/rails/pluralization_grammar.rb index beaaa8d736..4ee227b486 100644 --- a/lib/rubocop/cop/rails/pluralization_grammar.rb +++ b/lib/rubocop/cop/rails/pluralization_grammar.rb @@ -11,7 +11,7 @@ module Rails # 3.day.ago # 1.months.ago # 5.megabyte - # 1.gigabyte + # 1.gigabytes # # # good # 3.days.ago diff --git a/lib/rubocop/cop/rails/present.rb b/lib/rubocop/cop/rails/present.rb index 1d789cf7bd..3d77f33d6f 100644 --- a/lib/rubocop/cop/rails/present.rb +++ b/lib/rubocop/cop/rails/present.rb @@ -98,8 +98,6 @@ def on_and(node) end def on_or(node) - return unless cop_config['NilOrEmpty'] - exists_and_not_empty?(node) do |var1, var2| return unless var1 == var2 diff --git a/lib/rubocop/cop/rails/redundant_active_record_all_method.rb b/lib/rubocop/cop/rails/redundant_active_record_all_method.rb index ee5fa6afd6..252e890875 100644 --- a/lib/rubocop/cop/rails/redundant_active_record_all_method.rb +++ b/lib/rubocop/cop/rails/redundant_active_record_all_method.rb @@ -3,35 +3,6 @@ module RuboCop module Cop module Rails - # TODO: In the future, please support only RuboCop 1.52+ and use `RuboCop::Cop::AllowedReceivers`: - # https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/mixin/allowed_receivers.rb - # At that time, this duplicated module implementation can be removed. - module AllowedReceivers - def allowed_receiver?(receiver) - receiver_name = receiver_name(receiver) - - allowed_receivers.include?(receiver_name) - end - - def receiver_name(receiver) - return receiver_name(receiver.receiver) if receiver.receiver && !receiver.receiver.const_type? - - if receiver.send_type? - if receiver.receiver - "#{receiver_name(receiver.receiver)}.#{receiver.method_name}" - else - receiver.method_name.to_s - end - else - receiver.source - end - end - - def allowed_receivers - cop_config.fetch('AllowedReceivers', []) - end - end - # Detect redundant `all` used as a receiver for Active Record query methods. # # For the methods `delete_all` and `destroy_all`, this cop will only check cases where the receiver is a model. diff --git a/lib/rubocop/cop/rails/root_pathname_methods.rb b/lib/rubocop/cop/rails/root_pathname_methods.rb index 233b1744d0..5898d0b421 100644 --- a/lib/rubocop/cop/rails/root_pathname_methods.rb +++ b/lib/rubocop/cop/rails/root_pathname_methods.rb @@ -23,6 +23,8 @@ module Rails # File.binread(Rails.root.join('db', 'schema.rb')) # File.write(Rails.root.join('db', 'schema.rb'), content) # File.binwrite(Rails.root.join('db', 'schema.rb'), content) + # Dir.glob(Rails.root.join('db', 'schema.rb')) + # Dir[Rails.root.join('db', 'schema.rb')] # # # good # Rails.root.join('db', 'schema.rb').open @@ -31,12 +33,13 @@ module Rails # Rails.root.join('db', 'schema.rb').binread # Rails.root.join('db', 'schema.rb').write(content) # Rails.root.join('db', 'schema.rb').binwrite(content) + # Rails.root.glob("db/schema.rb") # class RootPathnameMethods < Base # rubocop:disable Metrics/ClassLength extend AutoCorrector include RangeHelp - MSG = '`%s` is a `Pathname` so you can just append `#%s`.' + MSG = '`%s` is a `Pathname`, so you can use `%s`.' DIR_GLOB_METHODS = %i[[] glob].to_set.freeze @@ -188,13 +191,14 @@ class RootPathnameMethods < Base # rubocop:disable Metrics/ClassLength def on_send(node) evidence(node) do |method, path, args, rails_root| - add_offense(node, message: format(MSG, method: method, rails_root: rails_root.source)) do |corrector| - replacement = if dir_glob?(node) - build_path_glob_replacement(path) - else - build_path_replacement(path, method, args) - end + replacement = if dir_glob?(node) + build_path_glob_replacement(path) + else + build_path_replacement(path, method, args) + end + message = format(MSG, rails_root: rails_root.source, replacement: replacement) + add_offense(node, message: message) do |corrector| corrector.replace(node, replacement) end end diff --git a/lib/rubocop/cop/rails/skips_model_validations.rb b/lib/rubocop/cop/rails/skips_model_validations.rb index 5a78926c92..58a6fe519d 100644 --- a/lib/rubocop/cop/rails/skips_model_validations.rb +++ b/lib/rubocop/cop/rails/skips_model_validations.rb @@ -100,7 +100,8 @@ def allowed_method?(node) end def forbidden_methods - obsolete_result = cop_config['Blacklist'] + # TODO: Remove when RuboCop Rails 3 releases. + obsolete_result = cop_config['Blacklist'] # rubocop:disable InternalAffairs/UndefinedConfig if obsolete_result warn '`Blacklist` has been renamed to `ForbiddenMethods`.' unless @displayed_forbidden_warning @displayed_forbidden_warning = true @@ -111,7 +112,8 @@ def forbidden_methods end def allowed_methods - obsolete_result = cop_config['Whitelist'] + # TODO: Remove when RuboCop Rails 3 releases. + obsolete_result = cop_config['Whitelist'] # rubocop:disable InternalAffairs/UndefinedConfig if obsolete_result warn '`Whitelist` has been renamed to `AllowedMethods`.' unless @displayed_allowed_warning @displayed_allowed_warning = true diff --git a/lib/rubocop/cop/rails/where_equals.rb b/lib/rubocop/cop/rails/where_equals.rb index b1d56b7c24..b538bedd8d 100644 --- a/lib/rubocop/cop/rails/where_equals.rb +++ b/lib/rubocop/cop/rails/where_equals.rb @@ -74,6 +74,7 @@ def offense_range(node) range_between(node.loc.selector.begin_pos, node.source_range.end_pos) end + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def extract_column_and_value(template_node, value_node) value = case template_node.value @@ -90,8 +91,12 @@ def extract_column_and_value(template_node, value_node) return end - [Regexp.last_match(1), value] + column_qualifier = Regexp.last_match(1) + return if column_qualifier.count('.') > 1 + + [column_qualifier, value] end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def build_good_method(method_name, column, value) if column.include?('.') diff --git a/lib/rubocop/cop/rails/where_not.rb b/lib/rubocop/cop/rails/where_not.rb index 96762f5e47..2b6300165e 100644 --- a/lib/rubocop/cop/rails/where_not.rb +++ b/lib/rubocop/cop/rails/where_not.rb @@ -68,6 +68,7 @@ def offense_range(node) range_between(node.loc.selector.begin_pos, node.source_range.end_pos) end + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def extract_column_and_value(template_node, value_node) value = case template_node.value @@ -84,8 +85,12 @@ def extract_column_and_value(template_node, value_node) return end - [Regexp.last_match(1), value] + column_qualifier = Regexp.last_match(1) + return if column_qualifier.count('.') > 1 + + [column_qualifier, value] end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def build_good_method(dot, column, value) dot ||= '.' diff --git a/lib/rubocop/cop/rails/where_range.rb b/lib/rubocop/cop/rails/where_range.rb index 4797a50e81..1c8fd4a0fb 100644 --- a/lib/rubocop/cop/rails/where_range.rb +++ b/lib/rubocop/cop/rails/where_range.rb @@ -140,6 +140,8 @@ def extract_column_and_value(template_node, values_node) rhs = pair2.value end end + else + return end if lhs @@ -150,7 +152,10 @@ def extract_column_and_value(template_node, values_node) rhs_source = parentheses_needed?(rhs) ? "(#{rhs.source})" : rhs.source end - [Regexp.last_match(1), "#{lhs_source}#{operator}#{rhs_source}"] if operator + column_qualifier = Regexp.last_match(1) + return if column_qualifier.count('.') > 1 + + [column_qualifier, "#{lhs_source}#{operator}#{rhs_source}"] if operator end # rubocop:enable Metrics diff --git a/lib/rubocop/rails/version.rb b/lib/rubocop/rails/version.rb index 438e0a2245..c77f1c36d1 100644 --- a/lib/rubocop/rails/version.rb +++ b/lib/rubocop/rails/version.rb @@ -4,7 +4,7 @@ module RuboCop module Rails # This module holds the RuboCop Rails version information. module Version - STRING = '2.26.0' + STRING = '2.26.1' def self.document_version STRING.match('\d+\.\d+').to_s diff --git a/relnotes/v2.26.1.md b/relnotes/v2.26.1.md new file mode 100644 index 0000000000..4a0505bc57 --- /dev/null +++ b/relnotes/v2.26.1.md @@ -0,0 +1,12 @@ +### Bug fixes + +* [#1343](https://github.com/rubocop/rubocop-rails/issues/1343): Fix false negatives for `Rails/EnumSyntax` for non-literal mappings. ([@earlopain][]) +* [#1340](https://github.com/rubocop/rubocop-rails/issues/1340): Fix a false positive for `Rails/WhereEquals`, `Rails/WhereNot`, and `Rails/WhereRange` when qualifying the database name. ([@earlopain][]) + +### Changes + +* [#1342](https://github.com/rubocop/rubocop-rails/issues/1342): Change `Rails/ApplicationRecord` to ignore migrations. ([@fatkodima][]) +* [#1350](https://github.com/rubocop/rubocop-rails/pull/1350): Change `Rails/EnumSyntax` to autocorrect underscored options. ([@fatkodima][]) + +[@earlopain]: https://github.com/earlopain +[@fatkodima]: https://github.com/fatkodima diff --git a/spec/rubocop/cop/rails/compact_blank_spec.rb b/spec/rubocop/cop/rails/compact_blank_spec.rb index 93d1ca2bd7..3b3cd9d77b 100644 --- a/spec/rubocop/cop/rails/compact_blank_spec.rb +++ b/spec/rubocop/cop/rails/compact_blank_spec.rb @@ -24,6 +24,17 @@ RUBY end + it 'registers and corrects an offense when using `reject { |k, v| v.blank? }`' do + expect_offense(<<~RUBY) + collection.reject { |k, v| v.blank? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + it 'registers and corrects an offense when using `delete_if { |e| e.blank? }`' do expect_offense(<<~RUBY) collection.delete_if { |e| e.blank? } @@ -46,6 +57,17 @@ RUBY end + it 'registers and corrects an offense when using `delete_if { |k, v| v.blank? }`' do + expect_offense(<<~RUBY) + collection.delete_if { |k, v| v.blank? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank!` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank! + RUBY + end + it 'does not registers an offense when using `reject! { |e| e.blank? }`' do expect_no_offenses(<<~RUBY) collection.reject! { |e| e.blank? } @@ -91,6 +113,17 @@ RUBY end + it 'registers and corrects an offense when using `select { |k, v| v.present? }`' do + expect_offense(<<~RUBY) + collection.select { |k, v| v.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank + RUBY + end + it 'registers and corrects an offense when using `keep_if { |e| e.present? }`' do expect_offense(<<~RUBY) collection.keep_if { |e| e.present? } @@ -113,6 +146,17 @@ RUBY end + it 'registers and corrects an offense when using `keep_if { |k, v| v.present? }`' do + expect_offense(<<~RUBY) + collection.keep_if { |k, v| v.present? } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `compact_blank!` instead. + RUBY + + expect_correction(<<~RUBY) + collection.compact_blank! + RUBY + end + it 'does not register an offense when using `select! { |e| e.present? }`' do expect_no_offenses(<<~RUBY) collection.select! { |e| e.present? } diff --git a/spec/rubocop/cop/rails/enum_syntax_spec.rb b/spec/rubocop/cop/rails/enum_syntax_spec.rb index 2abf4e47fa..9799fe66d1 100644 --- a/spec/rubocop/cop/rails/enum_syntax_spec.rb +++ b/spec/rubocop/cop/rails/enum_syntax_spec.rb @@ -47,12 +47,16 @@ end context 'with options prefixed with `_`' do - it 'registers an offense' do + it 'registers an offense and corrects' do expect_offense(<<~RUBY) enum :status, { active: 0, archived: 1 }, _prefix: true, _suffix: true ^^^^^^^ Enum defined with deprecated options in `status` enum declaration. Remove the `_` prefix. ^^^^^^^ Enum defined with deprecated options in `status` enum declaration. Remove the `_` prefix. RUBY + + expect_correction(<<~RUBY) + enum :status, { active: 0, archived: 1 }, prefix: true, suffix: true + RUBY end end @@ -82,6 +86,32 @@ end end + context 'when the enum name is underscored' do + it 'registers an offense' do + expect_offense(<<~RUBY) + enum :_key => { active: 0, archived: 1 }, _prefix: true + ^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum defined with keyword arguments in `_key` enum declaration. Use positional arguments instead. + RUBY + + expect_correction(<<~RUBY) + enum :_key, { active: 0, archived: 1 }, prefix: true + RUBY + end + end + + context 'when the enum value is not a literal' do + it 'registers an offense' do + expect_offense(<<~RUBY) + enum key: %i[foo bar].map.with_index { |v, i| [v, i] }.to_h + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum defined with keyword arguments in `key` enum declaration. Use positional arguments instead. + RUBY + + expect_correction(<<~RUBY) + enum :key, %i[foo bar].map.with_index { |v, i| [v, i] }.to_h + RUBY + end + end + it 'autocorrects' do expect_offense(<<~RUBY) enum status: { active: 0, archived: 1 } @@ -95,12 +125,12 @@ it 'autocorrects options too' do expect_offense(<<~RUBY) - enum status: { active: 0, archived: 1 }, _prefix: true, _suffix: true, _default: :active, _scopes: true + enum status: { active: 0, archived: 1 }, _prefix: true, _suffix: true, _default: :active, _scopes: true, _instance_methods: true ^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum defined with keyword arguments in `status` enum declaration. Use positional arguments instead. RUBY expect_correction(<<~RUBY) - enum :status, { active: 0, archived: 1 }, prefix: true, suffix: true, default: :active, scopes: true + enum :status, { active: 0, archived: 1 }, prefix: true, suffix: true, default: :active, scopes: true, instance_methods: true RUBY end end diff --git a/spec/rubocop/cop/rails/root_pathname_methods_spec.rb b/spec/rubocop/cop/rails/root_pathname_methods_spec.rb index 04b9508073..82f00ea5da 100644 --- a/spec/rubocop/cop/rails/root_pathname_methods_spec.rb +++ b/spec/rubocop/cop/rails/root_pathname_methods_spec.rb @@ -12,7 +12,7 @@ it "registers an offense when using `#{receiver}.#{method}(Rails.public_path)` (if arity exists)" do expect_offense(<<~RUBY, receiver: receiver, method: method) %{receiver}.%{method}(Rails.public_path) - ^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^ `Rails.public_path` is a `Pathname` so you can just append `#%{method}`. + ^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^ `Rails.public_path` is a `Pathname`, so you can use `Rails.public_path.%{method}`. RUBY expect_correction(<<~RUBY) @@ -23,7 +23,7 @@ it "registers an offense when using `::#{receiver}.#{method}(::Rails.root.join(...))` (if arity exists)" do expect_offense(<<~RUBY, receiver: receiver, method: method) ::%{receiver}.%{method}(::Rails.root.join('db', 'schema.rb')) - ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname` so you can just append `#%{method}`. + ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname`, so you can use `::Rails.root.join('db', 'schema.rb').%{method}`. RUBY expect_correction(<<~RUBY) @@ -34,7 +34,7 @@ it "registers an offense when using `::#{receiver}.#{method}(::Rails.root.join(...), ...)` (if arity exists)" do expect_offense(<<~RUBY, receiver: receiver, method: method) ::%{receiver}.%{method}(::Rails.root.join('db', 'schema.rb'), 20, 5) - ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname` so you can just append `#%{method}`. + ^^^{receiver}^^{method}^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `::Rails.root` is a `Pathname`, so you can use `::Rails.root.join('db', 'schema.rb').%{method}(20, 5)`. RUBY expect_correction(<<~RUBY) @@ -56,7 +56,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**/*.rb'))`" do expect_offense(<<~RUBY) Dir.glob(Rails.root.join('**/*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -67,7 +67,7 @@ it "registers an offense when using `::Dir.glob(Rails.root.join('**/*.rb'))`" do expect_offense(<<~RUBY) ::Dir.glob(Rails.root.join('**/*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -78,7 +78,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**/\#{path}/*.rb'))`" do expect_offense(<<~'RUBY') Dir.glob(Rails.root.join("**/#{path}/*.rb")) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("**/#{path}/*.rb")`. RUBY expect_correction(<<~'RUBY') @@ -89,7 +89,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**', '*.rb'))`" do expect_offense(<<~RUBY) Dir.glob(Rails.root.join('**', '*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -105,7 +105,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**', '*.rb'))`" do expect_offense(<<~RUBY) Dir.glob(Rails.root.join('**', '*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("**/*.rb")`. RUBY expect_correction(<<~RUBY) @@ -117,7 +117,7 @@ it "registers an offense when using `Dir.glob(Rails.root.join('**', \"\#{path}\", '*.rb'))`" do expect_offense(<<~'RUBY') Dir.glob(Rails.root.join('**', "#{path}", '*.rb')) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("**/#{path}/*.rb")`. RUBY expect_correction(<<~'RUBY') @@ -128,7 +128,7 @@ it 'registers an offense when using `Rails.env` argument within `Dir.glob`' do expect_offense(<<~RUBY) Dir.glob(Rails.root.join("db", "seeds", Rails.env, "*.rb")).sort.each do |file| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#glob`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob("db/seeds/\#{Rails.env}/*.rb")`. load file end RUBY @@ -145,7 +145,7 @@ it 'registers offense when using `Dir[Rails.root.join(...)]`' do expect_offense(<<~RUBY) Dir[Rails.root.join('spec/support/**/*.rb')] - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#[]`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.glob('spec/support/**/*.rb')`. RUBY expect_correction(<<~RUBY) @@ -192,7 +192,7 @@ it 'registers an offense when using `File.open(Rails.root.join(...), ...)` inside an iterator' do expect_offense(<<~RUBY) files.map { |file| File.open(Rails.root.join('db', file), 'wb') } - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#open`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join('db', file).open('wb')`. RUBY expect_correction(<<~RUBY) @@ -203,7 +203,7 @@ it 'registers an offense when using `File.open Rails.root.join ...` without parens' do expect_offense(<<~RUBY) file = File.open Rails.root.join 'docs', 'invoice.pdf' - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname` so you can just append `#open`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rails.root` is a `Pathname`, so you can use `Rails.root.join('docs', 'invoice.pdf').open`. RUBY expect_correction(<<~RUBY) diff --git a/spec/rubocop/cop/rails/where_equals_spec.rb b/spec/rubocop/cop/rails/where_equals_spec.rb index 1af170ebff..5c564a72e7 100644 --- a/spec/rubocop/cop/rails/where_equals_spec.rb +++ b/spec/rubocop/cop/rails/where_equals_spec.rb @@ -217,4 +217,10 @@ users.not('name = ?', 'Gabe') RUBY end + + it 'does not register an offense when qualifying the database' do + expect_no_offenses(<<~RUBY) + User.where('database.users.name = ?', 'Gabe') + RUBY + end end diff --git a/spec/rubocop/cop/rails/where_not_spec.rb b/spec/rubocop/cop/rails/where_not_spec.rb index 84d8aeded0..36e1ecca54 100644 --- a/spec/rubocop/cop/rails/where_not_spec.rb +++ b/spec/rubocop/cop/rails/where_not_spec.rb @@ -275,4 +275,10 @@ User.where('name <> ? AND age <> ?', 'john', 19) RUBY end + + it 'does not register an offense when qualifying the database' do + expect_no_offenses(<<~RUBY) + User.where('database.users.name != ?', 'Gabe') + RUBY + end end diff --git a/spec/rubocop/cop/rails/where_range_spec.rb b/spec/rubocop/cop/rails/where_range_spec.rb index 6a5a7b3353..4102fee308 100644 --- a/spec/rubocop/cop/rails/where_range_spec.rb +++ b/spec/rubocop/cop/rails/where_range_spec.rb @@ -221,6 +221,12 @@ Model.where(column: ...value) RUBY end + + it 'does not register an offense when qualifying the database' do + expect_no_offenses(<<~RUBY) + Model.where('database.table.column >= ?', value) + RUBY + end end end end