rubocop-rspec 1.15.0 → 1.15.1
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 +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
|