rubocop-rspec 1.5.3 → 1.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a5f78eba0374bbe357f1de4227be9e3b6282116
4
- data.tar.gz: 20fa1701861557f4c615613a9f3fe3300a758ac1
3
+ metadata.gz: 82d2c8c126eff832fb8c23b6a53a3e0d1a7e4f9c
4
+ data.tar.gz: c02b0c96893e673c18b0480f8e2755023ecb6987
5
5
  SHA512:
6
- metadata.gz: 098e42022cd531df17726bc09d7d392b990d08b63c22e59a4b71e28f7a7cc23613688d93fc1f5edc97cb9e97cea1bab92d6a03ddaa0405f74e822e74e02c7744
7
- data.tar.gz: 2461baf4ad9f1eadff4264a786bdeff878a50c164ac6576558ebabdd2b2e7870a5cc05996d419a499e9c97d7f7b32be67fd645e16f0a6c233fccb53adb0a1b15
6
+ metadata.gz: 1d6c8e1aeaa1e02427d474c2000c3cc50094746cf85e86a98965e1041aafb7b2be35e25616cce96b69f6a6803b2d1679e31647d112ea6e819267bfde52f24cb6
7
+ data.tar.gz: 643ac89c40e06801a88c7b19d49ee9109389f9a574717f9aee9ca527e48c38f0a95f8586979eecf5d9f26161a5ef3a0a502a1870c7a7fac62ed0ac96fd6b5140
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Master (unreleased)
4
4
 
5
+ ## 1.6.0 (2016-08-03)
6
+
7
+ * Add `SkipBlocks` option for `DescribedClass` cop. ([@backus][])
8
+
5
9
  ## 1.5.3 (2016-08-02)
6
10
 
7
11
  * Add `RSpec/NamedSubject` cop. ([@backus][])
@@ -8,6 +8,7 @@ RSpec/DescribeClass:
8
8
 
9
9
  RSpec/DescribedClass:
10
10
  Description: 'Use `described_class` for tested class / module'
11
+ SkipBlocks: false
11
12
  Enabled: true
12
13
 
13
14
  RSpec/DescribeMethod:
@@ -20,41 +20,94 @@ module RuboCop
20
20
  class DescribedClass < Cop
21
21
  include RuboCop::RSpec::TopLevelDescribe
22
22
 
23
- MESSAGE = 'Use `described_class` instead of `%s`'.freeze
23
+ DESCRIBED_CLASS = 'described_class'.freeze
24
+ MSG = "Use `#{DESCRIBED_CLASS}` instead of `%s`".freeze
24
25
 
25
- def on_block(node)
26
- method, _args, body = *node
27
- return unless top_level_describe?(method)
26
+ RSPEC_BLOCK_METHODS = '
27
+ :after
28
+ :around
29
+ :before
30
+ :context
31
+ :describe
32
+ :example
33
+ :example_group
34
+ :fcontext
35
+ :fdescribe
36
+ :feature
37
+ :fexample
38
+ :ffeature
39
+ :fit
40
+ :focus
41
+ :fscenario
42
+ :fspecify
43
+ :it
44
+ :let
45
+ :let!
46
+ :scenario
47
+ :specify
48
+ :xcontext
49
+ :xdescribe
50
+ :xexample
51
+ :xfeature
52
+ :xit
53
+ :xscenario
54
+ :xspecify
55
+ '.freeze
56
+
57
+ def_node_matcher :described_constant, <<-PATTERN
58
+ (block $(send _ :describe $(const ...)) (args) $_)
59
+ PATTERN
60
+
61
+ def_node_matcher :common_instance_exec_closure?, <<-PATTERN
62
+ (block (send (const nil {:Class :Module}) :new ...) ...)
63
+ PATTERN
28
64
 
