Class: RuboCop::Cop::Momocop::FactoryBotPropertyOrder

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
Momocop::Helpers::FactoryBotHelper, RangeHelp, Sevencop::CopConcerns::Ordered
Defined in:
lib/rubocop/cop/momocop/factory_bot_property_order.rb

Overview

Ensures that FactoryBot factories has ordered property definitions.

  1. Associations should be defined before other properties.

  2. Associations and properties should be defined in alphabetical order.

Examples:

# bad
factory :user, class: 'User' do
  address { '123 Main St' }
  association :profile
end

# good
factory :user, class: 'User' do
  association :profile
  address { '123 Main St' }
end

# bad
factory :user, class: 'User' do
  association :profile
  association :account
  zipcode { '111-1111' }
  address { '123 Main St' }
end

# good
factory :user, class: 'User' do
  association :account
  association :profile
  address { '123 Main St' }
  zipcode { '111-1111' }
end

Constant Summary collapse

MSG =
'Sort properties and associations alphabetically.'
RESTRICT_ON_SEND =
%i[factory].freeze

Constants included from Momocop::Helpers::FactoryBotHelper

Momocop::Helpers::FactoryBotHelper::RUBOCOP_HELPER_METHODS

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rubocop/cop/momocop/factory_bot_property_order.rb', line 48

def on_send(node)
  return unless inside_factory_bot_define?(node)

  block_node = node.block_node
  return unless block_node

  entire_definitions = defined_properties(block_node)

  sections =
    entire_definitions
    .slice_when { |a, b|
      (range_with_comments(b).first_line - range_with_comments(a).last_line) > 1
    }
    .select { |definitions| definitions.size >= 2 }

  sections.each do |definitions|
    add_offense(definitions.last) do |corrector|
      (a, b) =
        definitions
        .lazy
        .each_cons(2)
        .find { |a, b| (order(a) <=> order(b)) == 1 }

      break unless a && b

      swap(
        range_with_comments_and_lines(a),
        range_with_comments_and_lines(b),
        corrector:
      )
    end
  end
end