class RuboCop::Cop::RSpec::SpecFilePathFormat


# The default is ./config/initializers/inflections.rb.
# Configure ‘InflectorPath` with the path to the inflector file.
# like HTTP, etc. Set to “default” by default.
# Enable to use ActiveSupport’s inflector for custom acronyms
@example ‘EnforcedInflector: active_support`
whatever_spec.rb # describe MyClass, type: :routing do; end
# good
@example `IgnoreMetadata: {type=>routing}` (default)
my_class_spec.rb # describe MyClass, ’#method’
# good
@example ‘IgnoreMethods: true`
my_class_spec.rb # describe MyClass, ’#method’
# bad
@example ‘IgnoreMethods: false` (default)
rspec_spec.rb # describe RSpec
rubocop_spec.rb # describe RuboCop
# good
@example `CustomTransform: {RuboCop=>rubocop, RSpec=>rspec}` (default)
my_class/method_spec.rb # describe MyClass, ’#method’
my_class_method_spec.rb # describe MyClass, ‘#method’
my_class_spec.rb # describe MyClass
# good
my_class_spec.rb # describe MyClass, ‘#method’
whatever_spec.rb # describe MyClass
# bad
@example
Checks that spec file paths are consistent and well-formed.

def camel_to_snake_case(string)

def camel_to_snake_case(string)
  inflector.call(string)
end

def correct_path_pattern(class_name, arguments)

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

def custom_transform

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

def ensure_correct_file_path(send_node, class_name, arguments)

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

def expected_path(constant)

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

def filename_ends_with?(pattern)

def filename_ends_with?(pattern)
  expanded_file_path.match?("#{pattern}$")
end

def ignore?(method_name)

def ignore?(method_name)
  !method_name&.str_type? || ignore_methods?
end

def ignore_metadata

def ignore_metadata
  cop_config.fetch('IgnoreMetadata', {})
end

def ignore_metadata?(arguments)

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

def ignore_methods?

def ignore_methods?
  cop_config['IgnoreMethods']
end

def inflector

def inflector
  case cop_config.fetch('EnforcedInflector')
  when 'active_support'
    ActiveSupportInflector.prepare_availability(cop_config)
    ActiveSupportInflector
  when 'default'
    DefaultInflector
  else
    # :nocov:
    :noop
    # :nocov:
  end
end

def name_pattern(method_name)

def name_pattern(method_name)
  return if ignore?(method_name)
  method_name.str_content.gsub(/\s/, '_').gsub(/\W/, '')
end

def on_top_level_example_group(node)

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