forked from rubocop/rubocop-rspec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_path.rb
74 lines (61 loc) · 2.13 KB
/
file_path.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# encoding: utf-8
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# 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 `CustomTransform` modules or clases can be
# specified that should not as usual be transformed from CamelCase to
# snake_case (e.g. 'RuboCop' => 'rubocop' ).
#
# @example
# my_class/method_spec.rb # describe MyClass, '#method'
# my_class_method_spec.rb # describe MyClass, '#method'
# my_class_spec.rb # describe MyClass
class FilePath < Cop
include RuboCop::RSpec::TopLevelDescribe
MESSAGE = 'Spec path should end with `%s`'
METHOD_STRING_MATCHER = /^[\#\.].+/
def on_top_level_describe(node, args)
return unless single_top_level_describe?
object = args.first.const_name
return unless object
path_matcher = matcher(object, args[1])
return if source_filename =~ regexp_from_glob(path_matcher)
add_offense(node, :expression, format(MESSAGE, path_matcher))
end
private
def matcher(object, method)
path = File.join(parts(object))
if method && method.type == :str
path += '*' + method.children.first.gsub(/\W+/, '')
end
"#{path}*_spec.rb"
end
def parts(object)
object.split('::').map do |p|
custom_transform[p] || camel_to_underscore(p)
end
end
def source_filename
processed_source.buffer.name
end
def camel_to_underscore(string)
string.dup.tap do |result|
result.gsub!(/([^A-Z])([A-Z]+)/, '\\1_\\2')
result.gsub!(/([A-Z])([A-Z][^A-Z]+)/, '\\1_\\2')
result.downcase!
end
end
def regexp_from_glob(glob)
Regexp.new(glob.gsub('.', '\\.').gsub('*', '.*') + '$')
end
def custom_transform
cop_config['CustomTransform'] || []
end
end
end
end
end