rubocop-rspec 1.15.0 → 1.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/Rakefile +1 -1
- data/config/default.yml +2 -1
- data/lib/rubocop/cop/rspec/cop.rb +3 -2
- data/lib/rubocop/cop/rspec/describe_method.rb +2 -2
- data/lib/rubocop/cop/rspec/example_wording.rb +7 -11
- data/lib/rubocop/cop/rspec/expect_actual.rb +4 -4
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/leading_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/message_spies.rb +1 -1
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +23 -3
- data/lib/rubocop/rspec/concept.rb +3 -2
- data/lib/rubocop/rspec/hook.rb +1 -1
- data/lib/rubocop/rspec/language.rb +17 -17
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop/rspec/wording.rb +53 -19
- data/spec/expect_violation/expectation_spec.rb +1 -1
- data/spec/project/default_config_spec.rb +2 -2
- data/spec/rubocop/cop/rspec/cop_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/described_class_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/empty_example_group_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/example_wording_spec.rb +41 -2
- data/spec/rubocop/cop/rspec/iterated_expectation_spec.rb +8 -0
- data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb +39 -0
- data/spec/rubocop/rspec/example_spec.rb +1 -1
- data/spec/rubocop/rspec/language/selector_set_spec.rb +4 -4
- data/spec/rubocop/rspec/wording_spec.rb +14 -8
- data/spec/support/expect_violation.rb +10 -8
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a604474acdd504b70582e29579a8ec65a6bbbfa
|
4
|
+
data.tar.gz: f8fa3ac1215089b95341115ca35edb73ddb148c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0d4f97983ce7f1147d32b8948d22d5c7b30490a946e5500e2aa78f60daad47f9e68eac81e6da2825e83f8248a8a8ed4dfd538a30e4b7dcc9af462fee16bda2c
|
7
|
+
data.tar.gz: dd3bc63ff868cef005a10da71f873dc804d333fd8950de8636d980064341b386a74e281ba698d051859c7c4ddceb7ee257d527ac68c7129fd660f7321014b9ac
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
-
## 1.15.
|
5
|
+
## 1.15.1 (2017-04-30)
|
6
|
+
|
7
|
+
* Fix the handling of various edge cases in the `RSpec/ExampleWording` cop, including one that would cause autocorrect to crash. ([@dgollahon][])
|
8
|
+
* Fix `RSpec/IteratedExpectation` crashing when there is an assignment in the iteration. ([@Darhazer][])
|
9
|
+
* Fix false positive in `RSpec/SingleArgumentMessageChain` cop when the single argument is a hash. ([@Darhazer][])
|
10
|
+
|
11
|
+
## 1.15.0 (2017-03-26)
|
6
12
|
|
7
13
|
* Add `RSpec/DescribeSymbol` cop. ([@tsigo][])
|
8
14
|
* Fix error when `RSpec/OverwritingSetup` and `RSpec/ScatteredLet` analyzed empty example groups. ([@backus][])
|
data/Rakefile
CHANGED
data/config/default.yml
CHANGED
@@ -33,11 +33,12 @@ module RuboCop
|
|
33
33
|
# - '_test.rb$'
|
34
34
|
# - '(?:^|/)test/'
|
35
35
|
class Cop < WorkaroundCop
|
36
|
+
include RuboCop::RSpec::Language
|
37
|
+
include RuboCop::RSpec::Language::NodePattern
|
38
|
+
|
36
39
|
DEFAULT_CONFIGURATION =
|
37
40
|
RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
|
38
41
|
|
39
|
-
include RuboCop::RSpec::Language, RuboCop::RSpec::Language::NodePattern
|
40
|
-
|
41
42
|
# Invoke the original inherited hook so our cops are recognized
|
42
43
|
def self.inherited(subclass)
|
43
44
|
RuboCop::Cop::Cop.inherited(subclass)
|
@@ -17,8 +17,8 @@ module RuboCop
|
|
17
17
|
# describe MyClass, '.my_class_method' do
|
18
18
|
# end
|
19
19
|
class DescribeMethod < Cop
|
20
|
-
include RuboCop::RSpec::TopLevelDescribe
|
21
|
-
|
20
|
+
include RuboCop::RSpec::TopLevelDescribe
|
21
|
+
include RuboCop::RSpec::Util
|
22
22
|
|
23
23
|
MSG = 'The second argument to describe should be the method '\
|
24
24
|
"being tested. '#instance' or '.class'.".freeze
|
@@ -33,8 +33,8 @@ module RuboCop
|
|
33
33
|
MSG_SHOULD = 'Do not use should when describing your tests.'.freeze
|
34
34
|
MSG_IT = "Do not repeat 'it' when describing your tests.".freeze
|
35
35
|
|
36
|
-
SHOULD_PREFIX = '
|
37
|
-
IT_PREFIX =
|
36
|
+
SHOULD_PREFIX = /\Ashould(?:n't)?\b/i
|
37
|
+
IT_PREFIX = /\Ait /i
|
38
38
|
|
39
39
|
def_node_matcher(
|
40
40
|
:it_description,
|
@@ -43,20 +43,16 @@ module RuboCop
|
|
43
43
|
|
44
44
|
def on_block(node)
|
45
45
|
it_description(node) do |description_node, message|
|
46
|
-
|
47
|
-
|
48
|
-
if text.start_with?(SHOULD_PREFIX)
|
46
|
+
if message =~ SHOULD_PREFIX
|
49
47
|
add_wording_offense(description_node, MSG_SHOULD)
|
50
|
-
elsif
|
48
|
+
elsif message =~ IT_PREFIX
|
51
49
|
add_wording_offense(description_node, MSG_IT)
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
56
54
|
def autocorrect(range)
|
57
|
-
|
58
|
-
corrector.replace(range, replacement_text(range))
|
59
|
-
end
|
55
|
+
->(corrector) { corrector.replace(range, replacement_text(range)) }
|
60
56
|
end
|
61
57
|
|
62
58
|
private
|
@@ -77,13 +73,13 @@ module RuboCop
|
|
77
73
|
def replacement_text(range)
|
78
74
|
text = range.source
|
79
75
|
|
80
|
-
if text
|
76
|
+
if text =~ SHOULD_PREFIX
|
81
77
|
RuboCop::RSpec::Wording.new(
|
82
78
|
text,
|
83
79
|
ignore: ignored_words,
|
84
80
|
replace: custom_transform
|
85
81
|
).rewrite
|
86
|
-
|
82
|
+
else
|
87
83
|
text.sub(IT_PREFIX, '')
|
88
84
|
end
|
89
85
|
end
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
class ExpectActual < Cop
|
20
20
|
MSG = 'Provide the actual you are testing to `expect(...)`.'.freeze
|
21
21
|
|
22
|
-
SIMPLE_LITERALS = %i
|
22
|
+
SIMPLE_LITERALS = %i[
|
23
23
|
true
|
24
24
|
false
|
25
25
|
nil
|
@@ -30,16 +30,16 @@ module RuboCop
|
|
30
30
|
complex
|
31
31
|
rational
|
32
32
|
regopt
|
33
|
-
|
33
|
+
].freeze
|
34
34
|
|
35
|
-
COMPLEX_LITERALS = %i
|
35
|
+
COMPLEX_LITERALS = %i[
|
36
36
|
array
|
37
37
|
hash
|
38
38
|
pair
|
39
39
|
irange
|
40
40
|
erange
|
41
41
|
regexp
|
42
|
-
|
42
|
+
].freeze
|
43
43
|
|
44
44
|
def_node_matcher :expect_literal, '(send _ :expect $#literal?)'
|
45
45
|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
MSG = 'Prefer `%s` for setting message expectations.'.freeze
|
31
31
|
|
32
|
-
SUPPORTED_STYLES = %w
|
32
|
+
SUPPORTED_STYLES = %w[allow expect].freeze
|
33
33
|
|
34
34
|
def_node_matcher :message_expectation, <<-PATTERN
|
35
35
|
(send $(send nil {:expect :allow} ...) :to #receive_message?)
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
'expectations. Setup `%s` as a spy using `allow`'\
|
35
35
|
' or `instance_spy`.'.freeze
|
36
36
|
|
37
|
-
SUPPORTED_STYLES = %w
|
37
|
+
SUPPORTED_STYLES = %w[have_received receive].freeze
|
38
38
|
|
39
39
|
def_node_matcher :message_expectation, %(
|
40
40
|
(send (send nil :expect $_) {:to :to_not :not_to} ...)
|
@@ -19,12 +19,16 @@ module RuboCop
|
|
19
19
|
'`%<called>s` with a single argument.'.freeze
|
20
20
|
|
21
21
|
def_node_matcher :message_chain, <<-PATTERN
|
22
|
-
(send _ #{Matchers::MESSAGE_CHAIN.node_pattern_union}
|
22
|
+
(send _ #{Matchers::MESSAGE_CHAIN.node_pattern_union} $_)
|
23
23
|
PATTERN
|
24
24
|
|
25
|
+
def_node_matcher :single_key_hash?, '(hash pair)'
|
26
|
+
|
25
27
|
def on_send(node)
|
26
|
-
message_chain(node) do |
|
27
|
-
return if
|
28
|
+
message_chain(node) do |arg|
|
29
|
+
return if arg.to_s.include?('.')
|
30
|
+
|
31
|
+
return if arg.hash_type? && !single_key_hash?(arg)
|
28
32
|
|
29
33
|
add_offense(node, :selector)
|
30
34
|
end
|
@@ -33,11 +37,27 @@ module RuboCop
|
|
33
37
|
def autocorrect(node)
|
34
38
|
lambda do |corrector|
|
35
39
|
corrector.replace(node.loc.selector, replacement(node.method_name))
|
40
|
+
message_chain(node) do |arg|
|
41
|
+
autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg)
|
42
|
+
end
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
39
46
|
private
|
40
47
|
|
48
|
+
def autocorrect_hash_arg(corrector, arg)
|
49
|
+
key, value = *arg.children.first
|
50
|
+
|
51
|
+
corrector.replace(arg.loc.expression, key_to_arg(key))
|
52
|
+
corrector.insert_after(arg.parent.loc.end,
|
53
|
+
".and_return(#{value.source})")
|
54
|
+
end
|
55
|
+
|
56
|
+
def key_to_arg(node)
|
57
|
+
key, = *node
|
58
|
+
node.sym_type? ? ":#{key}" : node.source
|
59
|
+
end
|
60
|
+
|
41
61
|
def replacement(method)
|
42
62
|
method.equal?(:receive_message_chain) ? 'receive' : 'stub'
|
43
63
|
end
|
@@ -4,7 +4,8 @@ module RuboCop
|
|
4
4
|
module RSpec
|
5
5
|
# Wrapper for RSpec DSL methods
|
6
6
|
class Concept
|
7
|
-
include Language
|
7
|
+
include Language
|
8
|
+
include Language::NodePattern
|
8
9
|
extend NodePattern::Macros
|
9
10
|
|
10
11
|
def initialize(node)
|
@@ -12,7 +13,7 @@ module RuboCop
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def eql?(other)
|
15
|
-
node
|
16
|
+
node == other.node
|
16
17
|
end
|
17
18
|
|
18
19
|
alias == eql?
|
data/lib/rubocop/rspec/hook.rb
CHANGED
@@ -44,49 +44,49 @@ module RuboCop
|
|
44
44
|
end
|
45
45
|
|
46
46
|
module Matchers
|
47
|
-
MESSAGE_CHAIN = SelectorSet.new(%i
|
47
|
+
MESSAGE_CHAIN = SelectorSet.new(%i[receive_message_chain stub_chain])
|
48
48
|
end
|
49
49
|
|
50
50
|
module ExampleGroups
|
51
|
-
GROUPS = SelectorSet.new(%i
|
52
|
-
SKIPPED = SelectorSet.new(%i
|
53
|
-
FOCUSED = SelectorSet.new(%i
|
51
|
+
GROUPS = SelectorSet.new(%i[describe context feature example_group])
|
52
|
+
SKIPPED = SelectorSet.new(%i[xdescribe xcontext xfeature])
|
53
|
+
FOCUSED = SelectorSet.new(%i[fdescribe fcontext ffeature])
|
54
54
|
|
55
55
|
ALL = GROUPS + SKIPPED + FOCUSED
|
56
56
|
end
|
57
57
|
|
58
58
|
module SharedGroups
|
59
|
-
EXAMPLES = SelectorSet.new(%i
|
60
|
-
CONTEXT = SelectorSet.new(%i
|
59
|
+
EXAMPLES = SelectorSet.new(%i[shared_examples shared_examples_for])
|
60
|
+
CONTEXT = SelectorSet.new(%i[shared_context])
|
61
61
|
|
62
62
|
ALL = EXAMPLES + CONTEXT
|
63
63
|
end
|
64
64
|
|
65
65
|
module Includes
|
66
66
|
EXAMPLES = SelectorSet.new(
|
67
|
-
%i
|
67
|
+
%i[
|
68
68
|
it_behaves_like
|
69
69
|
it_should_behave_like
|
70
70
|
include_examples
|
71
|
-
|
71
|
+
]
|
72
72
|
)
|
73
|
-
CONTEXT = SelectorSet.new(%i
|
73
|
+
CONTEXT = SelectorSet.new(%i[include_context])
|
74
74
|
|
75
75
|
ALL = EXAMPLES + CONTEXT
|
76
76
|
end
|
77
77
|
|
78
78
|
module Examples
|
79
|
-
EXAMPLES = SelectorSet.new(%i
|
80
|
-
FOCUSED = SelectorSet.new(%i
|
81
|
-
SKIPPED = SelectorSet.new(%i
|
82
|
-
PENDING = SelectorSet.new(%i
|
79
|
+
EXAMPLES = SelectorSet.new(%i[it specify example scenario its])
|
80
|
+
FOCUSED = SelectorSet.new(%i[fit fspecify fexample fscenario focus])
|
81
|
+
SKIPPED = SelectorSet.new(%i[xit xspecify xexample xscenario skip])
|
82
|
+
PENDING = SelectorSet.new(%i[pending])
|
83
83
|
|
84
84
|
ALL = EXAMPLES + FOCUSED + SKIPPED + PENDING
|
85
85
|
end
|
86
86
|
|
87
87
|
module Hooks
|
88
88
|
ALL = SelectorSet.new(
|
89
|
-
%i
|
89
|
+
%i[
|
90
90
|
prepend_before
|
91
91
|
before
|
92
92
|
append_before
|
@@ -94,16 +94,16 @@ module RuboCop
|
|
94
94
|
prepend_after
|
95
95
|
after
|
96
96
|
append_after
|
97
|
-
|
97
|
+
]
|
98
98
|
)
|
99
99
|
end
|
100
100
|
|
101
101
|
module Helpers
|
102
|
-
ALL = SelectorSet.new(%i
|
102
|
+
ALL = SelectorSet.new(%i[let let!])
|
103
103
|
end
|
104
104
|
|
105
105
|
module Subject
|
106
|
-
ALL = SelectorSet.new(%i
|
106
|
+
ALL = SelectorSet.new(%i[subject subject!])
|
107
107
|
end
|
108
108
|
|
109
109
|
ALL =
|
@@ -4,6 +4,11 @@ module RuboCop
|
|
4
4
|
module RSpec
|
5
5
|
# RSpec example wording rewriter
|
6
6
|
class Wording
|
7
|
+
SHOULDNT_PREFIX = /\Ashould(?:n't| not)\b/i
|
8
|
+
SHOULDNT_BE_PREFIX = /#{SHOULDNT_PREFIX} be\b/i
|
9
|
+
ES_SUFFIX_PATTERN = /(?:o|s|x|ch|sh|z)\z/i
|
10
|
+
IES_SUFFIX_PATTERN = /[^aeou]y\z/i
|
11
|
+
|
7
12
|
def initialize(text, ignore:, replace:)
|
8
13
|
@text = text
|
9
14
|
@ignores = ignore
|
@@ -11,37 +16,66 @@ module RuboCop
|
|
11
16
|
end
|
12
17
|
|
13
18
|
def rewrite
|
14
|
-
text
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
end.join(' ')
|
19
|
+
case text
|
20
|
+
when SHOULDNT_BE_PREFIX
|
21
|
+
replace_prefix(SHOULDNT_BE_PREFIX, 'is not')
|
22
|
+
when SHOULDNT_PREFIX
|
23
|
+
replace_prefix(SHOULDNT_PREFIX, 'does not')
|
24
|
+
else
|
25
|
+
remove_should_and_pluralize
|
26
|
+
end
|
24
27
|
end
|
25
28
|
|
26
29
|
private
|
27
30
|
|
28
31
|
attr_reader :text, :ignores, :replacements
|
29
32
|
|
30
|
-
def
|
31
|
-
|
33
|
+
def replace_prefix(pattern, replacement)
|
34
|
+
text.sub(pattern) do |shouldnt|
|
35
|
+
uppercase?(shouldnt) ? replacement.upcase : replacement
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def uppercase?(word)
|
40
|
+
word.upcase.eql?(word)
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_should_and_pluralize
|
44
|
+
_should, *words = text.split
|
45
|
+
|
46
|
+
words.each_with_index do |word, index|
|
47
|
+
next if ignored_word?(word)
|
32
48
|
|
33
|
-
|
34
|
-
|
35
|
-
|
49
|
+
words[index] = substitute(word)
|
50
|
+
|
51
|
+
break
|
36
52
|
end
|
37
53
|
|
38
|
-
|
39
|
-
|
40
|
-
|
54
|
+
words.join(' ')
|
55
|
+
end
|
56
|
+
|
57
|
+
def ignored_word?(word)
|
58
|
+
ignores.any? { |ignore| ignore.casecmp(word).zero? }
|
59
|
+
end
|
60
|
+
|
61
|
+
def substitute(word)
|
62
|
+
# NOTE: Custom replacements are case sensitive.
|
63
|
+
return replacements.fetch(word) if replacements.key?(word)
|
64
|
+
|
65
|
+
case word
|
66
|
+
when ES_SUFFIX_PATTERN then append_suffix(word, 'es')
|
67
|
+
when IES_SUFFIX_PATTERN then append_suffix(word[0..-2], 'ies')
|
68
|
+
else append_suffix(word, 's')
|
41
69
|
end
|
70
|
+
end
|
42
71
|
|
43
|
-
|
72
|
+
def append_suffix(word, suffix)
|
73
|
+
suffix = suffix.upcase if uppercase?(word)
|
74
|
+
|
75
|
+
"#{word}#{suffix}"
|
44
76
|
end
|
77
|
+
|
78
|
+
private_constant(*constants(false))
|
45
79
|
end
|
46
80
|
end
|
47
81
|
end
|
@@ -14,11 +14,11 @@ RSpec.describe 'config/default.yml' do
|
|
14
14
|
"RSpec/#{cop_name}"
|
15
15
|
end
|
16
16
|
|
17
|
-
cop_names - %w
|
17
|
+
cop_names - %w[RSpec/Cop]
|
18
18
|
end
|
19
19
|
|
20
20
|
let(:config_keys) do
|
21
|
-
cop_names + %w
|
21
|
+
cop_names + %w[AllCops]
|
22
22
|
end
|
23
23
|
|
24
24
|
def cop_configuration(config_key)
|
@@ -63,7 +63,7 @@ RSpec.describe RuboCop::Cop::RSpec::EmptyExampleGroup, :config do
|
|
63
63
|
|
64
64
|
context 'when a custom include method is specified' do
|
65
65
|
let(:cop_config) do
|
66
|
-
{ 'CustomIncludeMethods' => %w
|
66
|
+
{ 'CustomIncludeMethods' => %w[it_has_special_behavior] }
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'does not flag an otherwise empty example group' do
|
@@ -4,8 +4,8 @@ RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do
|
|
4
4
|
context 'with configuration' do
|
5
5
|
let(:cop_config) do
|
6
6
|
{
|
7
|
-
'CustomTransform' => { 'have' => 'has'
|
8
|
-
'IgnoredWords' => %w
|
7
|
+
'CustomTransform' => { 'have' => 'has' },
|
8
|
+
'IgnoredWords' => %w[only really]
|
9
9
|
}
|
10
10
|
end
|
11
11
|
|
@@ -37,6 +37,22 @@ RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do
|
|
37
37
|
RUBY
|
38
38
|
end
|
39
39
|
|
40
|
+
it 'flags a lone should' do
|
41
|
+
expect_violation(<<-RUBY)
|
42
|
+
it 'should' do
|
43
|
+
^^^^^^ Do not use should when describing your tests.
|
44
|
+
end
|
45
|
+
RUBY
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'flags a lone should not' do
|
49
|
+
expect_violation(<<-RUBY)
|
50
|
+
it 'should not' do
|
51
|
+
^^^^^^^^^^ Do not use should when describing your tests.
|
52
|
+
end
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
40
56
|
it 'finds leading its' do
|
41
57
|
expect_violation(<<-RUBY)
|
42
58
|
it "it does something" do
|
@@ -59,13 +75,36 @@ RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do
|
|
59
75
|
RUBY
|
60
76
|
end
|
61
77
|
|
78
|
+
it 'skips descriptions starting with words that begin with `should`' do
|
79
|
+
expect_no_violations(<<-RUBY)
|
80
|
+
it 'shoulders the burden' do
|
81
|
+
end
|
82
|
+
RUBY
|
83
|
+
end
|
84
|
+
|
62
85
|
include_examples 'autocorrect',
|
63
86
|
'it "should only have trait" do end',
|
64
87
|
'it "only has trait" do end'
|
65
88
|
|
89
|
+
include_examples 'autocorrect',
|
90
|
+
'it "SHOULDN\'T only have trait" do end',
|
91
|
+
'it "DOES NOT only have trait" do end'
|
92
|
+
|
66
93
|
include_examples 'autocorrect',
|
67
94
|
'it "it does something" do end',
|
68
95
|
'it "does something" do end'
|
96
|
+
|
97
|
+
include_examples 'autocorrect',
|
98
|
+
'it "It does something" do end',
|
99
|
+
'it "does something" do end'
|
100
|
+
|
101
|
+
include_examples 'autocorrect',
|
102
|
+
'it "should" do end',
|
103
|
+
'it "" do end'
|
104
|
+
|
105
|
+
include_examples 'autocorrect',
|
106
|
+
'it "should not" do end',
|
107
|
+
'it "does not" do end'
|
69
108
|
end
|
70
109
|
|
71
110
|
context 'when configuration is empty' do
|
@@ -59,6 +59,14 @@ RSpec.describe RuboCop::Cop::RSpec::IteratedExpectation do
|
|
59
59
|
RUBY
|
60
60
|
end
|
61
61
|
|
62
|
+
it 'ignores assignments in the iteration' do
|
63
|
+
expect_no_violations(<<-RUBY)
|
64
|
+
it 'validates users' do
|
65
|
+
[user1, user2, user3].each { |user| array = array.concat(user) }
|
66
|
+
end
|
67
|
+
RUBY
|
68
|
+
end
|
69
|
+
|
62
70
|
it 'ignores `each` when there is a negative expectation' do
|
63
71
|
expect_no_violations(<<-RUBY)
|
64
72
|
it 'validates users' do
|
@@ -4,7 +4,7 @@ RSpec.describe RuboCop::Cop::RSpec::MultipleExpectations, :config do
|
|
4
4
|
subject(:cop) { described_class.new(config) }
|
5
5
|
|
6
6
|
context 'without configuration' do
|
7
|
-
let(:cop_config) {
|
7
|
+
let(:cop_config) { {} }
|
8
8
|
|
9
9
|
it 'flags multiple expectations' do
|
10
10
|
expect_violation(<<-RUBY)
|
@@ -47,6 +47,45 @@ RSpec.describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do
|
|
47
47
|
end
|
48
48
|
RUBY
|
49
49
|
end
|
50
|
+
|
51
|
+
context 'with single-key hash argument' do
|
52
|
+
it 'reports an offence' do
|
53
|
+
expect_violation(<<-RUBY)
|
54
|
+
before do
|
55
|
+
allow(foo).to receive_message_chain(bar: 42)
|
56
|
+
^^^^^^^^^^^^^^^^^^^^^ Use `receive` instead of calling `receive_message_chain` with a single argument.
|
57
|
+
end
|
58
|
+
RUBY
|
59
|
+
end
|
60
|
+
|
61
|
+
include_examples(
|
62
|
+
'autocorrect',
|
63
|
+
'before { allow(foo).to receive_message_chain(bar: 42) }',
|
64
|
+
'before { allow(foo).to receive(:bar).and_return(42) }'
|
65
|
+
)
|
66
|
+
|
67
|
+
include_examples(
|
68
|
+
'autocorrect',
|
69
|
+
'before { allow(foo).to receive_message_chain("bar" => 42) }',
|
70
|
+
'before { allow(foo).to receive("bar").and_return(42) }'
|
71
|
+
)
|
72
|
+
|
73
|
+
include_examples(
|
74
|
+
'autocorrect',
|
75
|
+
'before { allow(foo).to receive_message_chain(:"#{foo}" => 42) }',
|
76
|
+
'before { allow(foo).to receive(:"#{foo}").and_return(42) }'
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with multiple keys hash argument' do
|
81
|
+
it "doesn't report an offence" do
|
82
|
+
expect_no_violations(<<-RUBY)
|
83
|
+
before do
|
84
|
+
allow(foo).to receive_message_chain(bar: 42, baz: 42)
|
85
|
+
end
|
86
|
+
RUBY
|
87
|
+
end
|
88
|
+
end
|
50
89
|
end
|
51
90
|
|
52
91
|
describe 'stub_chain' do
|
@@ -28,7 +28,7 @@ RSpec.describe RuboCop::RSpec::Example do
|
|
28
28
|
|
29
29
|
it 'extracts implementation' do
|
30
30
|
expect(example('it("foo") { bar; baz }').implementation)
|
31
|
-
.to
|
31
|
+
.to eq(s(:begin, s(:send, nil, :bar), s(:send, nil, :baz)))
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'returns node' do
|
@@ -1,14 +1,14 @@
|
|
1
1
|
RSpec.describe RuboCop::RSpec::Language::SelectorSet do
|
2
|
-
subject(:selector_set) { described_class.new(%i
|
2
|
+
subject(:selector_set) { described_class.new(%i[foo bar]) }
|
3
3
|
|
4
4
|
it 'composes sets' do
|
5
|
-
combined = selector_set + described_class.new(%i
|
5
|
+
combined = selector_set + described_class.new(%i[baz])
|
6
6
|
|
7
|
-
expect(combined).to eq(described_class.new(%i
|
7
|
+
expect(combined).to eq(described_class.new(%i[foo bar baz]))
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'compares by value' do
|
11
|
-
expect(selector_set).not_to eq(described_class.new(%i
|
11
|
+
expect(selector_set).not_to eq(described_class.new(%i[foo bar baz]))
|
12
12
|
end
|
13
13
|
|
14
14
|
context '#include?' do
|
@@ -1,11 +1,6 @@
|
|
1
1
|
RSpec.describe RuboCop::RSpec::Wording do
|
2
|
-
let(:replacements)
|
3
|
-
|
4
|
-
end
|
5
|
-
|
6
|
-
let(:ignores) do
|
7
|
-
%w(only really)
|
8
|
-
end
|
2
|
+
let(:replacements) { { 'have' => 'has' } }
|
3
|
+
let(:ignores) { %w[only really] }
|
9
4
|
|
10
5
|
expected_rewrites =
|
11
6
|
{
|
@@ -26,7 +21,18 @@ RSpec.describe RuboCop::RSpec::Wording do
|
|
26
21
|
'should search the internet' => 'searches the internet',
|
27
22
|
'should wish me luck' => 'wishes me luck',
|
28
23
|
'should really only return one item' => 'really only returns one item',
|
29
|
-
"shouldn't return something" => 'does not return something'
|
24
|
+
"shouldn't return something" => 'does not return something',
|
25
|
+
'SHOULD RETAIN UPPERCASE' => 'RETAINS UPPERCASE',
|
26
|
+
"shouldn't be true" => 'is not true',
|
27
|
+
"SHOULDN'T BE true" => 'IS NOT true',
|
28
|
+
"SHOULDN'T NOT RETAIN UPPERCASE" => 'DOES NOT NOT RETAIN UPPERCASE',
|
29
|
+
'should WORRY' => 'WORRIES',
|
30
|
+
'should WISH me luck' => 'WISHES me luck',
|
31
|
+
'' => '',
|
32
|
+
'should' => '',
|
33
|
+
"shouldn't" => 'does not',
|
34
|
+
'should not' => 'does not',
|
35
|
+
'should fizz' => 'fizzes'
|
30
36
|
}
|
31
37
|
|
32
38
|
expected_rewrites.each do |old, new|
|
@@ -39,13 +39,14 @@ module ExpectViolation
|
|
39
39
|
end
|
40
40
|
|
41
41
|
class Expectation
|
42
|
+
include Adamantium
|
43
|
+
include Concord.new(:string)
|
44
|
+
|
42
45
|
VIOLATION_LINE_PATTERN = /\A *\^/
|
43
46
|
|
44
47
|
VIOLATION = :violation
|
45
48
|
SOURCE = :line
|
46
49
|
|
47
|
-
include Adamantium, Concord.new(:string)
|
48
|
-
|
49
50
|
def source
|
50
51
|
source_map.to_s
|
51
52
|
end
|
@@ -117,6 +118,10 @@ module ExpectViolation
|
|
117
118
|
end
|
118
119
|
|
119
120
|
class Assertion
|
121
|
+
include Adamantium
|
122
|
+
include Anima.new(:message, :column_range, :line_number)
|
123
|
+
include Comparable
|
124
|
+
|
120
125
|
def self.parse(text:, line_number:)
|
121
126
|
parser = Parser.new(text)
|
122
127
|
|
@@ -127,10 +132,6 @@ module ExpectViolation
|
|
127
132
|
)
|
128
133
|
end
|
129
134
|
|
130
|
-
include Anima.new(:message, :column_range, :line_number),
|
131
|
-
Adamantium,
|
132
|
-
Comparable
|
133
|
-
|
134
135
|
def <=>(other)
|
135
136
|
to_a <=> other.to_a
|
136
137
|
end
|
@@ -142,9 +143,10 @@ module ExpectViolation
|
|
142
143
|
end
|
143
144
|
|
144
145
|
class Parser
|
145
|
-
|
146
|
+
include Adamantium
|
147
|
+
include Concord.new(:text)
|
146
148
|
|
147
|
-
|
149
|
+
COLUMN_PATTERN = /^ *(?<carets>\^\^*) (?<message>.+)$/
|
148
150
|
|
149
151
|
def column_range
|
150
152
|
Range.new(*match.offset(:carets), true)
|
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.15.
|
4
|
+
version: 1.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Backus
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-05-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -281,7 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
281
281
|
version: '0'
|
282
282
|
requirements: []
|
283
283
|
rubyforge_project:
|
284
|
-
rubygems_version: 2.6.
|
284
|
+
rubygems_version: 2.6.11
|
285
285
|
signing_key:
|
286
286
|
specification_version: 4
|
287
287
|
summary: Code style checking for RSpec files
|