Skip to content

Commit 89d391d

Browse files
jonmarkgoerinosher
andauthored
[DEV-2349] add custom httpstatus cop here instead (#3)
* add custom cop here instead * Make it so it only checks spec files * try to make this simpler * Update version.rb --------- Co-authored-by: Erin Osher <[email protected]>
1 parent 149da04 commit 89d391d

File tree

5 files changed

+97
-1
lines changed

5 files changed

+97
-1
lines changed

.rubocop.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ require:
33
- rubocop-rails
44
- rubocop-performance
55
- rubocop-factory_bot
6+
- rubocop-rspec_rails
7+
- ./lib/custom/rack_utils_status_code
68

79
Layout/FirstHashElementIndentation:
810
Description: Enforces consistent indentation for the first key in a hash literal
@@ -151,3 +153,13 @@ Style/SymbolProc:
151153
Description: Allows block for method with arguments
152154
AllowMethodsWithArguments: true
153155
Enabled: true
156+
157+
RSpecRails/HaveHttpStatus:
158+
Enabled: true
159+
160+
Rails/HttpStatus:
161+
Enabled: true
162+
EnforcedStyle: symbolic
163+
164+
Custom/RackUtilsStatusCode:
165+
Enabled: true

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ gem 'rubocop-factory_bot'
1111
gem 'rubocop-performance'
1212
gem 'rubocop-rails'
1313
gem 'rubocop-rspec'
14+
gem 'rubocop-rspec_rails'
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Custom
6+
# This cop checks for uses of `Rack::Utils.status_code` in RSpec tests
7+
# and suggests using `have_http_status` instead.
8+
#
9+
# @example
10+
# # bad
11+
# expect(response.status).to be(Rack::Utils.status_code(:created))
12+
#
13+
# # good
14+
# expect(response).to have_http_status(:created)
15+
class RackUtilsStatusCode < RuboCop::Cop::Base
16+
extend AutoCorrector
17+
18+
MSG = 'Prefer `have_http_status` over `Rack::Utils.status_code`.'
19+
20+
def_node_matcher :rack_utils_status_code?, <<~PATTERN
21+
(send
22+
(const
23+
(const nil? :Rack) :Utils) :status_code $_)
24+
PATTERN
25+
26+
def_node_matcher :expect_response_status_pattern?, <<~PATTERN
27+
(send
28+
(send nil? :expect
29+
(send $(send nil? _) :status)
30+
)
31+
$_
32+
(send nil? {:be :eq :eql :equal}
33+
(send
34+
(const
35+
(const nil? :Rack) :Utils) :status_code $_)))
36+
PATTERN
37+
38+
def on_send(node)
39+
# Only proceed if we're in an expect statement
40+
expect_node = find_expect_node(node)
41+
return unless expect_node
42+
43+
rack_utils_status_code?(node) do |status_arg|
44+
add_offense(node, message: MSG) do |corrector|
45+
expect_response_status_pattern?(expect_node) do |response_obj, to_method, status_sym|
46+
# Replace just the Rack::Utils.status_code part with have_http_status
47+
replacement = "expect(#{response_obj.source}).#{to_method} have_http_status(#{status_sym.source})"
48+
corrector.replace(expect_node, replacement)
49+
end
50+
end
51+
end
52+
end
53+
54+
private
55+
56+
# Find the expect(...).to be(Rack::Utils.status_code(...)) node
57+
def find_expect_node(node)
58+
return nil unless node
59+
60+
if node.send_type? &&
61+
(node.method_name == :to || node.method_name == :to_not || node.method_name == :not_to) &&
62+
node.receiver&.send_type? &&
63+
node.receiver.method_name == :expect &&
64+
node.first_argument&.send_type? &&
65+
(node.first_argument.method_name == :be ||
66+
node.first_argument.method_name == :eq ||
67+
node.first_argument.method_name == :eql ||
68+
node.first_argument.method_name == :equal)
69+
70+
return node
71+
end
72+
73+
if node.parent
74+
find_expect_node(node.parent)
75+
else
76+
nil
77+
end
78+
end
79+
end
80+
end
81+
end
82+
end

lib/mlh-rubocop-config/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module MlhRubocopConfig
4-
VERSION = '1.0.3'
4+
VERSION = '2.0.0'
55
end

mlh-rubocop-config.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
2121
spec.add_dependency 'rubocop-performance'
2222
spec.add_dependency 'rubocop-rails'
2323
spec.add_dependency 'rubocop-rspec'
24+
spec.add_dependency 'rubocop-rspec_rails'
2425
end

0 commit comments

Comments
 (0)