rubocop-rspec 1.0.rc2 → 1.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +41 -19
  4. data/Rakefile +1 -1
  5. data/lib/rubocop-rspec.rb +8 -8
  6. data/lib/rubocop/cop/rspec/describe_class.rb +30 -0
  7. data/lib/rubocop/cop/rspec/describe_method.rb +37 -0
  8. data/lib/rubocop/cop/rspec/described_class.rb +58 -0
  9. data/lib/rubocop/cop/rspec/example_wording.rb +35 -0
  10. data/lib/rubocop/cop/rspec/file_name.rb +71 -0
  11. data/lib/rubocop/cop/rspec/instance_variable.rb +41 -0
  12. data/lib/rubocop/cop/rspec/multiple_describes.rb +37 -0
  13. data/lib/rubocop/rspec/inject.rb +1 -1
  14. data/lib/rubocop/rspec/top_level_describe.rb +1 -1
  15. data/lib/rubocop/rspec/version.rb +2 -2
  16. data/rubocop-rspec.gemspec +2 -2
  17. data/spec/project_spec.rb +6 -5
  18. data/spec/rubocop/cop/{rspec_describe_class_spec.rb → rspec/describe_class_spec.rb} +1 -1
  19. data/spec/rubocop/cop/{rspec_describe_method_spec.rb → rspec/describe_method_spec.rb} +1 -1
  20. data/spec/rubocop/cop/{rspec_described_class_spec.rb → rspec/described_class_spec.rb} +1 -1
  21. data/spec/rubocop/cop/{rspec_example_wording_spec.rb → rspec/example_wording_spec.rb} +1 -1
  22. data/spec/rubocop/cop/{rspec_file_name_spec.rb → rspec/file_name_spec.rb} +10 -2
  23. data/spec/rubocop/cop/{rspec_instance_variable_spec.rb → rspec/instance_variable_spec.rb} +1 -1
  24. data/spec/rubocop/cop/{rspec_multiple_describes_spec.rb → rspec/multiple_describes_spec.rb} +1 -1
  25. data/spec/spec_helper.rb +3 -3
  26. metadata +42 -41
  27. data/lib/rubocop/cop/rspec_describe_class.rb +0 -28
  28. data/lib/rubocop/cop/rspec_describe_method.rb +0 -35
  29. data/lib/rubocop/cop/rspec_described_class.rb +0 -56
  30. data/lib/rubocop/cop/rspec_example_wording.rb +0 -33
  31. data/lib/rubocop/cop/rspec_file_name.rb +0 -54
  32. data/lib/rubocop/cop/rspec_instance_variable.rb +0 -39
  33. data/lib/rubocop/cop/rspec_multiple_describes.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 08dd700b50fb2adf8683db8ed5868dede6ada896
4
- data.tar.gz: d75cd3f9367ebfe7e35df2e7ec641b8d66ea4d68
3
+ metadata.gz: bed7dbb7d971920ade6ba9925fbb552b01e79d44
4
+ data.tar.gz: 377e58808853d26bb9a0abdc5a8ceb0e7d613ca0
5
5
  SHA512:
6
- metadata.gz: 5d930412aa5d760bb7d4ca719ceae3dae07239c92eb795e4057b9e1200962c92f9595c88dec06516b2f3aa337bc6781b9a962c58a19f0fa5eeb1bba89c10ae07
7
- data.tar.gz: 74d79a149588115a0845bd5a8e0414bada5c4320a60a057f5fa04def3f31821aeb386af521aeb90f1437355b1cb1a2f0fc41078a88b043485282ad9e3834f2b6
6
+ metadata.gz: 281eb6abf3b67f2be3bf7ca2ce5f78ed088efec528a91d0a3d404fd7574eea928ada8425d56bf52617ab66af235122762c0fcbbe4c08f039edbbd9b65aee3f16
7
+ data.tar.gz: fbcc740631f20a639309ac9b96fa060b1d801ff59d117033e16d0a2a2b9e2e51619e53fbeabbea647aa7efeb4b43953ea704495c26ffd6d42d0882766ccfddea
@@ -1,5 +1,10 @@
1
1
  # Change log
2
2
 
3
+ ## 1.0.rc3
4
+
5
+ * Update to RuboCop `>= 0.23`. ([@geniou][])
6
+ * Add configuration option for `CustomTransformation` to `FileName` cop. ([@geniou][])
7
+
3
8
  ## 1.0.rc2
4
9
 
5
10
  * Gem is no longer 20MB (sorry!). ([@nevir][])
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- RuboCop RSpec
2
- =============
1
+ # RuboCop RSpec
3
2
 
