rubocop-rspec_rails 2.28.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 53524a3483350f80d17572e3e221a777dabb1421999fbbcb37ad30cb182358b1
4
+ data.tar.gz: af8ff0697f66b78c197fc34e8dbd207e75a64473075ccb1b65d00650582d80d5
5
+ SHA512:
6
+ metadata.gz: 6b42314769301898bd8723c2c8d5e29eee29cb1952b70e3e4abb892f75e8a13c2129933a3a99de8247510030f208925ab70c5a0a1f1ebaf950595a5c7d540152
7
+ data.tar.gz: 9ad058ef82208bb685249e7ed847da8fc4b06b6718033d9153adc6544d28845e91454524531a72f67f25497325876ed140d543e7173b839f72d12044ef37c429
data/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ # Changelog
2
+
3
+ ## Master (Unreleased)
4
+
5
+ ## 2.28.0 (2024-03-28)
6
+
7
+ - Extracted from `rubocop-rspec` into a separate repository. ([@ydah])
8
+
9
+ ## Previously (see [rubocop-rspec's changelist](https://github.com/rubocop/rubocop-rspec/blob/v2.27.1/CHANGELOG.md) for details)
10
+
11
+ - Add support for `assert_true`, `assert_false`, `assert_not_equal`, `assert_not_nil`, `*_empty`, `*_predicate`, `*_kind_of`, `*_in_delta`, `*_match`, `*_instance_of` and `*_includes` assertions in `RSpec/Rails/MinitestAssertions`. ([@ydah], [@G-Rath])
12
+ - Add configuration option `ResponseMethods` to `RSpec/Rails/HaveHttpStatus`. ([@ydah])
13
+ - Add support single quoted string and percent string and heredoc for `RSpec/Rails/HttpStatus`. ([@ydah])
14
+ - Add support `RSpec/Rails/HttpStatus` when `have_http_status` with string argument. ([@ydah])
15
+ - Mark to `Safe: false` for `RSpec/Rails/NegationBeValid` cop. ([@ydah])
16
+ - Add new `RSpec/Rails/NegationBeValid` cop. ([@ydah])
17
+ - Fix a false negative for `RSpec/ExcessiveDocstringSpacing` when finds description with em space. ([@ydah])
18
+ - Fix a false positive for `RSpec/EmptyExampleGroup` when example group with examples defined in `if` branch inside iterator. ([@ydah])
19
+ - Update the message output of `RSpec/ExpectActual` to include the word 'value'. ([@corydiamand])
20
+ - Fix a false negative for `RSpec/Pending` when `it` without body. ([@ydah])
21
+ - Add new `RSpec/ReceiveMessages` cop. ([@ydah])
22
+ - Change default.yml path to use `**/spec/*` instead of `spec/*`. ([@ydah])
23
+ - Add `AllowedIdentifiers` and `AllowedPatterns` configuration option to `RSpec/IndexedLet`. ([@ydah])
24
+ - Fix `RSpec/NamedSubject` when block has no body. ([@splattael])
25
+ - Fix `RSpec/LetBeforeExamples` autocorrect incompatible with `RSpec/ScatteredLet` autocorrect. ([@ydah])
26
+ - Update `RSpec/Focus` to support `shared_context` and `shared_examples`. ([@tmaier])
27
+ - Fix an error for `RSpec/Rails/HaveHttpStatus` with comparison with strings containing non-numeric characters. ([@ydah])
28
+ - Add support `be_status` style for `RSpec/Rails/HttpStatus`. ([@ydah])
29
+ - Fix order of expected and actual in correction for `RSpec/Rails/MinitestAssertions`. ([@mvz])
30
+ - Add `RSpec/Rails/TravelAround` cop. ([@r7kamura])
31
+ - Add new `RSpec/Rails/MinitestAssertions` cop. ([@ydah])
32
+ - Improved processing speed for `RSpec/Be`, `RSpec/ExpectActual`, `RSpec/ImplicitExpect`, `RSpec/MessageSpies`, `RSpec/PredicateMatcher` and `RSpec/Rails/HaveHttpStatus`. ([@ydah])
33
+ - Fix an error for `RSpec/Rails/InferredSpecType` with redundant type before other Hash metadata. ([@ydah])
34
+ - Add `RSpec/Rails/InferredSpecType` cop. ([@r7kamura])
35
+ - Add new `RSpec/Rails/HaveHttpStatus` cop. ([@akiomik])
36
+ - Exclude unrelated Rails directories from `RSpec/DescribeClass`. ([@MothOnMars])
37
+ - Add `RSpec/Rails/AvoidSetupHook` cop. ([@paydaylight])
38
+ - Change namespace of several cops (`Capybara/*` -> `RSpec/Capybara/*`, `FactoryBot/*` -> `RSpec/FactoryBot/*`, `Rails/*` -> `RSpec/Rails/*`). ([@pirj], [@bquorning])
39
+ - The `Rails/HttpStatus` cop is unavailable if the `rack` gem cannot be loaded. ([@bquorning])
40
+ - Fix `Rails/HttpStatus` not working with custom HTTP status codes. ([@bquorning])
41
+ - Add `RSpec/Rails/HttpStatus` cop to enforce consistent usage of the status format (numeric or symbolic). ([@anthony-robin], [@jojos003])
42
+
43
+ <!-- Contributors (alphabetically) -->
44
+
45
+ [@akiomik]: https://github.com/akiomik
46
+ [@anthony-robin]: https://github.com/anthony-robin
47
+ [@bquorning]: https://github.com/bquorning
48
+ [@corydiamand]: https://github.com/corydiamand
49
+ [@g-rath]: https://github.com/G-Rath
50
+ [@jojos003]: https://github.com/jojos003
51
+ [@mothonmars]: https://github.com/MothOnMars
52
+ [@mvz]: https://github.com/mvz
53
+ [@paydaylight]: https://github.com/paydaylight
54
+ [@pirj]: https://github.com/pirj
55
+ [@r7kamura]: https://github.com/r7kamura
56
+ [@splattael]: https://github.com/splattael
57
+ [@tmaier]: https://github.com/tmaier
58
+ [@ydah]: https://github.com/ydah
@@ -0,0 +1,17 @@
1
+ # The RuboCop Community Code of Conduct
2
+
3
+ **Note:** We have picked the following code of conduct based on [Ruby's own
4
+ code of conduct](https://www.ruby-lang.org/en/conduct/).
5
+
6
+ This document provides a few simple community guidelines for a safe, respectful,
7
+ productive, and collaborative place for any person who is willing to contribute
8
+ to the RuboCop community. It applies to all "collaborative spaces", which are
9
+ defined as community communications channels (such as mailing lists, submitted
10
+ patches, commit comments, etc.).
11
+
12
+ - Participants will be tolerant of opposing views.
13
+ - Participants must ensure that their language and actions are free of personal
14
+ attacks and disparaging personal remarks.
15
+ - When interpreting the words and actions of others, participants should always
16
+ assume good intentions.
17
+ - Behaviour which can be reasonably considered harassment will not be tolerated.
data/MIT-LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Ian MacLeod <ian@nevir.net>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # RuboCop RSpec Rails
2
+
3
+ [![Join the chat at https://gitter.im/rubocop-rspec/Lobby](https://badges.gitter.im/rubocop-rspec/Lobby.svg)](https://gitter.im/rubocop-rspec/Lobby)
4
+ [![Gem Version](https://badge.fury.io/rb/rubocop-rspec_rails.svg)](https://rubygems.org/gems/rubocop-rspec_rails)
5
+ ![CI](https://github.com/rubocop/rubocop-rspec_rails/workflows/CI/badge.svg)
6
+
7
+ [RSpec Rails](https://rspec.info/)-specific analysis for your projects, as an extension to
8
+ [RuboCop](https://github.com/rubocop/rubocop).
9
+
10
+ ## Installation
11
+
12
+ Just install the `rubocop-rspec_rails` gem
13
+
14
+ ```bash
15
+ gem install rubocop-rspec_rails
16
+ ```
17
+
18
+ or if you use bundler put this in your `Gemfile`
19
+
20
+ ```ruby
21
+ gem 'rubocop-rspec_rails', require: false
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ You need to tell RuboCop to load the RSpec Rails extension. There are three
27
+ ways to do this:
28
+
29
+ ### RuboCop configuration file
30
+
31
+ Put this into your `.rubocop.yml`.
32
+
33
+ ```yaml
34
+ require: rubocop-rspec_rails
35
+ ```
36
+
37
+ Alternatively, use the following array notation when specifying multiple extensions.
38
+
39
+ ```yaml
40
+ require:
41
+ - rubocop-rspec
42
+ - rubocop-rspec_rails
43
+ ```
44
+
45
+ Now you can run `rubocop` and it will automatically load the RuboCop RSpec Rails
46
+ cops together with the standard cops.
47
+
48
+ ### Command line
49
+
50
+ ```bash
51
+ rubocop --require rubocop-rspec_rails
52
+ ```
53
+
54
+ ### Rake task
55
+
56
+ ```ruby
57
+ RuboCop::RakeTask.new do |task|
58
+ task.requires << 'rubocop-rspec_rails'
59
+ end
60
+ ```
61
+
62
+ ## Documentation
63
+
64
+ You can read more about RuboCop RSpec Rails in its [official manual](https://docs.rubocop.org/rubocop-rspec_rails).
65
+
66
+ ## The Cops
67
+
68
+ All cops are located under
69
+ [`lib/rubocop/cop/rspec_rails`](lib/rubocop/cop/rspec_rails), and contain
70
+ examples/documentation.
71
+
72
+ In your `.rubocop.yml`, you may treat the RSpec Rails cops just like any other
73
+ cop. For example:
74
+
75
+ ```yaml
76
+ RSpecRails/AvoidSetupHook:
77
+ Exclude:
78
+ - spec/my_poorly_named_spec_file.rb
79
+ ```
80
+
81
+ ## Contributing
82
+
83
+ Checkout the [contribution guidelines](.github/CONTRIBUTING.md).
84
+
85
+ ## License
86
+
87
+ `rubocop-rspec_rails` is MIT licensed. [See the accompanying file](MIT-LICENSE.md) for
88
+ the full text.
@@ -0,0 +1,83 @@
1
+ ---
2
+ RSpecRails:
3
+ Enabled: true
4
+ DocumentationBaseURL: https://docs.rubocop.org/rubocop-rspec_rails
5
+ Include:
6
+ - "**/*_spec.rb"
7
+ - "**/spec/**/*"
8
+
9
+ RSpecRails/AvoidSetupHook:
10
+ Description: Checks that tests use RSpec `before` hook over Rails `setup` method.
11
+ Enabled: pending
12
+ VersionAdded: '2.4'
13
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/AvoidSetupHook
14
+
15
+ RSpecRails/HaveHttpStatus:
16
+ Description: Checks that tests use `have_http_status` instead of equality matchers.
17
+ Enabled: pending
18
+ ResponseMethods:
19
+ - response
20
+ - last_response
21
+ SafeAutoCorrect: false
22
+ VersionAdded: '2.12'
23
+ VersionChanged: '2.27'
24
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/HaveHttpStatus
25
+
26
+ RSpecRails/HttpStatus:
27
+ Description: Enforces use of symbolic or numeric value to describe HTTP status.
28
+ Enabled: true
29
+ EnforcedStyle: symbolic
30
+ SupportedStyles:
31
+ - numeric
32
+ - symbolic
33
+ - be_status
34
+ VersionAdded: '1.23'
35
+ VersionChanged: '2.20'
36
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/HttpStatus
37
+
38
+ RSpecRails/InferredSpecType:
39
+ Description: Identifies redundant spec type.
40
+ Enabled: pending
41
+ Safe: false
42
+ VersionAdded: '2.14'
43
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/InferredSpecType
44
+ Inferences:
45
+ channels: channel
46
+ controllers: controller
47
+ features: feature
48
+ generator: generator
49
+ helpers: helper
50
+ jobs: job
51
+ mailboxes: mailbox
52
+ mailers: mailer
53
+ models: model
54
+ requests: request
55
+ integration: request
56
+ api: request
57
+ routing: routing
58
+ system: system
59
+ views: view
60
+
61
+ RSpecRails/MinitestAssertions:
62
+ Description: Check if using Minitest-like matchers.
63
+ Enabled: pending
64
+ VersionAdded: '2.17'
65
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/MinitestAssertions
66
+
67
+ RSpecRails/NegationBeValid:
68
+ Description: Enforces use of `be_invalid` or `not_to` for negated be_valid.
69
+ Safe: false
70
+ EnforcedStyle: not_to
71
+ SupportedStyles:
72
+ - not_to
73
+ - be_invalid
74
+ Enabled: pending
75
+ VersionAdded: '2.23'
76
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/NegationBeValid
77
+
78
+ RSpecRails/TravelAround:
79
+ Description: Prefer to travel in `before` rather than `around`.
80
+ Enabled: pending
81
+ Safe: false
82
+ VersionAdded: '2.19'
83
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/TravelAround
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpecRails
6
+ # Checks that tests use RSpec `before` hook over Rails `setup` method.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # setup do
11
+ # allow(foo).to receive(:bar)
12
+ # end
13
+ #
14
+ # # good
15
+ # before do
16
+ # allow(foo).to receive(:bar)
17
+ # end
18
+ #
19
+ class AvoidSetupHook < ::RuboCop::Cop::RSpec::Base
20
+ extend AutoCorrector
21
+
22
+ MSG = 'Use `before` instead of `setup`.'
23
+
24
+ # @!method setup_call(node)
25
+ def_node_matcher :setup_call, <<~PATTERN
26
+ (block
27
+ $(send nil? :setup)
28
+ (args) _)
29
+ PATTERN
30
+
31
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
32
+ setup_call(node) do |setup|
33
+ add_offense(node) do |corrector|
34
+ corrector.replace setup, 'before'
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpecRails
6
+ # Checks that tests use `have_http_status` instead of equality matchers.
7
+ #
8
+ # @example ResponseMethods: ['response', 'last_response'] (default)
9
+ # # bad
10
+ # expect(response.status).to be(200)
11
+ # expect(last_response.code).to eq("200")
12
+ #
13
+ # # good
14
+ # expect(response).to have_http_status(200)
15
+ # expect(last_response).to have_http_status(200)
16
+ #
17
+ # @example ResponseMethods: ['foo_response']
18
+ # # bad
19
+ # expect(foo_response.status).to be(200)
20
+ #
21
+ # # good
22
+ # expect(foo_response).to have_http_status(200)
23
+ #
24
+ # # also good
25
+ # expect(response).to have_http_status(200)
26
+ # expect(last_response).to have_http_status(200)
27
+ #
28
+ class HaveHttpStatus < ::RuboCop::Cop::Base
29
+ extend AutoCorrector
30
+
31
+ MSG =
32
+ 'Prefer `expect(%<response>s).%<to>s ' \
33
+ 'have_http_status(%<status>s)` over `%<bad_code>s`.'
34
+
35
+ RUNNERS = %i[to to_not not_to].to_set
36
+ RESTRICT_ON_SEND = RUNNERS
37
+
38
+ # @!method match_status(node)
39
+ def_node_matcher :match_status, <<~PATTERN
40
+ (send
41
+ (send nil? :expect
42
+ $(send $(send nil? #response_methods?) {:status :code})
43
+ )
44
+ $RUNNERS
45
+ $(send nil? {:be :eq :eql :equal} ({int str} $_))
46
+ )
47
+ PATTERN
48
+
49
+ def on_send(node) # rubocop:disable Metrics/MethodLength
50
+ match_status(node) do
51
+ |response_status, response_method, to, match, status|
52
+ return unless status.to_s.match?(/\A\d+\z/)
53
+
54
+ message = format(MSG, response: response_method.method_name,
55
+ to: to, status: status,
56
+ bad_code: node.source)
57
+ add_offense(node, message: message) do |corrector|
58
+ corrector.replace(response_status, response_method.method_name)
59
+ corrector.replace(match.loc.selector, 'have_http_status')
60
+ corrector.replace(match.first_argument, status.to_s)
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def response_methods?(name)
68
+ response_methods.include?(name.to_s)
69
+ end
70
+
71
+ def response_methods
72
+ cop_config.fetch('ResponseMethods', [])
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack/utils'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module RSpecRails
8
+ # Enforces use of symbolic or numeric value to describe HTTP status.
9
+ #
10
+ # This cop inspects only `have_http_status` calls.
11
+ # So, this cop does not check if a method starting with `be_*` is used
12
+ # when setting for `EnforcedStyle: symbolic` or
13
+ # `EnforcedStyle: numeric`.
14
+ #
15
+ # @example `EnforcedStyle: symbolic` (default)
16
+ # # bad
17
+ # it { is_expected.to have_http_status 200 }
18
+ # it { is_expected.to have_http_status 404 }
19
+ # it { is_expected.to have_http_status "403" }
20
+ #
21
+ # # good
22
+ # it { is_expected.to have_http_status :ok }
23
+ # it { is_expected.to have_http_status :not_found }
24
+ # it { is_expected.to have_http_status :forbidden }
25
+ # it { is_expected.to have_http_status :success }
26
+ # it { is_expected.to have_http_status :error }
27
+ #
28
+ # @example `EnforcedStyle: numeric`
29
+ # # bad
30
+ # it { is_expected.to have_http_status :ok }
31
+ # it { is_expected.to have_http_status :not_found }
32
+ # it { is_expected.to have_http_status "forbidden" }
33
+ #
34
+ # # good
35
+ # it { is_expected.to have_http_status 200 }
36
+ # it { is_expected.to have_http_status 404 }
37
+ # it { is_expected.to have_http_status 403 }
38
+ # it { is_expected.to have_http_status :success }
39
+ # it { is_expected.to have_http_status :error }
40
+ #
41
+ # @example `EnforcedStyle: be_status`
42
+ # # bad
43
+ # it { is_expected.to have_http_status :ok }
44
+ # it { is_expected.to have_http_status :not_found }
45
+ # it { is_expected.to have_http_status "forbidden" }
46
+ # it { is_expected.to have_http_status 200 }
47
+ # it { is_expected.to have_http_status 404 }
48
+ # it { is_expected.to have_http_status "403" }
49
+ #
50
+ # # good
51
+ # it { is_expected.to be_ok }
52
+ # it { is_expected.to be_not_found }
53
+ # it { is_expected.to have_http_status :success }
54
+ # it { is_expected.to have_http_status :error }
55
+ #
56
+ class HttpStatus < ::RuboCop::Cop::RSpec::Base
57
+ extend AutoCorrector
58
+ include ConfigurableEnforcedStyle
59
+ RESTRICT_ON_SEND = %i[have_http_status].freeze
60
+
61
+ # @!method http_status(node)
62
+ def_node_matcher :http_status, <<~PATTERN
63
+ (send nil? :have_http_status ${int sym str})
64
+ PATTERN
65
+
66
+ def on_send(node)
67
+ http_status(node) do |arg|
68
+ return if arg.str_type? && arg.heredoc?
69
+
70
+ checker = checker_class.new(arg)
71
+ return unless checker.offensive?
72
+
73
+ add_offense(checker.offense_range,
74
+ message: checker.message) do |corrector|
75
+ corrector.replace(checker.offense_range, checker.prefer)
76
+ end
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def checker_class
83
+ case style
84
+ when :symbolic
85
+ SymbolicStyleChecker
86
+ when :numeric
87
+ NumericStyleChecker
88
+ when :be_status
89
+ BeStatusStyleChecker
90
+ end
91
+ end
92
+
93
+ # :nodoc:
94
+ class StyleCheckerBase
95
+ MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
96
+ 'to describe HTTP status code.'
97
+ ALLOWED_STATUSES = %i[error success missing redirect].freeze
98
+
99
+ attr_reader :node
100
+
101
+ def initialize(node)
102
+ @node = node
103
+ end
104
+
105
+ def message
106
+ format(MSG, prefer: prefer, current: current)
107
+ end
108
+
109
+ def current
110
+ offense_range.source
111
+ end
112
+
113
+ def offense_range
114
+ node
115
+ end
116
+
117
+ def allowed_symbol?
118
+ node.sym_type? && ALLOWED_STATUSES.include?(node.value)
119
+ end
120
+
121
+ def custom_http_status_code?
122
+ node.int_type? &&
123
+ !::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(node.source.to_i)
124
+ end
125
+ end
126
+
127
+ # :nodoc:
128
+ class SymbolicStyleChecker < StyleCheckerBase
129
+ def offensive?
130
+ !node.sym_type? && !custom_http_status_code?
131
+ end
132
+
133
+ def prefer
134
+ symbol.inspect
135
+ end
136
+
137
+ private
138
+
139
+ def symbol
140
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
141
+ end
142
+
143
+ def number
144
+ node.value.to_i
145
+ end
146
+ end
147
+
148
+ # :nodoc:
149
+ class NumericStyleChecker < StyleCheckerBase
150
+ def offensive?
151
+ !node.int_type? && !allowed_symbol?
152
+ end
153
+
154
+ def prefer
155
+ number.to_s
156
+ end
157
+
158
+ private
159
+
160
+ def symbol
161
+ node.value
162
+ end
163
+
164
+ def number
165
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol.to_sym]
166
+ end
167
+ end
168
+
169
+ # :nodoc:
170
+ class BeStatusStyleChecker < StyleCheckerBase
171
+ def offensive?
172
+ (!node.sym_type? && !custom_http_status_code?) ||
173
+ (!node.int_type? && !allowed_symbol?)
174
+ end
175
+
176
+ def offense_range
177
+ node.parent
178
+ end
179
+
180
+ def prefer
181
+ if node.sym_type?
182
+ "be_#{node.value}"
183
+ elsif node.int_type?
184
+ "be_#{symbol}"
185
+ elsif node.str_type?
186
+ "be_#{normalize_str}"
187
+ end
188
+ end
189
+
190
+ private
191
+
192
+ def symbol
193
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
194
+ end
195
+
196
+ def number
197
+ node.value.to_i
198
+ end
199
+
200
+ def normalize_str
201
+ str = node.value.to_s
202
+ if str.match?(/\A\d+\z/)
203
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(str.to_i)
204
+ else
205
+ str
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end