29
- _receiver, _method_name, object = *method
30
- return unless object && object.type.equal?(:const)
65
+ def_node_matcher :rspec_block?, <<-PATTERN
66
+ (block (send nil {#{RSPEC_BLOCK_METHODS}} ...) ...)
67
+ PATTERN
68
+
69
+ def_node_matcher :scope_changing_syntax?, '{def class module}'
70
+
71
+ def on_block(node)
72
+ describe, described_class, body = described_constant(node)
73
+ return unless top_level_describe?(describe)
31
74
 
32
- inspect_children(body, object)
75
+ find_constant_usage(body, described_class) do |match|
76
+ add_offense(match, :expression, format(MSG, match.const_name))
77
+ end
33
78
  end
34
79
 
35
80
  def autocorrect(node)
36
81
  lambda do |corrector|
37
- corrector.replace(node.loc.expression, 'described_class')
82
+ corrector.replace(node.loc.expression, DESCRIBED_CLASS)
38
83
  end
39
84
  end
40
85
 
41
86
  private
42
87
 
43
- def inspect_children(node, object)
88
+ def find_constant_usage(node, described_class, &block)
89
+ yield(node) if node.eql?(described_class)
90
+
44
91
  return unless node.instance_of?(Node)
45
- return if scope_change?(node) || node.type.equal?(:const)
92
+ return if scope_change?(node) || node.const_type?
46
93
 
47
94
  node.children.each do |child|
48
- if child.eql?(object)
49
- name = object.loc.expression.source
50
- add_offense(child, :expression, format(MESSAGE, name))
51
- end
52
- inspect_children(child, object)
95
+ find_constant_usage(child, described_class, &block)
53
96
  end
54
97
  end
55
98
 
56
99
  def scope_change?(node)
57
- [:def, :class, :module].include?(node.type)
100
+ scope_changing_syntax?(node) ||
101
+ common_instance_exec_closure?(node) ||
102
+ skippable_block?(node)
103
+ end
104
+
105
+ def skippable_block?(node)
106
+ node.block_type? && !rspec_block?(node) && skip_blocks?
107
+ end
108
+
109
+ def skip_blocks?
110
+ cop_config['SkipBlocks'].equal?(true)
58
111
  end
59
112
  end
60
113
  end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '1.5.3'.freeze
7
+ STRING = '1.6.0'.freeze
8
8
  end
9
9
  end
10
10
  end
@@ -1,5 +1,73 @@
1
- describe RuboCop::Cop::RSpec::DescribedClass do
2
- subject(:cop) { described_class.new }
1
+ describe RuboCop::Cop::RSpec::DescribedClass, :config do
2
+ subject(:cop) { described_class.new(config) }
3
+
4
+ shared_examples 'SkipBlocks enabled' do
5
+ it 'does not flag violations within non-rspec blocks' do
6
+ expect_violation(<<-RUBY)
7
+ describe MyClass do
8
+ controller(ApplicationController) do
9
+ bar = MyClass
10
+ end
11
+
12
+ before do
13
+ MyClass
14
+ ^^^^^^^ Use `described_class` instead of `MyClass`
15
+
16
+ Foo.custom_block do
17
+ MyClass
18
+ end
19
+ end
20
+ end
21
+ RUBY
22
+ end
23
+ end
24
+
25
+ shared_examples 'SkipBlocks disabled' do
26
+ it 'flags violations within all blocks' do
27
+ expect_violation(<<-RUBY)
28
+ describe MyClass do
29
+ controller(ApplicationController) do
30
+ bar = MyClass
31
+ ^^^^^^^ Use `described_class` instead of `MyClass`
32
+ end
33
+
34
+ before(:each) do
35
+ MyClass
36
+ ^^^^^^^ Use `described_class` instead of `MyClass`
37
+
38
+ Foo.custom_block do
39
+ MyClass
40
+ ^^^^^^^ Use `described_class` instead of `MyClass`
41
+ end
42
+ end
43
+ end
44
+ RUBY
45
+ end
46
+ end
47
+
48
+ context 'when SkipBlocks is `true`' do
49
+ let(:cop_config) { { 'SkipBlocks' => true } }
50
+
51
+ include_examples 'SkipBlocks enabled'
52
+ end
53
+
54
+ context 'when SkipBlocks anything besides `true`' do
55
+ let(:cop_config) { { 'SkipBlocks' => 'yes' } }
56
+
57
+ include_examples 'SkipBlocks disabled'
58
+ end
59
+
60
+ context 'when SkipBlocks is not set' do
61
+ let(:cop_config) { Hash.new }
62
+
63
+ include_examples 'SkipBlocks disabled'
64
+ end
65
+
66
+ context 'when SkipBlocks is `false`' do
67
+ let(:cop_config) { { 'SkipBlocks' => false } }
68
+
69
+ include_examples 'SkipBlocks disabled'
70
+ end
3
71
 
4
72
  it 'checks for the use of the described class' do
5
73
  expect_violation(<<-RUBY)
@@ -35,6 +103,9 @@ describe RuboCop::Cop::RSpec::DescribedClass do
35
103
  it 'ignores class if the scope is changing' do
36
104
  expect_no_violations(<<-RUBY)
37
105
  describe MyClass do
106
+ Class.new { foo = MyClass }
107
+ Module.new { bar = MyClass }
108
+
38
109
  def method
39
110
  include MyClass
40
111
  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.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian MacLeod
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-08-02 00:00:00.000000000 Z
12
+ date: 2016-08-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubocop