class RuboCop::Cop::RSpec::FilePath


my_class_spec.rb # describe MyClass, ‘#method’
# good
my_class_spec.rb # describe MyClass
# good
whatever_spec.rb # describe MyClass
# good
@example when configuration is ‘SpecSuffixOnly: true`
my_class_spec.rb # describe MyClass, ’#method’
# good
my_class_spec.rb # describe MyClass
# good
whatever_spec.rb # describe MyClass
# bad
@example when configuration is ‘IgnoreMethods: true`
my_class/method_spec.rb # describe MyClass, ’#method’
# good
my_class_method_spec.rb # describe MyClass, ‘#method’
# good
my_class_spec.rb # describe MyClass
# good
my_class_spec.rb # describe MyClass, ‘#method’
# bad
whatever_spec.rb # describe MyClass
# bad
@example
checking for consistency in the test subject or test methods.
be checked to ensure they end in ‘_spec.rb’. This option disables
With the configuration option ‘SpecSuffixOnly` test files will only
snake_case (e.g. ’RuboCop’ => ‘rubocop’ ).
be specified that should not as usual be transformed from CamelCase to
With the configuration option ‘CustomTransform` modules or classes can
be ignored when determining the enforced path.
With the configuration option `IgnoreMethods` the called out method will
class/module and its optionally called out method.
test subject and and enforces that it reflects the described
By default, this checks that spec file paths are consistent with the
Checks that spec file paths are consistent and well-formed.

def camel_to_snake_case(string)

def camel_to_snake_case(string)
  string
    .gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
    .gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
    .downcase
end

def custom_transform

def custom_transform
  cop_config.fetch('CustomTransform', {})
end

def ensure_correct_file_path(send_node, example_group, arguments)

def ensure_correct_file_path(send_node, example_group, arguments)
  pattern = pattern_for(example_group, arguments.first)
  return if filename_ends_with?(pattern)
  # For the suffix shown in the offense message, modify the regular
  # expression pattern to resemble a glob pattern for clearer error
  # messages.
  offense_suffix = pattern.gsub('.*', '*').sub('[^/]', '')
    .sub('\.', '.')
  add_offense(send_node, message: format(MSG, suffix: offense_suffix))
end

def expected_path(constant)

def expected_path(constant)
  File.join(
    constant.const_name.split('::').map do |name|
      custom_transform.fetch(name) { camel_to_snake_case(name) }
    end
  )
end

def filename_ends_with?(pattern)

def filename_ends_with?(pattern)
  filename = File.expand_path(processed_source.buffer.name)
  filename.match?("#{pattern}$")
end

def ignore_methods?

def ignore_methods?
  cop_config['IgnoreMethods']
end

def name_pattern(method_name)

def name_pattern(method_name)
  return unless method_name&.str_type?
  ".*#{method_name.str_content.gsub(/\W/, '')}" unless ignore_methods?
end

def on_top_level_example_group(node)

def on_top_level_example_group(node)
  return unless top_level_groups.one?
  example_group(node) do |send_node, example_group, arguments|
    next if routing_spec?(arguments)
    ensure_correct_file_path(send_node, example_group, arguments)
  end
end

def pattern_for(example_group, method_name)

def pattern_for(example_group, method_name)
  if spec_suffix_only? || !example_group.const_type?
    return pattern_for_spec_suffix_only?
  end
  [
    expected_path(example_group),
    name_pattern(method_name),
    '[^/]*_spec\.rb'
  ].join
end

def pattern_for_spec_suffix_only?

def pattern_for_spec_suffix_only?
  '.*_spec\.rb'
end

def relevant_rubocop_rspec_file?(_file)

def relevant_rubocop_rspec_file?(_file)
  true
end

def routing_spec?(args)

def routing_spec?(args)
  args.any?(&method(:routing_metadata?))
end

def spec_suffix_only?

def spec_suffix_only?
  cop_config['SpecSuffixOnly']
end