rubocop-rspec 1.27.0 → 1.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +1 -1
  4. data/config/default.yml +15 -10
  5. data/lib/rubocop/cop/rspec/describe_method.rb +1 -1
  6. data/lib/rubocop/cop/rspec/empty_example_group.rb +1 -1
  7. data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +2 -4
  8. data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +1 -3
  9. data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +1 -3
  10. data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +1 -3
  11. data/lib/rubocop/cop/rspec/example_without_description.rb +3 -4
  12. data/lib/rubocop/cop/rspec/expect_in_hook.rb +8 -23
  13. data/lib/rubocop/cop/rspec/expect_output.rb +0 -2
  14. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +146 -0
  15. data/lib/rubocop/cop/rspec/instance_spy.rb +0 -2
  16. data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
  17. data/lib/rubocop/cop/rspec/leading_subject.rb +1 -6
  18. data/lib/rubocop/cop/rspec/let_before_examples.rb +0 -2
  19. data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +35 -0
  20. data/lib/rubocop/cop/rspec/multiple_expectations.rb +1 -1
  21. data/lib/rubocop/cop/rspec/multiple_subjects.rb +4 -4
  22. data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
  23. data/lib/rubocop/cop/rspec/pending.rb +1 -1
  24. data/lib/rubocop/cop/rspec/receive_never.rb +43 -0
  25. data/lib/rubocop/cop/rspec/scattered_let.rb +0 -2
  26. data/lib/rubocop/cop/rspec/shared_context.rb +3 -3
  27. data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
  28. data/lib/rubocop/cop/rspec_cops.rb +4 -3
  29. data/lib/rubocop/rspec/align_let_brace.rb +1 -3
  30. data/lib/rubocop/rspec/blank_line_separation.rb +6 -0
  31. data/lib/rubocop/rspec/example_group.rb +0 -7
  32. data/lib/rubocop/rspec/language/node_pattern.rb +6 -0
  33. data/lib/rubocop/rspec/version.rb +1 -1
  34. data/rubocop-rspec.gemspec +2 -2
  35. data/spec/project/project_requires_spec.rb +13 -3
  36. data/spec/rubocop/cop/rspec/before_after_all_spec.rb +2 -2
  37. data/spec/rubocop/cop/rspec/empty_line_after_example_group_spec.rb +15 -0
  38. data/spec/rubocop/cop/rspec/factory_bot/attribute_defined_statically_spec.rb +156 -0
  39. data/spec/rubocop/cop/rspec/let_before_examples_spec.rb +0 -5
  40. data/spec/rubocop/cop/rspec/missing_example_group_argument_spec.rb +55 -0
  41. data/spec/rubocop/cop/rspec/overwriting_setup_spec.rb +0 -5
  42. data/spec/rubocop/cop/rspec/receive_never_spec.rb +45 -0
  43. data/spec/rubocop/cop/rspec/scattered_let_spec.rb +0 -5
  44. data/spec/shared/smoke_test_examples.rb +25 -0
  45. data/spec/smoke_tests/empty_spec.rb +0 -0
  46. data/spec/smoke_tests/factory_bot_spec.rb +11 -0
  47. data/spec/smoke_tests/no_tests_spec.rb +4 -0
  48. data/spec/smoke_tests/weird_rspec_spec.rb +233 -0
  49. data/spec/spec_helper.rb +4 -0
  50. metadata +24 -11
  51. data/lib/rubocop/cop/rspec/factory_bot/dynamic_attribute_defined_statically.rb +0 -93
  52. data/lib/rubocop/cop/rspec/factory_bot/static_attribute_defined_dynamically.rb +0 -81
  53. data/spec/rubocop/cop/rspec/factory_bot/dynamic_attribute_defined_statically_spec.rb +0 -139
  54. data/spec/rubocop/cop/rspec/factory_bot/static_attribute_defined_dynamically_spec.rb +0 -107
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Prefer declaring dynamic attribute values in a block.
8
- #
9
- # @see StaticAttributeDefinedDynamically
10
- #
11
- # @example
12
- # # bad
13
- # kind [:active, :rejected].sample
14
- #
15
- # # good
16
- # kind { [:active, :rejected].sample }
17
- #
18
- # # bad
19
- # closed_at 1.day.from_now
20
- #
21
- # # good
22
- # closed_at { 1.day.from_now }
23
- class DynamicAttributeDefinedStatically < Cop
24
- MSG = 'Use a block to set a dynamic value to an attribute.'.freeze
25
-
26
- def_node_matcher :value_matcher, <<-PATTERN
27
- (send nil? _ $...)
28
- PATTERN
29
-
30
- def_node_search :factory_attributes, <<-PATTERN
31
- (block (send nil? {:factory :trait} ...) _ { (begin $...) $(send ...) } )
32
- PATTERN
33
-
34
- def on_block(node)
35
- factory_attributes(node).to_a.flatten.each do |attribute|
36
- next if static_or_proc?(attribute)
37
- add_offense(attribute, location: :expression)
38
- end
39
- end
40
-
41
- def autocorrect(node)
42
- if !method_uses_parens?(node.location)
43
- autocorrect_without_parens(node)
44
- elsif value_hash_without_braces?(node.descendants.first)
45
- autocorrect_hash_without_braces(node)
46
- else
47
- autocorrect_replacing_parens(node)
48
- end
49
- end
50
-
51
- private
52
-
53
- def static_or_proc?(attribute)
54
- value_matcher(attribute).to_a.all? do |value|
55
- value.block_pass_type? || value.recursive_literal_or_const?
56
- end
57
- end
58
-
59
- def value_hash_without_braces?(node)
60
- node.hash_type? && !node.braces?
61
- end
62
-
63
- def method_uses_parens?(location)
64
- return false unless location.begin && location.end
65
- location.begin.source == '(' && location.end.source == ')'
66
- end
67
-
68
- def autocorrect_hash_without_braces(node)
69
- autocorrect_replacing_parens(node, ' { { ', ' } }')
70
- end
71
-
72
- def autocorrect_replacing_parens(node,
73
- start_token = ' { ',
74
- end_token = ' }')
75
- lambda do |corrector|
76
- corrector.replace(node.location.begin, start_token)
77
- corrector.replace(node.location.end, end_token)
78
- end
79
- end
80
-
81
- def autocorrect_without_parens(node)
82
- lambda do |corrector|
83
- arguments = node.descendants.first
84
- expression = arguments.location.expression
85
- corrector.insert_before(expression, '{ ')
86
- corrector.insert_after(expression, ' }')
87
- end
88
- end
89
- end
90
- end
91
- end
92
- end
93
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Prefer declaring static attribute values without a block.
8
- #
9
- # @see DynamicAttributeDefinedStatically
10
- #
11
- # @example
12
- # # bad
13
- # kind { :static }
14
- #
15
- # # good
16
- # kind :static
17
- #
18
- # # bad
19
- # comments_count { 0 }
20
- #
21
- # # good
22
- # comments_count 0
23
- #
24
- # # bad
25
- # type { User::MAGIC }
26
- #
27
- # # good
28
- # type User::MAGIC
29
- class StaticAttributeDefinedDynamically < Cop
30
- MSG = 'Do not use a block to set a static value ' \
31
- 'to an attribute.'.freeze
32
-
33
- def_node_matcher :block_value_matcher, <<-PATTERN
34
- (block (send nil? _) _ $...)
35
- PATTERN
36
-
37
- def_node_search :factory_attributes, <<-PATTERN
38
- (block (send nil? { :factory :trait } ...) _ { (begin $...) $(send ...) $(block ...) } )
39
- PATTERN
40
-
41
- def on_block(node)
42
- factory_attributes(node).to_a.flatten.each do |attribute|
43
- values = block_value_matcher(attribute)
44
- next if values.to_a.all? { |v| dynamic?(v) }
45
- add_offense(attribute, location: :expression)
46
- end
47
- end
48
-
49
- def autocorrect(node)
50
- lambda do |corrector|
51
- corrector.replace(
52
- node.loc.expression,
53
- autocorrected_source(node)
54
- )
55
- end
56
- end
57
-
58
- private
59
-
60
- def dynamic?(node)
61
- node && !node.recursive_literal_or_const?
62
- end
63
-
64
- def autocorrected_source(node)
65
- "#{node.send_node.source}#{autocorrected_attribute(node.body)}"
66
- end
67
-
68
- def autocorrected_attribute(body)
69
- if body.nil?
70
- ' nil'
71
- elsif body.hash_type?
72
- "(#{body.source})"
73
- else
74
- ' ' + body.source
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # rubocop:disable Metrics/LineLength
4
- RSpec.describe RuboCop::Cop::RSpec::FactoryBot::DynamicAttributeDefinedStatically do
5
- # rubocop:enable Metrics/LineLength
6
-
7
- subject(:cop) { described_class.new(config) }
8
-
9
- let(:config) { RuboCop::Config.new }
10
-
11
- %w[FactoryBot FactoryGirl].each do |factory_bot|
12
- context "when using #{factory_bot}" do
13
- it 'registers an offense for offending code' do
14
- expect_offense(<<-RUBY)
15
- #{factory_bot}.define do
16
- factory :post do
17
- published_at 1.day.from_now
18
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute.
19
- status [:draft, :published].sample
20
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute.
21
- created_at 1.day.ago
22
- ^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute.
23
- update_times [Time.current]
24
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute.
25
- meta_tags(foo: Time.current)
26
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute.
27
- end
28
- end
29
- RUBY
30
- end
31
-
32
- it 'registers an offense in a trait' do
33
- expect_offense(<<-RUBY)
34
- #{factory_bot}.define do
35
- factory :post do
36
- title "Something"
37
- trait :published do
38
- published_at 1.day.from_now
39
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use a block to set a dynamic value to an attribute.
40
- end
41
- end
42
- end
43
- RUBY
44
- end
45
-
46
- it 'accepts valid factory definitions' do
47
- expect_no_offenses(<<-RUBY)
48
- #{factory_bot}.define do
49
- factory :post do
50
- trait :published do
51
- published_at { 1.day.from_now }
52
- end
53
- created_at { 1.day.ago }
54
- status :draft
55
- comments_count 0
56
- title "Static"
57
- description { FFaker::Lorem.paragraph(10) }
58
- recent_statuses [:published, :draft]
59
- meta_tags(like_count: 2)
60
- other_tags({ foo: nil })
61
-
62
- before(:create, &:initialize_something)
63
- after(:create, &:rebuild_cache)
64
- end
65
- end
66
- RUBY
67
- end
68
-
69
- it 'accepts const as a static value' do
70
- expect_no_offenses(<<-RUBY)
71
- #{factory_bot}.define do
72
- factory(:post, class: PrivatePost) do
73
- tag Tag::MAGIC
74
- options({priority: Priotity::HIGH})
75
- end
76
- end
77
- RUBY
78
- end
79
-
80
- it 'does not add offense if out of factory girl block' do
81
- expect_no_offenses(<<-RUBY)
82
- status [:draft, :published].sample
83
- published_at 1.day.from_now
84
- created_at 1.day.ago
85
- update_times [Time.current]
86
- meta_tags(foo: Time.current)
87
- RUBY
88
- end
89
-
90
- it 'accepts valid sequence definition' do
91
- expect_no_offenses(<<-RUBY)
92
- #{factory_bot}.define do
93
- factory :post do
94
- sequence :negative_numbers, &:-@
95
- end
96
- end
97
- RUBY
98
- end
99
-
100
- bad = <<-RUBY
101
- #{factory_bot}.define do
102
- factory :post do
103
- status([:draft, :published].sample)
104
- published_at 1.day.from_now
105
- created_at(1.day.ago)
106
- updated_at Time.current
107
- update_times [Time.current]
108
- meta_tags(foo: Time.current)
109
- other_tags({ foo: Time.current })
110
-
111
- trait :old do
112
- published_at 1.week.ago
113
- end
114
- end
115
- end
116
- RUBY
117
-
118
- corrected = <<-RUBY
119
- #{factory_bot}.define do
120
- factory :post do
121
- status { [:draft, :published].sample }
122
- published_at { 1.day.from_now }
123
- created_at { 1.day.ago }
124
- updated_at { Time.current }
125
- update_times { [Time.current] }
126
- meta_tags { { foo: Time.current } }
127
- other_tags { { foo: Time.current } }
128
-
129
- trait :old do
130
- published_at { 1.week.ago }
131
- end
132
- end
133
- end
134
- RUBY
135
-
136
- include_examples 'autocorrect', bad, corrected
137
- end
138
- end
139
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # rubocop:disable Metrics/LineLength
4
- RSpec.describe RuboCop::Cop::RSpec::FactoryBot::StaticAttributeDefinedDynamically do
5
- # rubocop:enable Metrics/LineLength
6
-
7
- subject(:cop) { described_class.new(config) }
8
-
9
- let(:config) { RuboCop::Config.new }
10
-
11
- %w[FactoryBot FactoryGirl].each do |factory_bot|
12
- context "when using #{factory_bot}" do
13
- it 'registers an offense for offending code' do
14
- expect_offense(<<-RUBY)
15
- #{factory_bot}.define do
16
- factory :post do
17
- kind { :static }
18
- ^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
19
- comments_count { 0 }
20
- ^^^^^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
21
- type { User::MAGIC }
22
- ^^^^^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
23
- description { nil }
24
- ^^^^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
25
- recent_statuses { [:published, :draft] }
26
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
27
- meta_tags { { foo: 1 } }
28
- ^^^^^^^^^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
29
- title {}
30
- ^^^^^^^^ Do not use a block to set a static value to an attribute.
31
- end
32
- end
33
- RUBY
34
- end
35
-
36
- it 'registers an offense in a trait' do
37
- expect_offense(<<-RUBY)
38
- #{factory_bot}.define do
39
- factory :post do
40
- title "Something"
41
- trait :something_else do
42
- title { "Something Else" }
43
- ^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use a block to set a static value to an attribute.
44
- end
45
- end
46
- end
47
- RUBY
48
- end
49
-
50
- it 'accepts valid factory definitions' do
51
- expect_no_offenses(<<-RUBY)
52
- #{factory_bot}.define do
53
- factory :post do
54
- trait :something_else do
55
- title "Something Else"
56
- end
57
- title "Something"
58
- comments_count 0
59
- description { FFaker::Lorem.paragraph(10) }
60
- tag Tag::MAGIC
61
- recent_updates { [Time.current] }
62
- meta_tags { { first_like: Time.current } }
63
- before(:create) { 'foo' }
64
- end
65
- end
66
- RUBY
67
- end
68
-
69
- it 'does not add offense if out of factory girl block' do
70
- expect_no_offenses(<<-RUBY)
71
- kind { :static }
72
- comments_count { 0 }
73
- type { User::MAGIC }
74
- description { nil }
75
- RUBY
76
- end
77
-
78
- bad = <<-RUBY
79
- #{factory_bot}.define do
80
- factory :post do
81
- comments_count { 0 }
82
- type { User::MAGIC }
83
- description { nil }
84
- title {}
85
- recent_statuses { [:published, :draft] }
86
- meta_tags { { foo: 1 } }
87
- end
88
- end
89
- RUBY
90
-
91
- corrected = <<-RUBY
92
- #{factory_bot}.define do
93
- factory :post do
94
- comments_count 0
95
- type User::MAGIC
96
- description nil
97
- title nil
98
- recent_statuses [:published, :draft]
99
- meta_tags({ foo: 1 })
100
- end
101
- end
102
- RUBY
103
-
104
- include_examples 'autocorrect', bad, corrected
105
- end
106
- end
107
- end