class RuboCop::Cop::RSpec::FilePath
Checks that spec file paths are consistent with the test subject.
Checks the path of the spec file and enforces that it reflects the described class/module and its optionally called out method.
With the configuration option `IgnoreMethods` the called out method will be ignored when determining the enforced path.
With the configuration option `CustomTransform` modules or classes can be specified that should not as usual be transformed from CamelCase to snake_case (e.g. 'RuboCop' => 'rubocop' ).
@example
# bad whatever_spec.rb # describe MyClass # bad my_class_spec.rb # describe MyClass, '#method' # good my_class_spec.rb # describe MyClass # good my_class_method_spec.rb # describe MyClass, '#method' # good my_class/method_spec.rb # describe MyClass, '#method'
@example when configuration is `IgnoreMethods: true`
# bad whatever_spec.rb # describe MyClass # good my_class_spec.rb # describe MyClass # good my_class_spec.rb # describe MyClass, '#method'
Constants
- MSG
Public Instance Methods
on_top_level_describe(node, args)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 52 def on_top_level_describe(node, args) return unless const_described?(node) && single_top_level_describe? return if routing_spec?(args) glob = glob_for(args) return if filename_ends_with?(glob) add_offense(node, location: :expression, message: format(MSG, glob)) end
Private Instance Methods
camel_to_snake_case(string)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 87 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
custom_transform()
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 94 def custom_transform cop_config.fetch('CustomTransform', {}) end
expected_path(constant)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 79 def expected_path(constant) File.join( constant.const_name.split('::').map do |name| custom_transform.fetch(name) { camel_to_snake_case(name) } end ) end
filename_ends_with?(glob)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 102 def filename_ends_with?(glob) File.fnmatch?("*#{glob}", processed_source.buffer.name) end
glob_for((described_class, method_name))
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 69 def glob_for((described_class, method_name)) "#{expected_path(described_class)}#{name_glob(method_name)}*_spec.rb" end
ignore_methods?()
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 98 def ignore_methods? cop_config['IgnoreMethods'] end
name_glob(name)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 73 def name_glob(name) return unless name && name.str_type? "*#{name.str_content.gsub(/\W/, '')}" unless ignore_methods? end
relevant_rubocop_rspec_file?(_)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 106 def relevant_rubocop_rspec_file?(_) true end
routing_spec?(args)
click to toggle source
# File lib/rubocop/cop/rspec/file_path.rb, line 65 def routing_spec?(args) args.any?(&method(:routing_metadata?)) end