Merge branch 'master' into erbout
This commit is contained in:
commit
e7f1556d0e
@ -1,5 +1,7 @@
|
|||||||
*Edge*
|
*Edge*
|
||||||
|
|
||||||
|
* Added page.reload functionality. Resolves #277. [Sean Huber]
|
||||||
|
|
||||||
* Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens]
|
* Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens]
|
||||||
|
|
||||||
* Allow caches_action to accept a layout option [José Valim]
|
* Allow caches_action to accept a layout option [José Valim]
|
||||||
|
@ -49,21 +49,12 @@ def request_parameters
|
|||||||
def cookies
|
def cookies
|
||||||
return {} unless @env["HTTP_COOKIE"]
|
return {} unless @env["HTTP_COOKIE"]
|
||||||
|
|
||||||
if @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
|
unless @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
|
||||||
@env["rack.request.cookie_hash"]
|
|
||||||
else
|
|
||||||
@env["rack.request.cookie_string"] = @env["HTTP_COOKIE"]
|
@env["rack.request.cookie_string"] = @env["HTTP_COOKIE"]
|
||||||
# According to RFC 2109:
|
@env["rack.request.cookie_hash"] = CGI::Cookie::parse(@env["rack.request.cookie_string"])
|
||||||
# If multiple cookies satisfy the criteria above, they are ordered in
|
|
||||||
# the Cookie header such that those with more specific Path attributes
|
|
||||||
# precede those with less specific. Ordering with respect to other
|
|
||||||
# attributes (e.g., Domain) is unspecified.
|
|
||||||
@env["rack.request.cookie_hash"] =
|
|
||||||
parse_query(@env["rack.request.cookie_string"], ';,').inject({}) { |h, (k,v)|
|
|
||||||
h[k] = Array === v ? v.first : v
|
|
||||||
h
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@env["rack.request.cookie_hash"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def host_with_port_without_standard_port_handling
|
def host_with_port_without_standard_port_handling
|
||||||
@ -170,31 +161,6 @@ def stale_session_check!
|
|||||||
def session_options_with_string_keys
|
def session_options_with_string_keys
|
||||||
@session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).stringify_keys
|
@session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).stringify_keys
|
||||||
end
|
end
|
||||||
|
|
||||||
# From Rack::Utils
|
|
||||||
def parse_query(qs, d = '&;')
|
|
||||||
params = {}
|
|
||||||
(qs || '').split(/[#{d}] */n).inject(params) { |h,p|
|
|
||||||
k, v = unescape(p).split('=',2)
|
|
||||||
if cur = params[k]
|
|
||||||
if cur.class == Array
|
|
||||||
params[k] << v
|
|
||||||
else
|
|
||||||
params[k] = [cur, v]
|
|
||||||
end
|
|
||||||
else
|
|
||||||
params[k] = v
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
return params
|
|
||||||
end
|
|
||||||
|
|
||||||
def unescape(s)
|
|
||||||
s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
|
|
||||||
[$1.delete('%')].pack('H*')
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class RackResponse < AbstractResponse #:nodoc:
|
class RackResponse < AbstractResponse #:nodoc:
|
||||||
|
@ -868,6 +868,16 @@ def redirect_to(location)
|
|||||||
record "window.location.href = #{url.inspect}"
|
record "window.location.href = #{url.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Reloads the browser's current +location+ using JavaScript
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# # Generates: window.location.reload();
|
||||||
|
# page.reload
|
||||||
|
def reload
|
||||||
|
record 'window.location.reload()'
|
||||||
|
end
|
||||||
|
|
||||||
# Calls the JavaScript +function+, optionally with the given +arguments+.
|
# Calls the JavaScript +function+, optionally with the given +arguments+.
|
||||||
#
|
#
|
||||||
# If a block is given, the block will be passed to a new JavaScriptGenerator;
|
# If a block is given, the block will be passed to a new JavaScriptGenerator;
|
||||||
|
@ -33,10 +33,10 @@ def setup
|
|||||||
"REDIRECT_STATUS" => "200",
|
"REDIRECT_STATUS" => "200",
|
||||||
"REQUEST_METHOD" => "GET"
|
"REQUEST_METHOD" => "GET"
|
||||||
}
|
}
|
||||||
|
@request = ActionController::RackRequest.new(@env)
|
||||||
# some Nokia phone browsers omit the space after the semicolon separator.
|
# some Nokia phone browsers omit the space after the semicolon separator.
|
||||||
# some developers have grown accustomed to using comma in cookie values.
|
# some developers have grown accustomed to using comma in cookie values.
|
||||||
@alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"}
|
@alt_cookie_fmt_request = ActionController::RackRequest.new(@env.merge({"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"}))
|
||||||
@request = ActionController::RackRequest.new(@env)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_test; end
|
def default_test; end
|
||||||
@ -100,11 +100,11 @@ def test_host_if_ipv6_reference_with_port
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_cookie_syntax_resilience
|
def test_cookie_syntax_resilience
|
||||||
cookies = CGI::Cookie::parse(@env["HTTP_COOKIE"]);
|
cookies = @request.cookies
|
||||||
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"], cookies.inspect
|
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"], cookies.inspect
|
||||||
assert_equal ["yes"], cookies["is_admin"], cookies.inspect
|
assert_equal ["yes"], cookies["is_admin"], cookies.inspect
|
||||||
|
|
||||||
alt_cookies = CGI::Cookie::parse(@alt_cookie_fmt_request_hash["HTTP_COOKIE"]);
|
alt_cookies = @alt_cookie_fmt_request.cookies
|
||||||
assert_equal ["c84ace847,96670c052c6ceb2451fb0f2"], alt_cookies["_session_id"], alt_cookies.inspect
|
assert_equal ["c84ace847,96670c052c6ceb2451fb0f2"], alt_cookies["_session_id"], alt_cookies.inspect
|
||||||
assert_equal ["yes"], alt_cookies["is_admin"], alt_cookies.inspect
|
assert_equal ["yes"], alt_cookies["is_admin"], alt_cookies.inspect
|
||||||
end
|
end
|
||||||
|
@ -347,6 +347,11 @@ def test_redirect_to
|
|||||||
@generator.redirect_to("http://www.example.com/welcome?a=b&c=d")
|
@generator.redirect_to("http://www.example.com/welcome?a=b&c=d")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_reload
|
||||||
|
assert_equal 'window.location.reload();',
|
||||||
|
@generator.reload
|
||||||
|
end
|
||||||
|
|
||||||
def test_delay
|
def test_delay
|
||||||
@generator.delay(20) do
|
@generator.delay(20) do
|
||||||
@generator.hide('foo')
|
@generator.hide('foo')
|
||||||
|
@ -331,15 +331,26 @@ def initialize_schema_migrations_table
|
|||||||
end
|
end
|
||||||
|
|
||||||
def assume_migrated_upto_version(version)
|
def assume_migrated_upto_version(version)
|
||||||
|
version = version.to_i
|
||||||
sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
|
sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
|
||||||
|
|
||||||
migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
|
migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
|
||||||
versions = Dir['db/migrate/[0-9]*_*.rb'].map do |filename|
|
versions = Dir['db/migrate/[0-9]*_*.rb'].map do |filename|
|
||||||
filename.split('/').last.split('_').first.to_i
|
filename.split('/').last.split('_').first.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')" unless migrated.include?(version.to_i)
|
unless migrated.include?(version)
|
||||||
(versions - migrated).select { |v| v < version.to_i }.each do |v|
|
execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
|
||||||
|
end
|
||||||
|
|
||||||
|
inserted = Set.new
|
||||||
|
(versions - migrated).each do |v|
|
||||||
|
if inserted.include?(v)
|
||||||
|
raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict."
|
||||||
|
elsif v < version
|
||||||
execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
|
execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
|
||||||
|
inserted << v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
* Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under ActiveSupport [Josh Peek]
|
* Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under ActiveSupport [Josh Peek]
|
||||||
|
|
||||||
* Added StringQuestioneer for doing things like StringQuestioneer.new("production").production? # => true and StringQuestioneer.new("production").development? # => false [DHH]
|
* Added StringInquirer for doing things like StringInquirer.new("production").production? # => true and StringInquirer.new("production").development? # => false [DHH]
|
||||||
|
|
||||||
* Fixed Date#end_of_quarter to not blow up on May 31st [#289 state:resolved] (Danger)
|
* Fixed Date#end_of_quarter to not blow up on May 31st [#289 state:resolved] (Danger)
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
require 'active_support/ordered_options'
|
require 'active_support/ordered_options'
|
||||||
require 'active_support/option_merger'
|
require 'active_support/option_merger'
|
||||||
|
|
||||||
require 'active_support/string_questioneer'
|
require 'active_support/string_inquirer'
|
||||||
|
|
||||||
require 'active_support/values/time_zone'
|
require 'active_support/values/time_zone'
|
||||||
require 'active_support/duration'
|
require 'active_support/duration'
|
||||||
|
11
activesupport/lib/active_support/string_inquirer.rb
Normal file
11
activesupport/lib/active_support/string_inquirer.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module ActiveSupport
|
||||||
|
class StringInquirer < String
|
||||||
|
def method_missing(method_name, *arguments)
|
||||||
|
if method_name.to_s.ends_with?("?")
|
||||||
|
self == method_name.to_s[0..-2]
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,9 +0,0 @@
|
|||||||
class StringQuestioneer < String
|
|
||||||
def method_missing(method_name, *arguments)
|
|
||||||
if method_name.to_s.ends_with?("?")
|
|
||||||
self == method_name.to_s[0..-2]
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
15
activesupport/test/string_inquirer_test.rb
Normal file
15
activesupport/test/string_inquirer_test.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require 'abstract_unit'
|
||||||
|
|
||||||
|
class StringInquirerTest < Test::Unit::TestCase
|
||||||
|
def test_match
|
||||||
|
assert ActiveSupport::StringInquirer.new("production").production?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_miss
|
||||||
|
assert !ActiveSupport::StringInquirer.new("production").development?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_missing_question_mark
|
||||||
|
assert_raises(NoMethodError) { ActiveSupport::StringInquirer.new("production").production }
|
||||||
|
end
|
||||||
|
end
|
@ -1,15 +0,0 @@
|
|||||||
require 'abstract_unit'
|
|
||||||
|
|
||||||
class StringQuestioneerTest < Test::Unit::TestCase
|
|
||||||
def test_match
|
|
||||||
assert StringQuestioneer.new("production").production?
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_miss
|
|
||||||
assert !StringQuestioneer.new("production").development?
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_missing_question_mark
|
|
||||||
assert_raises(NoMethodError) { StringQuestioneer.new("production").production }
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,6 +1,6 @@
|
|||||||
*Edge*
|
*Edge*
|
||||||
|
|
||||||
* Wrapped Rails.env in StringQuestioneer so you can do Rails.env.development? [DHH]
|
* Wrapped Rails.env in StringInquirer so you can do Rails.env.development? [DHH]
|
||||||
|
|
||||||
* Fixed that RailsInfoController wasn't considering all requests local in development mode (Edgard Castro) [#310 state:resolved]
|
* Fixed that RailsInfoController wasn't considering all requests local in development mode (Edgard Castro) [#310 state:resolved]
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ def root
|
|||||||
end
|
end
|
||||||
|
|
||||||
def env
|
def env
|
||||||
StringQuestioneer.new(RAILS_ENV)
|
ActiveSupport::StringInquirer.new(RAILS_ENV)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cache
|
def cache
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext }
|
Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext }
|
||||||
|
|
||||||
# Load any custom rakefile extensions
|
# Load any custom rakefile extensions
|
||||||
Dir["#{RAILS_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
|
|
||||||
Dir["#{RAILS_ROOT}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }
|
Dir["#{RAILS_ROOT}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }
|
||||||
|
Dir["#{RAILS_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
|
||||||
|
@ -108,8 +108,8 @@ def test_should_add_plugin_load_paths_to_Dependencies_load_paths
|
|||||||
|
|
||||||
@loader.add_plugin_load_paths
|
@loader.add_plugin_load_paths
|
||||||
|
|
||||||
assert Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
|
assert ActiveSupport::Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
|
||||||
assert Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
|
assert ActiveSupport::Dependencies.load_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_should_add_plugin_load_paths_to_Dependencies_load_once_paths
|
def test_should_add_plugin_load_paths_to_Dependencies_load_once_paths
|
||||||
@ -117,8 +117,8 @@ def test_should_add_plugin_load_paths_to_Dependencies_load_once_paths
|
|||||||
|
|
||||||
@loader.add_plugin_load_paths
|
@loader.add_plugin_load_paths
|
||||||
|
|
||||||
assert Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
|
assert ActiveSupport::Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
|
||||||
assert Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
|
assert ActiveSupport::Dependencies.load_once_paths.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_should_add_all_load_paths_from_a_plugin_to_LOAD_PATH_array
|
def test_should_add_all_load_paths_from_a_plugin_to_LOAD_PATH_array
|
||||||
|
@ -30,6 +30,8 @@ def setup
|
|||||||
@controller = Rails::InfoController.new
|
@controller = Rails::InfoController.new
|
||||||
@request = ActionController::TestRequest.new
|
@request = ActionController::TestRequest.new
|
||||||
@response = ActionController::TestResponse.new
|
@response = ActionController::TestResponse.new
|
||||||
|
|
||||||
|
ActionController::Base.consider_all_requests_local = true
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_rails_info_properties_table_rendered_for_local_request
|
def test_rails_info_properties_table_rendered_for_local_request
|
||||||
@ -41,6 +43,8 @@ def test_rails_info_properties_table_rendered_for_local_request
|
|||||||
|
|
||||||
def test_rails_info_properties_error_rendered_for_non_local_request
|
def test_rails_info_properties_error_rendered_for_non_local_request
|
||||||
Rails::InfoController.local_request = false
|
Rails::InfoController.local_request = false
|
||||||
|
ActionController::Base.consider_all_requests_local = false
|
||||||
|
|
||||||
get :properties
|
get :properties
|
||||||
assert_tag :tag => 'p'
|
assert_tag :tag => 'p'
|
||||||
assert_response 500
|
assert_response 500
|
||||||
|
Loading…
Reference in New Issue
Block a user