rubocop-rspec 1.5.1 → 1.5.2

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile +0 -2
  4. data/README.md +0 -8
  5. data/Rakefile +1 -3
  6. data/lib/rubocop-rspec.rb +2 -2
  7. data/lib/rubocop/cop/rspec/any_instance.rb +1 -10
  8. data/lib/rubocop/cop/rspec/describe_class.rb +23 -15
  9. data/lib/rubocop/cop/rspec/describe_method.rb +4 -6
  10. data/lib/rubocop/cop/rspec/described_class.rb +5 -8
  11. data/lib/rubocop/cop/rspec/example_length.rb +4 -9
  12. data/lib/rubocop/cop/rspec/example_wording.rb +13 -37
  13. data/lib/rubocop/cop/rspec/file_path.rb +10 -13
  14. data/lib/rubocop/cop/rspec/focus.rb +48 -30
  15. data/lib/rubocop/cop/rspec/instance_variable.rb +0 -1
  16. data/lib/rubocop/cop/rspec/multiple_describes.rb +2 -3
  17. data/lib/rubocop/cop/rspec/not_to_not.rb +3 -5
  18. data/lib/rubocop/cop/rspec/verified_doubles.rb +7 -15
  19. data/lib/rubocop/rspec/inject.rb +0 -1
  20. data/lib/rubocop/rspec/top_level_describe.rb +0 -2
  21. data/lib/rubocop/rspec/util.rb +19 -0
  22. data/lib/rubocop/rspec/version.rb +1 -2
  23. data/lib/rubocop/rspec/wording.rb +47 -0
  24. data/rubocop-rspec.gemspec +2 -2
  25. data/spec/project_spec.rb +0 -2
  26. data/spec/rubocop/cop/rspec/any_instance_spec.rb +0 -2
  27. data/spec/rubocop/cop/rspec/describe_class_spec.rb +36 -2
  28. data/spec/rubocop/cop/rspec/describe_method_spec.rb +10 -3
  29. data/spec/rubocop/cop/rspec/described_class_spec.rb +32 -2
  30. data/spec/rubocop/cop/rspec/example_length_spec.rb +17 -3
  31. data/spec/rubocop/cop/rspec/example_wording_spec.rb +61 -62
  32. data/spec/rubocop/cop/rspec/file_path_spec.rb +61 -21
  33. data/spec/rubocop/cop/rspec/focus_spec.rb +11 -3
  34. data/spec/rubocop/cop/rspec/instance_variable_spec.rb +13 -2
  35. data/spec/rubocop/cop/rspec/multiple_describes_spec.rb +0 -2
  36. data/spec/rubocop/cop/rspec/not_to_not_spec.rb +0 -2
  37. data/spec/rubocop/cop/rspec/verified_doubles_spec.rb +41 -19
  38. data/spec/rubocop/rspec/util/one_spec.rb +21 -0
  39. data/spec/rubocop/rspec/wording_spec.rb +44 -0
  40. data/spec/spec_helper.rb +1 -9
  41. metadata +11 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e7b5f7025e117a87e31f15d9e2a8f052e590270
4
- data.tar.gz: 89bfe35b6ba5d2af8eb751403e87d765a73931ce
3
+ metadata.gz: 41d29a68e96541d0d09976b9cdc582f4c468a447
4
+ data.tar.gz: d38ae28874032c3035a8fd78e6865dfece308fe6
5
5
  SHA512:
6
- metadata.gz: 83f01b1e8b7a94599499b286ba65034c791b5939bfbfb84400db6950ed6c4092c27e0b1ac4544c6d21bcf068724495ea73408812cdf7216ef6199cf510c51cac
7
- data.tar.gz: da36f3a208108b5342d3718fc64a6a35dfcaf2fd9a0b18039f244f6a0ea1ad97e0b2a39ce4d78f8cff69fb2d189fbd5dce8403559c92157d4d8d10e6e436e488
6
+ metadata.gz: 109b7e39672639b8aeb325439b0501dcec5d9e96eecde7b014cbe5647403bc5d8715a6499bfe9a5ea86bd8ec05f94f17cd75a0c59d9f1882031b3463961fe92b
7
+ data.tar.gz: 3bb0205007875394a79cc08782dd82ce7186238e155ec18b7078a59aef9572ff8804cc252027f6c2977415fe200605f0741688011a6845ec0eb276e163a3e37d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Change log
2
2
 