4
3
  [![Gem Version](https://badge.fury.io/rb/rubocop-rspec.png)](https://rubygems.org/gems/rubocop-rspec)
5
4
  [![Dependency Status](https://gemnasium.com/nevir/rubocop-rspec.png)](https://gemnasium.com/nevir/rubocop-rspec)
@@ -11,46 +10,69 @@ RSpec-specific analysis for your projects, as an extension to
11
10
  [RuboCop](https://github.com/bbatsov/rubocop).
12
11
 
13
12
 
14
- Usage
15
- -----
13
+ ## Installation
16
14
 
17
- Add it to your bundle, or environment, and then you can load it via:
15
+ Just install the `rubocop-rspec` gem
16
+
17
+ ```bash
18
+ gem install rubocop-rspec
19
+ ```
20
+
21
+ or if you use bundler put this in your `Gemfile`
22
+
23
+ ```
24
+ gem 'rubocop-rspec'
25
+ ```
26
+
27
+
28
+ ## Usage
29
+
30
+ You need to tell RuboCop to load the RSpec extension. There are three
31
+ ways to do this:
32
+
33
+ ### RuboCop configuration file
34
+
35
+ Put this into you `.rubocop.yml`.
36
+
37
+ ```
38
+ require: rubocop-rspec
39
+ ```
40
+
41
+ Now you can run `rubocop` and it will autmaticly load the RuboCop RSpec
42
+ cops together with the standard cops.
43
+
44
+ ### Command line
18
45
 
19
46
  ```bash
20
47
  rubocop --require rubocop-rspec
21
48
  ```
22
49
 
23
- or as part of your rubocop rake task:
50
+ ### Rake task
24
51
 
25
52
  ```ruby
26
- Rubocop::RakeTask.new(:style) do |task|
53
+ RuboCop::RakeTask.new do |task|
27
54
  task.requires << 'rubocop-rspec'
28
55
  end
29
56
  ```
30
57
 
31
58
 
32
- The Cops
33
- --------
34
-
35
- **WARNING: Cop names are under flux and will likely change in the near future.**
36
- We're hoping to
37
- [introduce namespaces](https://github.com/bbatsov/rubocop/issues/1097) into the mix.
59
+ ## The Cops
38
60
 
39
- All cops are located under [`lib/rubocop/cop`](lib/rubocop/cop), and contain
61
+ All cops are located under
62
+ [`lib/rubocop/cop/spec`](lib/rubocop/cop/rspec), and contain
40
63
  examples/documentation.
41
64
 
42
- In your `.rubocop.yml`, you may treat the RSpec cops just like any other cop.
43
- For example:
65
+ In your `.rubocop.yml`, you may treat the RSpec cops just like any other
66
+ cop. For example:
44
67
 
45
68
  ```yaml
46
- RSpecFileName:
69
+ RSpec/FileName:
47
70
  Exclude:
48
71
  - spec/my_poorly_named_spec_file.rb
49
72
  ```
50
73
 
51
74
 
52
- License
53
- -------
75
+ ## License
54
76
 
55
77
  `rubocop-rspec` is MIT licensed. [See the accompanying file](MIT-LICENSE.md) for
56
78
  the full text.
data/Rakefile CHANGED
@@ -25,7 +25,7 @@ desc 'Run RuboCop over this gem'
25
25
  task :internal_investigation do
26
26
  require 'rubocop-rspec'
27
27
 
28
- result = Rubocop::CLI.new.run
28
+ result = RuboCop::CLI.new.run
29
29
  abort('RuboCop failed!') unless result == 0
30
30
  end
31
31
 
@@ -6,13 +6,13 @@ require 'rubocop/rspec/version'
6
6
  require 'rubocop/rspec/inject'
7
7
  require 'rubocop/rspec/top_level_describe'
8
8
 
9
- Rubocop::RSpec::Inject.defaults!
9
+ RuboCop::RSpec::Inject.defaults!
10
10
 
11
11
  # cops
12
- require 'rubocop/cop/rspec_describe_class'
13
- require 'rubocop/cop/rspec_describe_method'
14
- require 'rubocop/cop/rspec_described_class'
15
- require 'rubocop/cop/rspec_example_wording'
16
- require 'rubocop/cop/rspec_file_name'
17
- require 'rubocop/cop/rspec_instance_variable'
18
- require 'rubocop/cop/rspec_multiple_describes'
12
+ require 'rubocop/cop/rspec/describe_class'
13
+ require 'rubocop/cop/rspec/describe_method'
14
+ require 'rubocop/cop/rspec/described_class'
15
+ require 'rubocop/cop/rspec/example_wording'
16
+ require 'rubocop/cop/rspec/file_name'
17
+ require 'rubocop/cop/rspec/instance_variable'
18
+ require 'rubocop/cop/rspec/multiple_describes'
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Check that the first argument to the top level describe is the tested
7
+ # class or module.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # describe 'Do something' do
12
+ # end
13
+ #
14
+ # # good
15
+ # describe TestedClass do
16
+ # end
17
+ class DescribeClass < Cop
18
+ include RuboCop::RSpec::TopLevelDescribe
19
+
20
+ MESSAGE = 'The first argument to describe should be the class or ' \
21
+ 'module being tested.'
22
+
23
+ def on_top_level_describe(_node, args)
24
+ return if args.first && args.first.type == :const
25
+ add_offense(args.first, :expression, MESSAGE)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks that the second argument to the top level describe is the tested
7
+ # method name.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # describe MyClass, 'do something' do
12
+ # end
13
+ #
14
+ # # good
15
+ # describe MyClass, '#my_instance_method' do
16
+ # end
17
+ #
18
+ # describe MyClass, '.my_class_method' do
19
+ # end
20
+ class DescribeMethod < Cop
21
+ include RuboCop::RSpec::TopLevelDescribe
22
+
23
+ MESSAGE = 'The second argument to describe should be the method ' \
24
+ "being tested. '#instance' or '.class'"
25
+ METHOD_STRING_MATCHER = /^[\#\.].+/
26
+
27
+ def on_top_level_describe(_node, args)
28
+ second_arg = args[1]
29
+ return unless second_arg
30
+ return if METHOD_STRING_MATCHER =~ second_arg.children.first
31
+
32
+ add_offense(second_arg, :expression, MESSAGE)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # If the first argument of describe is a class, the class is exposed to
7
+ # each example via described_class - this should be used instead of
8
+ # repeating the class.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # describe MyClass do
13
+ # subject { MyClass.do_something }
14
+ # end
15
+ #
16
+ # # good
17
+ # describe MyClass do
18
+ # subject { described_class.do_something }
19
+ # end
20
+ class DescribedClass < Cop
21
+ include RuboCop::RSpec::TopLevelDescribe
22
+
23
+ MESSAGE = 'Use `described_class` instead of `%s`'
24
+
25
+ def on_block(node)
26
+ method, _args, body = *node
27
+ return unless top_level_describe?(method)
28
+
29
+ _receiver, method_name, object = *method
30
+ return unless method_name == :describe
31
+ return unless object && object.type == :const
32
+
33
+ inspect_children(body, object)
34
+ end
35
+
36
+ private
37
+
38
+ def inspect_children(node, object)
39
+ return unless node.is_a? Parser::AST::Node
40
+ return if scope_change?(node) || node.type == :const
41
+
42
+ node.children.each do |child|
43
+ if child == object
44
+ name = object.loc.expression.source
45
+ add_offense(child, :expression, format(MESSAGE, name))
46
+ break
47
+ end
48
+ inspect_children(child, object)
49
+ end
50
+ end
51
+
52
+ def scope_change?(node)
53
+ [:def, :class, :module].include?(node.type)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Do not use should when describing your tests.
7
+ # see: http://betterspecs.org/#should
8
+ #
9
+ # @example
10
+ # # bad
11
+ # it 'should find nothing' do
12
+ # end
13
+ #
14
+ # # good
15
+ # it 'finds nothing' do
16
+ # end
17
+ class ExampleWording < Cop
18
+ MSG = 'Do not use should when describing your tests.'
19
+
20
+ def on_block(node)
21
+ method, _, _ = *node
22
+ _, method_name, *args = *method
23
+
24
+ return unless method_name == :it
25
+
26
+ arguments = *(args.first)
27
+ message = arguments.first.to_s
28
+ return unless message.start_with?('should')
29
+
30
+ add_offense(method, :selector, MSG)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks the path of the spec file and enforces that it reflects the
7
+ # described class/module and its optionally called out method.
8
+ #
9
+ # With the configuration option `CustomTransform` modules or clases can be
10
+ # specified that should not as usual be transformed from CamelCase to
11
+ # snake_case (e.g. 'RuboCop' => 'rubocop' ).
12
+ #
13
+ # @example
14
+ # my_class/method_spec.rb # describe MyClass, '#method'
15
+ # my_class_method_spec.rb # describe MyClass, '#method'
16
+ # my_class_spec.rb # describe MyClass
17
+ class FileName < Cop
18
+ include RuboCop::RSpec::TopLevelDescribe
19
+
20
+ MESSAGE = 'Spec path should end with `%s`'
21
+ METHOD_STRING_MATCHER = /^[\#\.].+/
22
+
23
+ def on_top_level_describe(node, args)
24
+ return unless single_top_level_describe?
25
+ object = const_name(args.first)
26
+ return unless object
27
+
28
+ path_matcher = matcher(object, args[1])
29
+ return if source_filename =~ regexp_from_glob(path_matcher)
30
+
31
+ add_offense(node, :expression, format(MESSAGE, path_matcher))
32
+ end
33
+
34
+ private
35
+
36
+ def matcher(object, method)
37
+ path = File.join(parts(object))
38
+ path += '*' + method.children.first.gsub(/\W+/, '') if method
39
+
40
+ "#{path}*_spec.rb"
41
+ end
42
+
43
+ def parts(object)
44
+ object.split('::').map do |p|
45
+ custom_transform[p] || camel_to_underscore(p)
46
+ end
47
+ end
48
+
49
+ def source_filename
50
+ processed_source.buffer.name
51
+ end
52
+
53
+ def camel_to_underscore(string)
54
+ string.dup.tap do |result|
55
+ result.gsub!(/([^A-Z])([A-Z]+)/, '\\1_\\2')
56
+ result.gsub!(/([A-Z]{2,})([A-Z][^A-Z]+)/, '\\1_\\2')
57
+ result.downcase!
58
+ end
59
+ end
60
+
61
+ def regexp_from_glob(glob)
62
+ Regexp.new(glob.gsub('.', '\\.').gsub('*', '.*') + '$')
63
+ end
64
+
65
+ def custom_transform
66
+ cop_config['CustomTransform'] || []
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # When you have to assign a variable instead of using an instance
7
+ # variable, use let.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # describe MyClass do
12
+ # before { @foo = [] }
13
+ # it { expect(@foo).to be_emtpy }
14
+ # end
15
+ #
16
+ # # good
17
+ # describe MyClass do
18
+ # let(:foo) { [] }
19
+ # it { expect(foo).to be_emtpy }
20
+ # end
21
+ class InstanceVariable < Cop
22
+ MESSAGE = 'Use `let` instead of an instance variable'
23
+ EXAMPLE_GROUP_METHODS = [
24
+ :example_group, :describe, :context, :xdescribe, :xcontext,
25
+ :fdescribe, :fcontext, :shared_examples, :shared_context,
26
+ :share_examples_for, :shared_examples_for, :feature
27
+ ]
28
+
29
+ def on_block(node)
30
+ method, _args, _body = *node
31
+ _receiver, method_name, _object = *method
32
+ @in_spec = true if EXAMPLE_GROUP_METHODS.include?(method_name)
33
+ end
34
+
35
+ def on_ivar(node)
36
+ add_offense(node, :expression, MESSAGE) if @in_spec
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks for multiple top level describes. They should be nested if it is
7
+ # for the same class or module or seperated into different files.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # describe MyClass, '.do_someting' do
12
+ # end
13
+ # describe MyClass, '.do_someting_else' do
14
+ # end
15
+ #
16
+ # #good
17
+ # describe MyClass
18
+ # describe '.do_someting' do
19
+ # end
20
+ # describe '.do_someting_else' do
21
+ # end
22
+ # end
23
+ class MultipleDescribes < Cop
24
+ include RuboCop::RSpec::TopLevelDescribe
25
+
26
+ MESSAGE = 'Do not use multiple top level describes - try to nest them.'
27
+
28
+ def on_top_level_describe(node, _args)
29
+ return if single_top_level_describe?
30
+ return unless top_level_nodes.first == node
31
+
32
+ add_offense(node, :expression, MESSAGE)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'yaml'
4
4
 
5
- module Rubocop
5
+ module RuboCop
6
6
  module RSpec
7
7
  # Because RuboCop doesn't yet support plugins, we have to monkey patch in a
8
8
  # bit of our configuration.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Rubocop
3
+ module RuboCop
4
4
  module RSpec
5
5
  # Helper methods for top level describe cops
6
6
  module TopLevelDescribe
@@ -1,10 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Rubocop
3
+ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '1.0.rc2'
7
+ STRING = '1.0.rc3'
8
8
  end
9
9
  end
10
10
  end
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.email = ['ian@nevir.net', 'git@nilsgemeinhardt.de']
16
16
  spec.licenses = ['MIT']
17
17
 
18
- spec.version = Rubocop::RSpec::Version::STRING
18
+ spec.version = RuboCop::RSpec::Version::STRING
19
19
  spec.platform = Gem::Platform::RUBY
20
20
  spec.required_ruby_version = '>= 1.9.2'
21
21
 
@@ -30,5 +30,5 @@ Gem::Specification.new do |spec|
30
30
  spec.test_files = spec.files.grep(/^spec\//)
31
31
  spec.extra_rdoc_files = ['MIT-LICENSE.md', 'README.md']
32
32
 
33
- spec.add_runtime_dependency('rubocop', '~> 0.19', '>= 0.19')
33
+ spec.add_runtime_dependency('rubocop', '~> 0.23', '>= 0.23')
34
34
  end
@@ -2,20 +2,21 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe 'RuboCop Project' do # rubocop:disable RSpecDescribeClass
5
+ describe 'RuboCop Project' do # rubocop:disable RSpec/DescribeClass
6
6
  describe 'default configuration file' do
7
7
  let(:cop_names) do
8
8
  Dir.glob(File.join(File.dirname(__FILE__), '..', 'lib', 'rubocop', 'cop',
9
- '*.rb'))
9
+ 'rspec', '*.rb'))
10
10
  .map do |file|
11
- File.basename(file, '.rb')
11
+ cop_name = File.basename(file, '.rb')
12
12
  .gsub(/(^|_)(.)/) { Regexp.last_match(2).upcase }
13
- .gsub('Rspec', 'RSpec')
13
+
14
+ "RSpec/#{cop_name}"
14
15
  end
15
16
  end
16
17
 
17
18
  subject(:default_config) do
18
- Rubocop::ConfigLoader.load_file('config/default.yml')
19
+ RuboCop::ConfigLoader.load_file('config/default.yml')
19
20
  end
20
21
 
21
22
  it 'has configuration for all cops' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecDescribeClass do
5
+ describe RuboCop::Cop::RSpec::DescribeClass do
6
6
  subject(:cop) { described_class.new }
7
7
 
8
8
  it 'checks first-line describe statements' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecDescribeMethod do
5
+ describe RuboCop::Cop::RSpec::DescribeMethod do
6
6
  subject(:cop) { described_class.new }
7
7
 
8
8
  it 'enforces non-method names' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecDescribedClass do
5
+ describe RuboCop::Cop::RSpec::DescribedClass do
6
6
  subject(:cop) { described_class.new }
7
7
 
8
8
  it 'checks for the use of the described class' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecExampleWording do
5
+ describe RuboCop::Cop::RSpec::ExampleWording do
6
6
  subject(:cop) { described_class.new }
7
7
 
8
8
  it 'finds description with `should` at the beginning' do
@@ -2,8 +2,9 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecFileName do
6
- subject(:cop) { described_class.new }
5
+ describe RuboCop::Cop::RSpec::FileName, :config do
6
+ subject(:cop) { described_class.new(config) }
7
+ let(:cop_config) { { 'CustomTransform' => { 'FooFoo' => 'foofoo' } } }
7
8
 
8
9
  it 'checks the path' do
9
10
  inspect_source(cop,
@@ -140,4 +141,11 @@ describe Rubocop::Cop::RSpecFileName do
140
141
  'my_class/spaceship_operator_spec.rb')
141
142
  expect(cop.offenses).to be_empty
142
143
  end
144
+
145
+ it 'respects custom module name transformation' do
146
+ inspect_source(cop,
147
+ ["describe FooFoo::Some::Class, '#bar' do; end"],
148
+ 'foofoo/some/class/bar_spec.rb')
149
+ expect(cop.offenses).to be_empty
150
+ end
143
151
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecInstanceVariable do
5
+ describe RuboCop::Cop::RSpec::InstanceVariable do
6
6
  subject(:cop) { described_class.new }
7
7
 
8
8
  it 'finds an instance variable inside a describe' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::RSpecMultipleDescribes do
5
+ describe RuboCop::Cop::RSpec::MultipleDescribes do
6
6
  subject(:cop) { described_class.new }
7
7
 
8
8
  it 'finds multiple top level describes with class and method' do
@@ -15,12 +15,12 @@ require 'rubocop-rspec'
15
15
  def parse_source(source, file = nil)
16
16
  source = source.join($RS) if source.is_a?(Array)
17
17
  if file.is_a? String
18
- Rubocop::SourceParser.parse(source, file)
18
+ RuboCop::SourceParser.parse(source, file)
19
19
  elsif file
20
20
  file.write(source)
21
21
  file.rewind
22
- Rubocop::SourceParser.parse(source, file.path)
22
+ RuboCop::SourceParser.parse(source, file.path)
23
23
  else
24
- Rubocop::SourceParser.parse(source)
24
+ RuboCop::SourceParser.parse(source)
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.rc2
4
+ version: 1.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian MacLeod
@@ -9,28 +9,28 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-21 00:00:00.000000000 Z
12
+ date: 2014-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubocop
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '0.19'
21
- - - '>='
20
+ version: '0.23'
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: '0.19'
23
+ version: '0.23'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ~>
28
+ - - "~>"
29
29
  - !ruby/object:Gem::Version
30
- version: '0.19'
31
- - - '>='
30
+ version: '0.23'
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0.19'
33
+ version: '0.23'
34
34
  description: |2
35
35
  Code style checking for RSpec files.
36
36
  A plugin for the RuboCop code style enforcing & linting tool.
@@ -43,32 +43,32 @@ extra_rdoc_files:
43
43
  - MIT-LICENSE.md
44
44
  - README.md
45
45
  files:
46
- - lib/rubocop/cop/rspec_describe_class.rb
47
- - lib/rubocop/cop/rspec_describe_method.rb
48
- - lib/rubocop/cop/rspec_described_class.rb
49
- - lib/rubocop/cop/rspec_example_wording.rb
50
- - lib/rubocop/cop/rspec_file_name.rb
51
- - lib/rubocop/cop/rspec_instance_variable.rb
52
- - lib/rubocop/cop/rspec_multiple_describes.rb
46
+ - CHANGELOG.md
47
+ - Gemfile
48
+ - MIT-LICENSE.md
49
+ - README.md
50
+ - Rakefile
51
+ - lib/rubocop-rspec.rb
52
+ - lib/rubocop/cop/rspec/describe_class.rb
53
+ - lib/rubocop/cop/rspec/describe_method.rb
54
+ - lib/rubocop/cop/rspec/described_class.rb
55
+ - lib/rubocop/cop/rspec/example_wording.rb
56
+ - lib/rubocop/cop/rspec/file_name.rb
57
+ - lib/rubocop/cop/rspec/instance_variable.rb
58
+ - lib/rubocop/cop/rspec/multiple_describes.rb
53
59
  - lib/rubocop/rspec/inject.rb
54
60
  - lib/rubocop/rspec/top_level_describe.rb
55
61
  - lib/rubocop/rspec/version.rb
56
- - lib/rubocop-rspec.rb
62
+ - rubocop-rspec.gemspec
57
63
  - spec/project_spec.rb
58
- - spec/rubocop/cop/rspec_describe_class_spec.rb
59
- - spec/rubocop/cop/rspec_describe_method_spec.rb
60
- - spec/rubocop/cop/rspec_described_class_spec.rb
61
- - spec/rubocop/cop/rspec_example_wording_spec.rb
62
- - spec/rubocop/cop/rspec_file_name_spec.rb
63
- - spec/rubocop/cop/rspec_instance_variable_spec.rb
64
- - spec/rubocop/cop/rspec_multiple_describes_spec.rb
64
+ - spec/rubocop/cop/rspec/describe_class_spec.rb
65
+ - spec/rubocop/cop/rspec/describe_method_spec.rb
66
+ - spec/rubocop/cop/rspec/described_class_spec.rb
67
+ - spec/rubocop/cop/rspec/example_wording_spec.rb
68
+ - spec/rubocop/cop/rspec/file_name_spec.rb
69
+ - spec/rubocop/cop/rspec/instance_variable_spec.rb
70
+ - spec/rubocop/cop/rspec/multiple_describes_spec.rb
65
71
  - spec/spec_helper.rb
66
- - CHANGELOG.md
67
- - MIT-LICENSE.md
68
- - README.md
69
- - rubocop-rspec.gemspec
70
- - Gemfile
71
- - Rakefile
72
72
  homepage: http://github.com/nevir/rubocop-rspec
73
73
  licenses:
74
74
  - MIT
@@ -79,27 +79,28 @@ require_paths:
79
79
  - lib
80
80
  required_ruby_version: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - '>='
82
+ - - ">="
83
83
  - !ruby/object:Gem::Version
84
84
  version: 1.9.2
85
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>'
87
+ - - ">"
88
88
  - !ruby/object:Gem::Version
89
89
  version: 1.3.1
90
90
  requirements: []
91
91
  rubyforge_project:
92
- rubygems_version: 2.0.3
92
+ rubygems_version: 2.2.0
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: Code style checking for RSpec files
96
96
  test_files:
97
97
  - spec/project_spec.rb
98
- - spec/rubocop/cop/rspec_describe_class_spec.rb
99
- - spec/rubocop/cop/rspec_describe_method_spec.rb
100
- - spec/rubocop/cop/rspec_described_class_spec.rb
101
- - spec/rubocop/cop/rspec_example_wording_spec.rb
102
- - spec/rubocop/cop/rspec_file_name_spec.rb
103
- - spec/rubocop/cop/rspec_instance_variable_spec.rb
104
- - spec/rubocop/cop/rspec_multiple_describes_spec.rb
98
+ - spec/rubocop/cop/rspec/describe_class_spec.rb
99
+ - spec/rubocop/cop/rspec/describe_method_spec.rb
100
+ - spec/rubocop/cop/rspec/described_class_spec.rb
101
+ - spec/rubocop/cop/rspec/example_wording_spec.rb
102
+ - spec/rubocop/cop/rspec/file_name_spec.rb
103
+ - spec/rubocop/cop/rspec/instance_variable_spec.rb
104
+ - spec/rubocop/cop/rspec/multiple_describes_spec.rb
105
105
  - spec/spec_helper.rb
106
+ has_rdoc:
@@ -1,28 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # Check that the first argument to the top level describe is the tested
6
- # class or module.
7
- #
8
- # @example
9
- # # bad
10
- # describe 'Do something' do
11
- # end
12
- #
13
- # # good
14
- # describe TestedClass do
15
- # end
16
- class RSpecDescribeClass < Cop
17
- include RSpec::TopLevelDescribe
18
-
19
- MESSAGE = 'The first argument to describe should be the class or ' \
20
- 'module being tested.'
21
-
22
- def on_top_level_describe(_node, args)
23
- return if args.first && args.first.type == :const
24
- add_offense(args.first, :expression, MESSAGE)
25
- end
26
- end
27
- end
28
- end
@@ -1,35 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # Checks that the second argument to the top level describe is the tested
6
- # method name.
7
- #
8
- # @example
9
- # # bad
10
- # describe MyClass, 'do something' do
11
- # end
12
- #
13
- # # good
14
- # describe MyClass, '#my_instance_method' do
15
- # end
16
- #
17
- # describe MyClass, '.my_class_method' do
18
- # end
19
- class RSpecDescribeMethod < Cop
20
- include RSpec::TopLevelDescribe
21
-
22
- MESSAGE = 'The second argument to describe should be the method being ' \
23
- "tested. '#instance' or '.class'"
24
- METHOD_STRING_MATCHER = /^[\#\.].+/
25
-
26
- def on_top_level_describe(_node, args)
27
- second_arg = args[1]
28
- return unless second_arg
29
- return if METHOD_STRING_MATCHER =~ second_arg.children.first
30
-
31
- add_offense(second_arg, :expression, MESSAGE)
32
- end
33
- end
34
- end
35
- end
@@ -1,56 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # If the first argument of describe is a class, the class is exposed to
6
- # each example via described_class - this should be used instead of
7
- # repeating the class.
8
- #
9
- # @example
10
- # # bad
11
- # describe MyClass do
12
- # subject { MyClass.do_something }
13
- # end
14
- #
15
- # # good
16
- # describe MyClass do
17
- # subject { described_class.do_something }
18
- # end
19
- class RSpecDescribedClass < Cop
20
- include RSpec::TopLevelDescribe
21
-
22
- MESSAGE = 'Use `described_class` instead of `%s`'
23
-
24
- def on_block(node)
25
- method, _args, body = *node
26
- return unless top_level_describe?(method)
27
-
28
- _receiver, method_name, object = *method
29
- return unless method_name == :describe
30
- return unless object && object.type == :const
31
-
32
- inspect_children(body, object)
33
- end
34
-
35
- private
36
-
37
- def inspect_children(node, object)
38
- return unless node.is_a? Parser::AST::Node
39
- return if scope_change?(node) || node.type == :const
40
-
41
- node.children.each do |child|
42
- if child == object
43
- name = object.loc.expression.source
44
- add_offense(child, :expression, format(MESSAGE, name))
45
- break
46
- end
47
- inspect_children(child, object)
48
- end
49
- end
50
-
51
- def scope_change?(node)
52
- [:def, :class, :module].include?(node.type)
53
- end
54
- end
55
- end
56
- end
@@ -1,33 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # Do not use should when describing your tests.
6
- # see: http://betterspecs.org/#should
7
- #
8
- # @example
9
- # # bad
10
- # it 'should find nothing' do
11
- # end
12
- #
13
- # # good
14
- # it 'finds nothing' do
15
- # end
16
- class RSpecExampleWording < Cop
17
- MSG = 'Do not use should when describing your tests.'
18
-
19
- def on_block(node)
20
- method, _, _ = *node
21
- _, method_name, *args = *method
22
-
23
- return unless method_name == :it
24
-
25
- arguments = *(args.first)
26
- message = arguments.first.to_s
27
- return unless message.start_with?('should')
28
-
29
- add_offense(method, :selector, MSG)
30
- end
31
- end
32
- end
33
- end
@@ -1,54 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # Checks the path of the spec file and enforces that it reflects the
6
- # described class/module and its optionally called out method.
7
- #
8
- # @example
9
- # my_class/method_spec.rb # describe MyClass, '#method'
10
- # my_class_spec.rb # describe MyClass
11
- class RSpecFileName < Cop
12
- include RSpec::TopLevelDescribe
13
-
14
- MESSAGE = 'Spec path should end with `%s`'
15
- METHOD_STRING_MATCHER = /^[\#\.].+/
16
-
17
- def on_top_level_describe(node, args)
18
- return unless single_top_level_describe?
19
- object = const_name(args.first)
20
- return unless object
21
-
22
- path_matcher = matcher(object, args[1])
23
- return if source_filename =~ regexp_from_glob(path_matcher)
24
-
25
- add_offense(node, :expression, format(MESSAGE, path_matcher))
26
- end
27
-
28
- private
29
-
30
- def matcher(object, method)
31
- path = File.join(object.split('::').map { |p| camel_to_underscore(p) })
32
- path += '*' + method.children.first.gsub(/\W+/, '') if method
33
-
34
- "#{path}*_spec.rb"
35
- end
36
-
37
- def source_filename
38
- processed_source.buffer.name
39
- end
40
-
41
- def camel_to_underscore(string)
42
- string.dup.tap do |result|
43
- result.gsub!(/([^A-Z])([A-Z]+)/, '\\1_\\2')
44
- result.gsub!(/([A-Z]{2,})([A-Z][^A-Z]+)/, '\\1_\\2')
45
- result.downcase!
46
- end
47
- end
48
-
49
- def regexp_from_glob(glob)
50
- Regexp.new(glob.gsub('.', '\\.').gsub('*', '.*') + '$')
51
- end
52
- end
53
- end
54
- end
@@ -1,39 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # When you have to assign a variable instead of using an instance variable,
6
- # use let.
7
- #
8
- # @example
9
- # # bad
10
- # describe MyClass do
11
- # before { @foo = [] }
12
- # it { expect(@foo).to be_emtpy }
13
- # end
14
- #
15
- # # good
16
- # describe MyClass do
17
- # let(:foo) { [] }
18
- # it { expect(foo).to be_emtpy }
19
- # end
20
- class RSpecInstanceVariable < Cop
21
- MESSAGE = 'Use `let` instead of an instance variable'
22
- EXAMPLE_GROUP_METHODS = [
23
- :example_group, :describe, :context, :xdescribe, :xcontext, :fdescribe,
24
- :fcontext, :shared_examples, :shared_context, :share_examples_for,
25
- :shared_examples_for, :feature
26
- ]
27
-
28
- def on_block(node)
29
- method, _args, _body = *node
30
- _receiver, method_name, _object = *method
31
- @in_spec = true if EXAMPLE_GROUP_METHODS.include?(method_name)
32
- end
33
-
34
- def on_ivar(node)
35
- add_offense(node, :expression, MESSAGE) if @in_spec
36
- end
37
- end
38
- end
39
- end
@@ -1,35 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Rubocop
4
- module Cop
5
- # Checks for multiple top level describes. They should be nested if it is
6
- # for the same class or module or seperated into different files.
7
- #
8
- # @example
9
- # # bad
10
- # describe MyClass, '.do_someting' do
11
- # end
12
- # describe MyClass, '.do_someting_else' do
13
- # end
14
- #
15
- # #good
16
- # describe MyClass
17
- # describe '.do_someting' do
18
- # end
19
- # describe '.do_someting_else' do
20
- # end
21
- # end
22
- class RSpecMultipleDescribes < Cop
23
- include RSpec::TopLevelDescribe
24
-
25
- MESSAGE = 'Do not use multiple top level describes - try to nest them.'
26
-
27
- def on_top_level_describe(node, _args)
28
- return if single_top_level_describe?
29
- return unless top_level_nodes.first == node
30
-
31
- add_offense(node, :expression, MESSAGE)
32
- end
33
- end
34
- end
35
- end