rubocop-rspec 1.5.2 → 1.5.3

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: 41d29a68e96541d0d09976b9cdc582f4c468a447
4
- data.tar.gz: d38ae28874032c3035a8fd78e6865dfece308fe6
3
+ metadata.gz: 7a5f78eba0374bbe357f1de4227be9e3b6282116
4
+ data.tar.gz: 20fa1701861557f4c615613a9f3fe3300a758ac1
5
5
  SHA512:
6
- metadata.gz: 109b7e39672639b8aeb325439b0501dcec5d9e96eecde7b014cbe5647403bc5d8715a6499bfe9a5ea86bd8ec05f94f17cd75a0c59d9f1882031b3463961fe92b
7
- data.tar.gz: 3bb0205007875394a79cc08782dd82ce7186238e155ec18b7078a59aef9572ff8804cc252027f6c2977415fe200605f0741688011a6845ec0eb276e163a3e37d
6
+ metadata.gz: 098e42022cd531df17726bc09d7d392b990d08b63c22e59a4b71e28f7a7cc23613688d93fc1f5edc97cb9e97cea1bab92d6a03ddaa0405f74e822e74e02c7744
7
+ data.tar.gz: 2461baf4ad9f1eadff4264a786bdeff878a50c164ac6576558ebabdd2b2e7870a5cc05996d419a499e9c97d7f7b32be67fd645e16f0a6c233fccb53adb0a1b15
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Master (unreleased)
4
4
 
5
+ ## 1.5.3 (2016-08-02)
6
+
7
+ * Add `RSpec/NamedSubject` cop. ([@backus][])
8
+
5
9
  ## 1.5.2 (2016-08-01)
6
10
 
7
11
  * Drop support for ruby `2.0.0` and `2.1.0`. ([@backus][])
@@ -60,3 +60,7 @@ RSpec/ExampleLength:
60
60
  Description: 'Checks for long example'
61
61
  Enabled: true
62
62
  Max: 5
63
+
64
+ RSpec/NamedSubject:
65
+ Description: 'Name your RSpec subject if you reference it explicitly'
66
+ Enabled: true
@@ -19,5 +19,6 @@ require 'rubocop/cop/rspec/focus'
19
19
  require 'rubocop/cop/rspec/instance_variable'
20
20
  require 'rubocop/cop/rspec/example_length'
21
21
  require 'rubocop/cop/rspec/multiple_describes'
22
+ require 'rubocop/cop/rspec/named_subject'
22
23
  require 'rubocop/cop/rspec/not_to_not'
23
24
  require 'rubocop/cop/rspec/verified_doubles'
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Give `subject` a descriptive name if you reference it directly
7
+ #
8
+ # @example
9
+ # # bad
10
+ # RSpec.describe User do
11
+ # subject { described_class.new }
12
+ #
13
+ # it 'is valid' do
14
+ # expect(subject.valid?).to be(true)
15
+ # end
16
+ # end
17
+ #
18
+ # # good
19
+ # RSpec.describe Foo do
20
+ # subject(:user) { described_class.new }
21
+ #
22
+ # it 'is valid' do
23
+ # expect(user.valid?).to be(true)
24
+ # end
25
+ # end
26
+ #
27
+ # # also good
28
+ # RSpec.describe Foo do
29
+ # subject(:user) { described_class.new }
30
+ #
31
+ # it { should be_valid }
32
+ # end
33
+ class NamedSubject < Cop
34
+ MSG = 'Name your test subject if '\
35
+ 'you need to reference it explicitly.'.freeze
36
+
37
+ def_node_matcher :rspec_block?, <<-PATTERN
38
+ (block
39
+ (send nil {:it :specify :before :after :around} ...)
40
+ ...)
41
+ PATTERN
42
+
43
+ def_node_matcher :unnamed_subject, '$(send nil :subject)'
44
+
45
+ def on_block(node)
46
+ return unless rspec_block?(node)
47
+
48
+ subject_usage(node) do |subject_node|
49
+ add_offense(subject_node, :selector)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def subject_usage(node, &block)
56
+ return unless node.instance_of?(Node)
57
+
58
+ unnamed_subject(node, &block)
59
+
60
+ node.children.each do |child|
61
+ subject_usage(child, &block)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ 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.2'.freeze
7
+ STRING = '1.5.3'.freeze
8
8
  end
