class RuboCop::Cop::RSpec::FactoryBot::CreateList
3.times { create :user }
# good
create_list :user, 3
# bad
@example ‘EnforcedStyle: n_times`
3.times { |n| create :user, created_at: n.months.ago }
# good
create_list :user, 3
# good
3.times { create :user }
# bad
@example `EnforcedStyle: create_list`
This cop can be configured using the `EnforcedStyle` option
Checks for create_list usage.
def autocorrect(node)
def autocorrect(node) if style == :create_list autocorrect_n_times_to_create_list(node) else autocorrect_create_list_to_n_times(node) end end
def autocorrect_create_list_to_n_times(node)
def autocorrect_create_list_to_n_times(node) replacement = generate_n_times_block(node) lambda do |corrector| corrector.replace(node.loc.expression, replacement) end end
def autocorrect_n_times_to_create_list(node)
def autocorrect_n_times_to_create_list(node) block = node.parent count = block.receiver.source replacement = factory_call_replacement(block.body, count) lambda do |corrector| corrector.replace(block.loc.expression, replacement) end end
def build_options_string(options)
def build_options_string(options) options.map(&:source).join(', ') end
def contains_only_factory?(node)
def contains_only_factory?(node) if node.block_type? factory_call(node.send_node) else factory_call(node) end end
def factory_call_replacement(body, count)
def factory_call_replacement(body, count) receiver, factory, options = *factory_call(body) arguments = ":#{factory}, #{count}" options = build_options_string(options) arguments += ", #{options}" unless options.empty? replacement = format_receiver(receiver) replacement += format_method_call(body, 'create_list', arguments) replacement end
def format_method_call(node, method, arguments)
def format_method_call(node, method, arguments) if node.parenthesized? "#{method}(#{arguments})" else "#{method} #{arguments}" end end
def format_receiver(receiver)
def format_receiver(receiver) return '' unless receiver "#{receiver.source}." end
def generate_n_times_block(node)
def generate_n_times_block(node) receiver, factory, count, options = *factory_list_call(node) arguments = ":#{factory}" options = build_options_string(options) arguments += ", #{options}" unless options.empty? replacement = format_receiver(receiver) replacement += format_method_call(node, 'create', arguments) "#{count}.times { #{replacement} }" end
def on_block(node)
def on_block(node) return unless style == :create_list return unless n_times_block_without_arg?(node) return unless contains_only_factory?(node.body) add_offense(node.send_node, location: :expression, message: MSG_CREATE_LIST) end
def on_send(node)
def on_send(node) return unless style == :n_times factory_list_call(node) do |_receiver, _factory, count, _| add_offense( node, location: :selector, message: format(MSG_N_TIMES, number: count) ) end end