rubocop-rspec 1.35.0 → 1.36.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/config/default.yml +11 -0
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +16 -0
- data/lib/rubocop/cop/rspec/context_method.rb +53 -0
- data/lib/rubocop/cop/rspec/describe_class.rb +7 -10
- data/lib/rubocop/cop/rspec/described_class.rb +29 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +87 -0
- data/lib/rubocop/cop/rspec/example_wording.rb +28 -12
- data/lib/rubocop/cop/rspec/expect_change.rb +8 -8
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +2 -9
- data/lib/rubocop/cop/rspec/focus.rb +5 -10
- data/lib/rubocop/cop/rspec/instance_variable.rb +2 -1
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +13 -21
- data/lib/rubocop/cop/rspec/pending.rb +19 -25
- data/lib/rubocop/cop/rspec_cops.rb +2 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +7 -198
- data/Gemfile +0 -11
- data/Rakefile +0 -87
- data/rubocop-rspec.gemspec +0 -49
- data/spec/project/changelog_spec.rb +0 -76
- data/spec/project/default_config_spec.rb +0 -76
- data/spec/project/project_requires_spec.rb +0 -20
- data/spec/rubocop/cop/rspec/align_left_let_brace_spec.rb +0 -51
- data/spec/rubocop/cop/rspec/align_right_let_brace_spec.rb +0 -51
- data/spec/rubocop/cop/rspec/any_instance_spec.rb +0 -32
- data/spec/rubocop/cop/rspec/around_block_spec.rb +0 -121
- data/spec/rubocop/cop/rspec/be_eql_spec.rb +0 -81
- data/spec/rubocop/cop/rspec/be_spec.rb +0 -35
- data/spec/rubocop/cop/rspec/before_after_all_spec.rb +0 -52
- data/spec/rubocop/cop/rspec/capybara/current_path_expectation_spec.rb +0 -65
- data/spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb +0 -130
- data/spec/rubocop/cop/rspec/context_wording_spec.rb +0 -94
- data/spec/rubocop/cop/rspec/cop_spec.rb +0 -95
- data/spec/rubocop/cop/rspec/describe_class_spec.rb +0 -168
- data/spec/rubocop/cop/rspec/describe_method_spec.rb +0 -34
- data/spec/rubocop/cop/rspec/describe_symbol_spec.rb +0 -44
- data/spec/rubocop/cop/rspec/described_class_spec.rb +0 -352
- data/spec/rubocop/cop/rspec/dialect_spec.rb +0 -78
- data/spec/rubocop/cop/rspec/empty_example_group_spec.rb +0 -93
- data/spec/rubocop/cop/rspec/empty_line_after_example_group_spec.rb +0 -121
- data/spec/rubocop/cop/rspec/empty_line_after_final_let_spec.rb +0 -239
- data/spec/rubocop/cop/rspec/empty_line_after_hook_spec.rb +0 -133
- data/spec/rubocop/cop/rspec/empty_line_after_subject_spec.rb +0 -94
- data/spec/rubocop/cop/rspec/example_length_spec.rb +0 -78
- data/spec/rubocop/cop/rspec/example_without_description_spec.rb +0 -92
- data/spec/rubocop/cop/rspec/example_wording_spec.rb +0 -173
- data/spec/rubocop/cop/rspec/expect_actual_spec.rb +0 -150
- data/spec/rubocop/cop/rspec/expect_change_spec.rb +0 -86
- data/spec/rubocop/cop/rspec/expect_in_hook_spec.rb +0 -79
- data/spec/rubocop/cop/rspec/expect_output_spec.rb +0 -62
- data/spec/rubocop/cop/rspec/factory_bot/attribute_defined_statically_spec.rb +0 -208
- data/spec/rubocop/cop/rspec/factory_bot/create_list_spec.rb +0 -171
- data/spec/rubocop/cop/rspec/file_path_spec.rb +0 -200
- data/spec/rubocop/cop/rspec/focus_spec.rb +0 -139
- data/spec/rubocop/cop/rspec/hook_argument_spec.rb +0 -173
- data/spec/rubocop/cop/rspec/hooks_before_examples_spec.rb +0 -150
- data/spec/rubocop/cop/rspec/implicit_block_expectation_spec.rb +0 -135
- data/spec/rubocop/cop/rspec/implicit_expect_spec.rb +0 -102
- data/spec/rubocop/cop/rspec/implicit_subject_spec.rb +0 -188
- data/spec/rubocop/cop/rspec/instance_spy_spec.rb +0 -61
- data/spec/rubocop/cop/rspec/instance_variable_spec.rb +0 -95
- data/spec/rubocop/cop/rspec/invalid_predicate_matcher_spec.rb +0 -39
- data/spec/rubocop/cop/rspec/it_behaves_like_spec.rb +0 -47
- data/spec/rubocop/cop/rspec/iterated_expectation_spec.rb +0 -82
- data/spec/rubocop/cop/rspec/leading_subject_spec.rb +0 -119
- data/spec/rubocop/cop/rspec/leaky_constant_declaration_spec.rb +0 -91
- data/spec/rubocop/cop/rspec/let_before_examples_spec.rb +0 -137
- data/spec/rubocop/cop/rspec/let_setup_spec.rb +0 -66
- data/spec/rubocop/cop/rspec/message_chain_spec.rb +0 -23
- data/spec/rubocop/cop/rspec/message_expectation_spec.rb +0 -45
- data/spec/rubocop/cop/rspec/message_spies_spec.rb +0 -151
- data/spec/rubocop/cop/rspec/missing_example_group_argument_spec.rb +0 -57
- data/spec/rubocop/cop/rspec/multiple_describes_spec.rb +0 -30
- data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +0 -261
- data/spec/rubocop/cop/rspec/multiple_subjects_spec.rb +0 -83
- data/spec/rubocop/cop/rspec/named_subject_spec.rb +0 -123
- data/spec/rubocop/cop/rspec/nested_groups_spec.rb +0 -81
- data/spec/rubocop/cop/rspec/not_to_not_spec.rb +0 -77
- data/spec/rubocop/cop/rspec/overwriting_setup_spec.rb +0 -91
- data/spec/rubocop/cop/rspec/pending_spec.rb +0 -186
- data/spec/rubocop/cop/rspec/predicate_matcher_spec.rb +0 -354
- data/spec/rubocop/cop/rspec/rails/http_status_spec.rb +0 -90
- data/spec/rubocop/cop/rspec/receive_counts_spec.rb +0 -138
- data/spec/rubocop/cop/rspec/receive_never_spec.rb +0 -57
- data/spec/rubocop/cop/rspec/repeated_description_spec.rb +0 -76
- data/spec/rubocop/cop/rspec/repeated_example_spec.rb +0 -74
- data/spec/rubocop/cop/rspec/return_from_stub_spec.rb +0 -289
- data/spec/rubocop/cop/rspec/scattered_let_spec.rb +0 -28
- data/spec/rubocop/cop/rspec/scattered_setup_spec.rb +0 -98
- data/spec/rubocop/cop/rspec/shared_context_spec.rb +0 -137
- data/spec/rubocop/cop/rspec/shared_examples_spec.rb +0 -75
- data/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb +0 -178
- data/spec/rubocop/cop/rspec/subject_stub_spec.rb +0 -293
- data/spec/rubocop/cop/rspec/unspecified_exception_spec.rb +0 -177
- data/spec/rubocop/cop/rspec/verified_doubles_spec.rb +0 -86
- data/spec/rubocop/cop/rspec/void_expect_spec.rb +0 -49
- data/spec/rubocop/cop/rspec/yield_spec.rb +0 -81
- data/spec/rubocop/rspec/config_formatter_spec.rb +0 -52
- data/spec/rubocop/rspec/description_extractor_spec.rb +0 -63
- data/spec/rubocop/rspec/example_group_spec.rb +0 -44
- data/spec/rubocop/rspec/example_spec.rb +0 -62
- data/spec/rubocop/rspec/hook_spec.rb +0 -53
- data/spec/rubocop/rspec/language/selector_set_spec.rb +0 -53
- data/spec/rubocop/rspec/util/one_spec.rb +0 -23
- data/spec/rubocop/rspec/wording_spec.rb +0 -52
- data/spec/shared/autocorrect_behavior.rb +0 -9
- data/spec/shared/detects_style_behavior.rb +0 -9
- data/spec/shared/smoke_test_examples.rb +0 -27
- data/spec/smoke_tests/empty_spec.rb +0 -0
- data/spec/smoke_tests/factory_bot_spec.rb +0 -11
- data/spec/smoke_tests/no_tests_spec.rb +0 -4
- data/spec/smoke_tests/weird_rspec_spec.rb +0 -233
- data/spec/spec_helper.rb +0 -42
- data/spec/support/expect_offense.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5941ed5c040054adc2993a3da2b76e591a9096767e486727191702956bc04430
|
4
|
+
data.tar.gz: 34d3b8460cd36dcf5af8f1cdf918bbd43e43bf5e4c7a5a0fba829eb9c1980cbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d868ef13a01bdf13ba05eb54a0b39354017184001d44975ef3e1bbcb0d429f2ccac6675429308886cd3246e3ff83bf8f7e5e34b1b8613b9fdbfc879493f459a9
|
7
|
+
data.tar.gz: 05fae5ae2505feabbfdfa8203c57a0bbd6f9b398c33d80d9c848e2ed6fd9fdb78019c699b9f428b26533d3799c78051a5a5ddd5176d07224938f29217ca77e61
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 1.36.0 (2019-09-27)
|
6
|
+
|
7
|
+
* Fix `RSpec/DescribedClass`'s error when `described_class` is used as part of a constant. ([@pirj][])
|
8
|
+
* Fix `RSpec/ExampleWording` autocorrect of multi-line docstrings. ([@pirj][])
|
9
|
+
* Add `RSpec/ContextMethod` cop, to detect method names in `context`. ([@geniou][])
|
10
|
+
* Update RuboCop dependency to 0.68.1 with support for children matching node pattern syntax. ([@pirj][])
|
11
|
+
* Add `RSpec/EmptyLineAfterExample` cop to check that there is an empty line after example blocks. ([@pirj][])
|
12
|
+
* Fix `Capybara/CurrentPathExpectation` auto-corrector, to include option `ignore_query: true`. ([@onumis][])
|
13
|
+
* Fix `RSpec/Focus` detecting mixed array/hash metadata. ([@dgollahon][])
|
14
|
+
* Fix `RSpec/Focus` to also detect `pending` examples. ([@dgollahon][])
|
15
|
+
|
5
16
|
## 1.35.0 (2019-08-02)
|
6
17
|
|
7
18
|
* Add `RSpec/ImplicitBlockExpectation` cop. ([@pirj][])
|
@@ -440,3 +451,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
440
451
|
[@schmijos]: https://github.com/schmijos
|
441
452
|
[@foton]: https://github.com/foton
|
442
453
|
[@nc-holodakg]: https://github.com/nc-holodakg
|
454
|
+
[@onumis]: https://github.com/onumis
|
data/config/default.yml
CHANGED
@@ -49,6 +49,11 @@ RSpec/BeforeAfterAll:
|
|
49
49
|
- spec/support/**/*.rb
|
50
50
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeforeAfterAll
|
51
51
|
|
52
|
+
RSpec/ContextMethod:
|
53
|
+
Description: "`context` should not be used for specifying methods."
|
54
|
+
Enabled: true
|
55
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContextMethod
|
56
|
+
|
52
57
|
RSpec/ContextWording:
|
53
58
|
Description: Checks that `context` docstring starts with an allowed prefix.
|
54
59
|
Enabled: true
|
@@ -95,6 +100,12 @@ RSpec/EmptyExampleGroup:
|
|
95
100
|
CustomIncludeMethods: []
|
96
101
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyExampleGroup
|
97
102
|
|
103
|
+
RSpec/EmptyLineAfterExample:
|
104
|
+
Description: Checks if there is an empty line after example blocks.
|
105
|
+
Enabled: true
|
106
|
+
AllowConsecutiveOneLiners: true
|
107
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterExample
|
108
|
+
|
98
109
|
RSpec/EmptyLineAfterExampleGroup:
|
99
110
|
Description: Checks if there is an empty line after example group blocks.
|
100
111
|
Enabled: true
|
@@ -78,6 +78,7 @@ module RuboCop
|
|
78
78
|
'have_no_current_path'
|
79
79
|
end
|
80
80
|
corrector.replace(matcher_node.loc.selector, matcher_method)
|
81
|
+
add_ignore_query_options(corrector, node)
|
81
82
|
end
|
82
83
|
|
83
84
|
def convert_regexp_str_to_literal(corrector, matcher_node, regexp_str)
|
@@ -85,6 +86,21 @@ module RuboCop
|
|
85
86
|
regexp_expr = Regexp.new(regexp_str).inspect
|
86
87
|
corrector.replace(str_node.loc.expression, regexp_expr)
|
87
88
|
end
|
89
|
+
|
90
|
+
# `have_current_path` with no options will include the querystring
|
91
|
+
# while `page.current_path` does not.
|
92
|
+
# This ensures the option `ignore_query: true` is added
|
93
|
+
# except when the expectation is a regexp or string
|
94
|
+
def add_ignore_query_options(corrector, node)
|
95
|
+
expectation_node = node.parent.last_argument
|
96
|
+
expectation_last_child = expectation_node.children.last
|
97
|
+
return if %i[regexp str].include?(expectation_last_child.type)
|
98
|
+
|
99
|
+
corrector.insert_after(
|
100
|
+
expectation_last_child.loc.expression,
|
101
|
+
', ignore_query: true'
|
102
|
+
)
|
103
|
+
end
|
88
104
|
end
|
89
105
|
end
|
90
106
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# `context` should not be used for specifying methods.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# context '#foo_bar' do
|
11
|
+
# # ...
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# context '.foo_bar' do
|
15
|
+
# # ...
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# describe '#foo_bar' do
|
20
|
+
# # ...
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# describe '.foo_bar' do
|
24
|
+
# # ...
|
25
|
+
# end
|
26
|
+
class ContextMethod < Cop
|
27
|
+
MSG = 'Use `describe` for testing methods.'
|
28
|
+
|
29
|
+
def_node_matcher :context_method, <<-PATTERN
|
30
|
+
(block (send #{RSPEC} :context $(str #method_name?) ...) ...)
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_block(node)
|
34
|
+
context_method(node) do |context|
|
35
|
+
add_offense(context)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def autocorrect(node)
|
40
|
+
lambda do |corrector|
|
41
|
+
corrector.replace(node.parent.loc.selector, 'describe')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def method_name?(description)
|
48
|
+
description.start_with?('.', '#')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -29,17 +29,17 @@ module RuboCop
|
|
29
29
|
}
|
30
30
|
PATTERN
|
31
31
|
|
32
|
-
def_node_matcher :
|
33
|
-
(send #{RSPEC} :describe
|
34
|
-
|
35
|
-
|
36
|
-
(hash $...))
|
32
|
+
def_node_matcher :describe_with_rails_metadata?, <<-PATTERN
|
33
|
+
(send #{RSPEC} :describe !const ...
|
34
|
+
(hash <#rails_metadata? ...>)
|
35
|
+
)
|
37
36
|
PATTERN
|
38
37
|
|
39
38
|
def_node_matcher :rails_metadata?, <<-PATTERN
|
40
39
|
(pair
|
41
40
|
(sym :type)
|
42
|
-
(sym {:request :feature :system :routing :view})
|
41
|
+
(sym {:request :feature :system :routing :view})
|
42
|
+
)
|
43
43
|
PATTERN
|
44
44
|
|
45
45
|
def_node_matcher :shared_group?, SharedGroups::ALL.block_pattern
|
@@ -47,10 +47,7 @@ module RuboCop
|
|
47
47
|
def on_top_level_describe(node, args)
|
48
48
|
return if shared_group?(root_node)
|
49
49
|
return if valid_describe?(node)
|
50
|
-
|
51
|
-
describe_with_metadata(node) do |pairs|
|
52
|
-
return if pairs.any?(&method(:rails_metadata?))
|
53
|
-
end
|
50
|
+
return if describe_with_rails_metadata?(node)
|
54
51
|
|
55
52
|
add_offense(args.first)
|
56
53
|
end
|
@@ -8,7 +8,8 @@ module RuboCop
|
|
8
8
|
# If the first argument of describe is a class, the class is exposed to
|
9
9
|
# each example via described_class.
|
10
10
|
#
|
11
|
-
# This cop can be configured using the `EnforcedStyle`
|
11
|
+
# This cop can be configured using the `EnforcedStyle` and `SkipBlocks`
|
12
|
+
# options.
|
12
13
|
#
|
13
14
|
# @example `EnforcedStyle: described_class`
|
14
15
|
# # bad
|
@@ -32,6 +33,27 @@ module RuboCop
|
|
32
33
|
# subject { MyClass.do_something }
|
33
34
|
# end
|
34
35
|
#
|
36
|
+
# There's a known caveat with rspec-rails's `controller` helper that
|
37
|
+
# runs its block in a different context, and `described_class` is not
|
38
|
+
# available to it. `SkipBlocks` option excludes detection in all
|
39
|
+
# non-RSpec related blocks.
|
40
|
+
#
|
41
|
+
# To narrow down this setting to only a specific directory, it is
|
42
|
+
# possible to use an overriding configuration file local to that
|
43
|
+
# directory.
|
44
|
+
#
|
45
|
+
# @example `SkipBlocks: true`
|
46
|
+
# # spec/controllers/.rubocop.yml
|
47
|
+
# # RSpec/DescribedClass:
|
48
|
+
# # SkipBlocks: true
|
49
|
+
#
|
50
|
+
# # acceptable
|
51
|
+
# describe MyConcern do
|
52
|
+
# controller(ApplicationController) do
|
53
|
+
# include MyConcern
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
35
57
|
class DescribedClass < Cop
|
36
58
|
include ConfigurableEnforcedStyle
|
37
59
|
|
@@ -51,6 +73,10 @@ module RuboCop
|
|
51
73
|
(block (send _ :describe $(const ...) ...) (args) $_)
|
52
74
|
PATTERN
|
53
75
|
|
76
|
+
def_node_search :contains_described_class?, <<-PATTERN
|
77
|
+
(send nil? :described_class)
|
78
|
+
PATTERN
|
79
|
+
|
54
80
|
def on_block(node)
|
55
81
|
# In case the explicit style is used, we need to remember what's
|
56
82
|
# being described.
|
@@ -119,6 +145,8 @@ module RuboCop
|
|
119
145
|
|
120
146
|
def offensive_described_class?(node)
|
121
147
|
return unless node.const_type?
|
148
|
+
# E.g. `described_class::CONSTANT`
|
149
|
+
return if contains_described_class?(node)
|
122
150
|
|
123
151
|
nearest_described_class, = node.each_ancestor(:block)
|
124
152
|
.map { |ancestor| described_constant(ancestor) }.find(&:itself)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks if there is an empty line after example blocks.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# RSpec.describe Foo do
|
11
|
+
# it 'does this' do
|
12
|
+
# end
|
13
|
+
# it 'does that' do
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# RSpec.describe Foo do
|
19
|
+
# it 'does this' do
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# it 'does that' do
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # fair - it's ok to have non-separated one-liners
|
27
|
+
# RSpec.describe Foo do
|
28
|
+
# it { one }
|
29
|
+
# it { two }
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# @example with AllowConsecutiveOneLiners configuration
|
33
|
+
#
|
34
|
+
# # rubocop.yml
|
35
|
+
# # RSpec/EmptyLineAfterExample:
|
36
|
+
# # AllowConsecutiveOneLiners: false
|
37
|
+
#
|
38
|
+
# # bad
|
39
|
+
# RSpec.describe Foo do
|
40
|
+
# it { one }
|
41
|
+
# it { two }
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
class EmptyLineAfterExample < Cop
|
45
|
+
include RuboCop::RSpec::BlankLineSeparation
|
46
|
+
|
47
|
+
MSG = 'Add an empty line after `%<example>s`.'
|
48
|
+
|
49
|
+
def on_block(node)
|
50
|
+
return unless example?(node)
|
51
|
+
return if last_child?(node)
|
52
|
+
return if allowed_one_liner?(node)
|
53
|
+
|
54
|
+
missing_separating_line(node) do |location|
|
55
|
+
add_offense(node,
|
56
|
+
location: location,
|
57
|
+
message: format(MSG, example: node.method_name))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def allowed_one_liner?(node)
|
62
|
+
consecutive_one_liner?(node) && allow_consecutive_one_liners?
|
63
|
+
end
|
64
|
+
|
65
|
+
def allow_consecutive_one_liners?
|
66
|
+
cop_config['AllowConsecutiveOneLiners']
|
67
|
+
end
|
68
|
+
|
69
|
+
def consecutive_one_liner?(node)
|
70
|
+
node.line_count == 1 && next_one_line_example?(node)
|
71
|
+
end
|
72
|
+
|
73
|
+
def next_one_line_example?(node)
|
74
|
+
next_sibling = next_sibling(node)
|
75
|
+
return unless next_sibling
|
76
|
+
return unless example?(next_sibling)
|
77
|
+
|
78
|
+
next_sibling.line_count == 1
|
79
|
+
end
|
80
|
+
|
81
|
+
def next_sibling(node)
|
82
|
+
node.parent.children[node.sibling_index + 1]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -53,27 +53,30 @@ module RuboCop
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def autocorrect(
|
57
|
-
|
56
|
+
def autocorrect(node)
|
57
|
+
lambda do |corrector|
|
58
|
+
corrector.replace(docstring(node), replacement_text(node))
|
59
|
+
end
|
58
60
|
end
|
59
61
|
|
60
62
|
private
|
61
63
|
|
62
64
|
def add_wording_offense(node, message)
|
63
|
-
|
65
|
+
add_offense(node, location: docstring(node), message: message)
|
66
|
+
end
|
64
67
|
|
65
|
-
|
66
|
-
|
67
|
-
expr.source_buffer,
|
68
|
-
expr.begin_pos + 1,
|
69
|
-
expr.end_pos - 1
|
70
|
-
)
|
68
|
+
def docstring(node)
|
69
|
+
expr = node.loc.expression
|
71
70
|
|
72
|
-
|
71
|
+
Parser::Source::Range.new(
|
72
|
+
expr.source_buffer,
|
73
|
+
expr.begin_pos + 1,
|
74
|
+
expr.end_pos - 1
|
75
|
+
)
|
73
76
|
end
|
74
77
|
|
75
|
-
def replacement_text(
|
76
|
-
text =
|
78
|
+
def replacement_text(node)
|
79
|
+
text = text(node)
|
77
80
|
|
78
81
|
if text =~ SHOULD_PREFIX
|
79
82
|
RuboCop::RSpec::Wording.new(
|
@@ -86,6 +89,19 @@ module RuboCop
|
|
86
89
|
end
|
87
90
|
end
|
88
91
|
|
92
|
+
# Recursive processing is required to process nested dstr nodes
|
93
|
+
# that is the case for \-separated multiline strings with interpolation.
|
94
|
+
def text(node)
|
95
|
+
case node.type
|
96
|
+
when :dstr
|
97
|
+
node.node_parts.map { |child_node| text(child_node) }.join
|
98
|
+
when :str
|
99
|
+
node.value
|
100
|
+
when :begin
|
101
|
+
node.source
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
89
105
|
def custom_transform
|
90
106
|
cop_config.fetch('CustomTransform', {})
|
91
107
|
end
|
@@ -12,22 +12,22 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# @example `EnforcedStyle: block`
|
14
14
|
# # bad
|
15
|
-
# expect
|
15
|
+
# expect { run }.to change(Foo, :bar)
|
16
16
|
#
|
17
17
|
# # good
|
18
|
-
# expect
|
18
|
+
# expect { run }.to change { Foo.bar }
|
19
19
|
#
|
20
20
|
# @example `EnforcedStyle: method_call`
|
21
21
|
# # bad
|
22
|
-
# expect
|
23
|
-
# expect
|
22
|
+
# expect { run }.to change { Foo.bar }
|
23
|
+
# expect { run }.to change { foo.baz }
|
24
24
|
#
|
25
25
|
# # good
|
26
|
-
# expect
|
27
|
-
# expect
|
26
|
+
# expect { run }.to change(Foo, :bar)
|
27
|
+
# expect { run }.to change(foo, :baz)
|
28
28
|
# # also good when there are arguments or chained method calls
|
29
|
-
# expect
|
30
|
-
# expect
|
29
|
+
# expect { run }.to change { Foo.bar(:count) }
|
30
|
+
# expect { run }.to change { user.reload.name }
|
31
31
|
#
|
32
32
|
class ExpectChange < Cop
|
33
33
|
include ConfigurableEnforcedStyle
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
38
38
|
def on_block(node)
|
39
39
|
factory_attributes(node).to_a.flatten.each do |attribute|
|
40
40
|
next unless offensive_receiver?(attribute.receiver, node)
|
41
|
-
next if proc?(attribute) || association?(attribute)
|
41
|
+
next if proc?(attribute) || association?(attribute.first_argument)
|
42
42
|
|
43
43
|
add_offense(attribute)
|
44
44
|
end
|
@@ -72,14 +72,7 @@ module RuboCop
|
|
72
72
|
value_matcher(attribute).to_a.all?(&:block_pass_type?)
|
73
73
|
end
|
74
74
|
|
75
|
-
|
76
|
-
argument = attribute.first_argument
|
77
|
-
argument.hash_type? && factory_key?(argument)
|
78
|
-
end
|
79
|
-
|
80
|
-
def factory_key?(hash_node)
|
81
|
-
hash_node.keys.any? { |key| key.sym_type? && key.value == :factory }
|
82
|
-
end
|
75
|
+
def_node_matcher :association?, '(hash <(pair (sym :factory) _) ...>)'
|
83
76
|
|
84
77
|
def autocorrect_replacing_parens(node)
|
85
78
|
left_braces, right_braces = braces(node)
|
@@ -26,18 +26,16 @@ module RuboCop
|
|
26
26
|
ExampleGroups::GROUPS +
|
27
27
|
ExampleGroups::SKIPPED +
|
28
28
|
Examples::EXAMPLES +
|
29
|
-
Examples::SKIPPED
|
29
|
+
Examples::SKIPPED +
|
30
|
+
Examples::PENDING
|
30
31
|
|
31
32
|
focused = ExampleGroups::FOCUSED + Examples::FOCUSED
|
32
33
|
|
33
34
|
FOCUSABLE_SELECTORS = focusable.node_pattern_union
|
34
35
|
|
35
|
-
FOCUS_SYMBOL = s(:sym, :focus)
|
36
|
-
FOCUS_TRUE = s(:pair, FOCUS_SYMBOL, s(:true))
|
37
|
-
|
38
36
|
def_node_matcher :metadata, <<-PATTERN
|
39
|
-
{(send #{RSPEC} #{FOCUSABLE_SELECTORS}
|
40
|
-
(send #{RSPEC} #{FOCUSABLE_SELECTORS}
|
37
|
+
{(send #{RSPEC} #{FOCUSABLE_SELECTORS} <$(sym :focus) ...>)
|
38
|
+
(send #{RSPEC} #{FOCUSABLE_SELECTORS} ... (hash <$(pair (sym :focus) true) ...>))}
|
41
39
|
PATTERN
|
42
40
|
|
43
41
|
def_node_matcher :focused_block?, focused.send_pattern
|
@@ -53,10 +51,7 @@ module RuboCop
|
|
53
51
|
def focus_metadata(node, &block)
|
54
52
|
yield(node) if focused_block?(node)
|
55
53
|
|
56
|
-
metadata(node)
|
57
|
-
matches.grep(FOCUS_SYMBOL, &block)
|
58
|
-
matches.grep(FOCUS_TRUE, &block)
|
59
|
-
end
|
54
|
+
metadata(node, &block)
|
60
55
|
end
|
61
56
|
end
|
62
57
|
end
|