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.
@@ -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.18.1
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-02-05 00:00:00.000000000 Z
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.18'
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.18'
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/rspec/unit_spec_naming.rb
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/rspec/unit_spec_naming_spec.rb
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: '0'
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/rspec/unit_spec_naming_spec.rb
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