Rails 2.3.5
Upgrade to Rails 2.3.5. Also work around this bug: https://rails.lighthouseapp.com/projects/8994/tickets/3524 created by the aforementioned Rails release.
This commit is contained in:
parent
a6429f8c22
commit
e3832c6f79
187 changed files with 2316 additions and 891 deletions
|
@ -1,6 +1,18 @@
|
|||
module ActionController
|
||||
module Assertions
|
||||
module DomAssertions
|
||||
def self.strip_whitespace!(nodes)
|
||||
nodes.reject! do |node|
|
||||
if node.is_a?(HTML::Text)
|
||||
node.content.strip!
|
||||
node.content.empty?
|
||||
else
|
||||
strip_whitespace! node.children
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Test two HTML strings for equivalency (e.g., identical up to reordering of attributes)
|
||||
#
|
||||
# ==== Examples
|
||||
|
@ -12,13 +24,15 @@ module ActionController
|
|||
clean_backtrace do
|
||||
expected_dom = HTML::Document.new(expected).root
|
||||
actual_dom = HTML::Document.new(actual).root
|
||||
full_message = build_message(message, "<?> expected to be == to\n<?>.", expected_dom.to_s, actual_dom.to_s)
|
||||
DomAssertions.strip_whitespace!(expected_dom.children)
|
||||
DomAssertions.strip_whitespace!(actual_dom.children)
|
||||
|
||||
full_message = build_message(message, "<?> expected but was\n<?>.", expected_dom.to_s, actual_dom.to_s)
|
||||
assert_block(full_message) { expected_dom == actual_dom }
|
||||
end
|
||||
end
|
||||
|
||||
# The negated form of +assert_dom_equivalent+.
|
||||
# The negated form of +assert_dom_equal+.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
|
@ -29,8 +43,10 @@ module ActionController
|
|||
clean_backtrace do
|
||||
expected_dom = HTML::Document.new(expected).root
|
||||
actual_dom = HTML::Document.new(actual).root
|
||||
full_message = build_message(message, "<?> expected to be != to\n<?>.", expected_dom.to_s, actual_dom.to_s)
|
||||
DomAssertions.strip_whitespace!(expected_dom.children)
|
||||
DomAssertions.strip_whitespace!(actual_dom.children)
|
||||
|
||||
full_message = build_message(message, "<?> expected to be != to\n<?>.", expected_dom.to_s, actual_dom.to_s)
|
||||
assert_block(full_message) { expected_dom != actual_dom }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ module ActionController
|
|||
#
|
||||
# Use +css_select+ to select elements without making an assertions, either
|
||||
# from the response HTML or elements selected by the enclosing assertion.
|
||||
#
|
||||
#
|
||||
# In addition to HTML responses, you can make the following assertions:
|
||||
# * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations.
|
||||
# * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
|
||||
|
@ -24,6 +24,12 @@ module ActionController
|
|||
#
|
||||
# Also see HTML::Selector to learn how to use selectors.
|
||||
module SelectorAssertions
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
@selected = nil
|
||||
end
|
||||
|
||||
# :call-seq:
|
||||
# css_select(selector) => array
|
||||
# css_select(element, selector) => array
|
||||
|
@ -53,8 +59,8 @@ module ActionController
|
|||
# end
|
||||
#
|
||||
# # Selects all list items in unordered lists
|
||||
# items = css_select("ul>li")
|
||||
#
|
||||
# items = css_select("ul>li")
|
||||
#
|
||||
# # Selects all form tags and then all inputs inside the form
|
||||
# forms = css_select("form")
|
||||
# forms.each do |form|
|
||||
|
@ -212,7 +218,7 @@ module ActionController
|
|||
# Otherwise just operate on the response document.
|
||||
root = response_from_page_or_rjs
|
||||
end
|
||||
|
||||
|
||||
# First or second argument is the selector: string and we pass
|
||||
# all remaining arguments. Array and we pass the argument. Also
|
||||
# accepts selector itself.
|
||||
|
@ -225,7 +231,7 @@ module ActionController
|
|||
selector = arg
|
||||
else raise ArgumentError, "Expecting a selector as the first argument"
|
||||
end
|
||||
|
||||
|
||||
# Next argument is used for equality tests.
|
||||
equals = {}
|
||||
case arg = args.shift
|
||||
|
@ -315,10 +321,10 @@ module ActionController
|
|||
# Returns all matches elements.
|
||||
matches
|
||||
end
|
||||
|
||||
|
||||
def count_description(min, max) #:nodoc:
|
||||
pluralize = lambda {|word, quantity| word << (quantity == 1 ? '' : 's')}
|
||||
|
||||
|
||||
if min && max && (max != min)
|
||||
"between #{min} and #{max} elements"
|
||||
elsif min && !(min == 1 && max == 1)
|
||||
|
@ -327,7 +333,7 @@ module ActionController
|
|||
"at most #{max} #{pluralize['element', max]}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# :call-seq:
|
||||
# assert_select_rjs(id?) { |elements| ... }
|
||||
# assert_select_rjs(statement, id?) { |elements| ... }
|
||||
|
@ -344,7 +350,7 @@ module ActionController
|
|||
# that update or insert an element with that identifier.
|
||||
#
|
||||
# Use the first argument to narrow down assertions to only statements
|
||||
# of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>,
|
||||
# of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>,
|
||||
# <tt>:show</tt>, <tt>:hide</tt>, <tt>:toggle</tt>, <tt>:remove</tt> and
|
||||
# <tt>:insert_html</tt>.
|
||||
#
|
||||
|
@ -488,7 +494,7 @@ module ActionController
|
|||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
#
|
||||
# # Selects all paragraph tags from within the description of an RSS feed
|
||||
# assert_select_feed :rss, 2.0 do
|
||||
|
|
|
@ -502,7 +502,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
elsif block_given?
|
||||
key = key.dup
|
||||
value = value.dup if value
|
||||
value = value.dup if value.duplicable?
|
||||
yield key, value
|
||||
filtered_parameters[key] = value
|
||||
else
|
||||
|
|
|
@ -22,6 +22,7 @@ module ActionController #:nodoc:
|
|||
# ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
|
||||
# ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
|
||||
# ActionController::Base.cache_store = :mem_cache_store, "localhost"
|
||||
# ActionController::Base.cache_store = :mem_cache_store, Memcached::Rails.new("localhost:11211")
|
||||
# ActionController::Base.cache_store = MyOwnStore.new("parameter")
|
||||
module Caching
|
||||
autoload :Actions, 'action_controller/caching/actions'
|
||||
|
|
|
@ -87,8 +87,9 @@ module ActionController #:nodoc:
|
|||
def delete(key, options = {})
|
||||
options.symbolize_keys!
|
||||
options[:path] = "/" unless options.has_key?(:path)
|
||||
super(key.to_s)
|
||||
value = super(key.to_s)
|
||||
@controller.response.delete_cookie(key, options)
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -227,9 +227,9 @@ module ActionController
|
|||
end
|
||||
|
||||
def decode_credentials(header)
|
||||
header.to_s.gsub(/^Digest\s+/,'').split(',').inject({}) do |hash, pair|
|
||||
header.to_s.gsub(/^Digest\s+/,'').split(',').inject({}.with_indifferent_access) do |hash, pair|
|
||||
key, value = pair.split('=', 2)
|
||||
hash[key.strip.to_sym] = value.to_s.gsub(/^"|"$/,'').gsub(/'/, '')
|
||||
hash[key.strip] = value.to_s.gsub(/^"|"$/,'').gsub(/'/, '')
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
@ -289,6 +289,7 @@ module ActionController
|
|||
# allow a user to use new nonce without prompting user again for their
|
||||
# username and password.
|
||||
def validate_nonce(request, value, seconds_to_timeout=5*60)
|
||||
return false if value.nil?
|
||||
t = Base64.decode64(value).split(":").first.to_i
|
||||
nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
require 'stringio'
|
||||
require 'uri'
|
||||
require 'active_support/test_case'
|
||||
require 'action_controller/rack_lint_patch'
|
||||
|
||||
module ActionController
|
||||
module Integration #:nodoc:
|
||||
|
@ -268,7 +269,9 @@ module ActionController
|
|||
|
||||
env["QUERY_STRING"] ||= ""
|
||||
|
||||
data = data.is_a?(IO) ? data : StringIO.new(data || '')
|
||||
data ||= ''
|
||||
data.force_encoding(Encoding::ASCII_8BIT) if data.respond_to?(:force_encoding)
|
||||
data = data.is_a?(IO) ? data : StringIO.new(data)
|
||||
|
||||
env.update(
|
||||
"REQUEST_METHOD" => method.to_s.upcase,
|
||||
|
@ -476,6 +479,11 @@ EOF
|
|||
end
|
||||
|
||||
module Runner
|
||||
def initialize(*args)
|
||||
super
|
||||
@integration_session = nil
|
||||
end
|
||||
|
||||
# Reset the current session. This is useful for testing multiple sessions
|
||||
# in a single test case.
|
||||
def reset!
|
||||
|
@ -543,8 +551,12 @@ EOF
|
|||
# Delegate unhandled messages to the current session instance.
|
||||
def method_missing(sym, *args, &block)
|
||||
reset! unless @integration_session
|
||||
returning @integration_session.__send__(sym, *args, &block) do
|
||||
copy_session_variables!
|
||||
if @integration_session.respond_to?(sym)
|
||||
returning @integration_session.__send__(sym, *args, &block) do
|
||||
copy_session_variables!
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -194,6 +194,11 @@ module ActionController #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
@real_format = nil
|
||||
end
|
||||
|
||||
# Returns the name of the active layout. If the layout was specified as a method reference (through a symbol), this method
|
||||
# is called and the return value is used. Likewise if the layout was specified as an inline method (through a proc or method
|
||||
# object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
|
||||
|
@ -221,7 +226,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
def find_layout(layout, format, html_fallback=false) #:nodoc:
|
||||
view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", format, html_fallback)
|
||||
view_paths.find_template(layout.to_s =~ /\A\/|layouts\// ? layout : "layouts/#{layout}", format, html_fallback)
|
||||
rescue ActionView::MissingTemplate
|
||||
raise if Mime::Type.lookup_by_extension(format.to_s).html?
|
||||
end
|
||||
|
|
|
@ -10,3 +10,5 @@ use lambda { ActionController::Base.session_store },
|
|||
use "ActionController::ParamsParser"
|
||||
use "Rack::MethodOverride"
|
||||
use "Rack::Head"
|
||||
|
||||
use "ActionController::StringCoercion"
|
||||
|
|
|
@ -76,8 +76,7 @@ module ActionController
|
|||
record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1
|
||||
end
|
||||
|
||||
record = extract_record(record_or_hash_or_array)
|
||||
namespace = extract_namespace(record_or_hash_or_array)
|
||||
record = extract_record(record_or_hash_or_array)
|
||||
|
||||
args = case record_or_hash_or_array
|
||||
when Hash; [ record_or_hash_or_array ]
|
||||
|
@ -98,8 +97,7 @@ module ActionController
|
|||
end
|
||||
|
||||
args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
|
||||
|
||||
named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
|
||||
named_route = build_named_route_call(record_or_hash_or_array, inflection, options)
|
||||
|
||||
url_options = options.except(:action, :routing_type)
|
||||
unless url_options.empty?
|
||||
|
@ -153,7 +151,7 @@ module ActionController
|
|||
options[:routing_type] || :url
|
||||
end
|
||||
|
||||
def build_named_route_call(records, namespace, inflection, options = {})
|
||||
def build_named_route_call(records, inflection, options = {})
|
||||
unless records.is_a?(Array)
|
||||
record = extract_record(records)
|
||||
route = ''
|
||||
|
@ -163,7 +161,7 @@ module ActionController
|
|||
if parent.is_a?(Symbol) || parent.is_a?(String)
|
||||
string << "#{parent}_"
|
||||
else
|
||||
string << "#{RecordIdentifier.__send__("plural_class_name", parent)}".singularize
|
||||
string << RecordIdentifier.__send__("plural_class_name", parent).singularize
|
||||
string << "_"
|
||||
end
|
||||
end
|
||||
|
@ -172,12 +170,12 @@ module ActionController
|
|||
if record.is_a?(Symbol) || record.is_a?(String)
|
||||
route << "#{record}_"
|
||||
else
|
||||
route << "#{RecordIdentifier.__send__("plural_class_name", record)}"
|
||||
route << RecordIdentifier.__send__("plural_class_name", record)
|
||||
route = route.singularize if inflection == :singular
|
||||
route << "_"
|
||||
end
|
||||
|
||||
action_prefix(options) + namespace + route + routing_type(options).to_s
|
||||
action_prefix(options) + route + routing_type(options).to_s
|
||||
end
|
||||
|
||||
def extract_record(record_or_hash_or_array)
|
||||
|
@ -187,18 +185,5 @@ module ActionController
|
|||
else record_or_hash_or_array
|
||||
end
|
||||
end
|
||||
|
||||
# Remove the first symbols from the array and return the url prefix
|
||||
# implied by those symbols.
|
||||
def extract_namespace(record_or_hash_or_array)
|
||||
return "" unless record_or_hash_or_array.is_a?(Array)
|
||||
|
||||
namespace_keys = []
|
||||
while (key = record_or_hash_or_array.first) && key.is_a?(String) || key.is_a?(Symbol)
|
||||
namespace_keys << record_or_hash_or_array.shift
|
||||
end
|
||||
|
||||
namespace_keys.map {|k| "#{k}_"}.join
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
36
vendor/rails/actionpack/lib/action_controller/rack_lint_patch.rb
vendored
Normal file
36
vendor/rails/actionpack/lib/action_controller/rack_lint_patch.rb
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Rack 1.0 does not allow string subclass body. This does not play well with our ActionView::SafeBuffer.
|
||||
# The next release of Rack will be allowing string subclass body - http://github.com/rack/rack/commit/de668df02802a0335376a81ba709270e43ba9d55
|
||||
# TODO : Remove this monkey patch after the next release of Rack
|
||||
|
||||
module RackLintPatch
|
||||
module AllowStringSubclass
|
||||
def self.included(base)
|
||||
base.send :alias_method, :each, :each_with_hack
|
||||
end
|
||||
|
||||
def each_with_hack
|
||||
@closed = false
|
||||
|
||||
@body.each { |part|
|
||||
assert("Body yielded non-string value #{part.inspect}") {
|
||||
part.kind_of?(String)
|
||||
}
|
||||
yield part
|
||||
}
|
||||
|
||||
if @body.respond_to?(:to_path)
|
||||
assert("The file identified by body.to_path does not exist") {
|
||||
::File.exist? @body.to_path
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
app = proc {|env| [200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, [Class.new(String).new("Hello World!")]] }
|
||||
response = Rack::MockRequest.new(Rack::Lint.new(app)).get('/')
|
||||
rescue Rack::Lint::LintError => e
|
||||
raise(e) unless e.message =~ /Body yielded non-string value/
|
||||
Rack::Lint.send :include, AllowStringSubclass
|
||||
end
|
||||
end
|
|
@ -89,9 +89,13 @@ module ActionController #:nodoc:
|
|||
request.method == :get ||
|
||||
request.xhr? ||
|
||||
!verifiable_request_format? ||
|
||||
form_authenticity_token == params[request_forgery_protection_token]
|
||||
form_authenticity_token == form_authenticity_param
|
||||
end
|
||||
|
||||
|
||||
def form_authenticity_param
|
||||
params[request_forgery_protection_token]
|
||||
end
|
||||
|
||||
def verifiable_request_format?
|
||||
!request.content_type.nil? && request.content_type.verify_request?
|
||||
end
|
||||
|
|
|
@ -47,7 +47,8 @@ module ActionController # :nodoc:
|
|||
@block = nil
|
||||
|
||||
@body = "",
|
||||
@session, @assigns = [], []
|
||||
@session = []
|
||||
@assigns = []
|
||||
end
|
||||
|
||||
def location; headers['Location'] end
|
||||
|
|
29
vendor/rails/actionpack/lib/action_controller/string_coercion.rb
vendored
Normal file
29
vendor/rails/actionpack/lib/action_controller/string_coercion.rb
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
module ActionController
|
||||
class StringCoercion
|
||||
class UglyBody < ActiveSupport::BasicObject
|
||||
def initialize(body)
|
||||
@body = body
|
||||
end
|
||||
|
||||
def each
|
||||
@body.each do |part|
|
||||
yield part.to_s
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def method_missing(*args, &block)
|
||||
@body.__send__(*args, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
status, headers, body = @app.call(env)
|
||||
[status, headers, UglyBody.new(body)]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -105,6 +105,11 @@ module ActionController
|
|||
class TestCase < ActiveSupport::TestCase
|
||||
include TestProcess
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
@controller = nil
|
||||
end
|
||||
|
||||
module Assertions
|
||||
%w(response selector tag dom routing model).each do |kind|
|
||||
include ActionController::Assertions.const_get("#{kind.camelize}Assertions")
|
||||
|
@ -195,7 +200,7 @@ module ActionController
|
|||
@controller.send(:initialize_current_url)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
|
||||
def rescue_action_in_public!
|
||||
@request.remote_addr = '208.77.188.166' # example.com
|
||||
|
|
|
@ -91,7 +91,7 @@ module ActionController #:nodoc:
|
|||
@path || super()
|
||||
end
|
||||
|
||||
def assign_parameters(controller_path, action, parameters)
|
||||
def assign_parameters(controller_path, action, parameters = {})
|
||||
parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
|
||||
extra_keys = ActionController::Routing::Routes.extra_keys(parameters)
|
||||
non_path_parameters = get? ? query_parameters : request_parameters
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
module ActionController
|
||||
module Translation
|
||||
def translate(*args)
|
||||
I18n.translate *args
|
||||
I18n.translate(*args)
|
||||
end
|
||||
alias :t :translate
|
||||
|
||||
def localize(*args)
|
||||
I18n.localize *args
|
||||
I18n.localize(*args)
|
||||
end
|
||||
alias :l :localize
|
||||
end
|
||||
|
|
|
@ -3,14 +3,14 @@ module ActionController
|
|||
def self.included(base)
|
||||
base.class_eval do
|
||||
attr_accessor :original_path, :content_type
|
||||
alias_method :local_path, :path
|
||||
alias_method :local_path, :path if method_defined?(:path)
|
||||
end
|
||||
end
|
||||
|
||||
def self.extended(object)
|
||||
object.class_eval do
|
||||
attr_accessor :original_path, :content_type
|
||||
alias_method :local_path, :path
|
||||
alias_method :local_path, :path if method_defined?(:path)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ module HTML #:nodoc:
|
|||
end
|
||||
|
||||
closing = ( scanner.scan(/\//) ? :close : nil )
|
||||
return Text.new(parent, line, pos, content) unless name = scanner.scan(/[\w:-]+/)
|
||||
return Text.new(parent, line, pos, content) unless name = scanner.scan(/[-:\w\x00-\x09\x0b-\x0c\x0e-\x1f]+/)
|
||||
name.downcase!
|
||||
|
||||
unless closing
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue