diff options
Diffstat (limited to 'actionpack/lib/action_dispatch')
16 files changed, 93 insertions, 46 deletions
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb index 7be30be77a..0258d85564 100644 --- a/actionpack/lib/action_dispatch/http/cache.rb +++ b/actionpack/lib/action_dispatch/http/cache.rb @@ -150,8 +150,8 @@ module ActionDispatch directive, argument = segment.split("=", 2) if SPECIAL_KEYS.include? directive - key = directive.tr("-", "_") - cache_control[key.to_sym] = argument || true + directive.tr!("-", "_") + cache_control[directive.to_sym] = argument || true else cache_control[:extras] ||= [] cache_control[:extras] << segment diff --git a/actionpack/lib/action_dispatch/http/content_security_policy.rb b/actionpack/lib/action_dispatch/http/content_security_policy.rb index 9c430b57e3..e8cf1b95a5 100644 --- a/actionpack/lib/action_dispatch/http/content_security_policy.rb +++ b/actionpack/lib/action_dispatch/http/content_security_policy.rb @@ -33,7 +33,7 @@ module ActionDispatch #:nodoc: private def html_response?(headers) if content_type = headers[CONTENT_TYPE] - content_type =~ /html/ + /html/.match?(content_type) end end diff --git a/actionpack/lib/action_dispatch/http/feature_policy.rb b/actionpack/lib/action_dispatch/http/feature_policy.rb index 592b6e4393..78e982918d 100644 --- a/actionpack/lib/action_dispatch/http/feature_policy.rb +++ b/actionpack/lib/action_dispatch/http/feature_policy.rb @@ -33,7 +33,7 @@ module ActionDispatch #:nodoc: private def html_response?(headers) if content_type = headers[CONTENT_TYPE] - content_type =~ /html/ + /html/.match?(content_type) end end diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb index 7a7a493f64..7ad1ba3e0e 100644 --- a/actionpack/lib/action_dispatch/http/filter_parameters.rb +++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb @@ -23,7 +23,7 @@ module ActionDispatch # change { file: { code: "xxxx"} } # # env["action_dispatch.parameter_filter"] = -> (k, v) do - # v.reverse! if k =~ /secret/i + # v.reverse! if k.match?(/secret/i) # end # => reverses the value to all keys matching /secret/i module FilterParameters diff --git a/actionpack/lib/action_dispatch/http/filter_redirect.rb b/actionpack/lib/action_dispatch/http/filter_redirect.rb index d780d5f793..3bd1f5109d 100644 --- a/actionpack/lib/action_dispatch/http/filter_redirect.rb +++ b/actionpack/lib/action_dispatch/http/filter_redirect.rb @@ -27,7 +27,7 @@ module ActionDispatch if String === filter location.include?(filter) elsif Regexp === filter - location =~ filter + location.match?(filter) end end end diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index ac0ff133eb..6bf4e652d3 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -162,7 +162,7 @@ module ActionDispatch def valid_accept_header # :doc: (xhr? && (accept.present? || content_mime_type)) || - (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS) + (accept.present? && !accept.match?(BROWSER_LIKE_ACCEPTS)) end def use_accept_header # :doc: diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index ed1d50f3b9..60b78c0582 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -202,7 +202,7 @@ module Mime # For an input of <tt>'application'</tt>, returns <tt>[Mime[:html], Mime[:js], # Mime[:xml], Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form]</tt>. def parse_data_with_trailing_star(type) - Mime::SET.select { |m| m =~ type } + Mime::SET.select { |m| m.match?(type) } end # This method is opposite of register method. @@ -283,8 +283,14 @@ module Mime @synonyms.any? { |synonym| synonym.to_s =~ regexp } || @string =~ regexp end + def match?(mime_type) + return false unless mime_type + regexp = Regexp.new(Regexp.quote(mime_type.to_s)) + @synonyms.any? { |synonym| synonym.to_s.match?(regexp) } || @string.match?(regexp) + end + def html? - symbol == :html || @string =~ /html/ + (symbol == :html) || /html/.match?(@string) end def all?; false; end diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 4ac7c5c2bd..54dbb536c1 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -85,7 +85,7 @@ module ActionDispatch def controller_class_for(name) if name controller_param = name.underscore - const_name = "#{controller_param.camelize}Controller" + const_name = controller_param.camelize << "Controller" ActiveSupport::Dependencies.constantize(const_name) else PASS_NOT_FOUND @@ -265,7 +265,7 @@ module ActionDispatch # (case-insensitive), which may need to be manually added depending on the # choice of JavaScript libraries and frameworks. def xml_http_request? - get_header("HTTP_X_REQUESTED_WITH") =~ /XMLHttpRequest/i + /XMLHttpRequest/i.match?(get_header("HTTP_X_REQUESTED_WITH")) end alias :xhr? :xml_http_request? @@ -400,7 +400,7 @@ module ActionDispatch # True if the request came from localhost, 127.0.0.1, or ::1. def local? - LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip + LOCALHOST.match?(remote_addr) && LOCALHOST.match?(remote_ip) end def request_parameters=(params) diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 3b0f6378ea..225ae0a497 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -133,7 +133,7 @@ module ActionDispatch end def named_host?(host) - IP_HOST_REGEXP !~ host + !IP_HOST_REGEXP.match?(host) end def normalize_protocol(protocol) diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 9b5a5cf2b0..96bdf570af 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -439,7 +439,7 @@ module ActionDispatch # If host is not ip and matches domain regexp. # (ip confirms to domain regexp so we explicitly check for ip) - options[:domain] = if (request.host !~ /^[\d.]+$/) && (request.host =~ domain_regexp) + options[:domain] = if !request.host.match?(/^[\d.]+$/) && (request.host =~ domain_regexp) ".#{$&}" end elsif options[:domain].is_a? Array diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb index 00902ede21..237eccf45f 100644 --- a/actionpack/lib/action_dispatch/middleware/ssl.rb +++ b/actionpack/lib/action_dispatch/middleware/ssl.rb @@ -13,7 +13,7 @@ module ActionDispatch # # Requests can opt-out of redirection with +exclude+: # - # config.ssl_options = { redirect: { exclude: -> request { request.path =~ /healthcheck/ } } } + # config.ssl_options = { redirect: { exclude: -> request { /healthcheck/.match?(request.path) } } } # # Cookies will not be flagged as secure for excluded requests. # @@ -126,7 +126,7 @@ module ActionDispatch [ @redirect.fetch(:status, redirection_status(request)), { "Content-Type" => "text/html", "Location" => https_location_for(request) }, - @redirect.fetch(:body, []) ] + (@redirect[:body] || []) ] end def redirection_status(request) diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index 1f2f7757a3..eddcdbaeac 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -32,18 +32,13 @@ module ActionDispatch return false unless ::Rack::Utils.valid_path? path path = ::Rack::Utils.clean_path_info path - paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"] + return ::Rack::Utils.escape_path(path).b if file_readable?(path) - if match = paths.detect { |p| - path = File.join(@root, p.b) - begin - File.file?(path) && File.readable?(path) - rescue SystemCallError - false - end - } - return ::Rack::Utils.escape_path(match).b - end + path_with_ext = path + ext + return ::Rack::Utils.escape_path(path_with_ext).b if file_readable?(path_with_ext) + + path << "/" << @index << ext + return ::Rack::Utils.escape_path(path).b if file_readable?(path) end def call(env) @@ -83,11 +78,11 @@ module ActionDispatch end def gzip_encoding_accepted?(request) - request.accept_encoding.any? { |enc, quality| enc =~ /\bgzip\b/i } + request.accept_encoding.any? { |enc, quality| /\bgzip\b/i.match?(enc) } end def gzip_file_path(path) - can_gzip_mime = content_type(path) =~ /\A(?:text\/|application\/javascript)/ + can_gzip_mime = /\A(?:text\/|application\/javascript)/.match?(content_type(path)) gzip_path = "#{path}.gz" if can_gzip_mime && File.exist?(File.join(@root, ::Rack::Utils.unescape_path(gzip_path))) gzip_path @@ -95,6 +90,12 @@ module ActionDispatch false end end + + def file_readable?(path) + file_path = File.join(@root, path.b) + File.file?(file_path) && File.readable?(file_path) + rescue SystemCallError + end end # This middleware will attempt to return the contents of a file's body from diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index 6e40a18009..bf286c299d 100644 --- a/actionpack/lib/action_dispatch/routing/inspector.rb +++ b/actionpack/lib/action_dispatch/routing/inspector.rb @@ -94,7 +94,7 @@ module ActionDispatch if filter @routes.select do |route| route_wrapper = RouteWrapper.new(route) - filter.any? { |default, value| route_wrapper.send(default) =~ value } + filter.any? { |default, value| value.match?(route_wrapper.send(default)) } end else @routes diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index d1100089b1..da95e14cbb 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -112,7 +112,7 @@ module ActionDispatch end def self.optional_format?(path, format) - format != false && path !~ OPTIONAL_FORMAT_REGEX + format != false && !path.match?(OPTIONAL_FORMAT_REGEX) end def initialize(set:, ast:, controller:, default_action:, to:, formatted:, via:, options_constraints:, anchor:, scope_params:, options:) @@ -367,7 +367,7 @@ module ActionDispatch def translate_controller(controller) return controller if Regexp === controller - return controller.to_s if controller =~ /\A[a-z_0-9][a-z_0-9\/]*\z/ + return controller.to_s if /\A[a-z_0-9][a-z_0-9\/]*\z/.match?(controller) yield end @@ -403,7 +403,7 @@ module ActionDispatch # for root cases, where the latter is the correct one. def self.normalize_path(path) path = Journey::Router::Utils.normalize_path(path) - path.gsub!(%r{/(\(+)/?}, '\1/') unless path =~ %r{^/(\(+[^)]+\)){1,}$} + path.gsub!(%r{/(\(+)/?}, '\1/') unless %r{^/(\(+[^)]+\)){1,}$}.match?(path) path end @@ -996,7 +996,7 @@ module ActionDispatch # # Requests to routes can be constrained based on specific criteria: # - # constraints(-> (req) { req.env["HTTP_USER_AGENT"] =~ /iPhone/ }) do + # constraints(-> (req) { /iPhone/.match?(req.env["HTTP_USER_AGENT"]) }) do # resources :iphones # end # @@ -1006,7 +1006,7 @@ module ActionDispatch # # class Iphone # def self.matches?(request) - # request.env["HTTP_USER_AGENT"] =~ /iPhone/ + # /iPhone/.match?(request.env["HTTP_USER_AGENT"]) # end # end # @@ -1833,7 +1833,7 @@ module ActionDispatch # and return nil in case it isn't. Otherwise, we pass the invalid name # forward so the underlying router engine treats it and raises an exception. if as.nil? - candidate unless candidate !~ /\A[_a-z]/i || has_named_route?(candidate) + candidate unless !candidate.match?(/\A[_a-z]/i) || has_named_route?(candidate) else candidate end @@ -1887,7 +1887,7 @@ module ActionDispatch options_constraints = options.delete(:constraints) || {} path_types = paths.group_by(&:class) - path_types.fetch(String, []).each do |_path| + (path_types[String] || []).each do |_path| route_options = options.dup if _path && option_path raise ArgumentError, "Ambiguous route definition. Both :path and the route path were specified as strings." @@ -1896,7 +1896,7 @@ module ActionDispatch decomposed_match(_path, controller, route_options, _path, to, via, formatted, anchor, options_constraints) end - path_types.fetch(Symbol, []).each do |action| + (path_types[Symbol] || []).each do |action| route_options = options.dup decomposed_match(action, controller, route_options, option_path, to, via, formatted, anchor, options_constraints) end @@ -1916,7 +1916,7 @@ module ActionDispatch end def using_match_shorthand?(path) - path =~ %r{^/?[-\w]+/[-\w/]+$} + %r{^/?[-\w]+/[-\w/]+$}.match?(path) end def decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 5b35b68c44..db8c54ba84 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -836,7 +836,7 @@ module ActionDispatch def recognize_path(path, environment = {}) method = (environment[:method] || "GET").to_s.upcase - path = Journey::Router::Utils.normalize_path(path) unless path =~ %r{://} + path = Journey::Router::Utils.normalize_path(path) unless %r{://}.match?(path) extras = environment[:extras] || {} begin diff --git a/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb b/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb index 056ce51a61..cba053ee4c 100644 --- a/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +++ b/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb @@ -9,10 +9,16 @@ module ActionDispatch # # +take_screenshot+ can be used at any point in your system tests to take # a screenshot of the current state. This can be useful for debugging or - # automating visual testing. + # automating visual testing. You can take multiple screenshots per test + # to investigate changes at different points during your test. These will be + # named with a sequential prefix (or 'failed' for failing tests) # # The screenshot will be displayed in your console, if supported. # + # You can set the +RAILS_SYSTEM_TESTING_SCREENSHOT_HTML+ environment variable to + # save the HTML from the page that is being screenhoted so you can investigate the + # elements on the page at the time of the screenshot + # # You can set the +RAILS_SYSTEM_TESTING_SCREENSHOT+ environment variable to # control the output. Possible values are: # * [+simple+ (default)] Only displays the screenshot path. @@ -22,6 +28,8 @@ module ActionDispatch # * [+artifact+] Display the screenshot in the terminal, using the terminal # artifact format (https://buildkite.github.io/terminal-to-html/inline-images/). def take_screenshot + increment_unique + save_html if save_html? save_image puts display_image end @@ -38,17 +46,48 @@ module ActionDispatch end private + attr_accessor :_screenshot_counter + + def save_html? + ENV["RAILS_SYSTEM_TESTING_SCREENSHOT_HTML"] == "1" + end + + def increment_unique + @_screenshot_counter ||= 0 + @_screenshot_counter += 1 + end + + def unique + failed? ? "failures" : (_screenshot_counter || 0).to_s + end + def image_name - name = method_name[0...225] - failed? ? "failures_#{name}" : name + name = "#{unique}_#{method_name}" + name[0...225] end def image_path - @image_path ||= absolute_image_path.to_s + absolute_image_path.to_s + end + + def html_path + absolute_html_path.to_s + end + + def absolute_path + Rails.root.join("tmp/screenshots/#{image_name}") end def absolute_image_path - Rails.root.join("tmp/screenshots/#{image_name}.png") + "#{absolute_path}.png" + end + + def absolute_html_path + "#{absolute_path}.html" + end + + def save_html + page.save_page(absolute_html_path) end def save_image @@ -66,7 +105,8 @@ module ActionDispatch end def display_image - message = +"[Screenshot]: #{image_path}\n" + message = +"[Screenshot Image]: #{image_path}\n" + message << +"[Screenshot HTML]: #{html_path}\n" if save_html? case output_type when "artifact" |