rubocop-rspec 1.5.2 → 1.5.3

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: 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