diff options
Diffstat (limited to 'actionpack')
98 files changed, 763 insertions, 527 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index eef3db8f24..3123fc9786 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,51 @@ +* Use accept header in integration tests with `as: :json` + + Instead of appending the `format` to the request path. Rails will figure + out the format from the header instead. + + This allows devs to use `:as` on routes that don't have a format. + + Fixes #27144. + + *Kasper Timm Hansen* + +* Reset a new session directly after its creation in ActionDispatch::IntegrationTest#open_session. + + Fixes #22742. + + *Tawan Sierek* + +* Fixes incorrect output from rails routes when using singular resources. + + Fixes #26606. + + *Erick Reyna* + +* Fixes multiple calls to `logger.fatal` instead of a single call, + for every line in an exception backtrace, when printing trace + from `DebugExceptions` middleware. + + Fixes #26134. + + *Vipul A M* + +* Add support for arbitrary hashes in strong parameters: + + ```ruby + params.permit(preferences: {}) + ``` + + *Xavier Noria* + +* Add `ActionController::Parameters#merge!`, which behaves the same as `Hash#merge!`. + + *Yuji Yaginuma* + +* Allow keys not found in `RACK_KEY_TRANSLATION` for setting the environment when rendering + arbitrary templates. + + *Sammy Larbi* + * Remove deprecated support to non-keyword arguments in `ActionDispatch::IntegrationTest#process`, `#get`, `#post`, `#patch`, `#put`, `#delete`, and `#head`. diff --git a/actionpack/bin/test b/actionpack/bin/test index 84a05bba08..a7beb14b27 100755 --- a/actionpack/bin/test +++ b/actionpack/bin/test @@ -2,5 +2,3 @@ COMPONENT_ROOT = File.expand_path("..", __dir__) require File.expand_path("../tools/test", COMPONENT_ROOT) - -exit Minitest.run(ARGV) diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 8e588812f8..603c2e9ea7 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -215,7 +215,7 @@ module AbstractController # ==== Returns # * <tt>string</tt> - The name of the method that handles the action # * false - No valid method name could be found. - # Raise AbstractController::ActionNotFound. + # Raise +AbstractController::ActionNotFound+. def _find_action_name(action_name) _valid_action_name?(action_name) && method_for_action(action_name) end @@ -231,11 +231,11 @@ module AbstractController # with a template matching the action name is considered to exist. # # If you override this method to handle additional cases, you may - # also provide a method (like _handle_method_missing) to handle + # also provide a method (like +_handle_method_missing+) to handle # the case. # - # If none of these conditions are true, and method_for_action - # returns nil, an AbstractController::ActionNotFound exception will be raised. + # If none of these conditions are true, and +method_for_action+ + # returns +nil+, an +AbstractController::ActionNotFound+ exception will be raised. # # ==== Parameters # * <tt>action_name</tt> - An action name to find a method name for diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 2cb22cb53d..d339580435 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -1,6 +1,4 @@ require "abstract_controller/error" -require "active_support/concern" -require "active_support/core_ext/class/attribute" require "action_view" require "action_view/view_paths" require "set" @@ -80,7 +78,7 @@ module AbstractController # <tt>render :action => "foo"</tt> and <tt>render "foo/bar"</tt> to # <tt>render :file => "foo/bar"</tt>. # :api: plugin - def _normalize_args(action=nil, options={}) + def _normalize_args(action = nil, options = {}) if action.respond_to?(:permitted?) if action.permitted? action diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb index 89bf60a0bb..eb636fa3f6 100644 --- a/actionpack/lib/action_controller/metal/conditional_get.rb +++ b/actionpack/lib/action_controller/metal/conditional_get.rb @@ -238,7 +238,7 @@ module ActionController ) options.delete(:private) - response.cache_control[:extras] = options.map { |k,v| "#{k}=#{v}" } + response.cache_control[:extras] = options.map { |k, v| "#{k}=#{v}" } response.date = Time.now unless response.date? end diff --git a/actionpack/lib/action_controller/metal/etag_with_template_digest.rb b/actionpack/lib/action_controller/metal/etag_with_template_digest.rb index 6c103bb042..798564db96 100644 --- a/actionpack/lib/action_controller/metal/etag_with_template_digest.rb +++ b/actionpack/lib/action_controller/metal/etag_with_template_digest.rb @@ -40,7 +40,7 @@ module ActionController end # Pick the template digest to include in the ETag. If the +:template+ option - # is present, use the named template. If +:template+ is nil or absent, use + # is present, use the named template. If +:template+ is +nil+ or absent, use # the default controller/action template. If +:template+ is false, omit the # template digest from the ETag. def pick_template_for_etag(options) diff --git a/actionpack/lib/action_controller/metal/exceptions.rb b/actionpack/lib/action_controller/metal/exceptions.rb index 3761e6172b..175dd9eb9e 100644 --- a/actionpack/lib/action_controller/metal/exceptions.rb +++ b/actionpack/lib/action_controller/metal/exceptions.rb @@ -14,7 +14,7 @@ module ActionController class RoutingError < ActionControllerError #:nodoc: attr_reader :failures - def initialize(message, failures=[]) + def initialize(message, failures = []) super(message) @failures = failures end diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb index b8976497a4..9d43e752ac 100644 --- a/actionpack/lib/action_controller/metal/force_ssl.rb +++ b/actionpack/lib/action_controller/metal/force_ssl.rb @@ -89,7 +89,7 @@ module ActionController end secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS)) - flash.keep if respond_to?(:flash) + flash.keep if respond_to?(:flash) && request.respond_to?(:flash) redirect_to secure_url, options.slice(*REDIRECT_OPTIONS) end end diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index a335bf109e..5bf0a99fe4 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -224,7 +224,7 @@ module ActionController # Returns the expected response for a request of +http_method+ to +uri+ with the decoded +credentials+ and the expected +password+ # Optional parameter +password_is_ha1+ is set to +true+ by default, since best practice is to store ha1 digest instead # of a plain-text password. - def expected_response(http_method, uri, credentials, password, password_is_ha1=true) + def expected_response(http_method, uri, credentials, password, password_is_ha1 = true) ha1 = password_is_ha1 ? password : ha1(credentials, password) ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":")) ::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":")) @@ -246,7 +246,7 @@ module ActionController def decode_credentials(header) ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, "").split(",").map do |pair| key, value = pair.split("=", 2) - [key.strip, value.to_s.gsub(/^"|"$/,"").delete('\'')] + [key.strip, value.to_s.gsub(/^"|"$/, "").delete('\'')] end] end @@ -314,7 +314,7 @@ module ActionController # Can be much shorter if the Stale directive is implemented. This would # allow a user to use new nonce without prompting the user again for their # username and password. - def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60) + def validate_nonce(secret_key, request, value, seconds_to_timeout = 5 * 60) return false if value.nil? t = ::Base64.decode64(value).split(":").first.to_i nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 2ede96c667..f83396ae55 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -46,7 +46,7 @@ module ActionController render_output end - def send_file(path, options={}) + def send_file(path, options = {}) ActiveSupport::Notifications.instrument("send_file.action_controller", options.merge(path: path)) do super diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb index 26a16104db..fed99e6c82 100644 --- a/actionpack/lib/action_controller/metal/live.rb +++ b/actionpack/lib/action_controller/metal/live.rb @@ -247,7 +247,7 @@ module ActionController # Since we're processing the view in a different thread, copy the # thread locals from the main thread to the child thread. :'( - locals.each { |k,v| t2[k] = v } + locals.each { |k, v| t2[k] = v } begin super(name) diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb index 9d1b740025..86e817fe16 100644 --- a/actionpack/lib/action_controller/metal/params_wrapper.rb +++ b/actionpack/lib/action_controller/metal/params_wrapper.rb @@ -205,7 +205,7 @@ module ActionController model = name_or_model_or_options end - opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options) + opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options) opts.model = model opts.klass = self diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 2b060e3698..30798c1d99 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -1,12 +1,4 @@ module ActionController - class RedirectBackError < AbstractController::Error #:nodoc: - DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].' - - def initialize(message = nil) - super(message || DEFAULT_MESSAGE) - end - end - module Redirecting extend ActiveSupport::Concern diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 67365a143e..56cfb4fbba 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -67,13 +67,13 @@ module ActionController end def _set_rendered_content_type(format) - unless response.content_type + if format && !response.content_type self.content_type = format.to_s end end # Normalize arguments by catching blocks and setting them on :update. - def _normalize_args(action=nil, options={}, &blk) #:nodoc: + def _normalize_args(action = nil, options = {}, &blk) #:nodoc: options = super options[:update] = blk if block_given? options diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index b64617d084..acfeca1fcb 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -71,8 +71,8 @@ module ActionController # * +permit_all_parameters+ - If it's +true+, all the parameters will be # permitted by default. The default is +false+. # * +action_on_unpermitted_parameters+ - Allow to control the behavior when parameters - # that are not explicitly permitted are found. The values can be <tt>:log</tt> to - # write a message on the logger or <tt>:raise</tt> to raise + # that are not explicitly permitted are found. The values can be +false+ to just filter them + # out, <tt>:log</tt> to additionally write a message on the logger, or <tt>:raise</tt> to raise # ActionController::UnpermittedParameters exception. The default value is <tt>:log</tt> # in test and development environments, +false+ otherwise. # @@ -334,6 +334,15 @@ module ActionController # params = ActionController::Parameters.new(tags: ['rails', 'parameters']) # params.permit(tags: []) # + # Sometimes it is not possible or convenient to declare the valid keys of + # a hash parameter or its internal structure. Just map to an empty hash: + # + # params.permit(preferences: {}) + # + # but be careful because this opens the door to arbitrary input. In this + # case, +permit+ ensures values in the returned structure are permitted + # scalars and filters out anything else. + # # You can also use +permit+ on nested parameters, like: # # params = ActionController::Parameters.new({ @@ -382,14 +391,15 @@ module ActionController case filter when Symbol, String permitted_scalar_filter(params, filter) - when Hash then + when Hash hash_filter(params, filter) end end unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters - params.permit! + params.permitted = true + params end # Returns a parameter for the given +key+. If not found, @@ -539,7 +549,7 @@ module ActionController new_instance_with_inherited_permitted_status(@parameters.select(&block)) end - # Equivalent to Hash#keep_if, but returns nil if no changes were made. + # Equivalent to Hash#keep_if, but returns +nil+ if no changes were made. def select!(&block) @parameters.select!(&block) self @@ -573,6 +583,13 @@ module ActionController ) end + # Returns current <tt>ActionController::Parameters</tt> instance which + # +other_hash+ merges into current hash. + def merge!(other_hash) + @parameters.merge!(other_hash.to_h) + self + end + # This is required by ActiveModel attribute assignment, so that user can # pass +Parameters+ to a mass assignment methods in a model. It should not # matter as we are using +HashWithIndifferentAccess+ internally. @@ -680,7 +697,7 @@ module ActionController when Parameters if object.fields_for_style? hash = object.class.new - object.each { |k,v| hash[k] = yield v } + object.each { |k, v| hash[k] = yield v } hash else yield object @@ -759,6 +776,7 @@ module ActionController end EMPTY_ARRAY = [] + EMPTY_HASH = {} def hash_filter(params, filter) filter = filter.with_indifferent_access @@ -772,6 +790,11 @@ module ActionController array_of_permitted_scalars?(self[key]) do |val| params[key] = val end + elsif filter[key] == EMPTY_HASH + # Declaration { preferences: {} }. + if value.is_a?(Parameters) + params[key] = permit_any_in_parameters(value) + end elsif non_scalar?(value) # Declaration { user: :name } or { user: [:name, :age, { address: ... }] }. params[key] = each_element(value) do |element| @@ -781,6 +804,39 @@ module ActionController end end + def permit_any_in_parameters(params) + self.class.new.tap do |sanitized| + params.each do |key, value| + case value + when ->(v) { permitted_scalar?(v) } + sanitized[key] = value + when Array + sanitized[key] = permit_any_in_array(value) + when Parameters + sanitized[key] = permit_any_in_parameters(value) + else + # Filter this one out. + end + end + sanitized.permitted = true + end + end + + def permit_any_in_array(array) + [].tap do |sanitized| + array.each do |element| + case element + when ->(e) { permitted_scalar?(e) } + sanitized << element + when Parameters + sanitized << permit_any_in_parameters(element) + else + # Filter this one out. + end + end + end + end + def initialize_copy(source) super @parameters = @parameters.dup diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 6513a556ee..a7cdfe6a98 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -51,7 +51,7 @@ module ActionController extend ::AbstractController::Railties::RoutesHelpers.with(app.routes) extend ::ActionController::Railties::Helpers - options.each do |k,v| + options.each do |k, v| k = "#{k}=" if respond_to?(k) send(k, v) diff --git a/actionpack/lib/action_controller/renderer.rb b/actionpack/lib/action_controller/renderer.rb index 0739f16965..3ff80e6a39 100644 --- a/actionpack/lib/action_controller/renderer.rb +++ b/actionpack/lib/action_controller/renderer.rb @@ -83,7 +83,7 @@ module ActionController private def normalize_keys(env) new_env = {} - env.each_pair { |k,v| new_env[rack_key_for(k)] = rack_value_for(k, v) } + env.each_pair { |k, v| new_env[rack_key_for(k)] = rack_value_for(k, v) } new_env end @@ -102,7 +102,9 @@ module ActionController method: ->(v) { v.upcase }, } - def rack_key_for(key); RACK_KEY_TRANSLATION[key]; end + def rack_key_for(key) + RACK_KEY_TRANSLATION.fetch(key, key.to_s) + end def rack_value_for(key, value) RACK_VALUE_TRANSLATION.fetch(key, IDENTITY).call value diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 33c0201951..85f2501d42 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -112,8 +112,9 @@ module ActionController end end - set_header "CONTENT_LENGTH", data.length.to_s - set_header "rack.input", StringIO.new(data) + data_stream = StringIO.new(data) + set_header "CONTENT_LENGTH", data_stream.length.to_s + set_header "rack.input", data_stream end fetch_header("PATH_INFO") do |k| diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index d0c9413efa..e5f20003a3 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -29,8 +29,8 @@ module ActionDispatch content_mime_type && content_mime_type.to_s end - def has_content_type? - has_header? "CONTENT_TYPE" + def has_content_type? # :nodoc: + get_header "CONTENT_TYPE" end # Returns the accepted MIME type for the request. diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb index 01fe35f5c6..889f55a52a 100644 --- a/actionpack/lib/action_dispatch/http/parameter_filter.rb +++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb @@ -50,7 +50,7 @@ module ActionDispatch def initialize(regexps, deep_regexps, blocks) @regexps = regexps @deep_regexps = deep_regexps.any? ? deep_regexps : nil - @blocks = blocks + @blocks = blocks end def call(original_params, parents = []) diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index e8173e2a99..357ca56036 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -39,7 +39,7 @@ module ActionDispatch # :nodoc: super(header) end - def []=(k,v) + def []=(k, v) if @response.sending? || @response.sent? raise ActionDispatch::IllegalStateError, "header already sent" end @@ -249,7 +249,7 @@ module ActionDispatch # :nodoc: end end - # Sets the HTTP character set. In case of nil parameter + # Sets the HTTP character set. In case of +nil+ parameter # it sets the charset to utf-8. # # response.charset = 'utf-16' # => 'utf-16' diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb index 9aa73c862b..61ba052e45 100644 --- a/actionpack/lib/action_dispatch/http/upload.rb +++ b/actionpack/lib/action_dispatch/http/upload.rb @@ -24,7 +24,7 @@ module ActionDispatch attr_accessor :headers def initialize(hash) # :nodoc: - @tempfile = hash[:tempfile] + @tempfile = hash[:tempfile] raise(ArgumentError, ":tempfile is required") unless @tempfile @original_filename = hash[:filename] @@ -40,7 +40,7 @@ module ActionDispatch end # Shortcut for +tempfile.read+. - def read(length=nil, buffer=nil) + def read(length = nil, buffer = nil) @tempfile.read(length, buffer) end @@ -50,7 +50,7 @@ module ActionDispatch end # Shortcut for +tempfile.close+. - def close(unlink_now=false) + def close(unlink_now = false) @tempfile.close(unlink_now) end diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 06ffa983d1..a6937d54ff 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -66,7 +66,7 @@ module ActionDispatch end def path_for(options) - path = options[:script_name].to_s.chomp("/".freeze) + path = options[:script_name].to_s.chomp("/".freeze) path << options[:path] if options.key?(:path) add_trailing_slash(path) if options[:trailing_slash] @@ -80,7 +80,7 @@ module ActionDispatch def add_params(path, params) params = { params: params } unless params.is_a?(Hash) - params.reject! { |_,v| v.to_param.nil? } + params.reject! { |_, v| v.to_param.nil? } query = params.to_query path << "?#{query}" unless query.empty? end diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index dc8b24b089..20ff4441a0 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -1,10 +1,11 @@ require "action_controller/metal/exceptions" module ActionDispatch + # :stopdoc: module Journey # The Formatter class is used for formatting URLs. For example, parameters # passed to +url_for+ in Rails will eventually call Formatter#generate. - class Formatter # :nodoc: + class Formatter attr_reader :routes def initialize(routes) @@ -47,7 +48,7 @@ module ActionDispatch unmatched_keys = (missing_keys || []) & constraints.keys missing_keys = (missing_keys || []) - unmatched_keys - message = "No route matches #{Hash[constraints.sort_by { |k,v| k.to_s }].inspect}" + message = "No route matches #{Hash[constraints.sort_by { |k, v| k.to_s }].inspect}" message << ", missing required keys: #{missing_keys.sort.inspect}" if missing_keys && !missing_keys.empty? message << ", possible unmatched constraints: #{unmatched_keys.sort.inspect}" if unmatched_keys && !unmatched_keys.empty? @@ -178,4 +179,5 @@ module ActionDispatch end end end + # :startdoc: end diff --git a/actionpack/lib/action_dispatch/journey/gtg/builder.rb b/actionpack/lib/action_dispatch/journey/gtg/builder.rb index 9990c66627..0f8bed89bf 100644 --- a/actionpack/lib/action_dispatch/journey/gtg/builder.rb +++ b/actionpack/lib/action_dispatch/journey/gtg/builder.rb @@ -17,7 +17,7 @@ module ActionDispatch def transition_table dtrans = TransitionTable.new marked = {} - state_id = Hash.new { |h,k| h[k] = h.length } + state_id = Hash.new { |h, k| h[k] = h.length } start = firstpos(root) dstates = [start] diff --git a/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb b/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb index 0be18dc26f..beb9f1ef3b 100644 --- a/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb +++ b/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb @@ -12,7 +12,7 @@ module ActionDispatch @regexp_states = {} @string_states = {} @accepting = {} - @memos = Hash.new { |h,k| h[k] = [] } + @memos = Hash.new { |h, k| h[k] = [] } end def add_accepting(state) @@ -56,7 +56,7 @@ module ActionDispatch end def as_json(options = nil) - simple_regexp = Hash.new { |h,k| h[k] = {} } + simple_regexp = Hash.new { |h, k| h[k] = {} } @regexp_states.each do |from, hash| hash.each do |re, to| diff --git a/actionpack/lib/action_dispatch/journey/nfa/builder.rb b/actionpack/lib/action_dispatch/journey/nfa/builder.rb index 19e5752ae5..532f765094 100644 --- a/actionpack/lib/action_dispatch/journey/nfa/builder.rb +++ b/actionpack/lib/action_dispatch/journey/nfa/builder.rb @@ -36,7 +36,7 @@ module ActionDispatch def visit_OR(node) from = @i += 1 children = node.children.map { |c| visit(c) } - to = @i += 1 + to = @i += 1 children.each do |child| @tt[from, child.first] = nil diff --git a/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb b/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb index 4737adc724..543a670da0 100644 --- a/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb +++ b/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb @@ -10,7 +10,7 @@ module ActionDispatch attr_reader :memos def initialize - @table = Hash.new { |h,f| h[f] = {} } + @table = Hash.new { |h, f| h[f] = {} } @memos = {} @accepting = nil @inverted = nil diff --git a/actionpack/lib/action_dispatch/journey/parser.rb b/actionpack/lib/action_dispatch/journey/parser.rb index 01ff2109cb..ee91b11b42 100644 --- a/actionpack/lib/action_dispatch/journey/parser.rb +++ b/actionpack/lib/action_dispatch/journey/parser.rb @@ -8,6 +8,7 @@ require "racc/parser.rb" require "action_dispatch/journey/parser_extras" module ActionDispatch + # :stopdoc: module Journey class Parser < Racc::Parser ##### State transition tables begin ### @@ -193,4 +194,5 @@ module ActionDispatch end end # class Parser end # module Journey + # :startdoc: end # module ActionDispatch diff --git a/actionpack/lib/action_dispatch/journey/parser_extras.rb b/actionpack/lib/action_dispatch/journey/parser_extras.rb index ec26e634e8..4c7e82d93c 100644 --- a/actionpack/lib/action_dispatch/journey/parser_extras.rb +++ b/actionpack/lib/action_dispatch/journey/parser_extras.rb @@ -2,8 +2,9 @@ require "action_dispatch/journey/scanner" require "action_dispatch/journey/nodes/node" module ActionDispatch - module Journey # :nodoc: - class Parser < Racc::Parser # :nodoc: + # :stopdoc: + module Journey + class Parser < Racc::Parser include Journey::Nodes def self.parse(string) @@ -24,4 +25,5 @@ module ActionDispatch end end end + # :startdoc: end diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb index a9713ff292..0cc8d83ac8 100644 --- a/actionpack/lib/action_dispatch/journey/route.rb +++ b/actionpack/lib/action_dispatch/journey/route.rb @@ -1,6 +1,7 @@ module ActionDispatch - module Journey # :nodoc: - class Route # :nodoc: + # :stopdoc: + module Journey + class Route attr_reader :app, :path, :defaults, :name, :precedence attr_reader :constraints, :internal @@ -80,9 +81,9 @@ module ActionDispatch end end - def requirements # :nodoc: + def requirements # needed for rails `rails routes` - @defaults.merge(path.requirements).delete_if { |_,v| + @defaults.merge(path.requirements).delete_if { |_, v| /.+?/ == v } end @@ -97,7 +98,7 @@ module ActionDispatch def score(constraints) required_keys = path.required_names - supplied_keys = constraints.map { |k,v| v && k.to_s }.compact + supplied_keys = constraints.map { |k, v| v && k.to_s }.compact return -1 unless (required_keys - supplied_keys).empty? @@ -123,7 +124,7 @@ module ActionDispatch end def required_defaults - @required_defaults ||= @defaults.dup.delete_if do |k,_| + @required_defaults ||= @defaults.dup.delete_if do |k, _| parts.include?(k) || !required_default?(k) end end @@ -176,4 +177,5 @@ module ActionDispatch end end end + # :startdoc: end diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb index d0ef549335..084ae9325e 100644 --- a/actionpack/lib/action_dispatch/journey/router.rb +++ b/actionpack/lib/action_dispatch/journey/router.rb @@ -109,9 +109,9 @@ module ActionDispatch routes.sort_by!(&:precedence) routes.map! { |r| - match_data = r.path.match(req.path_info) + match_data = r.path.match(req.path_info) path_parameters = r.defaults.dup - match_data.names.zip(match_data.captures) { |name,val| + match_data.names.zip(match_data.captures) { |name, val| path_parameters[name.to_sym] = Utils.unescape_uri(val) if val } [match_data, path_parameters, r] diff --git a/actionpack/lib/action_dispatch/journey/visitors.rb b/actionpack/lib/action_dispatch/journey/visitors.rb index 452dc84cc5..cda859cba4 100644 --- a/actionpack/lib/action_dispatch/journey/visitors.rb +++ b/actionpack/lib/action_dispatch/journey/visitors.rb @@ -1,5 +1,6 @@ module ActionDispatch - module Journey # :nodoc: + # :stopdoc: + module Journey class Format ESCAPE_PATH = ->(value) { Router::Utils.escape_path(value) } ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) } @@ -21,7 +22,7 @@ module ActionDispatch @children = [] @parameters = [] - parts.each_with_index do |object,i| + parts.each_with_index do |object, i| case object when Journey::Format @children << i @@ -261,4 +262,5 @@ module ActionDispatch end end end + # :startdoc: end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 6f4fab396a..956c53e813 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -179,7 +179,7 @@ module ActionDispatch # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed - # cookie was tampered with by the user (or a 3rd party), nil will be returned. + # cookie was tampered with by the user (or a 3rd party), +nil+ will be returned. # # If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set, # legacy cookies signed with the old key generator will be transparently upgraded. @@ -202,7 +202,7 @@ module ActionDispatch end # Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read. - # If the cookie was tampered with by the user (or a 3rd party), nil will be returned. + # If the cookie was tampered with by the user (or a 3rd party), +nil+ will be returned. # # If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set, # legacy cookies signed with the old key generator will be transparently upgraded. @@ -332,13 +332,13 @@ module ActionDispatch def update_cookies_from_jar request_jar = @request.cookie_jar.instance_variable_get(:@cookies) - set_cookies = request_jar.reject { |k,_| @delete_cookies.key?(k) } + set_cookies = request_jar.reject { |k, _| @delete_cookies.key?(k) } @cookies.update set_cookies if set_cookies end def to_header - @cookies.map { |k,v| "#{escape(k)}=#{escape(v)}" }.join "; " + @cookies.map { |k, v| "#{escape(k)}=#{escape(v)}" }.join "; " end def handle_options(options) #:nodoc: diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index ee644f41c8..1c720c5a8e 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -38,7 +38,9 @@ module ActionDispatch end def render(*) - if logger = ActionView::Base.logger + logger = ActionView::Base.logger + + if logger && logger.respond_to?(:silence) logger.silence { super } else super @@ -173,7 +175,11 @@ module ActionDispatch end def log_array(logger, array) - array.map { |line| logger.fatal line } + if logger.formatter && logger.formatter.respond_to?(:tags_text) + logger.fatal array.join("\n#{logger.formatter.tags_text}") + else + logger.fatal array.join("\n") + end end def logger(request) diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb index 99dc37c568..397f0a8b92 100644 --- a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb +++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb @@ -127,7 +127,7 @@ module ActionDispatch File.open(full_path, "r") do |file| start = [line - 3, 0].max lines = file.each_line.drop(start).take(6) - Hash[*(start+1..(lines.count+start)).zip(lines).flatten] + Hash[*(start + 1..(lines.count + start)).zip(lines).flatten] end end end diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index 6900934712..6dddcc6ee1 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -129,7 +129,7 @@ module ActionDispatch end # Builds a hash containing the flashes to keep for the next request. - # If there are none to keep, returns nil. + # If there are none to keep, returns +nil+. def to_session_value #:nodoc: flashes_to_keep = @flashes.except(*@discard) return nil if flashes_to_keep.empty? diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index 8409109ede..57d325a9d8 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -63,7 +63,7 @@ module ActionDispatch # Other useful options include <tt>:key</tt>, <tt>:secure</tt> and # <tt>:httponly</tt>. class CookieStore < AbstractStore - def initialize(app, options={}) + def initialize(app, options = {}) super(app, options.merge!(cookie_only: true)) end @@ -102,7 +102,7 @@ module ActionDispatch end end - def persistent_session_id!(data, sid=nil) + def persistent_session_id!(data, sid = nil) data ||= {} data["session_id"] ||= sid || generate_sid data diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb index c9bd417aa2..557721c301 100644 --- a/actionpack/lib/action_dispatch/middleware/ssl.rb +++ b/actionpack/lib/action_dispatch/middleware/ssl.rb @@ -23,7 +23,7 @@ module ActionDispatch # `180.days` (recommended). # * `subdomains`: Set to `true` to tell the browser to apply these settings # to all subdomains. This protects your cookies from interception by a - # vulnerable site on a subdomain. Defaults to `false`. + # vulnerable site on a subdomain. Defaults to `true`. # * `preload`: Advertise that this site may be included in browsers' # preloaded HSTS lists. HSTS protects your site on every visit *except the # first visit* since it hasn't seen your HSTS header yet. To close this diff --git a/actionpack/lib/action_dispatch/request/session.rb b/actionpack/lib/action_dispatch/request/session.rb index b883ca0f61..a2a80f39fc 100644 --- a/actionpack/lib/action_dispatch/request/session.rb +++ b/actionpack/lib/action_dispatch/request/session.rb @@ -53,7 +53,7 @@ module ActionDispatch } end - def []=(k,v); @delegate[k] = v; end + def []=(k, v); @delegate[k] = v; end def to_hash; @delegate.dup; end def values_at(*args); @delegate.values_at(*args); end end @@ -85,7 +85,7 @@ module ActionDispatch end # Returns value of the key stored in the session or - # nil if the given key is not found in the session. + # +nil+ if the given key is not found in the session. def [](key) load_for_read! @delegate[key.to_s] @@ -124,7 +124,7 @@ module ActionDispatch # Returns the session as Hash. def to_hash load_for_read! - @delegate.dup.delete_if { |_,v| v.nil? } + @delegate.dup.delete_if { |_, v| v.nil? } end # Updates the session with given Hash. @@ -162,7 +162,7 @@ module ActionDispatch # :bar # end # # => :bar - def fetch(key, default=Unspecified, &block) + def fetch(key, default = Unspecified, &block) load_for_read! if default == Unspecified @delegate.fetch(key.to_s, &block) diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 61ebd0b8db..fe8bf6a35c 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/string/filters' + module ActionDispatch # The routing module provides URL rewriting in native Ruby. It's a way to # redirect incoming requests to controllers and actions. This replaces diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index c481c190bf..4efde09b8b 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,7 +1,6 @@ require "active_support/core_ext/hash/slice" require "active_support/core_ext/enumerable" require "active_support/core_ext/array/extract_options" -require "active_support/core_ext/regexp" require "action_dispatch/routing/redirection" require "action_dispatch/routing/endpoint" @@ -568,7 +567,7 @@ module ActionDispatch # [:format] # Allows you to specify the default value for optional +format+ # segment or disable it by supplying +false+. - def match(path, options=nil) + def match(path, options = nil) end # Mount a Rack-based application to be used within the application. @@ -1245,11 +1244,11 @@ module ActionDispatch # the plural): # # GET /profile/new - # POST /profile # GET /profile # GET /profile/edit # PATCH/PUT /profile # DELETE /profile + # POST /profile # # === Options # Takes same options as +resources+. @@ -1267,15 +1266,15 @@ module ActionDispatch concerns(options[:concerns]) if options[:concerns] - collection do - post :create - end if parent_resource.actions.include?(:create) - new do get :new end if parent_resource.actions.include?(:new) set_member_mappings_for_resource + + collection do + post :create + end if parent_resource.actions.include?(:create) end end diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb index 4f1aaeefc8..432b9bf4c1 100644 --- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb +++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb @@ -160,7 +160,7 @@ module ActionDispatch CACHE = { "path" => {}, "url" => {} } def self.get(action, type) - type = type.to_s + type = type.to_s CACHE[type].fetch(action) { build action, type } end @@ -266,7 +266,7 @@ module ActionDispatch args = [] - route = record_list.map { |parent| + route = record_list.map { |parent| case parent when Symbol, String parent.to_s @@ -304,7 +304,7 @@ module ActionDispatch private def get_method_for_class(klass) - name = @key_strategy.call klass.model_name + name = @key_strategy.call klass.model_name get_method_for_string name end diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index 87bcceccc0..4e2318a45e 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -61,15 +61,15 @@ module ActionDispatch end def escape(params) - Hash[params.map { |k,v| [k, Rack::Utils.escape(v)] }] + Hash[params.map { |k, v| [k, Rack::Utils.escape(v)] }] end def escape_fragment(params) - Hash[params.map { |k,v| [k, Journey::Router::Utils.escape_fragment(v)] }] + Hash[params.map { |k, v| [k, Journey::Router::Utils.escape_fragment(v)] }] end def escape_path(params) - Hash[params.map { |k,v| [k, Journey::Router::Utils.escape_path(v)] }] + Hash[params.map { |k, v| [k, Journey::Router::Utils.escape_path(v)] }] end end @@ -128,7 +128,7 @@ module ActionDispatch end def inspect - "redirect(#{status}, #{options.map { |k,v| "#{k}: #{v}" }.join(', ')})" + "redirect(#{status}, #{options.map { |k, v| "#{k}: #{v}" }.join(', ')})" end end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index a1bc357c8b..5853adb110 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -1,5 +1,4 @@ require "action_dispatch/journey" -require "active_support/concern" require "active_support/core_ext/object/to_query" require "active_support/core_ext/hash/slice" require "active_support/core_ext/module/remove_method" @@ -71,7 +70,7 @@ module ActionDispatch private :routes def initialize - @routes = {} + @routes = {} @path_helpers = Set.new @url_helpers = Set.new @url_helpers_module = Module.new @@ -208,7 +207,7 @@ module ActionDispatch params = parameterize_args(args) { |missing_key| missing_keys << missing_key } - constraints = Hash[@route.requirements.merge(params).sort_by { |k,v| k.to_s }] + constraints = Hash[@route.requirements.merge(params).sort_by { |k, v| k.to_s }] message = "No route matches #{constraints.inspect}" message << ", missing required keys: #{missing_keys.sort.inspect}" @@ -647,11 +646,11 @@ module ActionDispatch # Generate the path indicated by the arguments, and return an array of # the keys that were not used to generate it. - def extra_keys(options, recall={}) + def extra_keys(options, recall = {}) generate_extras(options, recall).last end - def generate_extras(options, recall={}) + def generate_extras(options, recall = {}) route_key = options.delete :use_route path, params = generate(route_key, options, recall) return path, params.keys @@ -693,7 +692,7 @@ module ActionDispatch password = options.delete :password end - recall = options.delete(:_recall) { {} } + recall = options.delete(:_recall) { {} } original_script_name = options.delete(:original_script_name) script_name = find_script_name options diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index a2eaccd9ef..817737341c 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -50,7 +50,7 @@ module ActionDispatch # # # Asserts that the redirection matches the regular expression # assert_redirected_to %r(\Ahttp://example.org) - def assert_redirected_to(options = {}, message=nil) + def assert_redirected_to(options = {}, message = nil) assert_response(:redirect, message) return true if options === @response.location diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index e53bc6af12..454dcb9307 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -37,7 +37,7 @@ module ActionDispatch # # # Test a custom route # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1') - def assert_recognizes(expected_options, path, extras={}, msg=nil) + def assert_recognizes(expected_options, path, extras = {}, msg = nil) if path.is_a?(Hash) && path[:method].to_s == "all" [:get, :post, :put, :delete].each do |method| assert_recognizes(expected_options, path.merge(method: method), extras, msg) @@ -75,7 +75,7 @@ module ActionDispatch # # # Asserts that the generated route gives us our custom route # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" } - def assert_generates(expected_path, options, defaults={}, extras={}, message=nil) + def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil) if expected_path =~ %r{://} fail_on(URI::InvalidURIError, message) do uri = URI.parse(expected_path) @@ -119,7 +119,7 @@ module ActionDispatch # # # Tests a route with an HTTP method # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" }) - def assert_routing(path, options, defaults={}, extras={}, message=nil) + def assert_routing(path, options, defaults = {}, extras = {}, message = nil) assert_recognizes(options, path, extras, message) controller, default_controller = options[:controller], defaults[:controller] diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index d137473ef4..021ffec862 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -11,62 +11,37 @@ require "action_dispatch/testing/request_encoder" module ActionDispatch module Integration #:nodoc: module RequestHelpers - # Performs a GET request with the given parameters. - # - # - +path+: The URI (as a String) on which you want to perform a GET - # request. - # - +params+: The HTTP parameters that you want to pass. This may - # be +nil+, - # a Hash, or a String that is appropriately encoded - # (<tt>application/x-www-form-urlencoded</tt> or - # <tt>multipart/form-data</tt>). - # - +headers+: Additional headers to pass, as a Hash. The headers will be - # merged into the Rack env hash. - # - +env+: Additional env to pass, as a Hash. The headers will be - # merged into the Rack env hash. - # - # This method returns a Response object, which one can use to - # inspect the details of the response. Furthermore, if this method was - # called from an ActionDispatch::IntegrationTest object, then that - # object's <tt>@response</tt> instance variable will point to the same - # response object. - # - # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with - # +#post+, +#patch+, +#put+, +#delete+, and +#head+. - # - # Example: - # - # get '/feed', params: { since: 201501011400 } - # post '/profile', headers: { "X-Test-Header" => "testvalue" } + # Performs a GET request with the given parameters. See +#process+ for more + # details. def get(path, **args) process(:get, path, **args) end - # Performs a POST request with the given parameters. See +#get+ for more + # Performs a POST request with the given parameters. See +#process+ for more # details. def post(path, **args) process(:post, path, **args) end - # Performs a PATCH request with the given parameters. See +#get+ for more + # Performs a PATCH request with the given parameters. See +#process+ for more # details. def patch(path, **args) process(:patch, path, **args) end - # Performs a PUT request with the given parameters. See +#get+ for more + # Performs a PUT request with the given parameters. See +#process+ for more # details. def put(path, **args) process(:put, path, **args) end - # Performs a DELETE request with the given parameters. See +#get+ for + # Performs a DELETE request with the given parameters. See +#process+ for # more details. def delete(path, **args) process(:delete, path, **args) end - # Performs a HEAD request with the given parameters. See +#get+ for more + # Performs a HEAD request with the given parameters. See +#process+ for more # details. def head(path, *args) process(:head, path, *args) @@ -94,7 +69,7 @@ module ActionDispatch DEFAULT_HOST = "www.example.com" include Minitest::Assertions - include RequestHelpers, Assertions + include TestProcess, RequestHelpers, Assertions %w( status status_message headers body redirect? ).each do |method| delegate method, to: :response, allow_nil: true @@ -198,101 +173,126 @@ module ActionDispatch @https end - # Set the host name to use in the next request. + # Performs the actual request. # - # session.host! "www.example.com" - alias :host! :host= - - private - def _mock_session - @_mock_session ||= Rack::MockSession.new(@app, host) + # - +method+: The HTTP method (GET, POST, PATCH, PUT, DELETE, HEAD, OPTIONS) + # as a symbol. + # - +path+: The URI (as a String) on which you want to perform the + # request. + # - +params+: The HTTP parameters that you want to pass. This may + # be +nil+, + # a Hash, or a String that is appropriately encoded + # (<tt>application/x-www-form-urlencoded</tt> or + # <tt>multipart/form-data</tt>). + # - +headers+: Additional headers to pass, as a Hash. The headers will be + # merged into the Rack env hash. + # - +env+: Additional env to pass, as a Hash. The headers will be + # merged into the Rack env hash. + # + # This method is rarely used directly. Use +#get+, +#post+, or other standard + # HTTP methods in integration tests. +#process+ is only required when using a + # request method that doesn't have a method defined in the integration tests. + # + # This method returns a Response object, which one can use to + # inspect the details of the response. Furthermore, if this method was + # called from an ActionDispatch::IntegrationTest object, then that + # object's <tt>@response</tt> instance variable will point to the same + # response object. + # + # Example: + # process :get, '/author', params: { since: 201501011400 } + def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil) + request_encoder = RequestEncoder.encoder(as) + headers ||= {} + + if method == :get && as == :json && params + headers["X-Http-Method-Override"] = "GET" + method = :post end - # Performs the actual request. - def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil) - request_encoder = RequestEncoder.encoder(as) - headers ||= {} + if path =~ %r{://} + path = build_expanded_path(path) do |location| + https! URI::HTTPS === location if location.scheme - if method == :get && as == :json && params - headers["X-Http-Method-Override"] = "GET" - method = :post + if url_host = location.host + default = Rack::Request::DEFAULT_PORTS[location.scheme] + url_host += ":#{location.port}" if default != location.port + host! url_host + end end + end - if path =~ %r{://} - path = build_expanded_path(path, request_encoder) do |location| - https! URI::HTTPS === location if location.scheme + hostname, port = host.split(":") - if url_host = location.host - default = Rack::Request::DEFAULT_PORTS[location.scheme] - url_host += ":#{location.port}" if default != location.port - host! url_host - end - end - elsif as - path = build_expanded_path(path, request_encoder) - end + request_env = { + :method => method, + :params => request_encoder.encode_params(params), - hostname, port = host.split(":") + "SERVER_NAME" => hostname, + "SERVER_PORT" => port || (https? ? "443" : "80"), + "HTTPS" => https? ? "on" : "off", + "rack.url_scheme" => https? ? "https" : "http", - request_env = { - :method => method, - :params => request_encoder.encode_params(params), + "REQUEST_URI" => path, + "HTTP_HOST" => host, + "REMOTE_ADDR" => remote_addr, + "CONTENT_TYPE" => request_encoder.content_type, + "HTTP_ACCEPT" => request_encoder.accept_header || accept + } - "SERVER_NAME" => hostname, - "SERVER_PORT" => port || (https? ? "443" : "80"), - "HTTPS" => https? ? "on" : "off", - "rack.url_scheme" => https? ? "https" : "http", + wrapped_headers = Http::Headers.from_hash({}) + wrapped_headers.merge!(headers) if headers - "REQUEST_URI" => path, - "HTTP_HOST" => host, - "REMOTE_ADDR" => remote_addr, - "CONTENT_TYPE" => request_encoder.content_type, - "HTTP_ACCEPT" => accept - } + if xhr + wrapped_headers["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" + wrapped_headers["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") + end - wrapped_headers = Http::Headers.from_hash({}) - wrapped_headers.merge!(headers) if headers + # this modifies the passed request_env directly + if wrapped_headers.present? + Http::Headers.from_hash(request_env).merge!(wrapped_headers) + end + if env.present? + Http::Headers.from_hash(request_env).merge!(env) + end - if xhr - wrapped_headers["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" - wrapped_headers["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") - end + session = Rack::Test::Session.new(_mock_session) - # this modifies the passed request_env directly - if wrapped_headers.present? - Http::Headers.from_hash(request_env).merge!(wrapped_headers) - end - if env.present? - Http::Headers.from_hash(request_env).merge!(env) - end + # NOTE: rack-test v0.5 doesn't build a default uri correctly + # Make sure requested path is always a full uri + session.request(build_full_uri(path, request_env), request_env) - session = Rack::Test::Session.new(_mock_session) + @request_count += 1 + @request = ActionDispatch::Request.new(session.last_request.env) + response = _mock_session.last_response + @response = ActionDispatch::TestResponse.from_response(response) + @response.request = @request + @html_document = nil + @url_options = nil - # NOTE: rack-test v0.5 doesn't build a default uri correctly - # Make sure requested path is always a full uri - session.request(build_full_uri(path, request_env), request_env) + @controller = @request.controller_instance - @request_count += 1 - @request = ActionDispatch::Request.new(session.last_request.env) - response = _mock_session.last_response - @response = ActionDispatch::TestResponse.from_response(response) - @response.request = @request - @html_document = nil - @url_options = nil + response.status + end - @controller = @request.controller_instance + # Set the host name to use in the next request. + # + # session.host! "www.example.com" + alias :host! :host= - response.status + private + def _mock_session + @_mock_session ||= Rack::MockSession.new(@app, host) end def build_full_uri(path, env) "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}" end - def build_expanded_path(path, request_encoder) + def build_expanded_path(path) location = URI.parse(path) yield location if block_given? - path = request_encoder.append_format_to location.path + path = location.path location.query ? "#{path}?#{location.query}" : path end end @@ -366,6 +366,7 @@ module ActionDispatch # simultaneously. def open_session dup.tap do |session| + session.reset! yield session if block_given? end end @@ -576,13 +577,15 @@ module ActionDispatch # end # end # - # The +as+ option sets the format to JSON, sets the content type to + # The +as+ option passes an "application/json" Accept header (thereby setting + # the request format to JSON unless overridden), sets the content type to # "application/json" and encodes the parameters as JSON. # # Calling +parsed_body+ on the response parses the response body based on the # last response MIME type. # - # For any custom MIME types you've registered, you can even add your own encoders with: + # Out of the box, only <tt>:json</tt> is supported. But for any custom MIME + # types you've registered, you can add your own encoders with: # # ActionDispatch::IntegrationTest.register_encoder :wibble, # param_encoder: -> params { params.to_wibble }, @@ -595,9 +598,7 @@ module ActionDispatch # Consult the Rails Testing Guide for more. class IntegrationTest < ActiveSupport::TestCase - include TestProcess - - undef :assigns + include TestProcess::FixtureFile module UrlOptions extend ActiveSupport::Concern diff --git a/actionpack/lib/action_dispatch/testing/request_encoder.rb b/actionpack/lib/action_dispatch/testing/request_encoder.rb index b0b994b2d0..8c27e9ecb7 100644 --- a/actionpack/lib/action_dispatch/testing/request_encoder.rb +++ b/actionpack/lib/action_dispatch/testing/request_encoder.rb @@ -1,10 +1,17 @@ module ActionDispatch class RequestEncoder # :nodoc: - @encoders = {} + class IdentityEncoder + def content_type; end + def accept_header; end + def encode_params(params); params; end + def response_parser; -> body { body }; end + end + + @encoders = { identity: IdentityEncoder.new } attr_reader :response_parser - def initialize(mime_name, param_encoder, response_parser, url_encoded_form = false) + def initialize(mime_name, param_encoder, response_parser) @mime = Mime[mime_name] unless @mime @@ -12,21 +19,15 @@ module ActionDispatch "unregistered MIME Type: #{mime_name}. See `Mime::Type.register`." end - @url_encoded_form = url_encoded_form - @path_format = ".#{@mime.symbol}" unless @url_encoded_form - @response_parser = response_parser || -> body { body } - @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc + @response_parser = response_parser || -> body { body } + @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc end - def append_format_to(path) - if @url_encoded_form - path - else - path + @path_format - end + def content_type + @mime.to_s end - def content_type + def accept_header @mime.to_s end @@ -40,7 +41,7 @@ module ActionDispatch end def self.encoder(name) - @encoders[name] || WWWFormEncoder + @encoders[name] || @encoders[:identity] end def self.register_encoder(mime_name, param_encoder: nil, response_parser: nil) @@ -48,7 +49,5 @@ module ActionDispatch end register_encoder :json, response_parser: -> body { JSON.parse(body) } - - WWWFormEncoder = new(:url_encoded_form, -> params { params }, nil, true) end end diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb index 8b03b776fa..0282eb15c3 100644 --- a/actionpack/lib/action_dispatch/testing/test_process.rb +++ b/actionpack/lib/action_dispatch/testing/test_process.rb @@ -3,6 +3,26 @@ require "action_dispatch/middleware/flash" module ActionDispatch module TestProcess + module FixtureFile + # Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.fixture_path, path), type)</tt>: + # + # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png') + # + # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter. + # This will not affect other platforms: + # + # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary) + def fixture_file_upload(path, mime_type = nil, binary = false) + if self.class.respond_to?(:fixture_path) && self.class.fixture_path && + !File.exist?(path) + path = File.join(self.class.fixture_path, path) + end + Rack::Test::UploadedFile.new(path, mime_type, binary) + end + end + + include FixtureFile + def assigns(key = nil) raise NoMethodError, "assigns has been extracted to a gem. To continue using it, @@ -24,21 +44,5 @@ module ActionDispatch def redirect_to_url @response.redirect_url end - - # Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.fixture_path, path), type)</tt>: - # - # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png') - # - # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter. - # This will not affect other platforms: - # - # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary) - def fixture_file_upload(path, mime_type = nil, binary = false) - if self.class.respond_to?(:fixture_path) && self.class.fixture_path && - !File.exist?(path) - path = File.join(self.class.fixture_path, path) - end - Rack::Test::UploadedFile.new(path, mime_type, binary) - end end end diff --git a/actionpack/test/abstract/collector_test.rb b/actionpack/test/abstract/collector_test.rb index 7fe19e6b10..1cd3526483 100644 --- a/actionpack/test/abstract/collector_test.rb +++ b/actionpack/test/abstract/collector_test.rb @@ -55,7 +55,7 @@ module AbstractController collector.js(:bar) { :baz } assert_equal [Mime[:html], [], nil], collector.responses[0] assert_equal [Mime[:text], [:foo], nil], collector.responses[1] - assert_equal [Mime[:js], [:bar]], collector.responses[2][0,2] + assert_equal [Mime[:js], [:bar]], collector.responses[2][0, 2] assert_equal :baz, collector.responses[2][2].call end end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 6d28753947..11a9092527 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -351,7 +351,7 @@ class ResourcesController < ActionController::Base end class CommentsController < ResourcesController; end -class AccountsController < ResourcesController; end +class AccountsController < ResourcesController; end class ImagesController < ResourcesController; end # Skips the current run on Rubinius using Minitest::Assertions#skip diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 18490c7d73..fa8d9dc09a 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -58,7 +58,7 @@ class FragmentCachingTest < ActionController::TestCase def test_fragment_cache_key assert_equal "views/what a key", @controller.fragment_cache_key("what a key") assert_equal "views/test.host/fragment_caching_test/some_action", - @controller.fragment_cache_key(controller: "fragment_caching_test",action: "some_action") + @controller.fragment_cache_key(controller: "fragment_caching_test", action: "some_action") end def test_read_fragment_with_caching_enabled diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index a34878cee8..e0fa1fbab8 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -506,20 +506,20 @@ class FilterTest < ActionController::TestCase private def filter_one - @filters ||= [] - @filters << "filter_one" + @filters ||= [] + @filters << "filter_one" end def action_two - @filters << "action_two" + @filters << "action_two" end def non_yielding_action - @filters << "it didn't yield" + @filters << "it didn't yield" end def action_three - @filters << "action_three" + @filters << "action_three" end end @@ -911,7 +911,7 @@ class ControllerWithFilterInstance < PostsController end class ControllerWithProcFilter < PostsController - around_action(only: :no_raise) do |c,b| + around_action(only: :no_raise) do |c, b| c.instance_variable_set(:"@before", true) b.call c.instance_variable_set(:"@after", true) @@ -961,34 +961,34 @@ class YieldingAroundFiltersTest < ActionController::TestCase def test_base controller = PostsController - assert_nothing_raised { test_process(controller,"no_raise") } - assert_nothing_raised { test_process(controller,"raises_before") } - assert_nothing_raised { test_process(controller,"raises_after") } - assert_nothing_raised { test_process(controller,"no_action") } + assert_nothing_raised { test_process(controller, "no_raise") } + assert_nothing_raised { test_process(controller, "raises_before") } + assert_nothing_raised { test_process(controller, "raises_after") } + assert_nothing_raised { test_process(controller, "no_action") } end def test_with_symbol controller = ControllerWithSymbolAsFilter - assert_nothing_raised { test_process(controller,"no_raise") } - assert_raise(Before) { test_process(controller,"raises_before") } - assert_raise(After) { test_process(controller,"raises_after") } - assert_nothing_raised { test_process(controller,"no_raise") } + assert_nothing_raised { test_process(controller, "no_raise") } + assert_raise(Before) { test_process(controller, "raises_before") } + assert_raise(After) { test_process(controller, "raises_after") } + assert_nothing_raised { test_process(controller, "no_raise") } end def test_with_class controller = ControllerWithFilterClass - assert_nothing_raised { test_process(controller,"no_raise") } - assert_raise(After) { test_process(controller,"raises_after") } + assert_nothing_raised { test_process(controller, "no_raise") } + assert_raise(After) { test_process(controller, "raises_after") } end def test_with_instance controller = ControllerWithFilterInstance - assert_nothing_raised { test_process(controller,"no_raise") } - assert_raise(After) { test_process(controller,"raises_after") } + assert_nothing_raised { test_process(controller, "no_raise") } + assert_raise(After) { test_process(controller, "raises_after") } end def test_with_proc - test_process(ControllerWithProcFilter,"no_raise") + test_process(ControllerWithProcFilter, "no_raise") assert @controller.instance_variable_get(:@before) assert @controller.instance_variable_get(:@after) end @@ -997,25 +997,25 @@ class YieldingAroundFiltersTest < ActionController::TestCase controller = ControllerWithNestedFilters assert_nothing_raised do begin - test_process(controller,"raises_both") + test_process(controller, "raises_both") rescue Before, After end end assert_raise Before do begin - test_process(controller,"raises_both") + test_process(controller, "raises_both") rescue After end end end def test_action_order_with_all_action_types - test_process(ControllerWithAllTypesOfFilters,"no_raise") + test_process(ControllerWithAllTypesOfFilters, "no_raise") assert_equal "before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)", @controller.instance_variable_get(:@ran_filter).join(" ") end def test_action_order_with_skip_action_method - test_process(ControllerWithTwoLessFilters,"no_raise") + test_process(ControllerWithTwoLessFilters, "no_raise") assert_equal "before around (before yield) around (after yield)", @controller.instance_variable_get(:@ran_filter).join(" ") end diff --git a/actionpack/test/controller/flash_hash_test.rb b/actionpack/test/controller/flash_hash_test.rb index 32f0db71f5..6b3abdd5be 100644 --- a/actionpack/test/controller/flash_hash_test.rb +++ b/actionpack/test/controller/flash_hash_test.rb @@ -102,8 +102,8 @@ module ActionDispatch @hash["foo"] = "bar" things = [] - @hash.each do |k,v| - things << [k,v] + @hash.each do |k, v| + things << [k, v] end assert_equal([%w{ hello world }, %w{ foo bar }].sort, things.sort) diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 343b7b643d..0b59e123d7 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -7,7 +7,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase before_action :authenticate_with_request, only: :display USERS = { "lifo" => "world", "pretty" => "please", - "dhh" => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":")) } + "dhh" => ::Digest::MD5::hexdigest(["dhh", "SuperSecret", "secret"].join(":")) } def index render plain: "Hello Secret" @@ -180,7 +180,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with password stored as ha1 digest hash" do @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "dhh", - password: ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":")), + password: ::Digest::MD5::hexdigest(["dhh", "SuperSecret", "secret"].join(":")), password_is_ha1: true) get :display diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 652c0f0dd2..d3aa81a0f7 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -145,7 +145,7 @@ class IntegrationTestTest < ActiveSupport::TestCase name.to_s == "foo" ? "pass" : super end end - @test.class.superclass.__send__(:include, mixin) + @test.class.superclass.include(mixin) begin assert_equal "pass", @test.foo ensure @@ -153,14 +153,6 @@ class IntegrationTestTest < ActiveSupport::TestCase mixin.__send__(:remove_method, :method_missing) end end - - def test_assigns_is_undefined_and_not_point_to_the_gem - e = assert_raises(NoMethodError) do - @test.assigns(:foo) - end - - assert_match(/undefined method/, e.message) - end end # Tests that integration tests don't call Controller test methods for processing. @@ -281,7 +273,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest self.cookies["cookie_2"] = "oatmeal" get "/cookie_monster" assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"] - assert_equal({ "cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate" }, cookies.to_hash) + assert_equal({ "cookie_1" => "", "cookie_2" => "oatmeal", "cookie_3" => "chocolate" }, cookies.to_hash) end end @@ -291,14 +283,14 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest assert_response :success assert_equal "foo=bar; path=/", headers["Set-Cookie"] - assert_equal({ "foo"=>"bar" }, cookies.to_hash) + assert_equal({ "foo" => "bar" }, cookies.to_hash) get "/get_cookie" assert_response :success assert_equal "bar", body assert_equal nil, headers["Set-Cookie"] - assert_equal({ "foo"=>"bar" }, cookies.to_hash) + assert_equal({ "foo" => "bar" }, cookies.to_hash) end end @@ -310,14 +302,14 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest assert_response :success assert_equal "foo=bar; path=/", headers["Set-Cookie"] - assert_equal({ "foo"=>"bar" }, cookies.to_hash) + assert_equal({ "foo" => "bar" }, cookies.to_hash) get "/get_cookie" assert_response :success assert_equal "bar", body assert_equal nil, headers["Set-Cookie"] - assert_equal({ "foo"=>"bar" }, cookies.to_hash) + assert_equal({ "foo" => "bar" }, cookies.to_hash) end end @@ -364,6 +356,14 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end end + test "creation of multiple integration sessions" do + integration_session # initialize first session + a = open_session + b = open_session + + refute_same(a.integration_session, b.integration_session) + end + def test_get_with_query_string with_test_route_set do get "/get_with_params?foo=bar" @@ -924,12 +924,16 @@ class IntegrationRequestsWithSessionSetup < ActionDispatch::IntegrationTest def test_cookies_set_in_setup_are_persisted_through_the_session get "/foo" - assert_equal({ "user_name"=>"david" }, cookies.to_hash) + assert_equal({ "user_name" => "david" }, cookies.to_hash) end end class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest class FooController < ActionController::Base + def foos + render plain: "ok" + end + def foos_json render json: params.permit(:foo) end @@ -958,13 +962,30 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest def test_encoding_as_json post_to_foos as: :json do assert_response :success - assert_match "foos_json.json", request.path assert_equal "application/json", request.content_type + assert_equal "application/json", request.accepts.first.to_s + assert_equal :json, request.format.ref assert_equal({ "foo" => "fighters" }, request.request_parameters) assert_equal({ "foo" => "fighters" }, response.parsed_body) end end + def test_doesnt_mangle_request_path + with_routing do |routes| + routes.draw do + ActiveSupport::Deprecation.silence do + post ":action" => FooController + end + end + + post "/foos" + assert_equal "/foos", request.path + + post "/foos_json", as: :json + assert_equal "/foos_json", request.path + end + end + def test_encoding_as_without_mime_registration assert_raise ArgumentError do ActionDispatch::IntegrationTest.register_encoder :wibble @@ -979,8 +1000,10 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest post_to_foos as: :wibble do assert_response :success - assert_match "foos_wibble.wibble", request.path + assert_equal "/foos_wibble", request.path assert_equal "text/wibble", request.content_type + assert_equal "text/wibble", request.accepts.first.to_s + assert_equal :wibble, request.format.ref assert_equal Hash.new, request.request_parameters # Unregistered MIME Type can't be parsed. assert_equal "ok", response.parsed_body end @@ -1078,8 +1101,8 @@ class IntegrationFileUploadTest < ActionDispatch::IntegrationTest def test_fixture_file_upload post "/test_file_upload", params: { - file: fixture_file_upload("/mona_lisa.jpg", "image/jpg") + file: fixture_file_upload("/ruby_on_rails.jpg", "image/jpg") } - assert_equal "159528", @response.body + assert_equal "45142", @response.body end end diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index 5cd8f82323..64b799f826 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -104,7 +104,7 @@ module RenderStreaming assert_equal nil, headers["Transfer-Encoding"] end - def assert_streaming!(cache="no-cache") + def assert_streaming!(cache = "no-cache") assert_status 200 assert_equal nil, headers["Content-Length"] assert_equal "chunked", headers["Transfer-Encoding"] diff --git a/actionpack/test/controller/parameters/mutators_test.rb b/actionpack/test/controller/parameters/mutators_test.rb index e060e5180f..e61bbdbe13 100644 --- a/actionpack/test/controller/parameters/mutators_test.rb +++ b/actionpack/test/controller/parameters/mutators_test.rb @@ -45,11 +45,11 @@ class ParametersMutatorsTest < ActiveSupport::TestCase test "keep_if retains permitted status" do @params.permit! - assert @params.keep_if { |k,v| k == "person" }.permitted? + assert @params.keep_if { |k, v| k == "person" }.permitted? end test "keep_if retains unpermitted status" do - assert_not @params.keep_if { |k,v| k == "person" }.permitted? + assert_not @params.keep_if { |k, v| k == "person" }.permitted? end test "reject! retains permitted status" do diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index 728d8e1279..92e134d313 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -28,7 +28,7 @@ class ParametersPermitTest < ActiveSupport::TestCase end def walk_permitted(params) - params.each do |k,v| + params.each do |k, v| case v when ActionController::Parameters walk_permitted v @@ -39,13 +39,13 @@ class ParametersPermitTest < ActiveSupport::TestCase end test "iteration should not impact permit" do - hash = { "foo"=>{ "bar"=>{ "0"=>{ "baz"=>"hello", "zot"=>"1" } } } } + hash = { "foo" => { "bar" => { "0" => { "baz" => "hello", "zot" => "1" } } } } params = ActionController::Parameters.new(hash) walk_permitted params sanitized = params[:foo].permit(bar: [:baz]) - assert_equal({ "0"=>{ "baz"=>"hello" } }, sanitized[:bar].to_unsafe_h) + assert_equal({ "0" => { "baz" => "hello" } }, sanitized[:bar].to_unsafe_h) end test "if nothing is permitted, the hash becomes empty" do @@ -168,6 +168,44 @@ class ParametersPermitTest < ActiveSupport::TestCase end end + test "key to empty hash: arbitrary hashes are permitted" do + params = ActionController::Parameters.new( + username: "fxn", + preferences: { + scheme: "Marazul", + font: { + name: "Source Code Pro", + size: 12 + }, + tabstops: [4, 8, 12, 16], + suspicious: [true, Object.new, false, /yo!/], + dubious: [{ a: :a, b: /wtf!/ }, { c: :c }], + injected: Object.new + }, + hacked: 1 # not a hash + ) + + permitted = params.permit(:username, preferences: {}, hacked: {}) + + assert permitted.permitted? + assert permitted[:preferences].permitted? + assert permitted[:preferences][:font].permitted? + assert permitted[:preferences][:dubious].all?(&:permitted?) + + assert_equal "fxn", permitted[:username] + assert_equal "Marazul", permitted[:preferences][:scheme] + assert_equal "Source Code Pro", permitted[:preferences][:font][:name] + assert_equal 12, permitted[:preferences][:font][:size] + assert_equal [4, 8, 12, 16], permitted[:preferences][:tabstops] + assert_equal [true, false], permitted[:preferences][:suspicious] + assert_equal :a, permitted[:preferences][:dubious][0][:a] + assert_equal :c, permitted[:preferences][:dubious][1][:c] + + assert_filtered_out permitted[:preferences][:dubious][0], :b + assert_filtered_out permitted[:preferences], :injected + assert_filtered_out permitted, :hacked + end + test "fetch raises ParameterMissing exception" do e = assert_raises(ActionController::ParameterMissing) do @params.fetch :foo @@ -244,6 +282,23 @@ class ParametersPermitTest < ActiveSupport::TestCase assert merged_params[:id] end + test "not permitted is sticky beyond merge!" do + assert_not @params.merge!(a: "b").permitted? + end + + test "permitted is sticky beyond merge!" do + @params.permit! + assert @params.merge!(a: "b").permitted? + end + + test "merge! with parameters" do + other_params = ActionController::Parameters.new(id: "1234").permit! + @params.merge!(other_params) + + assert_equal "1234", @params[:id] + assert_equal "32", @params[:person][:age] + end + test "modifying the parameters" do @params[:person][:hometown] = "Chicago" @params[:person][:family] = { brother: "Jonas" } @@ -322,8 +377,8 @@ class ParametersPermitTest < ActiveSupport::TestCase end test "to_unsafe_h returns unfiltered params even after accessing few keys" do - params = ActionController::Parameters.new("f"=>{ "language_facet"=>["Tibetan"] }) - expected = { "f"=>{ "language_facet"=>["Tibetan"] } } + params = ActionController::Parameters.new("f" => { "language_facet" => ["Tibetan"] }) + expected = { "f" => { "language_facet" => ["Tibetan"] } } assert params["f"].is_a? ActionController::Parameters assert_equal expected, params.to_unsafe_h diff --git a/actionpack/test/controller/parameters/serialization_test.rb b/actionpack/test/controller/parameters/serialization_test.rb index 4fb1564c68..6fba2fde91 100644 --- a/actionpack/test/controller/parameters/serialization_test.rb +++ b/actionpack/test/controller/parameters/serialization_test.rb @@ -14,12 +14,10 @@ class ParametersSerializationTest < ActiveSupport::TestCase test "yaml serialization" do params = ActionController::Parameters.new(key: :value) - assert_equal <<-end_of_yaml.strip_heredoc, YAML.dump(params) - --- !ruby/object:ActionController::Parameters - parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess - key: :value - permitted: false - end_of_yaml + yaml_dump = YAML.dump(params) + assert_match("--- !ruby/object:ActionController::Parameters", yaml_dump) + assert_match(/parameters: !ruby\/hash:ActiveSupport::HashWithIndifferentAccess\n\s+key: :value/, yaml_dump) + assert_match("permitted: false", yaml_dump) end test "yaml deserialization" do diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb index 1549405fe7..46a2ab8ccf 100644 --- a/actionpack/test/controller/params_wrapper_test.rb +++ b/actionpack/test/controller/params_wrapper_test.rb @@ -212,6 +212,16 @@ class ParamsWrapperTest < ActionController::TestCase ) end end + + def test_handles_empty_content_type + with_default_wrapper_options do + @request.env["CONTENT_TYPE"] = nil + _controller_class.dispatch(:parse, @request, @response) + + assert_equal 200, @response.status + assert_equal "", @response.body + end + end end class NamespacedParamsWrapperTest < ActionController::TestCase diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb index 213829bd9e..79552ec8f1 100644 --- a/actionpack/test/controller/render_json_test.rb +++ b/actionpack/test/controller/render_json_test.rb @@ -5,7 +5,7 @@ require "pathname" class RenderJsonTest < ActionController::TestCase class JsonRenderable - def as_json(options={}) + def as_json(options = {}) hash = { a: :b, c: :d, e: :f } hash.except!(*options[:except]) if options[:except] hash diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 76139d59e2..0c0f18f200 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -368,7 +368,7 @@ class ExpiresInRenderTest < ActionController::TestCase end def test_date_header_when_expires_in - time = Time.mktime(2011,10,30) + time = Time.mktime(2011, 10, 30) Time.stub :now, time do get :conditional_hello_with_expires_in assert_equal Time.now.httpdate, @response.headers["Date"] diff --git a/actionpack/test/controller/renderer_test.rb b/actionpack/test/controller/renderer_test.rb index d6f09f2d90..866600b935 100644 --- a/actionpack/test/controller/renderer_test.rb +++ b/actionpack/test/controller/renderer_test.rb @@ -60,6 +60,14 @@ class RendererTest < ActiveSupport::TestCase assert_equal "true", content end + test "rendering with custom env using a key that is not in RACK_KEY_TRANSLATION" do + value = "warden is here" + renderer = ApplicationController.renderer.new warden: value + content = renderer.render inline: "<%= request.env['warden'] %>" + + assert_equal value, content + end + test "rendering with defaults" do renderer = ApplicationController.renderer.new https: true content = renderer.render inline: "<%= request.ssl? %>" diff --git a/actionpack/test/controller/renderers_test.rb b/actionpack/test/controller/renderers_test.rb index 122f5be549..ccc700d79c 100644 --- a/actionpack/test/controller/renderers_test.rb +++ b/actionpack/test/controller/renderers_test.rb @@ -10,7 +10,7 @@ class RenderersTest < ActionController::TestCase end end class JsonRenderable - def as_json(options={}) + def as_json(options = {}) hash = { a: :b, c: :d, e: :f } hash.except!(*options[:except]) if options[:except] hash diff --git a/actionpack/test/controller/request/test_request_test.rb b/actionpack/test/controller/request/test_request_test.rb index fa049fbc9f..da6fa1388b 100644 --- a/actionpack/test/controller/request/test_request_test.rb +++ b/actionpack/test/controller/request/test_request_test.rb @@ -11,6 +11,16 @@ class ActionController::TestRequestTest < ActionController::TestCase assert_equal nil, ActionController::TestSession::DEFAULT_OPTIONS[:myparam] end + def test_content_length_has_bytes_count_value + non_ascii_parameters = { data: { content: "Latin + Кириллица" } } + @request.set_header "REQUEST_METHOD", "POST" + @request.set_header "CONTENT_TYPE", "application/json" + @request.assign_parameters(@routes, "test", "create", non_ascii_parameters, + "/test", [:data, :controller, :action]) + assert_equal(@request.get_header("CONTENT_LENGTH"), + StringIO.new(non_ascii_parameters.to_json).length.to_s) + end + ActionDispatch::Session::AbstractStore::DEFAULT_OPTIONS.each_key do |option| test "rack default session options #{option} exists in session options and is default" do assert_equal(ActionDispatch::Session::AbstractStore::DEFAULT_OPTIONS[option], diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index b572e7e8d5..0b3dc6c41f 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -27,7 +27,7 @@ class ResourcesTest < ActionController::TestCase def test_override_paths_for_member_and_collection_methods collection_methods = { rss: :get, reorder: :post, csv: :post } - member_methods = { rss: :get, atom: :get, upload: :post, fix: :post } + member_methods = { rss: :get, atom: :get, upload: :post, fix: :post } path_names = { new: "nuevo", rss: "canal", fix: "corrigir" } with_restful_routing :messages, @@ -792,7 +792,7 @@ class ResourcesTest < ActionController::TestCase end assert_simply_restful_for :product_reviews, controller: "messages", as: "reviews", name_prefix: "product_", path_prefix: "products/1/", options: { product_id: "1" } - assert_simply_restful_for :tutor_reviews,controller: "comments", as: "reviews", name_prefix: "tutor_", path_prefix: "tutors/1/", options: { tutor_id: "1" } + assert_simply_restful_for :tutor_reviews, controller: "comments", as: "reviews", name_prefix: "tutor_", path_prefix: "tutors/1/", options: { tutor_id: "1" } end end @@ -1306,7 +1306,7 @@ class ResourcesTest < ActionController::TestCase end def assert_named_route(expected, route, options) - actual = @controller.send(route, options) rescue $!.class.name + actual = @controller.send(route, options) rescue $!.class.name assert_equal expected, actual, "Error on route: #{route}(#{options.inspect})" end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 7be2ad2b28..56b39510bb 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -91,7 +91,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/faithfully-omg")) - assert_equal({ "artist"=>"journey", "song"=>"faithfully" }, hash) + assert_equal({ "artist" => "journey", "song" => "faithfully" }, hash) end def test_id_with_dash @@ -103,7 +103,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/faithfully-omg")) - assert_equal({ "id"=>"faithfully-omg" }, hash) + assert_equal({ "id" => "faithfully-omg" }, hash) end def test_dash_with_custom_regexp @@ -115,7 +115,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/123-omg")) - assert_equal({ "artist"=>"journey", "song"=>"123" }, hash) + assert_equal({ "artist" => "journey", "song" => "123" }, hash) assert_equal "Not Found", get(URI("http://example.org/journey/faithfully-omg")) end @@ -128,7 +128,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/omg-faithfully")) - assert_equal({ "artist"=>"journey", "song"=>"faithfully" }, hash) + assert_equal({ "artist" => "journey", "song" => "faithfully" }, hash) end def test_pre_dash_with_custom_regexp @@ -140,7 +140,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase end hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/omg-123")) - assert_equal({ "artist"=>"journey", "song"=>"123" }, hash) + assert_equal({ "artist" => "journey", "song" => "123" }, hash) assert_equal "Not Found", get(URI("http://example.org/journey/omg-faithfully")) end @@ -1931,7 +1931,7 @@ class RackMountIntegrationTests < ActiveSupport::TestCase get "clients" => "projects#index" get "ignorecase/geocode/:postalcode" => "geocode#show", :postalcode => /hx\d\d-\d[a-z]{2}/i - get "extended/geocode/:postalcode" => "geocode#show",:constraints => { + get "extended/geocode/:postalcode" => "geocode#show", :constraints => { postalcode: /# Postcode format \d{5} #Prefix (-\d{4})? #Suffix diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 8dc565ac8d..a28283f4d6 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -180,7 +180,7 @@ class SendFileTest < ActionController::TestCase "file.zip" => "application/zip", "file.unk" => "application/octet-stream", "zip" => "application/octet-stream" - }.each do |filename,expected_type| + }.each do |filename, expected_type| get __method__, params: { filename: filename } assert_equal expected_type, response.content_type end diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index 82f42e306f..05aa4ff6ad 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -231,7 +231,7 @@ XML def test_document_body_and_params_with_post post :test_params, params: { id: 1 } - assert_equal({ "id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body)) + assert_equal({ "id" => "1", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body)) end def test_document_body_with_post @@ -385,7 +385,7 @@ XML $stderr = STDERR end - assert err.empty? + assert err.empty?, err.inspect end def test_assert_generates @@ -651,7 +651,7 @@ XML def test_xhr_with_params get :test_params, params: { id: 1 }, xhr: true - assert_equal({ "id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body)) + assert_equal({ "id" => "1", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body)) end def test_xhr_with_session @@ -753,10 +753,10 @@ XML def test_multiple_mixed_method_process_should_scrub_rack_input post :test_params, params: { id: 1, foo: "an foo" } - assert_equal({ "id"=>"1", "foo" => "an foo", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body)) + assert_equal({ "id" => "1", "foo" => "an foo", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body)) get :test_params, params: { bar: "an bar" } - assert_equal({ "bar"=>"an bar", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body)) + assert_equal({ "bar" => "an bar", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body)) end %w(controller response request).each do |variable| @@ -781,7 +781,7 @@ XML READ_PLAIN = "r:binary" def test_test_uploaded_file - filename = "mona_lisa.jpg" + filename = "ruby_on_rails.jpg" path = "#{FILES_DIR}/#{filename}" content_type = "image/png" expected = File.read(path) @@ -801,13 +801,13 @@ XML def test_fixture_path_is_accessed_from_self_instead_of_active_support_test_case TestCaseTest.stub :fixture_path, FILES_DIR do - uploaded_file = fixture_file_upload("/mona_lisa.jpg", "image/png") - assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read + uploaded_file = fixture_file_upload("/ruby_on_rails.jpg", "image/png") + assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read end end def test_test_uploaded_file_with_binary - filename = "mona_lisa.jpg" + filename = "ruby_on_rails.jpg" path = "#{FILES_DIR}/#{filename}" content_type = "image/png" @@ -819,7 +819,7 @@ XML end def test_fixture_file_upload_with_binary - filename = "mona_lisa.jpg" + filename = "ruby_on_rails.jpg" path = "#{FILES_DIR}/#{filename}" content_type = "image/jpg" @@ -831,44 +831,44 @@ XML end def test_fixture_file_upload_should_be_able_access_to_tempfile - file = fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg") + file = fixture_file_upload(FILES_DIR + "/ruby_on_rails.jpg", "image/jpg") assert file.respond_to?(:tempfile), "expected tempfile should respond on fixture file object, got nothing" end def test_fixture_file_upload post :test_file_upload, params: { - file: fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg") + file: fixture_file_upload(FILES_DIR + "/ruby_on_rails.jpg", "image/jpg") } - assert_equal "159528", @response.body + assert_equal "45142", @response.body end def test_fixture_file_upload_relative_to_fixture_path TestCaseTest.stub :fixture_path, FILES_DIR do - uploaded_file = fixture_file_upload("mona_lisa.jpg", "image/jpg") - assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read + uploaded_file = fixture_file_upload("ruby_on_rails.jpg", "image/jpg") + assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read end end def test_fixture_file_upload_ignores_fixture_path_given_full_path TestCaseTest.stub :fixture_path, File.dirname(__FILE__) do - uploaded_file = fixture_file_upload("#{FILES_DIR}/mona_lisa.jpg", "image/jpg") - assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read + uploaded_file = fixture_file_upload("#{FILES_DIR}/ruby_on_rails.jpg", "image/jpg") + assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read end end def test_fixture_file_upload_ignores_nil_fixture_path - uploaded_file = fixture_file_upload("#{FILES_DIR}/mona_lisa.jpg", "image/jpg") - assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read + uploaded_file = fixture_file_upload("#{FILES_DIR}/ruby_on_rails.jpg", "image/jpg") + assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read end def test_action_dispatch_uploaded_file_upload - filename = "mona_lisa.jpg" + filename = "ruby_on_rails.jpg" path = "#{FILES_DIR}/#{filename}" post :test_file_upload, params: { file: Rack::Test::UploadedFile.new(path, "image/jpg", true) } - assert_equal "159528", @response.body + assert_equal "45142", @response.body end def test_test_uploaded_file_exception_when_file_doesnt_exist diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb index c7ea6c5ef6..f640e77b99 100644 --- a/actionpack/test/controller/url_for_integration_test.rb +++ b/actionpack/test/controller/url_for_integration_test.rb @@ -43,7 +43,7 @@ module ActionPack get "clients" => "projects#index" get "ignorecase/geocode/:postalcode" => "geocode#show", :postalcode => /hx\d\d-\d[a-z]{2}/i - get "extended/geocode/:postalcode" => "geocode#show",:constraints => { + get "extended/geocode/:postalcode" => "geocode#show", :constraints => { postalcode: /# Postcode format \d{5} #Prefix (-\d{4})? #Suffix @@ -73,99 +73,99 @@ module ActionPack end [ - ["/admin/users",[ { use_route: "admin_users" }]], - ["/admin/users",[ { controller: "admin/users" }]], - ["/admin/users",[ { controller: "admin/users", action: "index" }]], - ["/admin/users",[ { action: "index" }, { controller: "admin/users", action: "index" }, "/admin/users"]], - ["/admin/users",[ { controller: "users", action: "index" }, { controller: "admin/accounts", action: "show", id: "1" }, "/admin/accounts/show/1"]], - ["/people",[ { controller: "/people", action: "index" }, { controller: "admin/accounts", action: "foo", id: "bar" }, "/admin/accounts/foo/bar"]], - - ["/admin/posts",[ { controller: "admin/posts" }]], - ["/admin/posts/new",[ { controller: "admin/posts", action: "new" }]], - - ["/blog/2009",[ { controller: "posts", action: "show_date", year: 2009 }]], - ["/blog/2009/1",[ { controller: "posts", action: "show_date", year: 2009, month: 1 }]], - ["/blog/2009/1/1",[ { controller: "posts", action: "show_date", year: 2009, month: 1, day: 1 }]], - - ["/archive/2010",[ { controller: "archive", action: "index", year: "2010" }]], - ["/archive",[ { controller: "archive", action: "index" }]], - ["/archive?year=january",[ { controller: "archive", action: "index", year: "january" }]], - - ["/people",[ { controller: "people", action: "index" }]], - ["/people",[ { action: "index" }, { controller: "people", action: "index" }, "/people"]], - ["/people",[ { action: "index" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], - ["/people",[ { controller: "people", action: "index" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], - ["/people",[ {}, { controller: "people", action: "index" }, "/people"]], - ["/people/1",[ { controller: "people", action: "show" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], - ["/people/new",[ { use_route: "new_person" }]], - ["/people/new",[ { controller: "people", action: "new" }]], - ["/people/1",[ { use_route: "person", id: "1" }]], - ["/people/1",[ { controller: "people", action: "show", id: "1" }]], - ["/people/1.xml",[ { controller: "people", action: "show", id: "1", format: "xml" }]], - ["/people/1",[ { controller: "people", action: "show", id: 1 }]], - ["/people/1",[ { controller: "people", action: "show", id: Model.new("1") }]], - ["/people/1",[ { action: "show", id: "1" }, { controller: "people", action: "index" }, "/people"]], - ["/people/1",[ { action: "show", id: 1 }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], - ["/people",[ { controller: "people", action: "index" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], - ["/people/1",[ {}, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], - ["/people/1",[ { controller: "people", action: "show" }, { controller: "people", action: "index", id: "1" }, "/people/index/1"]], - ["/people/1/edit",[ { controller: "people", action: "edit", id: "1" }]], - ["/people/1/edit.xml",[ { controller: "people", action: "edit", id: "1", format: "xml" }]], - ["/people/1/edit",[ { use_route: "edit_person", id: "1" }]], - ["/people/1?legacy=true",[ { controller: "people", action: "show", id: "1", legacy: "true" }]], - ["/people?legacy=true",[ { controller: "people", action: "index", legacy: "true" }]], - - ["/id_default/2",[ { controller: "foo", action: "id_default", id: "2" }]], - ["/id_default",[ { controller: "foo", action: "id_default", id: "1" }]], - ["/id_default",[ { controller: "foo", action: "id_default", id: 1 }]], - ["/id_default",[ { controller: "foo", action: "id_default" }]], - ["/optional/bar",[ { controller: "posts", action: "index", optional: "bar" }]], - ["/posts",[ { controller: "posts", action: "index" }]], - - ["/project",[ { controller: "project", action: "index" }]], - ["/projects/1",[ { controller: "project", action: "index", project_id: "1" }]], - ["/projects/1",[ { controller: "project", action: "index" }, { project_id: "1", controller: "project", action: "index" }, "/projects/1"]], - ["/projects/1",[ { use_route: "project", controller: "project", action: "index", project_id: "1" }]], - ["/projects/1",[ { use_route: "project", controller: "project", action: "index" }, { controller: "project", action: "index", project_id: "1" }, "/projects/1"]], - - ["/clients",[ { controller: "projects", action: "index" }]], - ["/clients?project_id=1",[ { controller: "projects", action: "index", project_id: "1" }]], - ["/clients",[ { controller: "projects", action: "index" }, { project_id: "1", controller: "project", action: "index" }, "/projects/1"]], - - ["/comment/20",[ { id: 20 }, { controller: "comments", action: "show" }, "/comments/show"]], - ["/comment/20",[ { controller: "comments", id: 20, action: "show" }]], - ["/comments/boo",[ { controller: "comments", action: "boo" }]], - - ["/ws/posts/show/1",[ { controller: "posts", action: "show", id: "1", ws: true }]], - ["/ws/posts",[ { controller: "posts", action: "index", ws: true }]], - - ["/account",[ { controller: "account", action: "subscription" }]], - ["/account/billing",[ { controller: "account", action: "billing" }]], - - ["/pages/1/notes/show/1",[ { page_id: "1", controller: "notes", action: "show", id: "1" }]], - ["/pages/1/notes/list",[ { page_id: "1", controller: "notes", action: "list" }]], - ["/pages/1/notes",[ { page_id: "1", controller: "notes", action: "index" }]], - ["/pages/1/notes",[ { page_id: "1", controller: "notes" }]], - ["/notes",[ { page_id: nil, controller: "notes" }]], - ["/notes",[ { controller: "notes" }]], - ["/notes/print",[ { controller: "notes", action: "print" }]], - ["/notes/print",[ {}, { controller: "notes", action: "print" }, "/notes/print"]], - - ["/notes/index/1",[ { controller: "notes" }, { controller: "notes", action: "index", id: "1" }, "/notes/index/1"]], - ["/notes/index/1",[ { controller: "notes" }, { controller: "notes", id: "1", action: "index" }, "/notes/index/1"]], - ["/notes/index/1",[ { action: "index" }, { controller: "notes", id: "1", action: "index" }, "/notes/index/1"]], - ["/notes/index/1",[ {}, { controller: "notes", id: "1", action: "index" }, "/notes/index/1"]], - ["/notes/show/1",[ {}, { controller: "notes", action: "show", id: "1" }, "/notes/show/1"]], - ["/posts",[ { controller: "posts" }, { controller: "notes", action: "show", id: "1" }, "/notes/show/1"]], - ["/notes/list",[ { action: "list" }, { controller: "notes", action: "show", id: "1" }, "/notes/show/1"]], - - ["/posts/ping",[ { controller: "posts", action: "ping" }]], - ["/posts/show/1",[ { controller: "posts", action: "show", id: "1" }]], - ["/posts/show/1",[ { controller: "posts", action: "show", id: "1", format: "" }]], - ["/posts",[ { controller: "posts" }]], - ["/posts",[ { controller: "posts", action: "index" }]], - ["/posts/create",[ { action: "create" }, { day: nil, month: nil, controller: "posts", action: "show_date" }, "/blog"]], - ["/posts?foo=bar",[ { controller: "posts", foo: "bar" }]], + ["/admin/users", [ { use_route: "admin_users" }]], + ["/admin/users", [ { controller: "admin/users" }]], + ["/admin/users", [ { controller: "admin/users", action: "index" }]], + ["/admin/users", [ { action: "index" }, { controller: "admin/users", action: "index" }, "/admin/users"]], + ["/admin/users", [ { controller: "users", action: "index" }, { controller: "admin/accounts", action: "show", id: "1" }, "/admin/accounts/show/1"]], + ["/people", [ { controller: "/people", action: "index" }, { controller: "admin/accounts", action: "foo", id: "bar" }, "/admin/accounts/foo/bar"]], + + ["/admin/posts", [ { controller: "admin/posts" }]], + ["/admin/posts/new", [ { controller: "admin/posts", action: "new" }]], + + ["/blog/2009", [ { controller: "posts", action: "show_date", year: 2009 }]], + ["/blog/2009/1", [ { controller: "posts", action: "show_date", year: 2009, month: 1 }]], + ["/blog/2009/1/1", [ { controller: "posts", action: "show_date", year: 2009, month: 1, day: 1 }]], + + ["/archive/2010", [ { controller: "archive", action: "index", year: "2010" }]], + ["/archive", [ { controller: "archive", action: "index" }]], + ["/archive?year=january", [ { controller: "archive", action: "index", year: "january" }]], + + ["/people", [ { controller: "people", action: "index" }]], + ["/people", [ { action: "index" }, { controller: "people", action: "index" }, "/people"]], + ["/people", [ { action: "index" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], + ["/people", [ { controller: "people", action: "index" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], + ["/people", [ {}, { controller: "people", action: "index" }, "/people"]], + ["/people/1", [ { controller: "people", action: "show" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], + ["/people/new", [ { use_route: "new_person" }]], + ["/people/new", [ { controller: "people", action: "new" }]], + ["/people/1", [ { use_route: "person", id: "1" }]], + ["/people/1", [ { controller: "people", action: "show", id: "1" }]], + ["/people/1.xml", [ { controller: "people", action: "show", id: "1", format: "xml" }]], + ["/people/1", [ { controller: "people", action: "show", id: 1 }]], + ["/people/1", [ { controller: "people", action: "show", id: Model.new("1") }]], + ["/people/1", [ { action: "show", id: "1" }, { controller: "people", action: "index" }, "/people"]], + ["/people/1", [ { action: "show", id: 1 }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], + ["/people", [ { controller: "people", action: "index" }, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], + ["/people/1", [ {}, { controller: "people", action: "show", id: "1" }, "/people/show/1"]], + ["/people/1", [ { controller: "people", action: "show" }, { controller: "people", action: "index", id: "1" }, "/people/index/1"]], + ["/people/1/edit", [ { controller: "people", action: "edit", id: "1" }]], + ["/people/1/edit.xml", [ { controller: "people", action: "edit", id: "1", format: "xml" }]], + ["/people/1/edit", [ { use_route: "edit_person", id: "1" }]], + ["/people/1?legacy=true", [ { controller: "people", action: "show", id: "1", legacy: "true" }]], + ["/people?legacy=true", [ { controller: "people", action: "index", legacy: "true" }]], + + ["/id_default/2", [ { controller: "foo", action: "id_default", id: "2" }]], + ["/id_default", [ { controller: "foo", action: "id_default", id: "1" }]], + ["/id_default", [ { controller: "foo", action: "id_default", id: 1 }]], + ["/id_default", [ { controller: "foo", action: "id_default" }]], + ["/optional/bar", [ { controller: "posts", action: "index", optional: "bar" }]], + ["/posts", [ { controller: "posts", action: "index" }]], + + ["/project", [ { controller: "project", action: "index" }]], + ["/projects/1", [ { controller: "project", action: "index", project_id: "1" }]], + ["/projects/1", [ { controller: "project", action: "index" }, { project_id: "1", controller: "project", action: "index" }, "/projects/1"]], + ["/projects/1", [ { use_route: "project", controller: "project", action: "index", project_id: "1" }]], + ["/projects/1", [ { use_route: "project", controller: "project", action: "index" }, { controller: "project", action: "index", project_id: "1" }, "/projects/1"]], + + ["/clients", [ { controller: "projects", action: "index" }]], + ["/clients?project_id=1", [ { controller: "projects", action: "index", project_id: "1" }]], + ["/clients", [ { controller: "projects", action: "index" }, { project_id: "1", controller: "project", action: "index" }, "/projects/1"]], + + ["/comment/20", [ { id: 20 }, { controller: "comments", action: "show" }, "/comments/show"]], + ["/comment/20", [ { controller: "comments", id: 20, action: "show" }]], + ["/comments/boo", [ { controller: "comments", action: "boo" }]], + + ["/ws/posts/show/1", [ { controller: "posts", action: "show", id: "1", ws: true }]], + ["/ws/posts", [ { controller: "posts", action: "index", ws: true }]], + + ["/account", [ { controller: "account", action: "subscription" }]], + ["/account/billing", [ { controller: "account", action: "billing" }]], + + ["/pages/1/notes/show/1", [ { page_id: "1", controller: "notes", action: "show", id: "1" }]], + ["/pages/1/notes/list", [ { page_id: "1", controller: "notes", action: "list" }]], + ["/pages/1/notes", [ { page_id: "1", controller: "notes", action: "index" }]], + ["/pages/1/notes", [ { page_id: "1", controller: "notes" }]], + ["/notes", [ { page_id: nil, controller: "notes" }]], + ["/notes", [ { controller: "notes" }]], + ["/notes/print", [ { controller: "notes", action: "print" }]], + ["/notes/print", [ {}, { controller: "notes", action: "print" }, "/notes/print"]], + + ["/notes/index/1", [ { controller: "notes" }, { controller: "notes", action: "index", id: "1" }, "/notes/index/1"]], + ["/notes/index/1", [ { controller: "notes" }, { controller: "notes", id: "1", action: "index" }, "/notes/index/1"]], + ["/notes/index/1", [ { action: "index" }, { controller: "notes", id: "1", action: "index" }, "/notes/index/1"]], + ["/notes/index/1", [ {}, { controller: "notes", id: "1", action: "index" }, "/notes/index/1"]], + ["/notes/show/1", [ {}, { controller: "notes", action: "show", id: "1" }, "/notes/show/1"]], + ["/posts", [ { controller: "posts" }, { controller: "notes", action: "show", id: "1" }, "/notes/show/1"]], + ["/notes/list", [ { action: "list" }, { controller: "notes", action: "show", id: "1" }, "/notes/show/1"]], + + ["/posts/ping", [ { controller: "posts", action: "ping" }]], + ["/posts/show/1", [ { controller: "posts", action: "show", id: "1" }]], + ["/posts/show/1", [ { controller: "posts", action: "show", id: "1", format: "" }]], + ["/posts", [ { controller: "posts" }]], + ["/posts", [ { controller: "posts", action: "index" }]], + ["/posts/create", [ { action: "create" }, { day: nil, month: nil, controller: "posts", action: "show_date" }, "/blog"]], + ["/posts?foo=bar", [ { controller: "posts", foo: "bar" }]], ["/posts?foo%5B%5D=bar&foo%5B%5D=baz", [{ controller: "posts", foo: ["bar", "baz"] }]], ["/posts?page=2", [{ controller: "posts", page: 2 }]], ["/posts?q%5Bfoo%5D%5Ba%5D=b", [{ controller: "posts", q: { foo: { a: "b" } } }]], diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index 8d7190365d..4b6f33c545 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -223,13 +223,13 @@ module AbstractController def test_trailing_slash add_host! options = { controller: "foo", trailing_slash: true, action: "bar", id: "33" } - assert_equal("http://www.basecamphq.com/foo/bar/33/", W.new.url_for(options) ) + assert_equal("http://www.basecamphq.com/foo/bar/33/", W.new.url_for(options)) end def test_trailing_slash_with_protocol add_host! - options = { trailing_slash: true,protocol: "https", controller: "foo", action: "bar", id: "33" } - assert_equal("https://www.basecamphq.com/foo/bar/33/", W.new.url_for(options) ) + options = { trailing_slash: true, protocol: "https", controller: "foo", action: "bar", id: "33" } + assert_equal("https://www.basecamphq.com/foo/bar/33/", W.new.url_for(options)) assert_equal "https://www.basecamphq.com/foo/bar/33/?query=string", W.new.url_for(options.merge(query: "string")) end @@ -238,7 +238,7 @@ module AbstractController assert_equal "/foo/", W.new.url_for(options.merge(only_path: true)) options.update(action: "bar", id: "33") assert_equal "/foo/bar/33/", W.new.url_for(options.merge(only_path: true)) - assert_equal "/foo/bar/33/?query=string", W.new.url_for(options.merge(query: "string",only_path: true)) + assert_equal "/foo/bar/33/?query=string", W.new.url_for(options.merge(query: "string", only_path: true)) end def test_trailing_slash_with_anchor @@ -423,7 +423,7 @@ module AbstractController first_class.default_url_options[:host] = first_host second_class.default_url_options[:host] = second_host - assert_equal first_host, first_class.default_url_options[:host] + assert_equal first_host, first_class.default_url_options[:host] assert_equal second_host, second_class.default_url_options[:host] end diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 6dcd62572a..af3036d448 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -43,7 +43,7 @@ class CookieJarTest < ActiveSupport::TestCase def test_each request.cookie_jar["foo"] = :bar list = [] - request.cookie_jar.each do |k,v| + request.cookie_jar.each do |k, v| list << [k, v] end @@ -52,7 +52,7 @@ class CookieJarTest < ActiveSupport::TestCase def test_enumerable request.cookie_jar["foo"] = :bar - actual = request.cookie_jar.map { |k,v| [k.to_s, v.to_s] } + actual = request.cookie_jar.map { |k, v| [k.to_s, v.to_s] } assert_equal [["foo", "bar"]], actual end @@ -95,17 +95,17 @@ class CookiesTest < ActionController::TestCase end def authenticate_for_fourteen_days - cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) } + cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10, 5) } head :ok end def authenticate_for_fourteen_days_with_symbols - cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10,5) } + cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10, 5) } head :ok end def set_multiple_cookies - cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) } + cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10, 5) } cookies["login"] = "XJ-122" head :ok end @@ -205,7 +205,7 @@ class CookiesTest < ActionController::TestCase def delete_and_set_cookie cookies.delete :user_name - cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10,5) } + cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10, 5) } head :ok end diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb index 2c5e09e283..ea477e8908 100644 --- a/actionpack/test/dispatch/debug_exceptions_test.rb +++ b/actionpack/test/dispatch/debug_exceptions_test.rb @@ -287,7 +287,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest test "does not show filtered parameters" do @app = DevelopmentApp - get "/", params: { "foo"=>"bar" }, headers: { "action_dispatch.show_exceptions" => true, + get "/", params: { "foo" => "bar" }, headers: { "action_dispatch.show_exceptions" => true, "action_dispatch.parameter_filter" => [:foo] } assert_response 500 assert_match(""foo"=>"[FILTERED]"", body) @@ -384,6 +384,23 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest end end + test "logs with non active support loggers" do + @app = DevelopmentApp + io = StringIO.new + logger = Logger.new(io) + + _old, ActionView::Base.logger = ActionView::Base.logger, logger + begin + assert_nothing_raised do + get "/", headers: { "action_dispatch.show_exceptions" => true, "action_dispatch.logger" => logger } + end + ensure + ActionView::Base.logger = _old + end + + assert_match(/puke/, io.rewind && io.read) + end + test "uses backtrace cleaner from env" do @app = DevelopmentApp backtrace_cleaner = ActiveSupport::BacktraceCleaner.new diff --git a/actionpack/test/dispatch/header_test.rb b/actionpack/test/dispatch/header_test.rb index 6febd5cb68..958450072e 100644 --- a/actionpack/test/dispatch/header_test.rb +++ b/actionpack/test/dispatch/header_test.rb @@ -155,8 +155,8 @@ class HeaderTest < ActiveSupport::TestCase headers = make_headers(env) headers["Referer"] = "http://example.com/" headers.merge! "CONTENT_TYPE" => "text/plain" - assert_equal({ "HTTP_REFERER"=>"http://example.com/", - "CONTENT_TYPE"=>"text/plain" }, env) + assert_equal({ "HTTP_REFERER" => "http://example.com/", + "CONTENT_TYPE" => "text/plain" }, env) end test "fetch exception" do diff --git a/actionpack/test/dispatch/mime_type_test.rb b/actionpack/test/dispatch/mime_type_test.rb index e558efb88d..2ca03c535a 100644 --- a/actionpack/test/dispatch/mime_type_test.rb +++ b/actionpack/test/dispatch/mime_type_test.rb @@ -89,7 +89,7 @@ class MimeTypeTest < ActiveSupport::TestCase # (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.1) test "parse other broken acceptlines" do accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, , pronto/1.00.00, sslvpn/1.00.00.00, */*" - expect = ["image/gif", "image/x-xbitmap", "image/jpeg","image/pjpeg", "application/x-shockwave-flash", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/msword", "pronto/1.00.00", "sslvpn/1.00.00.00", "*/*"] + expect = ["image/gif", "image/x-xbitmap", "image/jpeg", "image/pjpeg", "application/x-shockwave-flash", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/msword", "pronto/1.00.00", "sslvpn/1.00.00.00", "*/*"] assert_equal expect.map(&:to_s), Mime::Type.parse(accept).map(&:to_s) end diff --git a/actionpack/test/dispatch/reloader_test.rb b/actionpack/test/dispatch/reloader_test.rb index e74b8e40fd..db68549b84 100644 --- a/actionpack/test/dispatch/reloader_test.rb +++ b/actionpack/test/dispatch/reloader_test.rb @@ -178,7 +178,7 @@ class ReloaderTest < ActiveSupport::TestCase def test_cleanup_callbacks_are_called_on_exceptions cleaned = false assert_deprecated do - Reloader.to_cleanup { cleaned = true } + Reloader.to_cleanup { cleaned = true } end begin diff --git a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb index e572c722a0..eb4bb14ed1 100644 --- a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb @@ -142,7 +142,7 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest test "uploads and reads binary file" do with_test_routing do - fixture = FIXTURE_PATH + "/mona_lisa.jpg" + fixture = FIXTURE_PATH + "/ruby_on_rails.jpg" params = { uploaded_data: fixture_file_upload(fixture, "image/jpg") } post "/read", params: params end diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb index 5c992be216..2499c33cef 100644 --- a/actionpack/test/dispatch/request/query_string_parsing_test.rb +++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb @@ -97,7 +97,7 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest assert_parses({ "action" => { "foo" => { "bar" => nil } } }, "action[foo][bar]") assert_parses({ "action" => { "foo" => { "bar" => [] } } }, "action[foo][bar][]") assert_parses({ "action" => { "foo" => [] } }, "action[foo][]") - assert_parses({ "action"=>{ "foo"=>[{ "bar"=>nil }] } }, "action[foo][][bar]") + assert_parses({ "action" => { "foo" => [{ "bar" => nil }] } }, "action[foo][][bar]") end def test_array_parses_without_nil @@ -114,7 +114,7 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest assert_parses({ "action" => { "foo" => { "bar" => [nil] } } }, "action[foo][bar][]") assert_parses({ "action" => { "foo" => [nil] } }, "action[foo][]") assert_parses({ "action" => { "foo" => [{ "bar" => nil }] } }, "action[foo][][bar]") - assert_parses({ "action" => ["1",nil] }, "action[]=1&action[]") + assert_parses({ "action" => ["1", nil] }, "action[]=1&action[]") ensure ActionDispatch::Request::Utils.perform_deep_munge = old_perform_deep_munge end diff --git a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb index 5c7558e48d..1169bf0cdb 100644 --- a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb @@ -55,7 +55,7 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest "products[second]=Pc", "=Save" ].join("&") - expected = { + expected = { "customers" => { "boston" => { "first" => { diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 13a87b8976..2f41851598 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -581,7 +581,7 @@ class RequestCookie < BaseRequestTest # some Nokia phone browsers omit the space after the semicolon separator. # some developers have grown accustomed to using comma in cookie values. - request = stub_request("HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes") + request = stub_request("HTTP_COOKIE" => "_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes") assert_equal "c84ace847", request.cookies["_session_id"], request.cookies.inspect assert_equal "yes", request.cookies["is_admin"], request.cookies.inspect end @@ -596,7 +596,7 @@ class RequestParamsParsing < BaseRequestTest "rack.input" => StringIO.new("flamenco=love") ) - assert_equal({ "flamenco"=> "love" }, request.request_parameters) + assert_equal({ "flamenco" => "love" }, request.request_parameters) end test "doesnt interpret request uri as query string when missing" do @@ -774,8 +774,8 @@ class RequestMethod < BaseRequestTest ensure # Reset original acronym set ActiveSupport::Inflector.inflections do |inflect| - inflect.send(:instance_variable_set,"@acronyms",existing_acrnoyms) - inflect.send(:instance_variable_set,"@acronym_regex",existing_acrnoym_regex) + inflect.send(:instance_variable_set, "@acronyms", existing_acrnoyms) + inflect.send(:instance_variable_set, "@acronym_regex", existing_acrnoym_regex) end end end @@ -1072,14 +1072,14 @@ end class RequestParameterFilter < BaseRequestTest test "process parameter filter" do test_hashes = [ - [{ "foo"=>"bar" },{ "foo"=>"bar" },%w'food'], - [{ "foo"=>"bar" },{ "foo"=>"[FILTERED]" },%w'foo'], - [{ "foo"=>"bar", "bar"=>"foo" },{ "foo"=>"[FILTERED]", "bar"=>"foo" },%w'foo baz'], - [{ "foo"=>"bar", "baz"=>"foo" },{ "foo"=>"[FILTERED]", "baz"=>"[FILTERED]" },%w'foo baz'], - [{ "bar"=>{ "foo"=>"bar","bar"=>"foo" } },{ "bar"=>{ "foo"=>"[FILTERED]","bar"=>"foo" } },%w'fo'], - [{ "foo"=>{ "foo"=>"bar","bar"=>"foo" } },{ "foo"=>"[FILTERED]" },%w'f banana'], - [{ "deep"=>{ "cc"=>{ "code"=>"bar","bar"=>"foo" },"ss"=>{ "code"=>"bar" } } },{ "deep"=>{ "cc"=>{ "code"=>"[FILTERED]","bar"=>"foo" },"ss"=>{ "code"=>"bar" } } },%w'deep.cc.code'], - [{ "baz"=>[{ "foo"=>"baz" }, "1"] }, { "baz"=>[{ "foo"=>"[FILTERED]" }, "1"] }, [/foo/]]] + [{ "foo" => "bar" }, { "foo" => "bar" }, %w'food'], + [{ "foo" => "bar" }, { "foo" => "[FILTERED]" }, %w'foo'], + [{ "foo" => "bar", "bar" => "foo" }, { "foo" => "[FILTERED]", "bar" => "foo" }, %w'foo baz'], + [{ "foo" => "bar", "baz" => "foo" }, { "foo" => "[FILTERED]", "baz" => "[FILTERED]" }, %w'foo baz'], + [{ "bar" => { "foo" => "bar", "bar" => "foo" } }, { "bar" => { "foo" => "[FILTERED]", "bar" => "foo" } }, %w'fo'], + [{ "foo" => { "foo" => "bar", "bar" => "foo" } }, { "foo" => "[FILTERED]" }, %w'f banana'], + [{ "deep" => { "cc" => { "code" => "bar", "bar" => "foo" }, "ss" => { "code" => "bar" } } }, { "deep" => { "cc" => { "code" => "[FILTERED]", "bar" => "foo" }, "ss" => { "code" => "bar" } } }, %w'deep.cc.code'], + [{ "baz" => [{ "foo" => "baz" }, "1"] }, { "baz" => [{ "foo" => "[FILTERED]" }, "1"] }, [/foo/]]] test_hashes.each do |before_filter, after_filter, filter_words| parameter_filter = ActionDispatch::Http::ParameterFilter.new(filter_words) @@ -1091,8 +1091,8 @@ class RequestParameterFilter < BaseRequestTest } parameter_filter = ActionDispatch::Http::ParameterFilter.new(filter_words) - before_filter["barg"] = { :bargain=>"gain", "blah"=>"bar", "bar"=>{ "bargain"=>{ "blah"=>"foo" } } } - after_filter["barg"] = { :bargain=>"niag", "blah"=>"[FILTERED]", "bar"=>{ "bargain"=>{ "blah"=>"[FILTERED]" } } } + before_filter["barg"] = { :bargain => "gain", "blah" => "bar", "bar" => { "bargain" => { "blah" => "foo" } } } + after_filter["barg"] = { :bargain => "niag", "blah" => "[FILTERED]", "bar" => { "bargain" => { "blah" => "[FILTERED]" } } } assert_equal after_filter, parameter_filter.filter(before_filter) end diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 4e547ab7d5..400af42bac 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -131,7 +131,7 @@ class ResponseTest < ActiveSupport::TestCase def test_only_set_charset_still_defaults_to_text_html response = ActionDispatch::Response.new response.charset = "utf-16" - _,headers,_ = response.to_a + _, headers, _ = response.to_a assert_equal "text/html; charset=utf-16", headers["Content-Type"] end @@ -229,7 +229,7 @@ class ResponseTest < ActiveSupport::TestCase test "multiple cookies" do @response.set_cookie("user_name", value: "david", path: "/") - @response.set_cookie("login", value: "foo&bar", path: "/", expires: Time.utc(2005, 10, 10,5)) + @response.set_cookie("login", value: "foo&bar", path: "/", expires: Time.utc(2005, 10, 10, 5)) _status, headers, _body = @response.to_a assert_equal "user_name=david; path=/\nlogin=foo%26bar; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000", headers["Set-Cookie"] assert_equal({ "login" => "foo&bar", "user_name" => "david" }, @response.cookies) @@ -237,7 +237,7 @@ class ResponseTest < ActiveSupport::TestCase test "delete cookies" do @response.set_cookie("user_name", value: "david", path: "/") - @response.set_cookie("login", value: "foo&bar", path: "/", expires: Time.utc(2005, 10, 10,5)) + @response.set_cookie("login", value: "foo&bar", path: "/", expires: Time.utc(2005, 10, 10, 5)) @response.delete_cookie("login") assert_equal({ "user_name" => "david", "login" => nil }, @response.cookies) end diff --git a/actionpack/test/dispatch/routing/ipv6_redirect_test.rb b/actionpack/test/dispatch/routing/ipv6_redirect_test.rb index 4987ed84e4..179aee9ba7 100644 --- a/actionpack/test/dispatch/routing/ipv6_redirect_test.rb +++ b/actionpack/test/dispatch/routing/ipv6_redirect_test.rb @@ -7,7 +7,7 @@ class IPv6IntegrationTest < ActionDispatch::IntegrationTest class ::BadRouteRequestController < ActionController::Base include Routes.url_helpers def index - render text: foo_path + render plain: foo_path end def foo diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index c01065932a..92d323f292 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -1933,7 +1933,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest post :preview, on: :new end - resource :admin, path_names: { new: "novo" }, path: "administrador" do + resource :admin, path_names: { new: "novo" }, path: "administrador" do post :preview, on: :new end @@ -3736,7 +3736,7 @@ private https!(old_https) end - def verify_redirect(url, status=301) + def verify_redirect(url, status = 301) assert_equal status, @response.status assert_equal url, @response.headers["Location"] assert_equal expected_redirect_body(url), @response.body @@ -4163,7 +4163,7 @@ class TestRedirectInterpolation < ActionDispatch::IntegrationTest end private - def verify_redirect(url, status=301) + def verify_redirect(url, status = 301) assert_equal status, @response.status assert_equal url, @response.headers["Location"] assert_equal expected_redirect_body(url), @response.body @@ -4696,15 +4696,15 @@ class TestUrlGenerationErrors < ActionDispatch::IntegrationTest end test "url helpers raise message with mixed parameters when generation fails" do - url, missing = { action: "show", controller: "products", id: nil, "id"=>"url-tested" }, [:id] + url, missing = { action: "show", controller: "products", id: nil, "id" => "url-tested" }, [:id] message = "No route matches #{url.inspect}, possible unmatched constraints: #{missing.inspect}" # Optimized url helper - error = assert_raises(ActionController::UrlGenerationError) { product_path(nil, "id"=>"url-tested") } + error = assert_raises(ActionController::UrlGenerationError) { product_path(nil, "id" => "url-tested") } assert_equal message, error.message # Non-optimized url helper - error = assert_raises(ActionController::UrlGenerationError, message) { product_path(id: nil, "id"=>"url-tested") } + error = assert_raises(ActionController::UrlGenerationError, message) { product_path(id: nil, "id" => "url-tested") } assert_equal message, error.message end end diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb index aca70e180c..3facbf59c2 100644 --- a/actionpack/test/dispatch/static_test.rb +++ b/actionpack/test/dispatch/static_test.rb @@ -143,16 +143,16 @@ module StaticTests assert_equal "Accept-Encoding", response.headers["Vary"] assert_equal "gzip", response.headers["Content-Encoding"] - response = get(file_name, "HTTP_ACCEPT_ENCODING" => "Gzip") - assert_gzip file_name, response + response = get(file_name, "HTTP_ACCEPT_ENCODING" => "Gzip") + assert_gzip file_name, response - response = get(file_name, "HTTP_ACCEPT_ENCODING" => "GZIP") - assert_gzip file_name, response + response = get(file_name, "HTTP_ACCEPT_ENCODING" => "GZIP") + assert_gzip file_name, response - response = get(file_name, "HTTP_ACCEPT_ENCODING" => "compress;q=0.5, gzip;q=1.0") - assert_gzip file_name, response + response = get(file_name, "HTTP_ACCEPT_ENCODING" => "compress;q=0.5, gzip;q=1.0") + assert_gzip file_name, response - response = get(file_name, "HTTP_ACCEPT_ENCODING" => "") + response = get(file_name, "HTTP_ACCEPT_ENCODING" => "") assert_not_equal "gzip", response.headers["Content-Encoding"] end @@ -166,7 +166,7 @@ module StaticTests def test_serves_gzip_with_propper_content_type_fallback file_name = "/gzip/foo.zoo" response = get(file_name, "HTTP_ACCEPT_ENCODING" => "gzip") - assert_gzip file_name, response + assert_gzip file_name, response default_response = get(file_name) # no gzip assert_equal default_response.headers["Content-Type"], response.headers["Content-Type"] @@ -204,7 +204,7 @@ module StaticTests end # Windows doesn't allow \ / : * ? " < > | in filenames - unless RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ + unless Gem.win_platform? def test_serves_static_file_with_colon with_static_file "/foo/foo:bar.html" do |file| assert_html file, get("/foo/foo%3Abar.html") @@ -269,14 +269,14 @@ class StaticTest < ActiveSupport::TestCase filename = "shared.html.erb" assert File.exist?(File.join(@root, "..", filename)) env = { - "REQUEST_METHOD"=>"GET", - "REQUEST_PATH"=>"/..%2F#{filename}", - "PATH_INFO"=>"/..%2F#{filename}", - "REQUEST_URI"=>"/..%2F#{filename}", - "HTTP_VERSION"=>"HTTP/1.1", - "SERVER_NAME"=>"localhost", - "SERVER_PORT"=>"8080", - "QUERY_STRING"=>"" + "REQUEST_METHOD" => "GET", + "REQUEST_PATH" => "/..%2F#{filename}", + "PATH_INFO" => "/..%2F#{filename}", + "REQUEST_URI" => "/..%2F#{filename}", + "HTTP_VERSION" => "HTTP/1.1", + "SERVER_NAME" => "localhost", + "SERVER_PORT" => "8080", + "QUERY_STRING" => "" } assert_equal(DummyApp.call(nil), @app.call(env)) end diff --git a/actionpack/test/dispatch/uploaded_file_test.rb b/actionpack/test/dispatch/uploaded_file_test.rb index 60d0246a68..51680216e4 100644 --- a/actionpack/test/dispatch/uploaded_file_test.rb +++ b/actionpack/test/dispatch/uploaded_file_test.rb @@ -58,25 +58,25 @@ module ActionDispatch end def test_delegates_close_to_tempfile - tf = Class.new { def close(unlink_now=false); "thunderhorse" end } + tf = Class.new { def close(unlink_now = false); "thunderhorse" end } uf = Http::UploadedFile.new(tempfile: tf.new) assert_equal "thunderhorse", uf.close end def test_close_accepts_parameter - tf = Class.new { def close(unlink_now=false); "thunderhorse: #{unlink_now}" end } + tf = Class.new { def close(unlink_now = false); "thunderhorse: #{unlink_now}" end } uf = Http::UploadedFile.new(tempfile: tf.new) assert_equal "thunderhorse: true", uf.close(true) end def test_delegates_read_to_tempfile - tf = Class.new { def read(length=nil, buffer=nil); "thunderhorse" end } + tf = Class.new { def read(length = nil, buffer = nil); "thunderhorse" end } uf = Http::UploadedFile.new(tempfile: tf.new) assert_equal "thunderhorse", uf.read end def test_delegates_read_to_tempfile_with_params - tf = Class.new { def read(length=nil, buffer=nil); [length, buffer] end } + tf = Class.new { def read(length = nil, buffer = nil); [length, buffer] end } uf = Http::UploadedFile.new(tempfile: tf.new) assert_equal %w{ thunder horse }, uf.read(*%w{ thunder horse }) end diff --git a/actionpack/test/fixtures/multipart/mona_lisa.jpg b/actionpack/test/fixtures/multipart/mona_lisa.jpg Binary files differdeleted file mode 100644 index 5cf3bef3d0..0000000000 --- a/actionpack/test/fixtures/multipart/mona_lisa.jpg +++ /dev/null diff --git a/actionpack/test/fixtures/multipart/ruby_on_rails.jpg b/actionpack/test/fixtures/multipart/ruby_on_rails.jpg Binary files differnew file mode 100644 index 0000000000..ed284ea0ba --- /dev/null +++ b/actionpack/test/fixtures/multipart/ruby_on_rails.jpg diff --git a/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb b/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb index cd0be6d1b5..18fa5cd923 100644 --- a/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +++ b/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb @@ -1,6 +1,6 @@ module SessionAutoloadTest class Foo - def initialize(bar="baz") + def initialize(bar = "baz") @bar = bar end def inspect diff --git a/actionpack/test/journey/gtg/builder_test.rb b/actionpack/test/journey/gtg/builder_test.rb index 2b314cdd4e..aa8427b265 100644 --- a/actionpack/test/journey/gtg/builder_test.rb +++ b/actionpack/test/journey/gtg/builder_test.rb @@ -5,18 +5,18 @@ module ActionDispatch module GTG class TestBuilder < ActiveSupport::TestCase def test_following_states_multi - table = tt ["a|a"] + table = tt ["a|a"] assert_equal 1, table.move([0], "a").length end def test_following_states_multi_regexp - table = tt [":a|b"] + table = tt [":a|b"] assert_equal 1, table.move([0], "fooo").length assert_equal 2, table.move([0], "b").length end def test_multi_path - table = tt ["/:a/d", "/b/c"] + table = tt ["/:a/d", "/b/c"] [ [1, "/"], @@ -38,7 +38,7 @@ module ActionDispatch /articles/:id(.:format) } - sim = NFA::Simulator.new table + sim = NFA::Simulator.new table match = sim.match "/articles/new" assert_equal 2, match.memos.length @@ -52,7 +52,7 @@ module ActionDispatch /articles/new(.:format) } - sim = NFA::Simulator.new table + sim = NFA::Simulator.new table match = sim.match "/articles/new" assert_equal 2, match.memos.length diff --git a/actionpack/test/journey/gtg/transition_table_test.rb b/actionpack/test/journey/gtg/transition_table_test.rb index 4c8b5032eb..c7315c0338 100644 --- a/actionpack/test/journey/gtg/transition_table_test.rb +++ b/actionpack/test/journey/gtg/transition_table_test.rb @@ -92,7 +92,7 @@ module ActionDispatch private def asts(paths) - parser = Journey::Parser.new + parser = Journey::Parser.new paths.map { |x| ast = parser.parse x ast.each { |n| n.memo = ast } diff --git a/actionpack/test/journey/nfa/simulator_test.rb b/actionpack/test/journey/nfa/simulator_test.rb index 183c892a53..38f99398cb 100644 --- a/actionpack/test/journey/nfa/simulator_test.rb +++ b/actionpack/test/journey/nfa/simulator_test.rb @@ -80,7 +80,7 @@ module ActionDispatch ast = Nodes::Or.new routes - nfa = Journey::NFA::Builder.new ast + nfa = Journey::NFA::Builder.new ast sim = Simulator.new nfa.transition_table md = sim.match "/articles" assert_equal [asts.first], md.memos diff --git a/actionpack/test/journey/nfa/transition_table_test.rb b/actionpack/test/journey/nfa/transition_table_test.rb index f3cf36a064..0bc6bc1cf8 100644 --- a/actionpack/test/journey/nfa/transition_table_test.rb +++ b/actionpack/test/journey/nfa/transition_table_test.rb @@ -53,10 +53,10 @@ module ActionDispatch end def test_alphabet - table = tt "a|:a" + table = tt "a|:a" assert_equal [/[^\.\/\?]+/, "a"], table.alphabet - table = tt "a|a" + table = tt "a|a" assert_equal ["a"], table.alphabet end diff --git a/actionpack/test/journey/route_test.rb b/actionpack/test/journey/route_test.rb index b6414fd101..d2a8163ffb 100644 --- a/actionpack/test/journey/route_test.rb +++ b/actionpack/test/journey/route_test.rb @@ -26,7 +26,7 @@ module ActionDispatch end def test_path_requirements_override_defaults - path = Path::Pattern.build(":name", { name: /love/ }, "/", true) + path = Path::Pattern.build(":name", { name: /love/ }, "/", true) defaults = { name: "tender" } route = Route.build("name", nil, path, {}, [], defaults) assert_equal(/love/, route.requirements[:name]) diff --git a/actionpack/test/journey/router_test.rb b/actionpack/test/journey/router_test.rb index 7b5916eb72..f223a125a3 100644 --- a/actionpack/test/journey/router_test.rb +++ b/actionpack/test/journey/router_test.rb @@ -6,8 +6,8 @@ module ActionDispatch attr_reader :mapper, :routes, :route_set, :router def setup - @app = Routing::RouteSet::Dispatcher.new({}) - @route_set = ActionDispatch::Routing::RouteSet.new + @app = Routing::RouteSet::Dispatcher.new({}) + @route_set = ActionDispatch::Routing::RouteSet.new @routes = @route_set.router.routes @router = @route_set.router @formatter = @route_set.formatter @@ -116,7 +116,7 @@ module ActionDispatch end def test_clear_trailing_slash_from_script_name_on_root_unanchored_routes - app = lambda { |env| [200, {}, ["success!"]] } + app = lambda { |env| [200, {}, ["success!"]] } get "/weblog", to: app env = rack_env("SCRIPT_NAME" => "", "PATH_INFO" => "/weblog") @@ -233,7 +233,7 @@ module ActionDispatch nil, Hash[params], {}, - lambda { |k,v| parameterized << [k,v]; v }) + lambda { |k, v| parameterized << [k, v]; v }) assert_equal params.map(&:to_s).sort, parameterized.map(&:to_s).sort end @@ -289,15 +289,15 @@ module ActionDispatch relative_url_root: nil } redirection_parameters = { - "action"=>"show", + "action" => "show", } missing_key = "name" - missing_parameters ={ + missing_parameters = { missing_key => "task_1" } request_parameters = primarty_parameters.merge(redirection_parameters).merge(missing_parameters) - message = "No route matches #{Hash[request_parameters.sort_by { |k,v|k.to_s }].inspect}, missing required keys: #{[missing_key.to_sym].inspect}" + message = "No route matches #{Hash[request_parameters.sort_by { |k, v|k.to_s }].inspect}, missing required keys: #{[missing_key.to_sym].inspect}" error = assert_raises(ActionController::UrlGenerationError) do @formatter.generate( @@ -338,7 +338,7 @@ module ActionDispatch route = @routes.first env = rails_env "PATH_INFO" => request_path - called = false + called = false router.recognize(env) do |r, params| assert_equal route, r @@ -358,7 +358,7 @@ module ActionDispatch get "/:segment/*splat", to: "foo#bar" env = rails_env "PATH_INFO" => request_path - called = false + called = false route = @routes.first router.recognize(env) do |r, params| @@ -395,7 +395,7 @@ module ActionDispatch get "/books(/:action(.:format))", controller: "books" route = @routes.first - env = rails_env "PATH_INFO" => "/books/list.rss" + env = rails_env "PATH_INFO" => "/books/list.rss" expected = { controller: "books", action: "list", format: "rss" } called = false router.recognize(env) do |r, params| @@ -427,7 +427,7 @@ module ActionDispatch get "/books(/:action(.:format))", to: "foo#bar" env = rails_env "PATH_INFO" => "/books/list.rss", - "REQUEST_METHOD" => "HEAD" + "REQUEST_METHOD" => "HEAD" called = false router.recognize(env) do |r, params| diff --git a/actionpack/test/journey/routes_test.rb b/actionpack/test/journey/routes_test.rb index ca735ea022..d8db5ffad1 100644 --- a/actionpack/test/journey/routes_test.rb +++ b/actionpack/test/journey/routes_test.rb @@ -6,7 +6,7 @@ module ActionDispatch attr_reader :routes, :mapper def setup - @route_set = ActionDispatch::Routing::RouteSet.new + @route_set = ActionDispatch::Routing::RouteSet.new @routes = @route_set.router.routes @router = @route_set.router @mapper = ActionDispatch::Routing::Mapper.new @route_set diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index ce9522d12a..046b4167bb 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -6,7 +6,7 @@ class Customer < Struct.new(:name, :id) undef_method :to_json - def to_xml(options={}) + def to_xml(options = {}) if options[:builder] options[:builder].name name else @@ -14,7 +14,7 @@ class Customer < Struct.new(:name, :id) end end - def to_js(options={}) + def to_js(options = {}) "name: #{name.inspect}" end alias :to_text :to_js |