3
+ ## Master (unreleased)
4
+
5
+ ## 1.5.2 (2016-08-01)
6
+
7
+ * Drop support for ruby `2.0.0` and `2.1.0`. ([@backus][])
8
+ * Internal refactorings and improved test coverage. ([@backus][])
9
+
3
10
  ## 1.5.1 (2016-07-20)
4
11
 
5
12
  * Fix `unrecognized parameter RSpec/VerifiedDoubles:IgnoreSymbolicNames` warning. ([@jeffreyc][])
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  source 'https://rubygems.org'
4
2
 
5
3
  gemspec
data/README.md CHANGED
@@ -80,14 +80,6 @@ RSpec/FilePath:
80
80
  4. Push to the branch (`git push origin my-new-feature`)
81
81
  5. Create new Pull Request
82
82
 
83
- For running the spec files, this project depends on RuboCop's spec helpers.
84
- This means that in order to run the specs locally, you need a (shallow) clone
85
- of the RuboCop repository:
86
-
87
- ```bash
88
- git submodule update --init vendor/rubocop
89
- ```
90
-
91
83
  ## License
92
84
 
93
85
  `rubocop-rspec` is MIT licensed. [See the accompanying file](MIT-LICENSE.md) for
data/Rakefile CHANGED
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'bundler'
4
2
  require 'bundler/gem_tasks'
5
3
  begin
@@ -26,7 +24,7 @@ task :internal_investigation do
26
24
  require 'rubocop-rspec'
27
25
 
28
26
  result = RuboCop::CLI.new.run
29
- abort('RuboCop failed!') unless result == 0
27
+ abort('RuboCop failed!') unless result.zero?
30
28
  end
31
29
 
32
30
  task default: [:spec, :internal_investigation]
data/lib/rubocop-rspec.rb CHANGED
@@ -1,10 +1,10 @@
1
- # encoding: utf-8
2
-
3
1
  require 'rubocop'
4
2
 
5
3
  require 'rubocop/rspec/version'
6
4
  require 'rubocop/rspec/inject'
7
5
  require 'rubocop/rspec/top_level_describe'
6
+ require 'rubocop/rspec/wording'
7
+ require 'rubocop/rspec/util'
8
8
 
9
9
  RuboCop::RSpec::Inject.defaults!
10
10
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module RuboCop
4
2
  module Cop
5
3
  module RSpec
@@ -33,14 +31,7 @@ module RuboCop
33
31
  _receiver, method_name, *_args = *node
34
32
  return unless ANY_INSTANCE_METHODS.include?(method_name)
35
33
 
36
- add_offense(
37
- node,
38
- :expression,
39
- format(
40
- MESSAGE % { method: method_name },
41
- node.loc.expression.source
42
- )
43
- )
34
+ add_offense(node, :expression, MESSAGE % { method: method_name })
44
35
  end
45
36
  end
46
37
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -21,25 +20,34 @@ module RuboCop
21
20
  class DescribeClass < Cop
22
21
  include RuboCop::RSpec::TopLevelDescribe
23
22
 
24
- REQUEST_PAIR = s(:pair, s(:sym, :type), s(:sym, :request))
25
- FEATURE_PAIR = s(:pair, s(:sym, :type), s(:sym, :feature))
26
- ROUTING_PAIR = s(:pair, s(:sym, :type), s(:sym, :routing))
27
- VIEW_PAIR = s(:pair, s(:sym, :type), s(:sym, :view))
23
+ MSG = 'The first argument to describe should be '\
24
+ 'the class or module being tested.'.freeze
28
25
 
29
- MESSAGE = 'The first argument to describe should be the class or ' \
30
- 'module being tested.'.freeze
26
+ def_node_matcher :valid_describe?, <<-PATTERN
27
+ {(send {(const nil :RSpec) nil} :describe const ...) (send nil :describe)}
28
+ PATTERN
31
29
 
