Class: RuboCop::Cop::RSpec::FactoryBot::CreateList

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
ConfigurableEnforcedStyle, RSpec::FactoryBot::Language
Defined in:
lib/rubocop/cop/rspec/factory_bot/create_list.rb

Overview

Checks for create_list usage.

This cop can be configured using the ‘EnforcedStyle` option

Examples:

‘EnforcedStyle: create_list` (default)

# bad
3.times { create :user }

# good
create_list :user, 3

# bad
3.times { create :user, age: 18 }

# good - index is used to alter the created models attributes
3.times { |n| create :user, age: n }

# good - contains a method call, may return different values
3.times { create :user, age: rand }

‘EnforcedStyle: n_times`

# bad
create_list :user, 3

# good
3.times { create :user }

Defined Under Namespace

Modules: Corrector Classes: CreateListCorrector, TimesCorrector

Constant Summary collapse

MSG_CREATE_LIST =
'Prefer create_list.'
MSG_N_TIMES =
'Prefer %<number>s.times.'
RESTRICT_ON_SEND =
%i[create_list].freeze

Constants included from RSpec::FactoryBot::Language

RSpec::FactoryBot::Language::METHODS

Instance Method Summary collapse

Methods included from RSpec::FactoryBot::Language

#factory_bot?

Methods inherited from Base

inherited, #on_new_investigation

Methods included from RSpec::Language::NodePattern

#block_pattern, #numblock_pattern, #send_pattern

Methods included from RSpec::Language

#example?, #example_group?, #example_group_with_body?, #hook?, #include?, #let?, #rspec?, #shared_group?, #spec_group?, #subject?

Instance Method Details

#arguments_include_method_call?(node) ⇒ Object



64
65
66
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 64

def_node_matcher :arguments_include_method_call?, <<-PATTERN
  (send ${nil? #factory_bot?} :create (sym $_) `$(send ...))
PATTERN

#array_new_or_n_times_block?(node) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 44

def_node_matcher :array_new_or_n_times_block?, <<-PATTERN
  (block
    {
      (send (const {nil? | cbase} :Array) :new (int _)) |
      (send (int _) :times)
    }
    ...
  )
PATTERN

#block_with_arg_and_used?(node) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 55

def_node_matcher :block_with_arg_and_used?, <<-PATTERN
  (block
    _
    (args (arg _value))
    `_value
  )
PATTERN

#factory_call(node) ⇒ Object



69
70
71
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 69

def_node_matcher :factory_call, <<-PATTERN
  (send ${nil? #factory_bot?} :create (sym $_) $...)
PATTERN

#factory_list_call(node) ⇒ Object



74
75
76
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 74

def_node_matcher :factory_list_call, <<-PATTERN
  (send {nil? #factory_bot?} :create_list (sym _) (int $_) ...)
PATTERN

#on_block(node) ⇒ Object

rubocop:todo InternalAffairs/NumblockHandler



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 78

def on_block(node) # rubocop:todo InternalAffairs/NumblockHandler
  return unless style == :create_list

  return unless array_new_or_n_times_block?(node)
  return if block_with_arg_and_used?(node)
  return unless node.body
  return if arguments_include_method_call?(node.body)
  return unless contains_only_factory?(node.body)

  add_offense(node.send_node, message: MSG_CREATE_LIST) do |corrector|
    CreateListCorrector.new(node.send_node).call(corrector)
  end
end

#on_send(node) ⇒ Object



92
93
94
95
96
97
98
99
100
101
# File 'lib/rubocop/cop/rspec/factory_bot/create_list.rb', line 92

def on_send(node)
  return unless style == :n_times

  factory_list_call(node) do |count|
    message = format(MSG_N_TIMES, number: count)
    add_offense(node.loc.selector, message: message) do |corrector|
      TimesCorrector.new(node).call(corrector)
    end
  end
end