9
9
  end
10
10
  end
@@ -35,4 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency 'rake'
36
36
  spec.add_development_dependency 'rspec', '>= 3.4'
37
37
  spec.add_development_dependency 'simplecov'
38
+ spec.add_development_dependency 'anima'
39
+ spec.add_development_dependency 'concord'
40
+ spec.add_development_dependency 'adamantium'
38
41
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe ExpectViolation::Expectation do
4
+ subject(:expectation) { described_class.new(string) }
5
+
6
+ context 'when given a single assertion on class end' do
7
+ let(:string) do
8
+ <<-SRC
9
+ class Foo
10
+ end
11
+ ^^^ The end of `Foo` should be annotated.
12
+ SRC
13
+ end
14
+
15
+ let(:assertion) { expectation.assertions.first }
16
+
17
+ it 'has one assertion' do
18
+ expect(expectation.assertions.size).to be(1)
19
+ end
20
+
21
+ it 'has an assertion on line 2' do
22
+ expect(assertion.line_number).to be(2)
23
+ end
24
+
25
+ it 'has an assertion on column range 1-3' do
26
+ expect(assertion.column_range).to eql(6...9)
27
+ end
28
+
29
+ it 'has an assertion with correct violation message' do
30
+ expect(assertion.message).to eql('The end of `Foo` should be annotated.')
31
+ end
32
+
33
+ it 'recreates source' do
34
+ expect(expectation.source).to eql(<<-RUBY)
35
+ class Foo
36
+ end
37
+ RUBY
38
+ end
39
+ end
40
+
41
+ context 'when given many assertions on two lines' do
42
+ let(:string) do
43
+ <<-SRC
44
+ foo bar
45
+ ^ Charlie
46
+ ^^ Charlie
47
+ ^^ Bronco
48
+ ^^ Alpha
49
+ baz
50
+ ^ Delta
51
+ SRC
52
+ end
53
+
54
+ let(:assertions) { expectation.assertions.sort }
55
+
56
+ it 'has two assertions' do
57
+ expect(expectation.assertions.size).to be(5)
58
+ end
59
+
60
+ it 'has assertions on lines 1 and 2' do
61
+ expect(assertions.map(&:line_number)).to eql(
62
+ [1, 1, 1, 1, 2]
63
+ )
64
+ end
65
+
66
+ it 'has assertions on column range 1-3' do
67
+ expect(assertions.map(&:column_range)).to eql(
68
+ [9...11, 10...11, 10...12, 10...12, 6...7]
69
+ )
70
+ end
71
+
72
+ it 'has an assertion with correct violation message' do
73
+ expect(assertions.map(&:message)).to eql(
74
+ %w(Charlie Charlie Alpha Bronco Delta)
75
+ )
76
+ end
77
+
78
+ it 'recreates source' do
79
+ expect(expectation.source).to eql(<<-RUBY)
80
+ foo bar
81
+ baz
82
+ RUBY
83
+ end
84
+ end
85
+ end
@@ -2,47 +2,29 @@ describe RuboCop::Cop::RSpec::AnyInstance do
2
2
  subject(:cop) { described_class.new }
3
3
 
4
4
  it 'finds `allow_any_instance_of` instead of an instance double' do
5
- inspect_source(
6
- cop,
7
- [
8
- 'before do',
9
- ' allow_any_instance_of(Object).to receive(:foo)',
10
- 'end'
11
- ]
12
- )
13
- expect(cop.messages)
14
- .to eq(['Avoid stubbing using `allow_any_instance_of`'])
15
- expect(cop.highlights).to eq(['allow_any_instance_of(Object)'])
16
- expect(cop.offenses.map(&:line).sort).to eq([2])
5
+ expect_violation(<<-RUBY)
6
+ before do
7
+ allow_any_instance_of(Object).to receive(:foo)
8
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `allow_any_instance_of`
9
+ end
10
+ RUBY
17
11
  end