32
- def on_top_level_describe(_node, args)
33
- return if args[0] && args[0].type == :const
30
+ def_node_matcher :describe_with_metadata, <<-PATTERN
31
+ (send {(const nil :RSpec) nil} :describe
32
+ !const
33
+ ...
34
+ (hash $...))
35
+ PATTERN
34
36
 
35
- return if args[1..-1].any? do |arg|
36
- next unless arg.hash_type?
37
- arg.children.any? do |n|
38
- [REQUEST_PAIR, FEATURE_PAIR, ROUTING_PAIR, VIEW_PAIR].include?(n)
39
- end
37
+ def_node_matcher :rails_metadata?, <<-PATTERN
38
+ (pair
39
+ (sym :type)
40
+ (sym {:request :feature :routing :view}))
41
+ PATTERN
42
+
43
+ def on_top_level_describe(node, args)
44
+ return if valid_describe?(node)
45
+
46
+ describe_with_metadata(node) do |pairs|
47
+ return if pairs.any?(&method(:rails_metadata?))
40
48
  end
41
49
 
42
- add_offense(args[0], :expression, MESSAGE)
50
+ add_offense(args.first, :expression)
43
51
  end
44
52
  end
45
53
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -19,16 +18,15 @@ module RuboCop
19
18
  # describe MyClass, '.my_class_method' do
20
19
  # end
21
20
  class DescribeMethod < Cop
22
- include RuboCop::RSpec::TopLevelDescribe
21
+ include RuboCop::RSpec::TopLevelDescribe, RuboCop::RSpec::Util
23
22
 
24
23
  MESSAGE = 'The second argument to describe should be the method ' \
25
24
  "being tested. '#instance' or '.class'".freeze
26
25
  METHOD_STRING_MATCHER = /^[\#\.].+/
27
26
 
28
- def on_top_level_describe(_node, args)
29
- second_arg = args[1]
30
- return unless second_arg && second_arg.type == :str
31
- return if METHOD_STRING_MATCHER =~ second_arg.children.first
27
+ def on_top_level_describe(_node, (_, second_arg))
28
+ return unless second_arg && second_arg.type.equal?(:str)
29
+ return if METHOD_STRING_MATCHER =~ one(second_arg.children)
32
30
 
33
31
  add_offense(second_arg, :expression, MESSAGE)
34
32
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -27,9 +26,8 @@ module RuboCop
27
26
  method, _args, body = *node
28
27
  return unless top_level_describe?(method)
29
28
 
30
- _receiver, method_name, object = *method
31
- return unless method_name == :describe
32
- return unless object && object.type == :const
29
+ _receiver, _method_name, object = *method
30
+ return unless object && object.type.equal?(:const)
33
31
 
34
32
  inspect_children(body, object)
35
33
  end
@@ -43,14 +41,13 @@ module RuboCop
43
41
  private
44
42
 
45
43
  def inspect_children(node, object)
46
- return unless node.is_a? Parser::AST::Node
47
- return if scope_change?(node) || node.type == :const
44
+ return unless node.instance_of?(Node)
45
+ return if scope_change?(node) || node.type.equal?(:const)
48
46
 
49
47
  node.children.each do |child|
50
- if child == object
48
+ if child.eql?(object)
51
49
  name = object.loc.expression.source
52
50
  add_offense(child, :expression, format(MESSAGE, name))
53
- break
54
51
  end
55
52
  inspect_children(child, object)
56
53
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -35,23 +34,19 @@ module RuboCop
35
34
 
36
35
  length = code_length(node)
37
36
 
38
- return unless length > max
39
- add_offense(node, :expression, message(length, max))
37
+ return unless length > max_length
38
+ add_offense(node, :expression, message(length))
40
39
  end
41
40
 
42
41
  private
43
42
 
44
- def max
45
- cop_config['Max']
46
- end
47
-
48
43
  def code_length(node)
49
- lines = node.source.lines.to_a[1..-2] || []
44
+ lines = node.source.lines[1..-2]
50
45
 
51
46
  lines.count { |line| !irrelevant_line(line) }
52
47
  end
53
48
 
54
- def message(length, max_length)
49
+ def message(length)
55
50
  format('Example has too many lines. [%d/%d]', length, max_length)
56
51
  end
57
52
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -25,9 +24,9 @@ module RuboCop
25
24
  method, = *node
26
25
  _, method_name, *args = *method
27
26
 
28
- return unless method_name == :it
27
+ return unless method_name.equal?(:it)
29
28
 
30
- arguments = *args.first
29
+ arguments = args.first.to_a
31
30
  message = arguments.first.to_s
32
31
  return unless message.downcase.start_with?('should')
33
32
 
@@ -36,53 +35,30 @@ module RuboCop
36
35
  arg1.begin_pos + 1,
37
36
  arg1.end_pos - 1)
