class RuboCop::Cop::RSpec::SpecFilePathFormat

Checks that spec file paths are consistent and well-formed.

@example

# bad
whatever_spec.rb         # describe MyClass
my_class_spec.rb         # describe MyClass, '#method'

# good
my_class_spec.rb         # describe MyClass
my_class_method_spec.rb  # describe MyClass, '#method'
my_class/method_spec.rb  # describe MyClass, '#method'

@example ‘CustomTransform: {RuboCop=>rubocop, RSpec=>rspec}` (default)

# good
rubocop_spec.rb          # describe RuboCop
rspec_spec.rb            # describe RSpec

@example ‘IgnoreMethods: false` (default)

# bad
my_class_spec.rb         # describe MyClass, '#method'

@example ‘IgnoreMethods: true`

# good
my_class_spec.rb         # describe MyClass, '#method'

@example ‘IgnoreMetadata: {type=>routing}` (default)

# good
whatever_spec.rb         # describe MyClass, type: :routing do; end

Constants

MSG

Public Instance Methods

on_top_level_example_group(node) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 50
def on_top_level_example_group(node)
  return unless top_level_groups.one?

  example_group_arguments(node) do |send_node, class_name, arguments|
    next if !class_name.const_type? || ignore_metadata?(arguments)

    ensure_correct_file_path(send_node, class_name, arguments)
  end
end

Private Instance Methods

camel_to_snake_case(string) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 108
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
correct_path_pattern(class_name, arguments) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 81
def correct_path_pattern(class_name, arguments)
  path = [expected_path(class_name)]
  path << '.*' unless ignore?(arguments.first)
  path << [name_pattern(arguments.first), '[^/]*_spec\.rb']
  path.join
end
custom_transform() click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 115
def custom_transform
  cop_config.fetch('CustomTransform', {})
end
ensure_correct_file_path(send_node, class_name, arguments) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 62
def ensure_correct_file_path(send_node, class_name, arguments)
  pattern = correct_path_pattern(class_name, arguments)
  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.
  suffix = pattern.sub('.*', '*').sub('[^/]*', '*').sub('\.', '.')
  add_offense(send_node, message: format(MSG, suffix: suffix))
end
expected_path(constant) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 98
def expected_path(constant)
  constants = namespace(constant) + constant.const_name.split('::')

  File.join(
    constants.map do |name|
      custom_transform.fetch(name) { camel_to_snake_case(name) }
    end
  )
end
filename_ends_with?(pattern) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 127
def filename_ends_with?(pattern)
  expanded_file_path.match?("#{pattern}$")
end
ignore?(method_name) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 94
def ignore?(method_name)
  !method_name&.str_type? || ignore_methods?
end
ignore_metadata() click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 123
def ignore_metadata
  cop_config.fetch('IgnoreMetadata', {})
end
ignore_metadata?(arguments) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 73
def ignore_metadata?(arguments)
  arguments.any? do |argument|
    metadata_key_value(argument).any? do |key, value|
      ignore_metadata.values_at(key.to_s).include?(value.to_s)
    end
  end
end
ignore_methods?() click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 119
def ignore_methods?
  cop_config['IgnoreMethods']
end
name_pattern(method_name) click to toggle source
# File lib/rubocop/cop/rspec/spec_file_path_format.rb, line 88
def name_pattern(method_name)
  return if ignore?(method_name)

  method_name.str_content.gsub(/\s/, '_').gsub(/\W/, '')
end