rubocop-rspec 0.18.1 → 1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/Gemfile.lock +10 -8
- data/README.md +19 -0
- data/config/default.yml +27 -5
- data/lib/rubocop-rspec.rb +9 -4
- data/lib/rubocop/cop/rspec_describe_class.rb +28 -0
- data/lib/rubocop/cop/rspec_describe_method.rb +35 -0
- data/lib/rubocop/cop/rspec_described_class.rb +56 -0
- data/lib/rubocop/cop/rspec_example_wording.rb +33 -0
- data/lib/rubocop/cop/rspec_file_name.rb +59 -0
- data/lib/rubocop/cop/rspec_instance_variable.rb +39 -0
- data/lib/rubocop/cop/rspec_multiple_describes.rb +35 -0
- data/lib/rubocop/rspec/top_level_describe.rb +59 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- data/pkg/rubocop-rspec-0.18.1.gem +0 -0
- data/pkg/rubocop-rspec-1.0.rc1.gem +0 -0
- data/rubocop-rspec.gemspec +3 -3
- data/spec/rubocop/cop/rspec_describe_class_spec.rb +36 -0
- data/spec/rubocop/cop/rspec_describe_method_spec.rb +22 -0
- data/spec/rubocop/cop/rspec_described_class_spec.rb +113 -0
- data/spec/rubocop/cop/rspec_example_wording_spec.rb +23 -0
- data/spec/rubocop/cop/rspec_file_name_spec.rb +122 -0
- data/spec/rubocop/cop/rspec_instance_variable_spec.rb +32 -0
- data/spec/rubocop/cop/rspec_multiple_describes_spec.rb +32 -0
- metadata +38 -9
- data/lib/rubocop/cop/rspec/unit_spec_naming.rb +0 -144
- data/spec/rubocop/cop/rspec/unit_spec_naming_spec.rb +0 -137
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Rubocop::Cop::RSpecMultipleDescribes do
|
6
|
+
subject(:cop) { described_class.new }
|
7
|
+
|
8
|
+
it 'finds multiple top level describes with class and method' do
|
9
|
+
inspect_source(cop, ["describe MyClass, '.do_something' do; end",
|
10
|
+
"describe MyClass, '.do_something_else' do; end"])
|
11
|
+
expect(cop.offenses.size).to eq(1)
|
12
|
+
expect(cop.offenses.map(&:line).sort).to eq([1])
|
13
|
+
expect(cop.messages).to eq(['Do not use multiple top level describes - ' \
|
14
|
+
'try to nest them.'])
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'finds multiple top level describes only with class' do
|
18
|
+
inspect_source(cop, ['describe MyClass do; end',
|
19
|
+
'describe MyOtherClass do; end'])
|
20
|
+
expect(cop.offenses.size).to eq(1)
|
21
|
+
expect(cop.offenses.map(&:line).sort).to eq([1])
|
22
|
+
expect(cop.messages).to eq(['Do not use multiple top level describes - ' \
|
23
|
+
'try to nest them.'])
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'skips single top level describe' do
|
27
|
+
inspect_source(cop, ["require 'spec_helper'",
|
28
|
+
'',
|
29
|
+
'describe MyClass do; end'])
|
30
|
+
expect(cop.offenses).to be_empty
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian MacLeod
|
8
|
+
- Nils Gemeinhardt
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-
|
12
|
+
date: 2014-05-18 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rubocop
|
@@ -16,25 +17,33 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - ~>
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
20
|
+
version: '0.19'
|
21
|
+
- - '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0.19'
|
20
24
|
type: :runtime
|
21
25
|
prerelease: false
|
22
26
|
version_requirements: !ruby/object:Gem::Requirement
|
23
27
|
requirements:
|
24
28
|
- - ~>
|
25
29
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
30
|
+
version: '0.19'
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.19'
|
27
34
|
description: |2
|
28
35
|
Code style checking for RSpec files.
|
29
36
|
A plugin for the RuboCop code style enforcing & linting tool.
|
30
37
|
email:
|
31
38
|
- ian@nevir.net
|
39
|
+
- git@nilsgemeinhardt.de
|
32
40
|
executables: []
|
33
41
|
extensions: []
|
34
42
|
extra_rdoc_files:
|
35
43
|
- MIT-LICENSE.md
|
36
44
|
- README.md
|
37
45
|
files:
|
46
|
+
- CHANGELOG.md
|
38
47
|
- config/default.yml
|
39
48
|
- coverage/assets/0.8.0/application.css
|
40
49
|
- coverage/assets/0.8.0/application.js
|
@@ -63,8 +72,15 @@ files:
|
|
63
72
|
- coverage/index.html
|
64
73
|
- Gemfile
|
65
74
|
- Gemfile.lock
|
66
|
-
- lib/rubocop/cop/
|
75
|
+
- lib/rubocop/cop/rspec_describe_class.rb
|
76
|
+
- lib/rubocop/cop/rspec_describe_method.rb
|
77
|
+
- lib/rubocop/cop/rspec_described_class.rb
|
78
|
+
- lib/rubocop/cop/rspec_example_wording.rb
|
79
|
+
- lib/rubocop/cop/rspec_file_name.rb
|
80
|
+
- lib/rubocop/cop/rspec_instance_variable.rb
|
81
|
+
- lib/rubocop/cop/rspec_multiple_describes.rb
|
67
82
|
- lib/rubocop/rspec/inject.rb
|
83
|
+
- lib/rubocop/rspec/top_level_describe.rb
|
68
84
|
- lib/rubocop/rspec/version.rb
|
69
85
|
- lib/rubocop-rspec.rb
|
70
86
|
- MIT-LICENSE.md
|
@@ -72,10 +88,17 @@ files:
|
|
72
88
|
- pkg/rubocop-rspec-0.17.0.gem
|
73
89
|
- pkg/rubocop-rspec-0.18.0.gem
|
74
90
|
- pkg/rubocop-rspec-0.18.1.gem
|
91
|
+
- pkg/rubocop-rspec-1.0.rc1.gem
|
75
92
|
- Rakefile
|
76
93
|
- README.md
|
77
94
|
- rubocop-rspec.gemspec
|
78
|
-
- spec/rubocop/cop/
|
95
|
+
- spec/rubocop/cop/rspec_describe_class_spec.rb
|
96
|
+
- spec/rubocop/cop/rspec_describe_method_spec.rb
|
97
|
+
- spec/rubocop/cop/rspec_described_class_spec.rb
|
98
|
+
- spec/rubocop/cop/rspec_example_wording_spec.rb
|
99
|
+
- spec/rubocop/cop/rspec_file_name_spec.rb
|
100
|
+
- spec/rubocop/cop/rspec_instance_variable_spec.rb
|
101
|
+
- spec/rubocop/cop/rspec_multiple_describes_spec.rb
|
79
102
|
- spec/spec_helper.rb
|
80
103
|
homepage: http://github.com/nevir/rubocop-rspec
|
81
104
|
licenses:
|
@@ -92,9 +115,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
115
|
version: 1.9.2
|
93
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
117
|
requirements:
|
95
|
-
- - '
|
118
|
+
- - '>'
|
96
119
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
120
|
+
version: 1.3.1
|
98
121
|
requirements: []
|
99
122
|
rubyforge_project:
|
100
123
|
rubygems_version: 2.0.3
|
@@ -102,5 +125,11 @@ signing_key:
|
|
102
125
|
specification_version: 4
|
103
126
|
summary: Code style checking for RSpec files
|
104
127
|
test_files:
|
105
|
-
- spec/rubocop/cop/
|
128
|
+
- spec/rubocop/cop/rspec_describe_class_spec.rb
|
129
|
+
- spec/rubocop/cop/rspec_describe_method_spec.rb
|
130
|
+
- spec/rubocop/cop/rspec_described_class_spec.rb
|
131
|
+
- spec/rubocop/cop/rspec_example_wording_spec.rb
|
132
|
+
- spec/rubocop/cop/rspec_file_name_spec.rb
|
133
|
+
- spec/rubocop/cop/rspec_instance_variable_spec.rb
|
134
|
+
- spec/rubocop/cop/rspec_multiple_describes_spec.rb
|
106
135
|
- spec/spec_helper.rb
|
@@ -1,144 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Rubocop
|
4
|
-
module Cop
|
5
|
-
module RSpec
|
6
|
-
# This cop checks that RSpec unit tests conform to a consistent naming
|
7
|
-
# scheme - both for the describe call, and the file path.
|
8
|
-
#
|
9
|
-
# Disabled by default. Generally, you want to scope it to your project's
|
10
|
-
# unit spec paths:
|
11
|
-
#
|
12
|
-
# UnitSpecNaming:
|
13
|
-
# Enabled: true
|
14
|
-
# Include:
|
15
|
-
# - 'spec/rubocop/*'
|
16
|
-
#
|
17
|
-
class UnitSpecNaming < Cop
|
18
|
-
DESCRIBE_CLASS_MSG = 'The first argument to describe should be the ' \
|
19
|
-
'class or module being tested.'
|
20
|
-
|
21
|
-
METHOD_STRING_MSG = 'The second argument to describe should be the ' \
|
22
|
-
"method being tested. '#instance' or '.class'"
|
23
|
-
|
24
|
-
CLASS_SPEC_MSG = 'Class unit spec should have a path ending with %s'
|
25
|
-
|
26
|
-
METHOD_SPEC_MSG = 'Unit spec should have a path matching %s'
|
27
|
-
|
28
|
-
METHOD_STRING_MATCHER = /^[\#\.].+/
|
29
|
-
|
30
|
-
def on_send(node)
|
31
|
-
return unless top_level_describe? node
|
32
|
-
_receiver, _method_name, *args = *node
|
33
|
-
# Ignore non-string args (RSpec metadata)
|
34
|
-
args = [args.first] + args[1..-1].select { |a| a.type == :str }
|
35
|
-
|
36
|
-
if cop_config['EnforceDescribeStatement']
|
37
|
-
enforce_describe_statement(node, args)
|
38
|
-
end
|
39
|
-
|
40
|
-
if offences.size == 0 && cop_config['EnforceFilenames']
|
41
|
-
enforce_filename(node, args)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def enforce_describe_statement(node, args)
|
48
|
-
check_described_class(node, args.first)
|
49
|
-
check_described_method(node, args[1])
|
50
|
-
end
|
51
|
-
|
52
|
-
def enforce_filename(node, args)
|
53
|
-
path_parts = const_name(args.first).split('::').map do |part|
|
54
|
-
camel_to_underscore(part)
|
55
|
-
end
|
56
|
-
|
57
|
-
if !args[1]
|
58
|
-
check_class_spec(node, path_parts)
|
59
|
-
else
|
60
|
-
method_str = args[1].children.first if args[1]
|
61
|
-
path_parts << 'class_methods' if method_str.start_with? '.'
|
62
|
-
check_method_spec(node, path_parts, method_str)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def check_described_class(node, first_arg)
|
67
|
-
if !first_arg || first_arg.type != :const
|
68
|
-
add_offence(first_arg || node, :expression, DESCRIBE_CLASS_MSG)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def check_described_method(node, second_arg)
|
73
|
-
return unless second_arg
|
74
|
-
|
75
|
-
unless METHOD_STRING_MATCHER =~ second_arg.children.first
|
76
|
-
add_offence(second_arg, :expression, METHOD_STRING_MSG)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def check_class_spec(node, path_parts)
|
81
|
-
spec_path = File.join(path_parts) + '_spec.rb'
|
82
|
-
unless source_filename.end_with? spec_path
|
83
|
-
add_offence(node, :expression, format(CLASS_SPEC_MSG, spec_path))
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def check_method_spec(node, path_parts, method_str)
|
88
|
-
matcher_parts = path_parts.dup
|
89
|
-
# Strip out symbols; it's not worth enforcing a vocabulary for them.
|
90
|
-
matcher_parts << method_str[1..-1].gsub(/\W+/, '*') + '_spec.rb'
|
91
|
-
|
92
|
-
glob_matcher = File.join(matcher_parts)
|
93
|
-
unless source_filename =~ regexp_from_glob(glob_matcher)
|
94
|
-
message = format(METHOD_SPEC_MSG, glob_matcher)
|
95
|
-
add_offence(node, :expression, message)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def top_level_describe?(node)
|
100
|
-
_receiver, method_name, *_args = *node
|
101
|
-
return false unless method_name == :describe
|
102
|
-
|
103
|
-
root_node = processed_source.ast
|
104
|
-
top_level_nodes = describe_statement_children(root_node)
|
105
|
-
# If we have no top level describe statements, we need to check any
|
106
|
-
# blocks on the top level (e.g. after a require).
|
107
|
-
if top_level_nodes.size == 0
|
108
|
-
top_level_nodes = node_children(root_node).map do |child|
|
109
|
-
describe_statement_children(child) if child.type == :block
|
110
|
-
end.flatten.compact
|
111
|
-
end
|
112
|
-
|
113
|
-
top_level_nodes.include? node
|
114
|
-
end
|
115
|
-
|
116
|
-
def describe_statement_children(node)
|
117
|
-
node_children(node).select do |element|
|
118
|
-
element.type == :send && element.children[1] == :describe
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def source_filename
|
123
|
-
processed_source.buffer.name
|
124
|
-
end
|
125
|
-
|
126
|
-
def camel_to_underscore(string)
|
127
|
-
string.dup.tap do |result|
|
128
|
-
result.gsub!(/([^A-Z])([A-Z]+)/, '\\1_\\2')
|
129
|
-
result.gsub!(/([A-Z]{2,})([A-Z][^A-Z]+)/, '\\1_\\2')
|
130
|
-
result.downcase!
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def regexp_from_glob(glob)
|
135
|
-
Regexp.new(glob.gsub('.', '\\.').gsub('*', '.*') + '$')
|
136
|
-
end
|
137
|
-
|
138
|
-
def node_children(node)
|
139
|
-
node.children.select { |e| e.is_a? Parser::AST::Node }
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Rubocop::Cop::RSpec::UnitSpecNaming, :config do
|
6
|
-
subject(:cop) { described_class.new(config) }
|
7
|
-
|
8
|
-
context 'describe statement enforcement' do
|
9
|
-
let(:cop_config) { { 'EnforceFilenames' => false } }
|
10
|
-
|
11
|
-
it 'checks first-line describe statements' do
|
12
|
-
inspect_source(cop,
|
13
|
-
['describe "bad describe" do; end'])
|
14
|
-
expect(cop.offences.size).to eq(1)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'checks describe statements after a require' do
|
18
|
-
inspect_source(cop,
|
19
|
-
["require 'spec_helper'",
|
20
|
-
'describe "bad describe" do; end'])
|
21
|
-
expect(cop.offences.size).to eq(1)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'ignores nested describe statements' do
|
25
|
-
inspect_source(cop,
|
26
|
-
['describe Some::Class do',
|
27
|
-
' describe "bad describe" do; end',
|
28
|
-
'end'])
|
29
|
-
expect(cop.offences).to eq([])
|
30
|
-
end
|
31
|
-
|
32
|
-
it "doesn't blow up on single-line describes" do
|
33
|
-
inspect_source(cop,
|
34
|
-
['describe Some::Class'])
|
35
|
-
expect(cop.offences).to eq([])
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'checks class method naming' do
|
39
|
-
inspect_source(cop,
|
40
|
-
["describe Some::Class, '.asdf' do; end"])
|
41
|
-
expect(cop.offences).to eq([])
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'checks instance method naming' do
|
45
|
-
inspect_source(cop,
|
46
|
-
["describe Some::Class, '#fdsa' do; end"])
|
47
|
-
expect(cop.offences).to eq([])
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'enforces non-method names' do
|
51
|
-
inspect_source(cop,
|
52
|
-
["describe Some::Class, 'nope' do; end"])
|
53
|
-
expect(cop.offences.size).to eq(1)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'filename enforcement' do
|
58
|
-
let(:cop_config) { { 'EnforceDescribeStatement' => false } }
|
59
|
-
|
60
|
-
it 'checks class specs' do
|
61
|
-
inspect_source(cop,
|
62
|
-
['describe Some::Class do; end'],
|
63
|
-
'some/class_spec.rb')
|
64
|
-
expect(cop.offences).to eq([])
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'handles CamelCaps class names' do
|
68
|
-
inspect_source(cop,
|
69
|
-
['describe MyClass do; end'],
|
70
|
-
'my_class_spec.rb')
|
71
|
-
expect(cop.offences).to eq([])
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'handles ACRONYMClassNames' do
|
75
|
-
inspect_source(cop,
|
76
|
-
['describe ABCOne::Two do; end'],
|
77
|
-
'abc_one/two_spec.rb')
|
78
|
-
expect(cop.offences).to eq([])
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'handles ALLCAPS class names' do
|
82
|
-
inspect_source(cop,
|
83
|
-
['describe ALLCAPS do; end'],
|
84
|
-
'allcaps_spec.rb')
|
85
|
-
expect(cop.offences).to eq([])
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'checks instance methods' do
|
89
|
-
inspect_source(cop,
|
90
|
-
["describe Some::Class, '#inst' do; end"],
|
91
|
-
'some/class/inst_spec.rb')
|
92
|
-
expect(cop.offences).to eq([])
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'checks class methods' do
|
96
|
-
inspect_source(cop,
|
97
|
-
["describe Some::Class, '.inst' do; end"],
|
98
|
-
'some/class/class_methods/inst_spec.rb')
|
99
|
-
expect(cop.offences).to eq([])
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'ignores non-alphanumeric characters' do
|
103
|
-
inspect_source(cop,
|
104
|
-
["describe Some::Class, '#pred?' do; end"],
|
105
|
-
'some/class/pred_spec.rb')
|
106
|
-
expect(cop.offences).to eq([])
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'allows flexibility with predicates' do
|
110
|
-
inspect_source(cop,
|
111
|
-
["describe Some::Class, '#thing?' do; end"],
|
112
|
-
'some/class/thing_predicate_spec.rb')
|
113
|
-
expect(cop.offences).to eq([])
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'allows flexibility with operators' do
|
117
|
-
inspect_source(cop,
|
118
|
-
["describe MyClass, '#<=>' do; end"],
|
119
|
-
'my_class/spaceship_operator_spec.rb')
|
120
|
-
expect(cop.offences).to eq([])
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'checks the path' do
|
124
|
-
inspect_source(cop,
|
125
|
-
["describe MyClass, '#foo' do; end"],
|
126
|
-
'my_clas/foo_spec.rb')
|
127
|
-
expect(cop.offences.size).to eq(1)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'checks class spec paths' do
|
131
|
-
inspect_source(cop,
|
132
|
-
['describe MyClass do; end'],
|
133
|
-
'my_clas_spec.rb')
|
134
|
-
expect(cop.offences.size).to eq(1)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|