lib/rubocop/cop/rspec/rails/http_status.rb in rubocop-rspec-2.27.1 vs lib/rubocop/cop/rspec/rails/http_status.rb in rubocop-rspec-2.28.0
- old
+ new
@@ -1,214 +1,61 @@
# frozen_string_literal: true
-require 'rack/utils'
-
module RuboCop
module Cop
module RSpec
module Rails
- # Enforces use of symbolic or numeric value to describe HTTP status.
- #
- # This cop inspects only `have_http_status` calls.
- # So, this cop does not check if a method starting with `be_*` is used
- # when setting for `EnforcedStyle: symbolic` or
- # `EnforcedStyle: numeric`.
- #
- # @example `EnforcedStyle: symbolic` (default)
- # # bad
- # it { is_expected.to have_http_status 200 }
- # it { is_expected.to have_http_status 404 }
- # it { is_expected.to have_http_status "403" }
- #
- # # good
- # it { is_expected.to have_http_status :ok }
- # it { is_expected.to have_http_status :not_found }
- # it { is_expected.to have_http_status :forbidden }
- # it { is_expected.to have_http_status :success }
- # it { is_expected.to have_http_status :error }
- #
- # @example `EnforcedStyle: numeric`
- # # bad
- # it { is_expected.to have_http_status :ok }
- # it { is_expected.to have_http_status :not_found }
- # it { is_expected.to have_http_status "forbidden" }
- #
- # # good
- # it { is_expected.to have_http_status 200 }
- # it { is_expected.to have_http_status 404 }
- # it { is_expected.to have_http_status 403 }
- # it { is_expected.to have_http_status :success }
- # it { is_expected.to have_http_status :error }
- #
- # @example `EnforcedStyle: be_status`
- # # bad
- # it { is_expected.to have_http_status :ok }
- # it { is_expected.to have_http_status :not_found }
- # it { is_expected.to have_http_status "forbidden" }
- # it { is_expected.to have_http_status 200 }
- # it { is_expected.to have_http_status 404 }
- # it { is_expected.to have_http_status "403" }
- #
- # # good
- # it { is_expected.to be_ok }
- # it { is_expected.to be_not_found }
- # it { is_expected.to have_http_status :success }
- # it { is_expected.to have_http_status :error }
- #
- class HttpStatus < Base
- extend AutoCorrector
- include ConfigurableEnforcedStyle
- RESTRICT_ON_SEND = %i[have_http_status].freeze
-
- # @!method http_status(node)
- def_node_matcher :http_status, <<~PATTERN
- (send nil? :have_http_status ${int sym str})
- PATTERN
-
- def on_send(node)
- http_status(node) do |arg|
- return if arg.str_type? && arg.heredoc?
-
- checker = checker_class.new(arg)
- return unless checker.offensive?
-
- add_offense(checker.offense_range,
- message: checker.message) do |corrector|
- corrector.replace(checker.offense_range, checker.prefer)
- end
- end
- end
-
- private
-
- def checker_class
- case style
- when :symbolic
- SymbolicStyleChecker
- when :numeric
- NumericStyleChecker
- when :be_status
- BeStatusStyleChecker
- end
- end
-
- # :nodoc:
- class StyleCheckerBase
- MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
- 'to describe HTTP status code.'
- ALLOWED_STATUSES = %i[error success missing redirect].freeze
-
- attr_reader :node
-
- def initialize(node)
- @node = node
- end
-
- def message
- format(MSG, prefer: prefer, current: current)
- end
-
- def current
- offense_range.source
- end
-
- def offense_range
- node
- end
-
- def allowed_symbol?
- node.sym_type? && ALLOWED_STATUSES.include?(node.value)
- end
-
- def custom_http_status_code?
- node.int_type? &&
- !::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(node.source.to_i)
- end
- end
-
- # :nodoc:
- class SymbolicStyleChecker < StyleCheckerBase
- def offensive?
- !node.sym_type? && !custom_http_status_code?
- end
-
- def prefer
- symbol.inspect
- end
-
- private
-
- def symbol
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
- end
-
- def number
- node.value.to_i
- end
- end
-
- # :nodoc:
- class NumericStyleChecker < StyleCheckerBase
- def offensive?
- !node.int_type? && !allowed_symbol?
- end
-
- def prefer
- number.to_s
- end
-
- private
-
- def symbol
- node.value
- end
-
- def number
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol.to_sym]
- end
- end
-
- # :nodoc:
- class BeStatusStyleChecker < StyleCheckerBase
- def offensive?
- (!node.sym_type? && !custom_http_status_code?) ||
- (!node.int_type? && !allowed_symbol?)
- end
-
- def offense_range
- node.parent
- end
-
- def prefer
- if node.sym_type?
- "be_#{node.value}"
- elsif node.int_type?
- "be_#{symbol}"
- elsif node.str_type?
- "be_#{normalize_str}"
- end
- end
-
- private
-
- def symbol
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
- end
-
- def number
- node.value.to_i
- end
-
- def normalize_str
- str = node.value.to_s
- if str.match?(/\A\d+\z/)
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(str.to_i)
- else
- str
- end
- end
- end
- end
+ # @!parse
+ # # Enforces use of symbolic or numeric value to describe HTTP status.
+ # #
+ # # This cop inspects only `have_http_status` calls.
+ # # So, this cop does not check if a method starting with `be_*` is
+ # # used when setting for `EnforcedStyle: symbolic` or
+ # # `EnforcedStyle: numeric`.
+ # #
+ # # @example `EnforcedStyle: symbolic` (default)
+ # # # bad
+ # # it { is_expected.to have_http_status 200 }
+ # # it { is_expected.to have_http_status 404 }
+ # # it { is_expected.to have_http_status "403" }
+ # #
+ # # # good
+ # # it { is_expected.to have_http_status :ok }
+ # # it { is_expected.to have_http_status :not_found }
+ # # it { is_expected.to have_http_status :forbidden }
+ # # it { is_expected.to have_http_status :success }
+ # # it { is_expected.to have_http_status :error }
+ # #
+ # # @example `EnforcedStyle: numeric`
+ # # # bad
+ # # it { is_expected.to have_http_status :ok }
+ # # it { is_expected.to have_http_status :not_found }
+ # # it { is_expected.to have_http_status "forbidden" }
+ # #
+ # # # good
+ # # it { is_expected.to have_http_status 200 }
+ # # it { is_expected.to have_http_status 404 }
+ # # it { is_expected.to have_http_status 403 }
+ # # it { is_expected.to have_http_status :success }
+ # # it { is_expected.to have_http_status :error }
+ # #
+ # # @example `EnforcedStyle: be_status`
+ # # # bad
+ # # it { is_expected.to have_http_status :ok }
+ # # it { is_expected.to have_http_status :not_found }
+ # # it { is_expected.to have_http_status "forbidden" }
+ # # it { is_expected.to have_http_status 200 }
+ # # it { is_expected.to have_http_status 404 }
+ # # it { is_expected.to have_http_status "403" }
+ # #
+ # # # good
+ # # it { is_expected.to be_ok }
+ # # it { is_expected.to be_not_found }
+ # # it { is_expected.to have_http_status :success }
+ # # it { is_expected.to have_http_status :error }
+ # #
+ # class HttpStatus < RuboCop::Cop::RSpecRails::Base; end
+ HttpStatus = ::RuboCop::Cop::RSpecRails::HttpStatus
end
end
end
end