18
12
 
19
13
  it 'finds `expect_any_instance_of` instead of an instance double' do
20
- inspect_source(
21
- cop,
22
- [
23
- 'before do',
24
- ' expect_any_instance_of(Object).to receive(:foo)',
25
- 'end'
26
- ]
27
- )
28
- expect(cop.messages)
29
- .to eq(['Avoid stubbing using `expect_any_instance_of`'])
30
- expect(cop.highlights).to eq(['expect_any_instance_of(Object)'])
31
- expect(cop.offenses.map(&:line).sort).to eq([2])
14
+ expect_violation(<<-RUBY)
15
+ before do
16
+ expect_any_instance_of(Object).to receive(:foo)
17
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `expect_any_instance_of`
18
+ end
19
+ RUBY
32
20
  end
33
21
 
34
22
  it 'finds old `any_instance` syntax instead of an instance double' do
35
- inspect_source(
36
- cop,
37
- [
38
- 'before do',
39
- ' Object.any_instance.should_receive(:foo)',
40
- 'end'
41
- ]
42
- )
43
- expect(cop.messages)
44
- .to eq(['Avoid stubbing using `any_instance`'])
45
- expect(cop.highlights).to eq(['Object.any_instance'])
46
- expect(cop.offenses.map(&:line).sort).to eq([2])
23
+ expect_violation(<<-RUBY)
24
+ before do
25
+ Object.any_instance.should_receive(:foo)
26
+ ^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `any_instance`
27
+ end
28
+ RUBY
47
29
  end
48
30
  end
@@ -2,109 +2,112 @@ describe RuboCop::Cop::RSpec::DescribeClass do
2
2
  subject(:cop) { described_class.new }
3
3
 
4
4
  it 'checks first-line describe statements' do
5
- inspect_source(cop, 'describe "bad describe" do; end')
6
- expect(cop.offenses.size).to eq(1)
7
- expect(cop.offenses.map(&:line).sort).to eq([1])
8
- expect(cop.messages).to eq(['The first argument to describe should be ' \
9
- 'the class or module being tested.'])
5
+ expect_violation(<<-RUBY)
6
+ describe "bad describe" do
7
+ ^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
8
+ end
9
+ RUBY
10
10
  end
11
11
 
12
12
  it 'supports RSpec.describe' do
13
- inspect_source(cop, 'RSpec.describe Foo do; end')
14
- expect(cop.offenses).to be_empty
13
+ expect_no_violations(<<-RUBY)
14
+ RSpec.describe Foo do
15
+ end
16
+ RUBY
15
17
  end
16
18
 
17
19
  it 'checks describe statements after a require' do
18
- inspect_source(
19
- cop,
20
- [
21
- "require 'spec_helper'",
22
- 'describe "bad describe" do; end'
23
- ]
24
- )
25
- expect(cop.offenses.size).to eq(1)
26
- expect(cop.offenses.map(&:line).sort).to eq([2])
27
- expect(cop.messages).to eq(['The first argument to describe should be ' \
28
- 'the class or module being tested.'])
20
+ expect_violation(<<-RUBY)
21
+ require 'spec_helper'
22
+ describe "bad describe" do
23
+ ^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
24
+ end
25
+ RUBY
29
26
  end
30
27
 
31
28
  it 'checks highlights the first argument of a describe' do
32
- inspect_source(cop, 'describe "bad describe", "blah blah" do; end')
33
- expect(cop.offenses.first.location.column_range).to eq(9...23)
29
+ expect_violation(<<-RUBY)
30
+ describe "bad describe", "blah blah" do
31
+ ^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
32
+ end
33
+ RUBY
34
34
  end
35
35
 
36
36
  it 'ignores nested describe statements' do
37
- inspect_source(
38
- cop,
39
- [
40
- 'describe Some::Class do',
41
- ' describe "bad describe" do; end',
42
- 'end'
43
- ]
44
- )
45
- expect(cop.offenses).to be_empty
37
+ expect_no_violations(<<-RUBY)
38
+ describe Some::Class do
39
+ describe "bad describe" do
40
+ end
41
+ end
42
+ RUBY
46
43
  end
