rubocop-rspec_rails 2.28.0

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 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