rubocop-rspec 1.5.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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