47
44
 
48
45
  it 'ignores request specs' do
49
- inspect_source(cop, "describe 'my new feature', type: :request do; end")
50
- expect(cop.offenses).to be_empty
46
+ expect_no_violations(<<-RUBY)
47
+ describe 'my new feature', type: :request do
48
+ end
49
+ RUBY
51
50
  end
52
51
 
53
52
  it 'ignores feature specs' do
54
- inspect_source(cop, "describe 'my new feature', type: :feature do; end")
55
- expect(cop.offenses).to be_empty
53
+ expect_no_violations(<<-RUBY)
54
+ describe 'my new feature', type: :feature do
55
+ end
56
+ RUBY
56
57
  end
57
58
 
58
59
  it 'ignores feature specs when RSpec.describe is used' do
59
- inspect_source(
60
- cop,
61
- "RSpec.describe 'my new feature', type: :feature do; end"
62
- )
63
-
64
- expect(cop.offenses).to be_empty
60
+ expect_no_violations(<<-RUBY)
61
+ RSpec.describe 'my new feature', type: :feature do
62
+ end
63
+ RUBY
65
64
  end
66
65
 
67
66
  it 'flags specs with non :type metadata' do
68
- inspect_source(cop, "describe 'my new feature', foo: :feature do; end")
69
- expect(cop.messages).to eq(['The first argument to describe should be ' \
70
- 'the class or module being tested.'])
67
+ expect_violation(<<-RUBY)
68
+ describe 'my new feature', foo: :feature do
69
+ ^^^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
70
+ end
71
+ RUBY
71
72
  end
72
73
 
73
74
  it 'flags normal metadata in describe' do
74
- inspect_source(cop, "describe 'my new feature', blah, type: :wow do; end")
75
- expect(cop.messages).to eq(['The first argument to describe should be ' \
76
- 'the class or module being tested.'])
75
+ expect_violation(<<-RUBY)
76
+ describe 'my new feature', blah, type: :wow do
77
+ ^^^^^^^^^^^^^^^^ The first argument to describe should be the class or module being tested.
78
+ end
79
+ RUBY
77
80
  end
78
81
 
79
82
  it 'ignores feature specs - also with complex options' do
80
- inspect_source(
81
- cop,
82
- [
83
- "describe 'my new feature',",
84
- ' :test, :type => :feature, :foo => :bar do;',
85
- 'end'
86
- ]
87
- )
88
- expect(cop.offenses).to be_empty
83
+ expect_no_violations(<<-RUBY)
84
+ describe 'my new feature', :test, :type => :feature, :foo => :bar do
85
+ end
86
+ RUBY
89
87
  end
90
88
 
91
89
  it 'ignores an empty describe' do
92
- inspect_source(cop, 'describe do; end')
93
- expect(cop.offenses).to be_empty
90
+ expect_no_violations(<<-RUBY)
91
+ describe do
92
+ end
93
+ RUBY
94
94
  end
95
95
 
96
96
  it 'ignores routing specs' do
97
- inspect_source(cop, "describe 'my new route', type: :routing do; end")
98
- expect(cop.offenses).to be_empty
97
+ expect_no_violations(<<-RUBY)
98
+ describe 'my new route', type: :routing do
99
+ end
100
+ RUBY
99
101
  end
100
102
 
101
103
  it 'ignores view specs' do
102
- inspect_source(cop, "describe 'widgets/index', type: :view do; end")
103
- expect(cop.offenses).to be_empty
104
+ expect_no_violations(<<-RUBY)
105
+ describe 'widgets/index', type: :view do
106
+ end
107
+ RUBY
104
108
  end
105
109
 
106
110
  it "doesn't blow up on single-line describes" do
107
- inspect_source(cop, 'describe Some::Class')
108
- expect(cop.offenses).to be_empty
111
+ expect_no_violations('describe Some::Class')
109
112
  end
110
113
  end