38
37
 
39
- add_offense(message, message, MSG)
38
+ add_offense(message, message)
40
39
  end
41
40
 
42
41
  def autocorrect(range)
43
42
  lambda do |corrector|
44
- corrector.replace(range, corrected_message(range))
43
+ corrector.replace(
44
+ range,
45
+ RuboCop::RSpec::Wording.new(
46
+ range.source,
47
+ ignore: ignored_words,
48
+ replace: custom_transform
49
+ ).rewrite
50
+ )
45
51
  end
46
52
  end
47
53
 
48
54
  private
49
55
 
50
- def corrected_message(range)
51
- range.source.split(' ').tap do |words|
52
- first_word = words.shift
53
- words.unshift('not') if first_word == "shouldn't"
54
-
55
- words.each_with_index do |value, key|
56
- next if ignored_words.include?(value)
57
- words[key] = simple_present(words[key])
58
- break
59
- end
60
- end.join(' ')
61
- end
62
-
63
- def simple_present(word)
64
- return custom_transform[word] if custom_transform[word]
65
-
66
- # ends with o s x ch sh or ss
67
- if %w(o s x]).include?(word[-1]) ||
68
- %w(ch sh ss]).include?(word[-2..-1])
69
- return "#{word}es"
70
- end
71
-
72
- # ends with y
73
- if word[-1] == 'y' && !%w(a u i o e).include?(word[-2])
74
- return "#{word[0..-2]}ies"
75
- end
76
-
77
- "#{word}s"
78
- end
79
-
80
56
  def custom_transform
81
- cop_config['CustomTransform'] || []
57
+ cop_config.fetch('CustomTransform', {})
82
58
  end
83
59
 
84
60
  def ignored_words
85
- cop_config['IgnoredWords'] || []
61
+ cop_config.fetch('IgnoredWords', [])
86
62
  end
87
63
  end
88
64
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -29,7 +28,7 @@ module RuboCop
29
28
  object = args.first.const_name
30
29
  return unless object
31
30
 
32
- path_matcher = matcher(object, args[1])
31
+ path_matcher = matcher(object, args.at(1))
33
32
  return if source_filename =~ regexp_from_glob(path_matcher)
34
33
 
35
34
  add_offense(node, :expression, format(MESSAGE, path_matcher))
@@ -38,16 +37,15 @@ module RuboCop
38
37
  private
39
38
 
40
39
  def routing_spec?(args)
41
- args[1..-1].any? do |arg|
42
- next unless arg.hash_type?
40
+ args.any? do |arg|
43
41
  arg.children.include?(ROUTING_PAIR)
44
42
  end
45
43
  end
46
44
 
47
45
  def matcher(object, method)
48
46
  path = File.join(parts(object))
49
- if method && method.type == :str
50
- path += '*' + method.children.first.gsub(/\W+/, '')
47
+ if method && method.type.equal?(:str)
48
+ path += '*' + method.str_content.gsub(/\W+/, '')
51
49
  end
52
50
 
53
51
  "#{path}*_spec.rb"
@@ -64,19 +62,18 @@ module RuboCop
64
62
  end
65
63
 
66
64
  def camel_to_underscore(string)
67
- string.dup.tap do |result|
68
- result.gsub!(/([^A-Z])([A-Z]+)/, '\\1_\\2')
69
- result.gsub!(/([A-Z])([A-Z\d][^A-Z\d]+)/, '\\1_\\2')
70
- result.downcase!
71
- end
65
+ string
66
+ .gsub(/([^A-Z])([A-Z]+)/, '\\1_\\2')
67
+ .gsub(/([A-Z])([A-Z\d][^A-Z\d]+)/, '\\1_\\2')
68
+ .downcase
72
69
  end
73
70
 
74
71
  def regexp_from_glob(glob)
75
- Regexp.new(glob.gsub('.', '\\.').gsub('*', '.*') + '$')
72
+ Regexp.new(glob.sub('.', '\\.').gsub('*', '.*') + '$')
76
73
  end
77
74
 
78
75
  def custom_transform
79
- cop_config['CustomTransform'] || []
76
+ cop_config['CustomTransform'] || {}
80
77
  end
81
78
  end
82
79
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module RuboCop
@@ -21,44 +20,63 @@ module RuboCop
21
20
  # describe MyClass do
22
21
  # end
23
22
  class Focus < Cop
24
- MESSAGE = 'Focused spec found.'.freeze
23
+ MSG = 'Focused spec found.'.freeze
25
24
 
26
- FOCUSABLE_BLOCKS = [
27
- :example_group, :describe, :context, :xdescribe, :xcontext,
28
- :it, :example, :specify, :xit, :xexample, :xspecify,
29
- :feature, :scenario, :xfeature, :xscenario
30
- ].freeze
25
+ FOCUSABLE_SELECTORS = '
26
+ :context
27
+ :describe
28
+ :example
29
+ :example_group
30
+ :feature
31
+ :it
32
+ :scenario
33
+ :specify
34
+ :xcontext
35
+ :xdescribe
36
+ :xexample
37
+ :xfeature
38
+ :xit
39
+ :xscenario
40
+ :xspecify
41
+ '.freeze
31
42
 
32
- FOCUSED_BLOCKS = [
33
- :fdescribe, :fcontext,
34
- :focus, :fexample, :fit, :fspecify,
35
- :ffeature, :fscenario
36
- ].freeze
43
+ FOCUSING_SELECTORS = '
44
+ :fcontext
45
+ :fdescribe
46
+ :fexample
47
+ :ffeature
48
+ :fit
49
+ :focus
50
+ :fscenario
51
+ :fspecify
52
+ '.freeze
37
53
 
38
- FOCUS_KEY = s(:sym, :focus)
54
+ FOCUS_SYMBOL = s(:sym, :focus)
55
+ FOCUS_TRUE = s(:pair, FOCUS_SYMBOL, s(:true))
39
56
 
40
- FOCUS_TRUE_PAIR = s(:pair, FOCUS_KEY, s(:true))
57
+ def_node_matcher :metadata, <<-PATTERN
58
+ {(send nil {#{FOCUSABLE_SELECTORS}} ... (hash $...))
59
+ (send nil {#{FOCUSABLE_SELECTORS}} $...)}
60
+ PATTERN
41
61
 
42
- def on_send(node)
43
- _receiver, method_name, *_args = *node
44
- @focusable_block = FOCUSABLE_BLOCKS.include?(method_name)
45
- if FOCUSED_BLOCKS.include?(method_name)
46
- add_offense(node, :expression, MESSAGE)
47
- end
62
+ def_node_matcher :focused_block?, <<-PATTERN
63
+ (send nil {#{FOCUSING_SELECTORS}} ...)
64
+ PATTERN
48
65
 
49
- # check for :focus
50
- return unless @focusable_block
51
- node.children.any? do |n|
52
- add_offense(n, :expression, MESSAGE) if n == FOCUS_KEY
66
+ def on_send(node)
67
+ focus_metadata(node) do |focus|
68
+ add_offense(focus, :expression)
53
69
  end
54
70
  end
55
71
 
56
- def on_hash(node)
57
- return unless @focusable_block
58
- return if node.children.any? do |n|
59
- if [FOCUS_TRUE_PAIR].include?(n)
60
- add_offense(n, :expression, MESSAGE)
61
- end
72
+ private
73
+
74
+ def focus_metadata(node, &block)
75
+ yield(node) if focused_block?(node)
76
+
77
+ metadata(node) do |matches|
78
+ matches.grep(FOCUS_SYMBOL, &block)
79
+ matches.grep(FOCUS_TRUE, &block)
62
80
  end
63
81
  end
64
82
  end