mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Merge commit 'rails/master'
Conflicts: activerecord/lib/active_record/base.rb activerecord/lib/active_record/migration.rb activerecord/test/cases/helper.rb
This commit is contained in:
8
Rakefile
8
Rakefile
@@ -1,6 +1,5 @@
|
||||
require 'rake'
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/contrib/sshpublisher'
|
||||
|
||||
env = %(PKG_BUILD="#{ENV['PKG_BUILD']}") if ENV['PKG_BUILD']
|
||||
|
||||
@@ -13,12 +12,14 @@ end
|
||||
desc 'Run all tests by default'
|
||||
task :default => :test
|
||||
|
||||
%w(test rdoc pgem package release).each do |task_name|
|
||||
%w(test isolated_test rdoc pgem package release).each do |task_name|
|
||||
desc "Run #{task_name} task for all projects"
|
||||
task task_name do
|
||||
errors = []
|
||||
PROJECTS.each do |project|
|
||||
system %(cd #{project} && #{env} #{$0} #{task_name})
|
||||
system(%(cd #{project} && #{env} #{$0} #{task_name})) || errors << project
|
||||
end
|
||||
fail("Errors in #{errors.join(', ')}") unless errors.empty?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,6 +75,7 @@ end
|
||||
|
||||
desc "Publish API docs for Rails as a whole and for each component"
|
||||
task :pdoc => :rdoc do
|
||||
require 'rake/contrib/sshpublisher'
|
||||
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/api", "doc/rdoc").upload
|
||||
PROJECTS.each do |project|
|
||||
system %(cd #{project} && #{env} #{$0} pdoc)
|
||||
|
||||
@@ -28,6 +28,12 @@ Rake::TestTask.new { |t|
|
||||
t.warning = false
|
||||
}
|
||||
|
||||
task :isolated_test do
|
||||
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
|
||||
Dir.glob("test/*_test.rb").all? do |file|
|
||||
system(ruby, '-Ilib:test', file)
|
||||
end or raise "Failures"
|
||||
end
|
||||
|
||||
# Generate the RDoc documentation
|
||||
Rake::RDocTask.new { |rdoc|
|
||||
|
||||
@@ -12,6 +12,7 @@ end
|
||||
|
||||
require 'tmail'
|
||||
|
||||
require 'active_support/core_ext/kernel/reporting'
|
||||
silence_warnings do
|
||||
TMail::Encoder.const_set("MAX_LINE_LEN", 200)
|
||||
end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
*Edge*
|
||||
|
||||
* Instead of checking Rails.env.test? in Failsafe middleware, check env["rails.raise_exceptions"] [Bryan Helmkamp]
|
||||
|
||||
* Fixed that TestResponse.cookies was returning cookies unescaped #1867 [Doug McInnes]
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ task :default => [ :test ]
|
||||
# Run the unit tests
|
||||
|
||||
desc "Run all unit tests"
|
||||
task :test => [:test_action_pack, :test_active_record_integration, :test_new_base]
|
||||
task :test => [:test_action_pack, :test_active_record_integration]
|
||||
|
||||
Rake::TestTask.new(:test_action_pack) do |t|
|
||||
t.libs << "test"
|
||||
@@ -34,6 +34,12 @@ Rake::TestTask.new(:test_action_pack) do |t|
|
||||
t.verbose = true
|
||||
#t.warning = true
|
||||
end
|
||||
task :isolated_test do
|
||||
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
|
||||
Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file|
|
||||
system(ruby, '-Ilib:test', file)
|
||||
end or raise "Failures"
|
||||
end
|
||||
|
||||
desc 'ActiveRecord Integration Tests'
|
||||
Rake::TestTask.new(:test_active_record_integration) do |t|
|
||||
|
||||
34
actionpack/examples/minimal.rb
Normal file
34
actionpack/examples/minimal.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
||||
require 'action_controller'
|
||||
require 'action_controller/new_base' if ENV['NEW']
|
||||
require 'benchmark'
|
||||
|
||||
class BaseController < ActionController::Base
|
||||
def index
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
n = (ENV['N'] || 10000).to_i
|
||||
input = StringIO.new('')
|
||||
|
||||
def call_index(controller, input, n)
|
||||
n.times do
|
||||
controller.action(:index).call({ 'rack.input' => input })
|
||||
end
|
||||
|
||||
puts controller.name
|
||||
status, headers, body = controller.action(:index).call({ 'rack.input' => input })
|
||||
|
||||
puts status
|
||||
puts headers.to_yaml
|
||||
puts '---'
|
||||
body.each do |part|
|
||||
puts part
|
||||
end
|
||||
puts '---'
|
||||
end
|
||||
|
||||
elapsed = Benchmark.realtime { call_index BaseController, input, n }
|
||||
|
||||
puts "%dms elapsed, %d requests/sec" % [1000 * elapsed, n / elapsed]
|
||||
@@ -21,16 +21,9 @@
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
|
||||
begin
|
||||
require 'active_support'
|
||||
rescue LoadError
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
if File.directory?(activesupport_path)
|
||||
$:.unshift activesupport_path
|
||||
require 'active_support'
|
||||
end
|
||||
end
|
||||
require 'active_support/core/all'
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
$:.unshift activesupport_path if File.directory?(activesupport_path)
|
||||
require 'active_support'
|
||||
|
||||
require File.join(File.dirname(__FILE__), "action_pack")
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
require "active_support/core_ext/module/attr_internal"
|
||||
require "active_support/core_ext/module/delegation"
|
||||
|
||||
module AbstractController
|
||||
autoload :Base, "action_controller/abstract/base"
|
||||
autoload :Callbacks, "action_controller/abstract/callbacks"
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
require 'active_support/core_ext/module/attr_internal'
|
||||
|
||||
module AbstractController
|
||||
class Error < StandardError; end
|
||||
|
||||
class DoubleRenderError < Error
|
||||
DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
|
||||
|
||||
def initialize(message = nil)
|
||||
super(message || DEFAULT_MESSAGE)
|
||||
end
|
||||
end
|
||||
|
||||
class Base
|
||||
|
||||
attr_internal :response_body
|
||||
@@ -13,6 +25,15 @@ module AbstractController
|
||||
end
|
||||
|
||||
alias_method :abstract?, :abstract
|
||||
|
||||
def inherited(klass)
|
||||
::AbstractController::Base.subclasses << klass.to_s
|
||||
super
|
||||
end
|
||||
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
def internal_methods
|
||||
controller = self
|
||||
@@ -48,12 +69,13 @@ module AbstractController
|
||||
end
|
||||
|
||||
def process(action_name)
|
||||
unless respond_to_action?(action_name)
|
||||
@_action_name = action_name = action_name.to_s
|
||||
|
||||
unless action_name = method_for_action(action_name)
|
||||
raise ActionNotFound, "The action '#{action_name}' could not be found"
|
||||
end
|
||||
|
||||
@_action_name = action_name
|
||||
process_action
|
||||
|
||||
process_action(action_name)
|
||||
self
|
||||
end
|
||||
|
||||
@@ -63,23 +85,31 @@ module AbstractController
|
||||
self.class.action_methods
|
||||
end
|
||||
|
||||
def action_method?(action)
|
||||
action_methods.include?(action)
|
||||
end
|
||||
|
||||
# It is possible for respond_to?(action_name) to be false and
|
||||
# respond_to?(:action_missing) to be false if respond_to_action?
|
||||
# is overridden in a subclass. For instance, ActionController::Base
|
||||
# overrides it to include the case where a template matching the
|
||||
# action_name is found.
|
||||
def process_action
|
||||
if respond_to?(action_name) then send(action_name)
|
||||
elsif respond_to?(:action_missing, true) then action_missing(action_name)
|
||||
end
|
||||
def process_action(method_name)
|
||||
send(method_name)
|
||||
end
|
||||
|
||||
|
||||
def _handle_action_missing
|
||||
action_missing(@_action_name)
|
||||
end
|
||||
|
||||
# Override this to change the conditions that will raise an
|
||||
# ActionNotFound error. If you accept a difference case,
|
||||
# you must handle it by also overriding process_action and
|
||||
# handling the case.
|
||||
def respond_to_action?(action_name)
|
||||
action_methods.include?(action_name) || respond_to?(:action_missing, true)
|
||||
def method_for_action(action_name)
|
||||
if action_method?(action_name) then action_name
|
||||
elsif respond_to?(:action_missing, true) then "_handle_action_missing"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,11 +5,11 @@ module AbstractController
|
||||
depends_on ActiveSupport::NewCallbacks
|
||||
|
||||
included do
|
||||
define_callbacks :process_action
|
||||
define_callbacks :process_action, "response_body"
|
||||
end
|
||||
|
||||
def process_action
|
||||
_run_process_action_callbacks(action_name) do
|
||||
def process_action(method_name)
|
||||
_run_process_action_callbacks(method_name) do
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,7 +51,7 @@ module AbstractController
|
||||
end
|
||||
|
||||
def _render_template(template, options)
|
||||
_action_view._render_template_with_layout(template, options[:_layout], options)
|
||||
_action_view._render_template_from_controller(template, options[:_layout], options, options[:_partial])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,9 +1,44 @@
|
||||
require 'active_support/core_ext/class/attribute_accessors'
|
||||
|
||||
module AbstractController
|
||||
module Logger
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
class DelayedLog
|
||||
def initialize(&blk)
|
||||
@blk = blk
|
||||
end
|
||||
|
||||
def to_s
|
||||
@blk.call
|
||||
end
|
||||
alias to_str to_s
|
||||
end
|
||||
|
||||
included do
|
||||
cattr_accessor :logger
|
||||
end
|
||||
|
||||
def process(action)
|
||||
ret = super
|
||||
|
||||
if logger
|
||||
log = DelayedLog.new do
|
||||
"\n\nProcessing #{self.class.name}\##{action_name} " \
|
||||
"to #{request.formats} " \
|
||||
"(for #{request_origin}) [#{request.method.to_s.upcase}]"
|
||||
end
|
||||
|
||||
logger.info(log)
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
def request_origin
|
||||
# this *needs* to be cached!
|
||||
# otherwise you'd get different results if calling it more than once
|
||||
@request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
require "action_controller/abstract/logger"
|
||||
|
||||
module AbstractController
|
||||
class AbstractControllerError < StandardError; end
|
||||
class DoubleRenderError < AbstractControllerError
|
||||
DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
|
||||
|
||||
def initialize(message = nil)
|
||||
super(message || DEFAULT_MESSAGE)
|
||||
end
|
||||
end
|
||||
|
||||
module Renderer
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
@@ -27,12 +18,12 @@ module AbstractController
|
||||
@_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
|
||||
end
|
||||
|
||||
def render(options = {})
|
||||
def render(*args)
|
||||
if response_body
|
||||
raise AbstractController::DoubleRenderError, "OMG"
|
||||
end
|
||||
|
||||
self.response_body = render_to_body(options)
|
||||
self.response_body = render_to_body(*args)
|
||||
end
|
||||
|
||||
# Raw rendering of a template to a Rack-compatible body.
|
||||
@@ -43,10 +34,16 @@ module AbstractController
|
||||
# :api: plugin
|
||||
def render_to_body(options = {})
|
||||
name = options[:_template_name] || action_name
|
||||
|
||||
options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix])
|
||||
|
||||
_render_template(options[:_template], options)
|
||||
|
||||
# TODO: Refactor so we can just use the normal template logic for this
|
||||
if options[:_partial_object]
|
||||
_action_view._render_partial_from_controller(options)
|
||||
else
|
||||
options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats},
|
||||
options[:_prefix], options[:_partial])
|
||||
|
||||
_render_template(options[:_template], options)
|
||||
end
|
||||
end
|
||||
|
||||
# Raw rendering of a template to a string.
|
||||
@@ -60,7 +57,7 @@ module AbstractController
|
||||
end
|
||||
|
||||
def _render_template(template, options)
|
||||
_action_view._render_template_with_layout(template)
|
||||
_action_view._render_template_from_controller(template, nil, options, options[:_partial])
|
||||
end
|
||||
|
||||
def view_paths() _view_paths end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
require 'action_controller/deprecated'
|
||||
require 'set'
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
require 'active_support/core_ext/module/attr_internal'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
class ActionControllerError < StandardError #:nodoc:
|
||||
@@ -366,9 +368,8 @@ module ActionController #:nodoc:
|
||||
attr_reader :template
|
||||
|
||||
def action(name, env)
|
||||
# HACK: For global rescue to have access to the original request and response
|
||||
request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
|
||||
response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
|
||||
request = ActionDispatch::Request.new(env)
|
||||
response = ActionDispatch::Response.new
|
||||
self.action_name = name && name.to_s
|
||||
process(request, response).to_a
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'benchmark'
|
||||
require 'active_support/core_ext/benchmark'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
# The benchmarking module times the performance of actions and reports to the logger. If the Active Record
|
||||
|
||||
@@ -160,7 +160,7 @@ module ActionController #:nodoc:
|
||||
def convert_only_and_except_options_to_sets_of_strings(opts)
|
||||
[:only, :except].each do |key|
|
||||
if values = opts[key]
|
||||
opts[key] = Array(values).map(&:to_s).to_set
|
||||
opts[key] = Array(values).map {|val| val.to_s }.to_set
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -571,12 +571,7 @@ module ActionController #:nodoc:
|
||||
|
||||
# Returns an array of Filter objects for this controller.
|
||||
def filter_chain
|
||||
if chain = read_inheritable_attribute('filter_chain')
|
||||
return chain
|
||||
else
|
||||
write_inheritable_attribute('filter_chain', FilterChain.new)
|
||||
return filter_chain
|
||||
end
|
||||
read_inheritable_attribute('filter_chain') || write_inheritable_attribute('filter_chain', FilterChain.new)
|
||||
end
|
||||
|
||||
# Returns all the before filters for this class and all its ancestors.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/base64'
|
||||
|
||||
module ActionController
|
||||
module HttpAuthentication
|
||||
# Makes it dead easy to do HTTP Basic authentication.
|
||||
@@ -276,7 +278,7 @@ module ActionController
|
||||
t = time.to_i
|
||||
hashed = [t, secret_key]
|
||||
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
|
||||
Base64.encode64("#{t}:#{digest}").gsub("\n", '')
|
||||
ActiveSupport::Base64.encode64("#{t}:#{digest}").gsub("\n", '')
|
||||
end
|
||||
|
||||
# Might want a shorter timeout depending on whether the request
|
||||
@@ -285,7 +287,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)
|
||||
t = Base64.decode64(value).split(":").first.to_i
|
||||
t = ActiveSupport::Base64.decode64(value).split(":").first.to_i
|
||||
nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
require 'active_support/core_ext/enumerable'
|
||||
require 'active_support/core_ext/class/delegating_attributes'
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
module Layout #:nodoc:
|
||||
def self.included(base)
|
||||
|
||||
@@ -70,7 +70,9 @@ module ActionController
|
||||
def redirect_to_full_url(url, status)
|
||||
raise DoubleRenderError if performed?
|
||||
logger.info("Redirected to #{url}") if logger && logger.info?
|
||||
response.redirect(url, interpret_status(status))
|
||||
response.status = interpret_status(status)
|
||||
response.location = url.gsub(/[\r\n]/, '')
|
||||
response.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
|
||||
@performed_redirect = true
|
||||
end
|
||||
|
||||
|
||||
@@ -1,46 +1,11 @@
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module ActionController
|
||||
# Dispatches requests to the appropriate controller and takes care of
|
||||
# reloading the app after each request when Dependencies.load? is true.
|
||||
class Dispatcher
|
||||
class << self
|
||||
def define_dispatcher_callbacks(cache_classes)
|
||||
unless cache_classes
|
||||
# Development mode callbacks
|
||||
before_dispatch :reload_application
|
||||
after_dispatch :cleanup_application
|
||||
|
||||
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
|
||||
end
|
||||
|
||||
if defined?(ActiveRecord)
|
||||
to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
|
||||
end
|
||||
|
||||
after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
|
||||
|
||||
to_prepare do
|
||||
I18n.reload!
|
||||
end
|
||||
end
|
||||
|
||||
# Add a preparation callback. Preparation callbacks are run before every
|
||||
# request in development mode, and before the first request in production
|
||||
# mode.
|
||||
#
|
||||
# An optional identifier may be supplied for the callback. If provided,
|
||||
# to_prepare may be called again with the same identifier to replace the
|
||||
# existing callback. Passing an identifier is a suggested practice if the
|
||||
# code adding a preparation block may be reloaded.
|
||||
def to_prepare(identifier = nil, &block)
|
||||
@prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
|
||||
callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
|
||||
@prepare_dispatch_callbacks.replace_or_append!(callback)
|
||||
end
|
||||
|
||||
def run_prepare_callbacks
|
||||
new.send :run_callbacks, :prepare_dispatch
|
||||
end
|
||||
end
|
||||
cattr_accessor :prepare_each_request
|
||||
self.prepare_each_request = false
|
||||
|
||||
cattr_accessor :router
|
||||
self.router = Routing::Routes
|
||||
@@ -51,37 +16,50 @@ module ActionController
|
||||
middleware.instance_eval(File.read(middlewares), middlewares, 1)
|
||||
end
|
||||
|
||||
include ActiveSupport::Callbacks
|
||||
define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
|
||||
class << self
|
||||
def define_dispatcher_callbacks(cache_classes)
|
||||
unless cache_classes
|
||||
# Run prepare callbacks before every request in development mode
|
||||
self.prepare_each_request = true
|
||||
|
||||
def initialize
|
||||
@app = @@middleware.build(@@router)
|
||||
freeze
|
||||
end
|
||||
# Development mode callbacks
|
||||
ActionDispatch::Callbacks.before_dispatch do |app|
|
||||
ActionController::Dispatcher.router.reload
|
||||
end
|
||||
|
||||
def call(env)
|
||||
run_callbacks :before_dispatch
|
||||
@app.call(env)
|
||||
ensure
|
||||
run_callbacks :after_dispatch, :enumerator => :reverse_each
|
||||
end
|
||||
ActionDispatch::Callbacks.after_dispatch do
|
||||
# Cleanup the application before processing the current request.
|
||||
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
|
||||
ActiveSupport::Dependencies.clear
|
||||
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
|
||||
end
|
||||
|
||||
def reload_application
|
||||
# Run prepare callbacks before every request in development mode
|
||||
run_callbacks :prepare_dispatch
|
||||
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
|
||||
end
|
||||
|
||||
@@router.reload
|
||||
end
|
||||
if defined?(ActiveRecord)
|
||||
to_prepare(:activerecord_instantiate_observers) do
|
||||
ActiveRecord::Base.instantiate_observers
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_application
|
||||
# Cleanup the application before processing the current request.
|
||||
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
|
||||
ActiveSupport::Dependencies.clear
|
||||
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
|
||||
end
|
||||
if Base.logger && Base.logger.respond_to?(:flush)
|
||||
after_dispatch do
|
||||
Base.logger.flush
|
||||
end
|
||||
end
|
||||
|
||||
def flush_logger
|
||||
Base.logger.flush
|
||||
to_prepare do
|
||||
I18n.reload!
|
||||
end
|
||||
end
|
||||
|
||||
delegate :to_prepare, :prepare_dispatch, :before_dispatch, :after_dispatch,
|
||||
:to => ActionDispatch::Callbacks
|
||||
|
||||
def new
|
||||
@@middleware.build(@@router)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,10 +2,11 @@ use "Rack::Lock", :if => lambda {
|
||||
!ActionController::Base.allow_concurrency
|
||||
}
|
||||
|
||||
use "ActionDispatch::Failsafe"
|
||||
use "ActionDispatch::ShowExceptions", lambda { ActionController::Base.consider_all_requests_local }
|
||||
use "ActionDispatch::Callbacks", lambda { ActionController::Dispatcher.prepare_each_request }
|
||||
use "ActionDispatch::Rescue", lambda {
|
||||
controller = (::ApplicationController rescue ActionController::Base)
|
||||
# TODO: Replace with controller.action(:_rescue_action)
|
||||
controller.method(:rescue_action)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ module ActionController
|
||||
autoload :Http, "action_controller/new_base/http"
|
||||
autoload :Layouts, "action_controller/new_base/layouts"
|
||||
autoload :Rails2Compatibility, "action_controller/new_base/compatibility"
|
||||
autoload :Redirector, "action_controller/new_base/redirector"
|
||||
autoload :Renderer, "action_controller/new_base/renderer"
|
||||
autoload :Rescue, "action_controller/new_base/rescuable"
|
||||
autoload :Testing, "action_controller/new_base/testing"
|
||||
autoload :UrlFor, "action_controller/new_base/url_for"
|
||||
|
||||
|
||||
@@ -8,17 +8,44 @@ module ActionController
|
||||
|
||||
include ActionController::HideActions
|
||||
include ActionController::UrlFor
|
||||
include ActionController::Redirector
|
||||
include ActionController::Renderer
|
||||
include ActionController::Layouts
|
||||
include ActionController::ConditionalGet
|
||||
|
||||
|
||||
# Legacy modules
|
||||
include SessionManagement
|
||||
include ActionDispatch::StatusCodes
|
||||
|
||||
|
||||
# Rails 2.x compatibility
|
||||
include ActionController::Rails2Compatibility
|
||||
|
||||
|
||||
# TODO: Extract into its own module
|
||||
# This should be moved together with other normalizing behavior
|
||||
module ImplicitRender
|
||||
def process_action(method_name)
|
||||
ret = super
|
||||
render if response_body.nil?
|
||||
ret
|
||||
end
|
||||
|
||||
def _implicit_render
|
||||
render
|
||||
end
|
||||
|
||||
def method_for_action(action_name)
|
||||
super || begin
|
||||
if view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path)
|
||||
"_implicit_render"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include ImplicitRender
|
||||
|
||||
include ActionController::Rescue
|
||||
|
||||
def self.inherited(klass)
|
||||
::ActionController::Base.subclasses << klass.to_s
|
||||
super
|
||||
@@ -34,29 +61,83 @@ module ActionController
|
||||
end
|
||||
end
|
||||
|
||||
def render(action = action_name, options = {})
|
||||
def render_to_body(action = nil, options = {})
|
||||
if action.is_a?(Hash)
|
||||
options, action = action, nil
|
||||
else
|
||||
options.merge! :action => action
|
||||
elsif action.is_a?(String) || action.is_a?(Symbol)
|
||||
key = case action = action.to_s
|
||||
when %r{^/} then :file
|
||||
when %r{/} then :template
|
||||
else :action
|
||||
end
|
||||
options.merge! key => action
|
||||
elsif action
|
||||
options.merge! :partial => action
|
||||
end
|
||||
|
||||
super(options)
|
||||
if options.key?(:action) && options[:action].to_s.index("/")
|
||||
options[:template] = options.delete(:action)
|
||||
end
|
||||
|
||||
# options = {:template => options.to_s} if options.is_a?(String) || options.is_a?(Symbol)
|
||||
super(options) || " "
|
||||
end
|
||||
|
||||
def render_to_body(options = {})
|
||||
options = {:template => options} if options.is_a?(String)
|
||||
super
|
||||
end
|
||||
|
||||
def process_action
|
||||
ret = super
|
||||
render if response_body.nil?
|
||||
ret
|
||||
end
|
||||
|
||||
def respond_to_action?(action_name)
|
||||
super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path)
|
||||
# Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
|
||||
#
|
||||
# * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
|
||||
# * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
|
||||
# * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection.
|
||||
# * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
|
||||
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
|
||||
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
|
||||
#
|
||||
# Examples:
|
||||
# redirect_to :action => "show", :id => 5
|
||||
# redirect_to post
|
||||
# redirect_to "http://www.rubyonrails.org"
|
||||
# redirect_to "/images/screenshot.jpg"
|
||||
# redirect_to articles_url
|
||||
# redirect_to :back
|
||||
#
|
||||
# The redirection happens as a "302 Moved" header unless otherwise specified.
|
||||
#
|
||||
# Examples:
|
||||
# redirect_to post_url(@post), :status=>:found
|
||||
# redirect_to :action=>'atom', :status=>:moved_permanently
|
||||
# redirect_to post_url(@post), :status=>301
|
||||
# redirect_to :action=>'atom', :status=>302
|
||||
#
|
||||
# When using <tt>redirect_to :back</tt>, if there is no referrer,
|
||||
# RedirectBackError will be raised. You may specify some fallback
|
||||
# behavior for this case by rescuing RedirectBackError.
|
||||
def redirect_to(options = {}, response_status = {}) #:doc:
|
||||
raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
|
||||
|
||||
status = if options.is_a?(Hash) && options.key?(:status)
|
||||
interpret_status(options.delete(:status))
|
||||
elsif response_status.key?(:status)
|
||||
interpret_status(response_status[:status])
|
||||
else
|
||||
302
|
||||
end
|
||||
|
||||
url = case options
|
||||
# The scheme name consist of a letter followed by any combination of
|
||||
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
||||
# characters; and is terminated by a colon (":").
|
||||
when %r{^\w[\w\d+.-]*:.*}
|
||||
options
|
||||
when String
|
||||
request.protocol + request.host_with_port + options
|
||||
when :back
|
||||
raise RedirectBackError unless refer = request.headers["Referer"]
|
||||
refer
|
||||
else
|
||||
url_for(options)
|
||||
end
|
||||
|
||||
super(url, status)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,27 +8,51 @@ module ActionController
|
||||
::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError
|
||||
|
||||
cattr_accessor :session_options
|
||||
self.send(:class_variable_set, "@@session_options", {})
|
||||
self.session_options = {}
|
||||
|
||||
cattr_accessor :allow_concurrency
|
||||
self.send(:class_variable_set, "@@allow_concurrency", false)
|
||||
self.allow_concurrency = false
|
||||
|
||||
cattr_accessor :param_parsers
|
||||
self.send(:class_variable_set, "@@param_parsers", { Mime::MULTIPART_FORM => :multipart_form,
|
||||
Mime::URL_ENCODED_FORM => :url_encoded_form,
|
||||
Mime::XML => :xml_simple,
|
||||
Mime::JSON => :json })
|
||||
self.param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
|
||||
Mime::URL_ENCODED_FORM => :url_encoded_form,
|
||||
Mime::XML => :xml_simple,
|
||||
Mime::JSON => :json }
|
||||
|
||||
cattr_accessor :relative_url_root
|
||||
self.send(:class_variable_set, "@@relative_url_root", ENV['RAILS_RELATIVE_URL_ROOT'])
|
||||
self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
|
||||
|
||||
cattr_accessor :default_charset
|
||||
self.send(:class_variable_set, "@@default_charset", "utf-8")
|
||||
self.default_charset = "utf-8"
|
||||
|
||||
cattr_reader :protected_instance_variables
|
||||
self.send(:class_variable_set, "@@protected_instance_variables", %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
|
||||
# cattr_reader :protected_instance_variables
|
||||
cattr_accessor :protected_instance_variables
|
||||
self.protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
|
||||
@action_name @before_filter_chain_aborted @action_cache_path @_headers @_params
|
||||
@_flash @_response))
|
||||
@_flash @_response)
|
||||
|
||||
# Indicates whether or not optimise the generated named
|
||||
# route helper methods
|
||||
cattr_accessor :optimise_named_routes
|
||||
self.optimise_named_routes = true
|
||||
|
||||
cattr_accessor :resources_path_names
|
||||
self.resources_path_names = { :new => 'new', :edit => 'edit' }
|
||||
|
||||
# Controls the resource action separator
|
||||
cattr_accessor :resource_action_separator
|
||||
self.resource_action_separator = "/"
|
||||
|
||||
cattr_accessor :use_accept_header
|
||||
self.use_accept_header = true
|
||||
|
||||
cattr_accessor :page_cache_directory
|
||||
self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
|
||||
|
||||
cattr_reader :cache_store
|
||||
|
||||
cattr_accessor :consider_all_requests_local
|
||||
self.consider_all_requests_local = true
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
@@ -37,8 +61,18 @@ module ActionController
|
||||
def rescue_action(env)
|
||||
raise env["action_dispatch.rescue.exception"]
|
||||
end
|
||||
|
||||
# Defines the storage option for cached fragments
|
||||
def cache_store=(store_option)
|
||||
@@cache_store = ActiveSupport::Cache.lookup_store(store_option)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def initialize(*)
|
||||
super
|
||||
@template = _action_view
|
||||
end
|
||||
|
||||
def render_to_body(options)
|
||||
if options.is_a?(Hash) && options.key?(:template)
|
||||
options[:template].sub!(/^\//, '')
|
||||
@@ -48,6 +82,14 @@ module ActionController
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def _handle_method_missing
|
||||
method_missing(@_action_name.to_sym)
|
||||
end
|
||||
|
||||
def method_for_action(action_name)
|
||||
super || (respond_to?(:method_missing) && "_handle_method_missing")
|
||||
end
|
||||
|
||||
def _layout_for_name(name)
|
||||
name &&= name.sub(%r{^/?layouts/}, '')
|
||||
|
||||
@@ -12,8 +12,8 @@ module ActionController
|
||||
|
||||
private
|
||||
|
||||
def respond_to_action?(action_name)
|
||||
!hidden_actions.include?(action_name) && (super || respond_to?(:method_missing))
|
||||
def action_method?(action_name)
|
||||
!hidden_actions.include?(action_name) && super
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
require 'action_controller/abstract'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module ActionController
|
||||
class Http < AbstractController::Base
|
||||
abstract!
|
||||
@@ -21,11 +24,6 @@ module ActionController
|
||||
# :api: public
|
||||
def controller_path() self.class.controller_path end
|
||||
|
||||
# :api: private
|
||||
def self.internal_methods
|
||||
ActionController::Http.public_instance_methods(true)
|
||||
end
|
||||
|
||||
# :api: private
|
||||
def self.action_names() action_methods end
|
||||
|
||||
@@ -38,26 +36,32 @@ module ActionController
|
||||
controller.call(env).to_rack
|
||||
end
|
||||
|
||||
delegate :headers, :to => "@_response"
|
||||
|
||||
def params
|
||||
@_params ||= @_request.parameters
|
||||
end
|
||||
|
||||
# :api: private
|
||||
def call(name, env)
|
||||
@_request = ActionDispatch::Request.new(env)
|
||||
@_response = ActionDispatch::Response.new
|
||||
@_response.request = request
|
||||
process(name)
|
||||
@_response.body = response_body
|
||||
@_response.prepare!
|
||||
to_rack
|
||||
end
|
||||
|
||||
def self.action(name)
|
||||
@actions ||= {}
|
||||
@actions[name] ||= proc do |env|
|
||||
@actions[name.to_s] ||= proc do |env|
|
||||
new.call(name, env)
|
||||
end
|
||||
end
|
||||
|
||||
# :api: private
|
||||
def to_rack
|
||||
@_response.body = response_body
|
||||
@_response.prepare!
|
||||
@_response.to_a
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ module ActionController
|
||||
# render :text => ..., :layout => ...
|
||||
# or
|
||||
# render :anything_else
|
||||
if (!options.key?(:text) && !options.key?(:inline)) || options.key?(:layout)
|
||||
if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout)
|
||||
options[:_layout] = options.key?(:layout) ? _layout_for_option(options[:layout]) : _default_layout
|
||||
end
|
||||
|
||||
|
||||
19
actionpack/lib/action_controller/new_base/redirector.rb
Normal file
19
actionpack/lib/action_controller/new_base/redirector.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
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 Redirector
|
||||
def redirect_to(url, status) #:doc:
|
||||
raise AbstractController::DoubleRenderError if response_body
|
||||
logger.info("Redirected to #{url}") if logger && logger.info?
|
||||
response.status = status
|
||||
response.location = url.gsub(/[\r\n]/, '')
|
||||
self.response_body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,13 +9,9 @@ module ActionController
|
||||
super
|
||||
end
|
||||
|
||||
def render(options = {})
|
||||
def render_to_body(options)
|
||||
_process_options(options)
|
||||
|
||||
super(options)
|
||||
end
|
||||
|
||||
def render_to_body(options)
|
||||
if options.key?(:text)
|
||||
options[:_template] = ActionView::TextTemplate.new(_text(options))
|
||||
template = nil
|
||||
@@ -25,12 +21,18 @@ module ActionController
|
||||
options[:_template] = template
|
||||
elsif options.key?(:template)
|
||||
options[:_template_name] = options[:template]
|
||||
elsif options.key?(:file)
|
||||
options[:_template_name] = options[:file]
|
||||
elsif options.key?(:partial)
|
||||
_render_partial(options[:partial], options)
|
||||
else
|
||||
options[:_template_name] = (options[:action] || action_name).to_s
|
||||
options[:_prefix] = _prefix
|
||||
end
|
||||
|
||||
ret = super(options)
|
||||
|
||||
options[:_template] ||= _action_view._partial
|
||||
response.content_type ||= options[:_template].mime_type
|
||||
ret
|
||||
end
|
||||
@@ -49,6 +51,21 @@ module ActionController
|
||||
else text.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def _render_partial(partial, options)
|
||||
case partial
|
||||
when true
|
||||
options[:_prefix] = _prefix
|
||||
when String
|
||||
options[:_prefix] = _prefix unless partial.index('/')
|
||||
options[:_template_name] = partial
|
||||
else
|
||||
options[:_partial_object] = true
|
||||
return
|
||||
end
|
||||
|
||||
options[:_partial] = options[:object] || true
|
||||
end
|
||||
|
||||
def _process_options(options)
|
||||
status, content_type = options.values_at(:status, :content_type)
|
||||
|
||||
53
actionpack/lib/action_controller/new_base/rescuable.rb
Normal file
53
actionpack/lib/action_controller/new_base/rescuable.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
module ActionController #:nodoc:
|
||||
# Actions that fail to perform as expected throw exceptions. These
|
||||
# exceptions can either be rescued for the public view (with a nice
|
||||
# user-friendly explanation) or for the developers view (with tons of
|
||||
# debugging information). The developers view is already implemented by
|
||||
# the Action Controller, but the public view should be tailored to your
|
||||
# specific application.
|
||||
#
|
||||
# The default behavior for public exceptions is to render a static html
|
||||
# file with the name of the error code thrown. If no such file exists, an
|
||||
# empty response is sent with the correct status code.
|
||||
#
|
||||
# You can override what constitutes a local request by overriding the
|
||||
# <tt>local_request?</tt> method in your own controller. Custom rescue
|
||||
# behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
|
||||
# and <tt>rescue_action_locally</tt> methods.
|
||||
module Rescue
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
included do
|
||||
include ActiveSupport::Rescuable
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# This can be removed once we can move action(:_rescue_action) into middlewares.rb
|
||||
# Currently, it does controller.method(:rescue_action), which is hiding the implementation
|
||||
# difference between the old and new base.
|
||||
def rescue_action(env)
|
||||
action(:_rescue_action).call(env)
|
||||
end
|
||||
end
|
||||
|
||||
attr_internal :rescued_exception
|
||||
|
||||
private
|
||||
|
||||
def method_for_action(action_name)
|
||||
return action_name if self.rescued_exception = request.env.delete("action_dispatch.rescue.exception")
|
||||
super
|
||||
end
|
||||
|
||||
def _rescue_action
|
||||
rescue_with_handler(rescued_exception) || raise(rescued_exception)
|
||||
end
|
||||
|
||||
def process_action(*)
|
||||
super
|
||||
rescue Exception => exception
|
||||
self.rescued_exception = exception
|
||||
_rescue_action
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,7 +7,7 @@ module ActionController
|
||||
@_response = response
|
||||
@_response.request = request
|
||||
ret = process(request.parameters[:action])
|
||||
@_response.body = self.response_body
|
||||
@_response.body = self.response_body || " "
|
||||
@_response.prepare!
|
||||
set_test_assigns
|
||||
ret
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/module'
|
||||
|
||||
module ActionController
|
||||
# The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or
|
||||
# Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
require 'cgi'
|
||||
require 'uri'
|
||||
require 'set'
|
||||
|
||||
require 'active_support/core_ext/module/aliasing'
|
||||
require 'active_support/core_ext/module/attribute_accessors'
|
||||
require 'action_controller/routing/optimisations'
|
||||
require 'action_controller/routing/routing_ext'
|
||||
require 'action_controller/routing/route'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/hash/except'
|
||||
|
||||
module ActionController
|
||||
module Routing
|
||||
class RouteBuilder #:nodoc:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/object/misc'
|
||||
|
||||
module ActionController
|
||||
module Routing
|
||||
class Route #:nodoc:
|
||||
@@ -65,7 +67,7 @@ module ActionController
|
||||
# map.connect '/page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
|
||||
#
|
||||
def parameter_shell
|
||||
@parameter_shell ||= returning({}) do |shell|
|
||||
@parameter_shell ||= {}.tap do |shell|
|
||||
requirements.each do |key, requirement|
|
||||
shell[key] = requirement unless requirement.is_a? Regexp
|
||||
end
|
||||
@@ -76,7 +78,7 @@ module ActionController
|
||||
# includes keys that appear inside the path, and keys that have requirements
|
||||
# placed upon them.
|
||||
def significant_keys
|
||||
@significant_keys ||= returning([]) do |sk|
|
||||
@significant_keys ||= [].tap do |sk|
|
||||
segments.each { |segment| sk << segment.key if segment.respond_to? :key }
|
||||
sk.concat requirements.keys
|
||||
sk.uniq!
|
||||
@@ -86,7 +88,7 @@ module ActionController
|
||||
# Return a hash of key/value pairs representing the keys in the route that
|
||||
# have defaults, or which are specified by non-regexp requirements.
|
||||
def defaults
|
||||
@defaults ||= returning({}) do |hash|
|
||||
@defaults ||= {}.tap do |hash|
|
||||
segments.each do |segment|
|
||||
next unless segment.respond_to? :default
|
||||
hash[segment.key] = segment.default unless segment.default.nil?
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'rack/session/abstract/id'
|
||||
require 'active_support/core_ext/object/conversions'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
class TestRequest < ActionDispatch::TestRequest #:nodoc:
|
||||
@@ -131,9 +132,6 @@ module ActionController #:nodoc:
|
||||
@request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
|
||||
build_request_uri(action, parameters)
|
||||
|
||||
@request.env["action_controller.rescue.request"] = @request
|
||||
@request.env["action_controller.rescue.response"] = @response
|
||||
|
||||
Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
|
||||
|
||||
env = @request.env
|
||||
@@ -161,11 +159,13 @@ module ActionController #:nodoc:
|
||||
alias xhr :xml_http_request
|
||||
|
||||
def assigns(key = nil)
|
||||
if key.nil?
|
||||
@controller.template.assigns
|
||||
else
|
||||
@controller.template.assigns[key.to_s]
|
||||
assigns = {}
|
||||
@controller.instance_variable_names.each do |ivar|
|
||||
next if ActionController::Base.protected_instance_variables.include?(ivar)
|
||||
assigns[ivar[1..-1]] = @controller.instance_variable_get(ivar)
|
||||
end
|
||||
|
||||
key.nil? ? assigns : assigns[key.to_s]
|
||||
end
|
||||
|
||||
def session
|
||||
|
||||
@@ -50,6 +50,7 @@ module ActionController
|
||||
@request.session = ActionController::TestSession.new(session) unless session.nil?
|
||||
@request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
|
||||
build_request_uri(action, parameters)
|
||||
@controller.request = @request
|
||||
@controller.params.merge!(parameters)
|
||||
# Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
|
||||
@controller.process_with_test(@request, @response)
|
||||
|
||||
@@ -73,7 +73,7 @@ module HTML
|
||||
|
||||
# Specifies the default Set of tags that the #sanitize helper will allow unscathed.
|
||||
self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var sub
|
||||
sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dt dd abbr
|
||||
sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr
|
||||
acronym a img blockquote del ins))
|
||||
|
||||
# Specifies the default Set of html attributes that the #sanitize helper will leave
|
||||
|
||||
@@ -21,16 +21,9 @@
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
|
||||
begin
|
||||
require 'active_support'
|
||||
rescue LoadError
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
if File.directory?(activesupport_path)
|
||||
$:.unshift activesupport_path
|
||||
require 'active_support'
|
||||
end
|
||||
end
|
||||
require 'active_support/core/all'
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
$:.unshift activesupport_path if File.directory?(activesupport_path)
|
||||
require 'active_support'
|
||||
|
||||
begin
|
||||
gem 'rack', '~> 1.1.pre'
|
||||
@@ -45,7 +38,7 @@ module ActionDispatch
|
||||
autoload :Response, 'action_dispatch/http/response'
|
||||
autoload :StatusCodes, 'action_dispatch/http/status_codes'
|
||||
|
||||
autoload :Failsafe, 'action_dispatch/middleware/failsafe'
|
||||
autoload :Callbacks, 'action_dispatch/middleware/callbacks'
|
||||
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
|
||||
autoload :Rescue, 'action_dispatch/middleware/rescue'
|
||||
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'set'
|
||||
require 'active_support/core_ext/class/attribute_accessors'
|
||||
|
||||
module Mime
|
||||
SET = []
|
||||
|
||||
@@ -3,6 +3,7 @@ require 'stringio'
|
||||
require 'strscan'
|
||||
|
||||
require 'active_support/memoizable'
|
||||
require 'active_support/core_ext/hash/indifferent_access'
|
||||
|
||||
module ActionDispatch
|
||||
class Request < Rack::Request
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'digest/md5'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module ActionDispatch # :nodoc:
|
||||
# Represents an HTTP response generated by a controller action. One can use
|
||||
@@ -156,12 +157,6 @@ module ActionDispatch # :nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
def redirect(url, status)
|
||||
self.status = status
|
||||
self.location = url.gsub(/[\r\n]/, '')
|
||||
self.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
|
||||
end
|
||||
|
||||
def sending_file?
|
||||
headers["Content-Transfer-Encoding"] == "binary"
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/inflector'
|
||||
|
||||
module ActionDispatch
|
||||
module StatusCodes #:nodoc:
|
||||
STATUS_CODES = Rack::Utils::HTTP_STATUS_CODES.merge({
|
||||
@@ -16,7 +18,7 @@ module ActionDispatch
|
||||
# :created or :not_implemented) into its corresponding HTTP status
|
||||
# code (like 200 or 501).
|
||||
SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) { |hash, (code, message)|
|
||||
hash[message.gsub(/ /, "").underscore.to_sym] = code
|
||||
hash[ActiveSupport::Inflector.underscore(message.gsub(/ /, "")).to_sym] = code
|
||||
hash
|
||||
}.freeze
|
||||
|
||||
@@ -37,4 +39,4 @@ module ActionDispatch
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
40
actionpack/lib/action_dispatch/middleware/callbacks.rb
Normal file
40
actionpack/lib/action_dispatch/middleware/callbacks.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
module ActionDispatch
|
||||
class Callbacks
|
||||
include ActiveSupport::Callbacks
|
||||
define_callbacks :prepare, :before, :after
|
||||
|
||||
class << self
|
||||
# DEPRECATED
|
||||
alias_method :prepare_dispatch, :prepare
|
||||
alias_method :before_dispatch, :before
|
||||
alias_method :after_dispatch, :after
|
||||
end
|
||||
|
||||
# Add a preparation callback. Preparation callbacks are run before every
|
||||
# request in development mode, and before the first request in production
|
||||
# mode.
|
||||
#
|
||||
# An optional identifier may be supplied for the callback. If provided,
|
||||
# to_prepare may be called again with the same identifier to replace the
|
||||
# existing callback. Passing an identifier is a suggested practice if the
|
||||
# code adding a preparation block may be reloaded.
|
||||
def self.to_prepare(identifier = nil, &block)
|
||||
@prepare_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
|
||||
callback = ActiveSupport::Callbacks::Callback.new(:prepare, block, :identifier => identifier)
|
||||
@prepare_callbacks.replace_or_append!(callback)
|
||||
end
|
||||
|
||||
def initialize(app, prepare_each_request = false)
|
||||
@app, @prepare_each_request = app, prepare_each_request
|
||||
run_callbacks :prepare
|
||||
end
|
||||
|
||||
def call(env)
|
||||
run_callbacks :before
|
||||
run_callbacks :prepare if @prepare_each_request
|
||||
@app.call(env)
|
||||
ensure
|
||||
run_callbacks :after, :enumerator => :reverse_each
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,52 +0,0 @@
|
||||
module ActionDispatch
|
||||
class Failsafe
|
||||
cattr_accessor :error_file_path
|
||||
self.error_file_path = Rails.public_path if defined?(Rails.public_path)
|
||||
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@app.call(env)
|
||||
rescue Exception => exception
|
||||
# Reraise exception in test environment
|
||||
if defined?(Rails) && Rails.env.test?
|
||||
raise exception
|
||||
else
|
||||
failsafe_response(exception)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def failsafe_response(exception)
|
||||
log_failsafe_exception(exception)
|
||||
[500, {'Content-Type' => 'text/html'}, failsafe_response_body]
|
||||
rescue Exception => failsafe_error # Logger or IO errors
|
||||
$stderr.puts "Error during failsafe response: #{failsafe_error}"
|
||||
end
|
||||
|
||||
def failsafe_response_body
|
||||
error_path = "#{self.class.error_file_path}/500.html"
|
||||
if File.exist?(error_path)
|
||||
[File.read(error_path)]
|
||||
else
|
||||
["<html><body><h1>500 Internal Server Error</h1></body></html>"]
|
||||
end
|
||||
end
|
||||
|
||||
def log_failsafe_exception(exception)
|
||||
message = "/!\\ FAILSAFE /!\\ #{Time.now}\n Status: 500 Internal Server Error\n"
|
||||
message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception
|
||||
failsafe_logger.fatal(message)
|
||||
end
|
||||
|
||||
def failsafe_logger
|
||||
if defined?(Rails) && Rails.logger
|
||||
Rails.logger
|
||||
else
|
||||
Logger.new($stderr)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -32,16 +32,14 @@ module ActionDispatch
|
||||
when Proc
|
||||
strategy.call(request.raw_post)
|
||||
when :xml_simple, :xml_node
|
||||
body = request.raw_post
|
||||
body.blank? ? {} : Hash.from_xml(body).with_indifferent_access
|
||||
request.body.size == 0 ? {} : Hash.from_xml(request.body).with_indifferent_access
|
||||
when :yaml
|
||||
YAML.load(request.raw_post)
|
||||
YAML.load(request.body)
|
||||
when :json
|
||||
body = request.raw_post
|
||||
if body.blank?
|
||||
if request.body.size == 0
|
||||
{}
|
||||
else
|
||||
data = ActiveSupport::JSON.decode(body)
|
||||
data = ActiveSupport::JSON.decode(request.body)
|
||||
data = {:_json => data} unless data.is_a?(Hash)
|
||||
data.with_indifferent_access
|
||||
end
|
||||
|
||||
@@ -4,8 +4,11 @@ module ActionDispatch
|
||||
|
||||
LOCALHOST = '127.0.0.1'.freeze
|
||||
|
||||
DEFAULT_RESCUE_RESPONSE = :internal_server_error
|
||||
DEFAULT_RESCUE_RESPONSES = {
|
||||
RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
|
||||
|
||||
cattr_accessor :rescue_responses
|
||||
@@rescue_responses = Hash.new(:internal_server_error)
|
||||
@@rescue_responses.update({
|
||||
'ActionController::RoutingError' => :not_found,
|
||||
'ActionController::UnknownAction' => :not_found,
|
||||
'ActiveRecord::RecordNotFound' => :not_found,
|
||||
@@ -15,25 +18,19 @@ module ActionDispatch
|
||||
'ActionController::MethodNotAllowed' => :method_not_allowed,
|
||||
'ActionController::NotImplemented' => :not_implemented,
|
||||
'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
|
||||
}
|
||||
})
|
||||
|
||||
DEFAULT_RESCUE_TEMPLATE = 'diagnostics'
|
||||
DEFAULT_RESCUE_TEMPLATES = {
|
||||
cattr_accessor :rescue_templates
|
||||
@@rescue_templates = Hash.new('diagnostics')
|
||||
@@rescue_templates.update({
|
||||
'ActionView::MissingTemplate' => 'missing_template',
|
||||
'ActionController::RoutingError' => 'routing_error',
|
||||
'ActionController::UnknownAction' => 'unknown_action',
|
||||
'ActionView::TemplateError' => 'template_error'
|
||||
}
|
||||
})
|
||||
|
||||
RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
|
||||
|
||||
cattr_accessor :rescue_responses
|
||||
@@rescue_responses = Hash.new(DEFAULT_RESCUE_RESPONSE)
|
||||
@@rescue_responses.update DEFAULT_RESCUE_RESPONSES
|
||||
|
||||
cattr_accessor :rescue_templates
|
||||
@@rescue_templates = Hash.new(DEFAULT_RESCUE_TEMPLATE)
|
||||
@@rescue_templates.update DEFAULT_RESCUE_TEMPLATES
|
||||
FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'},
|
||||
['<html><body><h1>500 Internal Server Error</h1></body></html>']]
|
||||
|
||||
def initialize(app, consider_all_requests_local = false)
|
||||
@app = app
|
||||
@@ -43,34 +40,35 @@ module ActionDispatch
|
||||
def call(env)
|
||||
@app.call(env)
|
||||
rescue Exception => exception
|
||||
raise exception if env['rack.test']
|
||||
|
||||
log_error(exception) if logger
|
||||
|
||||
request = Request.new(env)
|
||||
if @consider_all_requests_local || local_request?(request)
|
||||
rescue_action_locally(request, exception)
|
||||
else
|
||||
rescue_action_in_public(exception)
|
||||
end
|
||||
raise exception if env['action_dispatch.show_exceptions'] == false
|
||||
render_exception(env, exception)
|
||||
end
|
||||
|
||||
private
|
||||
def render_exception(env, exception)
|
||||
log_error(exception)
|
||||
|
||||
request = Request.new(env)
|
||||
if @consider_all_requests_local || local_request?(request)
|
||||
rescue_action_locally(request, exception)
|
||||
else
|
||||
rescue_action_in_public(exception)
|
||||
end
|
||||
rescue Exception => failsafe_error
|
||||
$stderr.puts "Error during failsafe response: #{failsafe_error}"
|
||||
FAILSAFE_RESPONSE
|
||||
end
|
||||
|
||||
# Render detailed diagnostics for unhandled exceptions rescued from
|
||||
# a controller action.
|
||||
def rescue_action_locally(request, exception)
|
||||
template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
|
||||
:template => template,
|
||||
:request => request,
|
||||
:exception => exception
|
||||
)
|
||||
file = "rescues/#{@@rescue_templates[exception.class.name]}.erb"
|
||||
body = template.render(:file => file, :layout => 'rescues/layout.erb')
|
||||
|
||||
headers = {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}
|
||||
status = status_code(exception)
|
||||
|
||||
[status, headers, body]
|
||||
render(status_code(exception), body)
|
||||
end
|
||||
|
||||
# Attempts to render a static error page based on the
|
||||
@@ -86,11 +84,11 @@ module ActionDispatch
|
||||
path = "#{public_path}/#{status}.html"
|
||||
|
||||
if locale_path && File.exist?(locale_path)
|
||||
render_public_file(status, locale_path)
|
||||
render(status, File.read(locale_path))
|
||||
elsif File.exist?(path)
|
||||
render_public_file(status, path)
|
||||
render(status, File.read(path))
|
||||
else
|
||||
[status, {'Content-Type' => 'text/html', 'Content-Length' => '0'}, []]
|
||||
render(status, '')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -99,24 +97,21 @@ module ActionDispatch
|
||||
request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
|
||||
end
|
||||
|
||||
def render_public_file(status, path)
|
||||
body = File.read(path)
|
||||
[status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, body]
|
||||
end
|
||||
|
||||
def status_code(exception)
|
||||
interpret_status(@@rescue_responses[exception.class.name]).to_i
|
||||
end
|
||||
|
||||
def public_path
|
||||
if defined?(Rails)
|
||||
Rails.public_path
|
||||
else
|
||||
"public"
|
||||
end
|
||||
def render(status, body)
|
||||
[status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, body]
|
||||
end
|
||||
|
||||
def log_error(exception) #:doc:
|
||||
def public_path
|
||||
defined?(Rails.public_path) ? Rails.public_path : 'public_path'
|
||||
end
|
||||
|
||||
def log_error(exception)
|
||||
return unless logger
|
||||
|
||||
ActiveSupport::Deprecation.silence do
|
||||
if ActionView::TemplateError === exception
|
||||
logger.fatal(exception.to_s)
|
||||
@@ -136,9 +131,7 @@ module ActionDispatch
|
||||
end
|
||||
|
||||
def logger
|
||||
if defined?(Rails.logger)
|
||||
Rails.logger
|
||||
end
|
||||
defined?(Rails.logger) ? Rails.logger : Logger.new($stderr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,16 +21,10 @@
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
|
||||
begin
|
||||
require 'active_support'
|
||||
rescue LoadError
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
if File.directory?(activesupport_path)
|
||||
$:.unshift activesupport_path
|
||||
require 'active_support'
|
||||
end
|
||||
end
|
||||
require 'active_support/core/all'
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
$:.unshift activesupport_path if File.directory?(activesupport_path)
|
||||
require 'active_support'
|
||||
require 'active_support/core_ext/class/attribute_accessors'
|
||||
|
||||
require File.join(File.dirname(__FILE__), "action_pack")
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
require 'active_support/core_ext/module/attr_internal'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module ActionView #:nodoc:
|
||||
class ActionViewError < StandardError #:nodoc:
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@ require 'cgi'
|
||||
require 'action_view/helpers/date_helper'
|
||||
require 'action_view/helpers/tag_helper'
|
||||
require 'action_view/helpers/form_tag_helper'
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
|
||||
module ActionView
|
||||
module Helpers
|
||||
@@ -1039,8 +1040,8 @@ module ActionView
|
||||
end
|
||||
end
|
||||
|
||||
class Base
|
||||
cattr_accessor :default_form_builder
|
||||
self.default_form_builder = ::ActionView::Helpers::FormBuilder
|
||||
class << Base
|
||||
attr_accessor :default_form_builder
|
||||
end
|
||||
end
|
||||
Base.default_form_builder = ::ActionView::Helpers::FormBuilder
|
||||
end
|
||||
|
||||
@@ -230,6 +230,8 @@ module ActionView
|
||||
#
|
||||
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
|
||||
def options_for_select(container, selected = nil)
|
||||
return container if String === container
|
||||
|
||||
container = container.to_a if Hash === container
|
||||
selected, disabled = extract_selected_and_disabled(selected)
|
||||
|
||||
|
||||
@@ -248,6 +248,11 @@ module ActionView
|
||||
# number_to_human_size(483989, :precision => 0) # => 473 KB
|
||||
# number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,18 MB
|
||||
#
|
||||
# Zeros after the decimal point are always stripped out, regardless of the
|
||||
# specified precision:
|
||||
# helper.number_to_human_size(1234567890123, :precision => 5) # => "1.12283 TB"
|
||||
# helper.number_to_human_size(524288000, :precision=>5) # => "500 MB"
|
||||
#
|
||||
# You can still use <tt>number_to_human_size</tt> with the old API that accepts the
|
||||
# +precision+ as its optional second parameter:
|
||||
# number_to_human_size(1234567, 2) # => 1.18 MB
|
||||
@@ -293,7 +298,7 @@ module ActionView
|
||||
:precision => precision,
|
||||
:separator => separator,
|
||||
:delimiter => delimiter
|
||||
).sub(/(\d)(#{escaped_separator}[1-9]*)?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
|
||||
).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
|
||||
storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
|
||||
rescue
|
||||
number
|
||||
|
||||
@@ -9,7 +9,7 @@ module ActionView
|
||||
include ERB::Util
|
||||
|
||||
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked).to_set
|
||||
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym))
|
||||
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attr| attr.to_sym })
|
||||
|
||||
# Returns an empty HTML tag of type +name+ which by default is XHTML
|
||||
# compliant. Set +open+ to true to create an open tag compatible
|
||||
|
||||
@@ -535,7 +535,7 @@ module ActionView
|
||||
link_attributes = html_options.stringify_keys
|
||||
text.gsub(AUTO_LINK_RE) do
|
||||
href = $&
|
||||
punctuation = ''
|
||||
punctuation = []
|
||||
left, right = $`, $'
|
||||
# detect already linked URLs and URLs in the middle of a tag
|
||||
if left =~ /<[^>]+$/ && right =~ /^[^>]*>/
|
||||
@@ -543,17 +543,18 @@ module ActionView
|
||||
href
|
||||
else
|
||||
# don't include trailing punctuation character as part of the URL
|
||||
if href.sub!(/[^\w\/-]$/, '') and punctuation = $& and opening = BRACKETS[punctuation]
|
||||
if href.scan(opening).size > href.scan(punctuation).size
|
||||
href << punctuation
|
||||
punctuation = ''
|
||||
while href.sub!(/[^\w\/-]$/, '')
|
||||
punctuation.push $&
|
||||
if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
|
||||
href << punctuation.pop
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
link_text = block_given?? yield(href) : href
|
||||
href = 'http://' + href unless href.index('http') == 0
|
||||
|
||||
content_tag(:a, h(link_text), link_attributes.merge('href' => href)) + punctuation
|
||||
content_tag(:a, h(link_text), link_attributes.merge('href' => href)) + punctuation.reverse.join('')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -171,11 +171,21 @@ module ActionView
|
||||
# <% end %>
|
||||
module Partials
|
||||
extend ActiveSupport::Memoizable
|
||||
extend ActiveSupport::DependencyModule
|
||||
|
||||
included do
|
||||
attr_accessor :_partial
|
||||
end
|
||||
|
||||
def _render_partial_from_controller(*args)
|
||||
@assigns_added = false
|
||||
_render_partial(*args)
|
||||
end
|
||||
|
||||
def _render_partial(options = {}) #:nodoc:
|
||||
options[:locals] ||= {}
|
||||
|
||||
case path = partial = options[:partial]
|
||||
case path = partial = options[:partial]
|
||||
when *_array_like_objects
|
||||
return _render_partial_collection(partial, options)
|
||||
else
|
||||
@@ -222,16 +232,7 @@ module ActionView
|
||||
ensure
|
||||
@_proc_for_layout = nil
|
||||
end
|
||||
|
||||
def _render_partial_with_layout(layout, options)
|
||||
if layout
|
||||
prefix = controller && !layout.include?("/") ? controller.controller_path : nil
|
||||
layout = find_by_parts(layout, {:formats => formats}, prefix, true)
|
||||
end
|
||||
content = _render_partial(options)
|
||||
return _render_content_with_layout(content, layout, options[:locals])
|
||||
end
|
||||
|
||||
|
||||
def _deprecated_ivar_assign(template)
|
||||
if respond_to?(:controller)
|
||||
ivar = :"@#{template.variable_name}"
|
||||
@@ -287,13 +288,17 @@ module ActionView
|
||||
locals = (options[:locals] ||= {})
|
||||
object ||= locals[:object] || locals[template.variable_name]
|
||||
|
||||
_set_locals(object, locals, template, options)
|
||||
_set_locals(object, locals, template, options)
|
||||
|
||||
self._partial = template
|
||||
|
||||
_render_template(template, locals)
|
||||
end
|
||||
end
|
||||
|
||||
def _set_locals(object, locals, template, options)
|
||||
object ||= _deprecated_ivar_assign(template)
|
||||
|
||||
locals[:object] = locals[template.variable_name] = object
|
||||
locals[options[:as]] = object if options[:as]
|
||||
end
|
||||
@@ -316,6 +321,9 @@ module ActionView
|
||||
locals[template.counter_name] = index
|
||||
|
||||
index += 1
|
||||
|
||||
self._partial = template
|
||||
|
||||
_render_template(template, locals)
|
||||
end.join(spacer)
|
||||
end
|
||||
|
||||
@@ -95,6 +95,11 @@ module ActionView
|
||||
layout ? _render_content_with_layout(text, layout, options[:locals]) : text
|
||||
end
|
||||
|
||||
def _render_template_from_controller(*args)
|
||||
@assigns_added = nil
|
||||
_render_template_with_layout(*args)
|
||||
end
|
||||
|
||||
def _render_template_with_layout(template, layout = nil, options = {}, partial = false)
|
||||
if controller && logger
|
||||
logger.info("Rendering #{template.identifier}" +
|
||||
|
||||
@@ -33,7 +33,7 @@ module ActionView #:nodoc:
|
||||
end
|
||||
|
||||
def template_handler_extensions
|
||||
@@template_handlers.keys.map(&:to_s).sort
|
||||
@@template_handlers.keys.map {|key| key.to_s }.sort
|
||||
end
|
||||
|
||||
def registered_template_handler(extension)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'erb'
|
||||
require 'active_support/core_ext/class/attribute_accessors'
|
||||
|
||||
module ActionView
|
||||
module TemplateHandlers
|
||||
|
||||
@@ -201,11 +201,10 @@ module AbstractController
|
||||
def fail() self.response_body = "fail" end
|
||||
|
||||
private
|
||||
|
||||
def respond_to_action?(action_name)
|
||||
action_name.to_s != "fail"
|
||||
|
||||
def method_for_action(action_name)
|
||||
action_name.to_s != "fail" && action_name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TestRespondToAction < ActiveSupport::TestCase
|
||||
|
||||
@@ -193,5 +193,24 @@ module AbstractController
|
||||
end
|
||||
end
|
||||
|
||||
class SetsResponseBody < ControllerWithCallbacks
|
||||
before_filter :set_body
|
||||
|
||||
def index
|
||||
self.response_body = "Fail"
|
||||
end
|
||||
|
||||
def set_body
|
||||
self.response_body = "Success"
|
||||
end
|
||||
end
|
||||
|
||||
class TestHalting < ActiveSupport::TestCase
|
||||
test "when a callback sets the response body, the action should not be invoked" do
|
||||
result = SetsResponseBody.process(:index)
|
||||
assert_equal "Success", result.response_body
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,7 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
require 'active_support/core/all'
|
||||
require 'active_support'
|
||||
require 'active_support/test_case'
|
||||
require 'action_controller/abstract'
|
||||
require 'action_view'
|
||||
@@ -18,4 +18,4 @@ begin
|
||||
Debugger.start
|
||||
rescue LoadError
|
||||
# Debugging disabled. `gem install ruby-debug` to enable.
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
if ENV["new_base"]
|
||||
require "abstract_unit2"
|
||||
else
|
||||
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
||||
$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
|
||||
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
|
||||
@@ -34,7 +37,8 @@ ActionController::Base.session_store = nil
|
||||
# Register danish language for testing
|
||||
I18n.backend.store_translations 'da', {}
|
||||
I18n.backend.store_translations 'pt-BR', {}
|
||||
ORIGINAL_LOCALES = I18n.available_locales.map(&:to_s).sort
|
||||
ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
|
||||
|
||||
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
|
||||
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
|
||||
end
|
||||
@@ -5,18 +5,25 @@ $:.unshift(File.dirname(__FILE__) + '/lib')
|
||||
|
||||
require 'test/unit'
|
||||
require 'active_support'
|
||||
require 'active_support/core/all'
|
||||
require 'active_support/test_case'
|
||||
require 'action_controller/abstract'
|
||||
require 'action_controller/new_base'
|
||||
require 'fixture_template'
|
||||
require 'action_controller/testing/process2'
|
||||
require 'action_view/test_case'
|
||||
require 'action_controller/testing/integration'
|
||||
require 'active_support/dependencies'
|
||||
|
||||
ActiveSupport::Dependencies.hook!
|
||||
|
||||
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
|
||||
|
||||
module ActionController
|
||||
|
||||
Base.session = {
|
||||
:key => '_testing_session',
|
||||
:secret => '8273f16463985e2b3747dc25e30f2528'
|
||||
}
|
||||
|
||||
class ActionControllerError < StandardError #:nodoc:
|
||||
end
|
||||
|
||||
@@ -75,7 +82,7 @@ module ActionController
|
||||
end
|
||||
|
||||
class Base
|
||||
use ActionController::Testing
|
||||
include ActionController::Testing
|
||||
end
|
||||
|
||||
Base.view_paths = FIXTURE_LOAD_PATH
|
||||
@@ -89,45 +96,44 @@ module ActionController
|
||||
end
|
||||
|
||||
def assert_template(options = {}, message = nil)
|
||||
validate_response!
|
||||
validate_request!
|
||||
|
||||
clean_backtrace do
|
||||
case options
|
||||
when NilClass, String
|
||||
hax = @controller._action_view.instance_variable_get(:@_rendered)
|
||||
rendered = (hax[:template] || []).map { |t| t.identifier }
|
||||
msg = build_message(message,
|
||||
"expecting <?> but rendering with <?>",
|
||||
options, rendered.join(', '))
|
||||
assert_block(msg) do
|
||||
if options.nil?
|
||||
hax[:template].blank?
|
||||
else
|
||||
rendered.any? { |t| t.match(options) }
|
||||
end
|
||||
end
|
||||
when Hash
|
||||
if expected_partial = options[:partial]
|
||||
partials = hax[:partials]
|
||||
if expected_count = options[:count]
|
||||
found = partials.detect { |p, _| p.identifier.match(expected_partial) }
|
||||
actual_count = found.nil? ? 0 : found.second
|
||||
msg = build_message(message,
|
||||
"expecting ? to be rendered ? time(s) but rendered ? time(s)",
|
||||
expected_partial, expected_count, actual_count)
|
||||
assert(actual_count == expected_count.to_i, msg)
|
||||
else
|
||||
msg = build_message(message,
|
||||
"expecting partial <?> but action rendered <?>",
|
||||
options[:partial], partials.keys)
|
||||
assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
|
||||
end
|
||||
hax = @controller._action_view.instance_variable_get(:@_rendered)
|
||||
|
||||
case options
|
||||
when NilClass, String
|
||||
rendered = (hax[:template] || []).map { |t| t.identifier }
|
||||
msg = build_message(message,
|
||||
"expecting <?> but rendering with <?>",
|
||||
options, rendered.join(', '))
|
||||
assert_block(msg) do
|
||||
if options.nil?
|
||||
hax[:template].blank?
|
||||
else
|
||||
assert hax[:partials].empty?,
|
||||
"Expected no partials to be rendered"
|
||||
rendered.any? { |t| t.match(options) }
|
||||
end
|
||||
end
|
||||
when Hash
|
||||
if expected_partial = options[:partial]
|
||||
partials = hax[:partials]
|
||||
if expected_count = options[:count]
|
||||
found = partials.detect { |p, _| p.identifier.match(expected_partial) }
|
||||
actual_count = found.nil? ? 0 : found.second
|
||||
msg = build_message(message,
|
||||
"expecting ? to be rendered ? time(s) but rendered ? time(s)",
|
||||
expected_partial, expected_count, actual_count)
|
||||
assert(actual_count == expected_count.to_i, msg)
|
||||
else
|
||||
msg = build_message(message,
|
||||
"expecting partial <?> but action rendered <?>",
|
||||
options[:partial], partials.keys)
|
||||
assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
|
||||
end
|
||||
else
|
||||
assert hax[:partials].empty?,
|
||||
"Expected no partials to be rendered"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,9 +28,9 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
def call_reset_session
|
||||
session[:bar]
|
||||
session[:foo]
|
||||
reset_session
|
||||
session[:bar] = "baz"
|
||||
session[:foo] = "baz"
|
||||
head :ok
|
||||
end
|
||||
|
||||
@@ -91,7 +91,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
|
||||
|
||||
get '/get_session_value'
|
||||
assert_response :success
|
||||
assert_equal 'foo: nil', response.body
|
||||
assert_equal 'foo: "baz"', response.body
|
||||
|
||||
get '/get_session_id'
|
||||
assert_response :success
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'active_record_unit'
|
||||
require 'fixtures/project'
|
||||
|
||||
class Task < ActiveRecord::Base
|
||||
set_table_name 'projects'
|
||||
|
||||
@@ -12,6 +12,9 @@ class ActionPackAssertionsController < ActionController::Base
|
||||
# a standard template
|
||||
def hello_xml_world() render :template => "test/hello_xml_world"; end
|
||||
|
||||
# a standard partial
|
||||
def partial() render :partial => 'test/partial'; end
|
||||
|
||||
# a redirect to an internal location
|
||||
def redirect_internal() redirect_to "/nothing"; end
|
||||
|
||||
@@ -331,6 +334,26 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_assert_template_with_partial
|
||||
get :partial
|
||||
assert_template :partial => '_partial'
|
||||
end
|
||||
|
||||
def test_assert_template_with_nil
|
||||
get :nothing
|
||||
assert_template nil
|
||||
end
|
||||
|
||||
def test_assert_template_with_string
|
||||
get :hello_world
|
||||
assert_template 'hello_world'
|
||||
end
|
||||
|
||||
def test_assert_template_with_symbol
|
||||
get :hello_world
|
||||
assert_template :hello_world
|
||||
end
|
||||
|
||||
# check if we were rendered by a file-based template?
|
||||
def test_rendered_action
|
||||
process :nothing
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'abstract_unit'
|
||||
require 'logger'
|
||||
|
||||
class Address
|
||||
def Address.count(conditions = nil, join = nil)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'abstract_unit'
|
||||
require 'logger'
|
||||
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
|
||||
|
||||
# Provide some controller to run the tests on.
|
||||
@@ -116,7 +117,7 @@ class PerformActionTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
def method_missing(method, *args)
|
||||
@logged << args.first
|
||||
@logged << args.first.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'abstract_unit'
|
||||
require 'logger'
|
||||
|
||||
class CaptureController < ActionController::Base
|
||||
def self.controller_name; "test"; end
|
||||
|
||||
@@ -6,20 +6,20 @@ class DispatcherTest < Test::Unit::TestCase
|
||||
def setup
|
||||
ENV['REQUEST_METHOD'] = 'GET'
|
||||
|
||||
Dispatcher.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
|
||||
middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/dispatch/middlewares.rb"))
|
||||
middleware.instance_eval(File.read(middlewares))
|
||||
end
|
||||
|
||||
# Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
|
||||
Dispatcher.instance_variable_set("@prepare_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
||||
Dispatcher.instance_variable_set("@before_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
||||
Dispatcher.instance_variable_set("@after_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
||||
ActionDispatch::Callbacks.instance_variable_set("@prepare_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
||||
ActionDispatch::Callbacks.instance_variable_set("@before_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
||||
ActionDispatch::Callbacks.instance_variable_set("@after_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
|
||||
|
||||
@old_router, Dispatcher.router = Dispatcher.router, mock()
|
||||
Dispatcher.router.stubs(:call).returns([200, {}, 'response'])
|
||||
Dispatcher.router.stubs(:reload)
|
||||
Dispatcher.stubs(:require_dependency)
|
||||
end
|
||||
|
||||
def teardown
|
||||
Dispatcher.router = @old_router
|
||||
@dispatcher = nil
|
||||
ENV.delete 'REQUEST_METHOD'
|
||||
end
|
||||
|
||||
@@ -29,12 +29,12 @@ class DispatcherTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_reloads_routes_before_dispatch_if_in_loading_mode
|
||||
ActionController::Routing::Routes.expects(:reload).once
|
||||
Dispatcher.router.expects(:reload).once
|
||||
dispatch(false)
|
||||
end
|
||||
|
||||
def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
|
||||
ActionController::Routing::Routes.expects(:reload).never
|
||||
Dispatcher.router.expects(:reload).never
|
||||
ActiveSupport::Dependencies.expects(:clear).never
|
||||
|
||||
dispatch
|
||||
@@ -55,7 +55,7 @@ class DispatcherTest < Test::Unit::TestCase
|
||||
assert_nil a || b || c
|
||||
|
||||
# Run callbacks
|
||||
Dispatcher.run_prepare_callbacks
|
||||
dispatch
|
||||
|
||||
assert_equal 1, a
|
||||
assert_equal 2, b
|
||||
@@ -72,16 +72,22 @@ class DispatcherTest < Test::Unit::TestCase
|
||||
Dispatcher.to_prepare(:unique_id) { |*args| a = b = 1 }
|
||||
Dispatcher.to_prepare(:unique_id) { |*args| a = 2 }
|
||||
|
||||
Dispatcher.run_prepare_callbacks
|
||||
dispatch
|
||||
assert_equal 2, a
|
||||
assert_equal nil, b
|
||||
end
|
||||
|
||||
private
|
||||
def dispatch(cache_classes = true)
|
||||
ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
|
||||
ActionController::Dispatcher.prepare_each_request = false
|
||||
Dispatcher.define_dispatcher_callbacks(cache_classes)
|
||||
Dispatcher.new.call({'rack.input' => StringIO.new('')})
|
||||
Dispatcher.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
|
||||
middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/dispatch/middlewares.rb"))
|
||||
middleware.instance_eval(File.read(middlewares))
|
||||
end
|
||||
|
||||
@dispatcher ||= Dispatcher.new
|
||||
@dispatcher.call({'rack.input' => StringIO.new(''), 'action_dispatch.show_exceptions' => false})
|
||||
end
|
||||
|
||||
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
|
||||
|
||||
@@ -607,7 +607,6 @@ class FilterTest < Test::Unit::TestCase
|
||||
def test_dynamic_dispatch
|
||||
%w(foo bar baz).each do |action|
|
||||
request = ActionController::TestRequest.new
|
||||
request.env["action_controller.rescue.request"] = request
|
||||
request.query_parameters[:choose] = action
|
||||
response = DynamicDispatchController.action.call(request.env).last
|
||||
assert_equal action, response.body
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'abstract_unit'
|
||||
require 'active_support/core_ext/kernel/reporting'
|
||||
|
||||
ActionController::Base.helpers_dir = File.dirname(__FILE__) + '/../fixtures/helpers'
|
||||
|
||||
@@ -103,7 +104,6 @@ class HelperTest < Test::Unit::TestCase
|
||||
|
||||
def call_controller(klass, action)
|
||||
request = ActionController::TestRequest.new
|
||||
request.env["action_controller.rescue.request"] = request
|
||||
klass.action(action).call(request.env)
|
||||
end
|
||||
|
||||
@@ -111,7 +111,6 @@ class HelperTest < Test::Unit::TestCase
|
||||
assert_equal 'hello: Iz guuut!',
|
||||
call_controller(Fun::GamesController, "render_hello_world").last.body
|
||||
# request = ActionController::TestRequest.new
|
||||
# request.env["action_controller.rescue.request"] = request
|
||||
#
|
||||
# resp = Fun::GamesController.action(:render_hello_world).call(request.env)
|
||||
# assert_equal 'hello: Iz guuut!', resp.last.body
|
||||
@@ -216,7 +215,6 @@ class IsolatedHelpersTest < Test::Unit::TestCase
|
||||
|
||||
def call_controller(klass, action)
|
||||
request = ActionController::TestRequest.new
|
||||
request.env["action_controller.rescue.request"] = request
|
||||
klass.action(action).call(request.env)
|
||||
end
|
||||
|
||||
|
||||
37
actionpack/test/controller/render_js_test.rb
Normal file
37
actionpack/test/controller/render_js_test.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
require 'abstract_unit'
|
||||
require 'controller/fake_models'
|
||||
require 'pathname'
|
||||
|
||||
class TestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
def render_vanilla_js_hello
|
||||
render :js => "alert('hello')"
|
||||
end
|
||||
|
||||
def greeting
|
||||
# let's just rely on the template
|
||||
end
|
||||
|
||||
def partial
|
||||
render :partial => 'partial'
|
||||
end
|
||||
end
|
||||
|
||||
class RenderTest < ActionController::TestCase
|
||||
def test_render_vanilla_js
|
||||
get :render_vanilla_js_hello
|
||||
assert_equal "alert('hello')", @response.body
|
||||
assert_equal "text/javascript", @response.content_type
|
||||
end
|
||||
|
||||
def test_render_with_default_from_accept_header
|
||||
xhr :get, :greeting
|
||||
assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
|
||||
end
|
||||
|
||||
def test_should_render_js_partial
|
||||
xhr :get, :partial, :format => 'js'
|
||||
assert_equal 'partial js', @response.body
|
||||
end
|
||||
end
|
||||
80
actionpack/test/controller/render_json_test.rb
Normal file
80
actionpack/test/controller/render_json_test.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
require 'abstract_unit'
|
||||
require 'controller/fake_models'
|
||||
require 'pathname'
|
||||
|
||||
class TestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
def render_json_nil
|
||||
render :json => nil
|
||||
end
|
||||
|
||||
def render_json_hello_world
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world')
|
||||
end
|
||||
|
||||
def render_json_hello_world_with_callback
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
|
||||
end
|
||||
|
||||
def render_json_with_custom_content_type
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
|
||||
end
|
||||
|
||||
def render_symbol_json
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world')
|
||||
end
|
||||
|
||||
def render_json_with_render_to_string
|
||||
render :json => {:hello => render_to_string(:partial => 'partial')}
|
||||
end
|
||||
end
|
||||
|
||||
class RenderTest < ActionController::TestCase
|
||||
tests TestController
|
||||
|
||||
def setup
|
||||
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
||||
# a more accurate simulation of what happens in "real life".
|
||||
super
|
||||
@controller.logger = Logger.new(nil)
|
||||
|
||||
@request.host = "www.nextangle.com"
|
||||
end
|
||||
|
||||
def test_render_json_nil
|
||||
get :render_json_nil
|
||||
assert_equal 'null', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json
|
||||
get :render_json_hello_world
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json_with_callback
|
||||
get :render_json_hello_world_with_callback
|
||||
assert_equal 'alert({"hello":"world"})', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json_with_custom_content_type
|
||||
get :render_json_with_custom_content_type
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
assert_equal 'text/javascript', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_symbol_json
|
||||
get :render_symbol_json
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json_with_render_to_string
|
||||
get :render_json_with_render_to_string
|
||||
assert_equal '{"hello":"partial html"}', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
end
|
||||
222
actionpack/test/controller/render_other_test.rb
Normal file
222
actionpack/test/controller/render_other_test.rb
Normal file
@@ -0,0 +1,222 @@
|
||||
require 'abstract_unit'
|
||||
require 'controller/fake_models'
|
||||
require 'pathname'
|
||||
|
||||
class TestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
module RenderTestHelper
|
||||
def rjs_helper_method_from_module
|
||||
page.visual_effect :highlight
|
||||
end
|
||||
end
|
||||
|
||||
helper RenderTestHelper
|
||||
helper do
|
||||
def rjs_helper_method(value)
|
||||
page.visual_effect :highlight, value
|
||||
end
|
||||
end
|
||||
|
||||
def enum_rjs_test
|
||||
render :update do |page|
|
||||
page.select('.product').each do |value|
|
||||
page.rjs_helper_method_from_module
|
||||
page.rjs_helper_method(value)
|
||||
page.sortable(value, :url => { :action => "order" })
|
||||
page.draggable(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_explicit_html_template
|
||||
end
|
||||
|
||||
def render_custom_code_rjs
|
||||
render :update, :status => 404 do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
|
||||
def render_implicit_html_template
|
||||
end
|
||||
|
||||
def render_js_with_explicit_template
|
||||
@project_id = 4
|
||||
render :template => 'test/delete_with_js'
|
||||
end
|
||||
|
||||
def render_js_with_explicit_action_template
|
||||
@project_id = 4
|
||||
render :action => 'delete_with_js'
|
||||
end
|
||||
|
||||
def delete_with_js
|
||||
@project_id = 4
|
||||
end
|
||||
|
||||
def update_page
|
||||
render :update do |page|
|
||||
page.replace_html 'balance', '$37,000,000.00'
|
||||
page.visual_effect :highlight, 'balance'
|
||||
end
|
||||
end
|
||||
|
||||
def update_page_with_instance_variables
|
||||
@money = '$37,000,000.00'
|
||||
@div_id = 'balance'
|
||||
render :update do |page|
|
||||
page.replace_html @div_id, @money
|
||||
page.visual_effect :highlight, @div_id
|
||||
end
|
||||
end
|
||||
|
||||
def update_page_with_view_method
|
||||
render :update do |page|
|
||||
page.replace_html 'person', pluralize(2, 'person')
|
||||
end
|
||||
end
|
||||
|
||||
def partial_as_rjs
|
||||
render :update do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
|
||||
def respond_to_partial_as_rjs
|
||||
respond_to do |format|
|
||||
format.js do
|
||||
render :update do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_alternate_default
|
||||
# For this test, the method "default_render" is overridden:
|
||||
@alternate_default_render = lambda do
|
||||
render :update do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def determine_layout
|
||||
case action_name
|
||||
when "render_js_with_explicit_template",
|
||||
"render_js_with_explicit_action_template",
|
||||
"delete_with_js", "update_page", "update_page_with_instance_variables"
|
||||
|
||||
"layouts/standard"
|
||||
when "action_talk_to_layout", "layout_overriding_layout"
|
||||
"layouts/talk_from_action"
|
||||
when "render_implicit_html_template_from_xhr_request"
|
||||
(request.xhr? ? 'layouts/xhr' : 'layouts/standard')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class RenderTest < ActionController::TestCase
|
||||
tests TestController
|
||||
|
||||
def setup
|
||||
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
||||
# a more accurate simulation of what happens in "real life".
|
||||
super
|
||||
@controller.logger = Logger.new(nil)
|
||||
|
||||
@request.host = "www.nextangle.com"
|
||||
end
|
||||
|
||||
def test_enum_rjs_test
|
||||
ActiveSupport::SecureRandom.stubs(:base64).returns("asdf")
|
||||
get :enum_rjs_test
|
||||
body = %{
|
||||
$$(".product").each(function(value, index) {
|
||||
new Effect.Highlight(element,{});
|
||||
new Effect.Highlight(value,{});
|
||||
Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}});
|
||||
new Draggable(value, {});
|
||||
});
|
||||
}.gsub(/^ /, '').strip
|
||||
assert_equal body, @response.body
|
||||
end
|
||||
|
||||
def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template
|
||||
[:js, "js"].each do |format|
|
||||
assert_nothing_raised do
|
||||
get :render_explicit_html_template, :format => format
|
||||
assert_equal %(document.write("Hello world\\n");), @response.body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_custom_code_rjs
|
||||
get :render_custom_code_rjs
|
||||
assert_response 404
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_render_in_an_rjs_template_should_pick_html_templates_when_available
|
||||
[:js, "js"].each do |format|
|
||||
assert_nothing_raised do
|
||||
get :render_implicit_html_template, :format => format
|
||||
assert_equal %(document.write("Hello world\\n");), @response.body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_rjs_template_explicitly
|
||||
get :render_js_with_explicit_template
|
||||
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
||||
end
|
||||
|
||||
def test_rendering_rjs_action_explicitly
|
||||
get :render_js_with_explicit_action_template
|
||||
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
||||
end
|
||||
|
||||
def test_render_rjs_with_default
|
||||
get :delete_with_js
|
||||
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
||||
end
|
||||
|
||||
def test_update_page
|
||||
get :update_page
|
||||
assert_template nil
|
||||
assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type']
|
||||
assert_equal 2, @response.body.split($/).length
|
||||
end
|
||||
|
||||
def test_update_page_with_instance_variables
|
||||
get :update_page_with_instance_variables
|
||||
assert_template nil
|
||||
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
|
||||
assert_match /balance/, @response.body
|
||||
assert_match /\$37/, @response.body
|
||||
end
|
||||
|
||||
def test_update_page_with_view_method
|
||||
get :update_page_with_view_method
|
||||
assert_template nil
|
||||
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
|
||||
assert_match /2 people/, @response.body
|
||||
end
|
||||
|
||||
def test_should_render_html_formatted_partial_with_rjs
|
||||
xhr :get, :partial_as_rjs
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_should_render_html_formatted_partial_with_rjs_and_js_format
|
||||
xhr :get, :respond_to_partial_as_rjs
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_should_render_with_alternate_default_render
|
||||
xhr :get, :render_alternate_default
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
require ENV['new_base'] ? 'abstract_unit2' : 'abstract_unit'
|
||||
require 'abstract_unit'
|
||||
require 'controller/fake_models'
|
||||
require 'pathname'
|
||||
|
||||
@@ -145,18 +145,21 @@ class TestController < ActionController::Base
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def render_file_with_instance_variables
|
||||
@secret = 'in the sauce'
|
||||
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
|
||||
render :file => path
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def render_file_as_string_with_instance_variables
|
||||
@secret = 'in the sauce'
|
||||
path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
|
||||
render path
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def render_file_not_using_full_path
|
||||
@secret = 'in the sauce'
|
||||
render :file => 'test/render_file_with_ivar'
|
||||
@@ -203,41 +206,11 @@ class TestController < ActionController::Base
|
||||
render :inline => "<%= controller_name %>"
|
||||
end
|
||||
|
||||
def render_json_nil
|
||||
render :json => nil
|
||||
end
|
||||
|
||||
def render_json_hello_world
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world')
|
||||
end
|
||||
|
||||
def render_json_hello_world_with_callback
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
|
||||
end
|
||||
|
||||
def render_json_with_custom_content_type
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
|
||||
end
|
||||
|
||||
def render_symbol_json
|
||||
render :json => ActiveSupport::JSON.encode(:hello => 'world')
|
||||
end
|
||||
|
||||
def render_json_with_render_to_string
|
||||
render :json => {:hello => render_to_string(:partial => 'partial')}
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def render_custom_code
|
||||
render :text => "hello world", :status => 404
|
||||
end
|
||||
|
||||
def render_custom_code_rjs
|
||||
render :update, :status => 404 do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def render_text_with_nil
|
||||
render :text => nil
|
||||
@@ -253,10 +226,6 @@ class TestController < ActionController::Base
|
||||
render :text => "appended"
|
||||
end
|
||||
|
||||
def render_vanilla_js_hello
|
||||
render :js => "alert('hello')"
|
||||
end
|
||||
|
||||
# This test is testing 3 things:
|
||||
# render :file in AV :ported:
|
||||
# render :template in AC :ported:
|
||||
@@ -271,10 +240,6 @@ class TestController < ActionController::Base
|
||||
render "test/hello"
|
||||
end
|
||||
|
||||
def render_xml_with_custom_content_type
|
||||
render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
|
||||
end
|
||||
|
||||
def render_line_offset
|
||||
render :inline => '<% raise %>', :locals => {:foo => 'bar'}
|
||||
end
|
||||
@@ -297,6 +262,7 @@ class TestController < ActionController::Base
|
||||
render :action => "hello_world"
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def builder_layout_test
|
||||
render :action => "hello", :layout => "layouts/builder"
|
||||
end
|
||||
@@ -306,6 +272,7 @@ class TestController < ActionController::Base
|
||||
render :action => "hello_world_container"
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def partials_list
|
||||
@test_unchanged = 'hello'
|
||||
@customers = [ Customer.new("david"), Customer.new("mary") ]
|
||||
@@ -331,12 +298,6 @@ class TestController < ActionController::Base
|
||||
:locals => { :local_name => name }
|
||||
end
|
||||
|
||||
def render_implicit_html_template
|
||||
end
|
||||
|
||||
def render_explicit_html_template
|
||||
end
|
||||
|
||||
def render_implicit_html_template_from_xhr_request
|
||||
end
|
||||
|
||||
@@ -470,66 +431,6 @@ class TestController < ActionController::Base
|
||||
render :template => "test/hello_world_from_rxml.builder"
|
||||
end
|
||||
|
||||
module RenderTestHelper
|
||||
def rjs_helper_method_from_module
|
||||
page.visual_effect :highlight
|
||||
end
|
||||
end
|
||||
|
||||
helper RenderTestHelper
|
||||
helper do
|
||||
def rjs_helper_method(value)
|
||||
page.visual_effect :highlight, value
|
||||
end
|
||||
end
|
||||
|
||||
def enum_rjs_test
|
||||
render :update do |page|
|
||||
page.select('.product').each do |value|
|
||||
page.rjs_helper_method_from_module
|
||||
page.rjs_helper_method(value)
|
||||
page.sortable(value, :url => { :action => "order" })
|
||||
page.draggable(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def delete_with_js
|
||||
@project_id = 4
|
||||
end
|
||||
|
||||
def render_js_with_explicit_template
|
||||
@project_id = 4
|
||||
render :template => 'test/delete_with_js'
|
||||
end
|
||||
|
||||
def render_js_with_explicit_action_template
|
||||
@project_id = 4
|
||||
render :action => 'delete_with_js'
|
||||
end
|
||||
|
||||
def update_page
|
||||
render :update do |page|
|
||||
page.replace_html 'balance', '$37,000,000.00'
|
||||
page.visual_effect :highlight, 'balance'
|
||||
end
|
||||
end
|
||||
|
||||
def update_page_with_instance_variables
|
||||
@money = '$37,000,000.00'
|
||||
@div_id = 'balance'
|
||||
render :update do |page|
|
||||
page.replace_html @div_id, @money
|
||||
page.visual_effect :highlight, @div_id
|
||||
end
|
||||
end
|
||||
|
||||
def update_page_with_view_method
|
||||
render :update do |page|
|
||||
page.replace_html 'person', pluralize(2, 'person')
|
||||
end
|
||||
end
|
||||
|
||||
def action_talk_to_layout
|
||||
# Action template sets variable that's picked up by layout
|
||||
end
|
||||
@@ -573,25 +474,6 @@ class TestController < ActionController::Base
|
||||
head :forbidden, :x_custom_header => "something"
|
||||
end
|
||||
|
||||
def render_with_location
|
||||
render :xml => "<hello/>", :location => "http://example.com", :status => 201
|
||||
end
|
||||
|
||||
def render_with_object_location
|
||||
customer = Customer.new("Some guy", 1)
|
||||
render :xml => "<customer/>", :location => customer_url(customer), :status => :created
|
||||
end
|
||||
|
||||
def render_with_to_xml
|
||||
to_xmlable = Class.new do
|
||||
def to_xml
|
||||
"<i-am-xml/>"
|
||||
end
|
||||
end.new
|
||||
|
||||
render :xml => to_xmlable
|
||||
end
|
||||
|
||||
def render_using_layout_around_block
|
||||
render :action => "using_layout_around_block"
|
||||
end
|
||||
@@ -608,22 +490,6 @@ class TestController < ActionController::Base
|
||||
render :partial => 'partial.html.erb'
|
||||
end
|
||||
|
||||
def partial_as_rjs
|
||||
render :update do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
|
||||
def respond_to_partial_as_rjs
|
||||
respond_to do |format|
|
||||
format.js do
|
||||
render :update do |page|
|
||||
page.replace :foo, :partial => 'partial'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def partial
|
||||
render :partial => 'partial'
|
||||
end
|
||||
@@ -880,82 +746,54 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal 'Hello world!', @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_with_instance_variables
|
||||
get :render_file_with_instance_variables
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_as_string_with_instance_variables
|
||||
get :render_file_as_string_with_instance_variables
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_not_using_full_path
|
||||
get :render_file_not_using_full_path
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_not_using_full_path_with_dot_in_path
|
||||
get :render_file_not_using_full_path_with_dot_in_path
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_using_pathname
|
||||
get :render_file_using_pathname
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_with_locals
|
||||
get :render_file_with_locals
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_file_as_string_with_locals
|
||||
get :render_file_as_string_with_locals
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
# :assessed:
|
||||
def test_render_file_from_template
|
||||
get :render_file_from_template
|
||||
assert_equal "The secret is in the sauce\n", @response.body
|
||||
end
|
||||
|
||||
def test_render_json_nil
|
||||
get :render_json_nil
|
||||
assert_equal 'null', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json
|
||||
get :render_json_hello_world
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json_with_callback
|
||||
get :render_json_hello_world_with_callback
|
||||
assert_equal 'alert({"hello":"world"})', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json_with_custom_content_type
|
||||
get :render_json_with_custom_content_type
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
assert_equal 'text/javascript', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_symbol_json
|
||||
get :render_symbol_json
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
def test_render_json_with_render_to_string
|
||||
get :render_json_with_render_to_string
|
||||
assert_equal '{"hello":"partial html"}', @response.body
|
||||
assert_equal 'application/json', @response.content_type
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_custom_code
|
||||
get :render_custom_code
|
||||
@@ -964,12 +802,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal 'hello world', @response.body
|
||||
end
|
||||
|
||||
def test_render_custom_code_rjs
|
||||
get :render_custom_code_rjs
|
||||
assert_response 404
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_text_with_nil
|
||||
get :render_text_with_nil
|
||||
@@ -1023,12 +855,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal "test", @response.body # name is explicitly set to 'test' inside the controller.
|
||||
end
|
||||
|
||||
def test_render_vanilla_js
|
||||
get :render_vanilla_js_hello
|
||||
assert_equal "alert('hello')", @response.body
|
||||
assert_equal "text/javascript", @response.content_type
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_xml
|
||||
get :render_xml_hello
|
||||
@@ -1036,6 +862,7 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal "application/xml", @response.content_type
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_render_xml_as_string_template
|
||||
get :render_xml_hello_as_string_template
|
||||
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
|
||||
@@ -1048,25 +875,13 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal "<p>This is grand!</p>\n", @response.body
|
||||
end
|
||||
|
||||
# :move: test in AV
|
||||
def test_render_xml_with_partial
|
||||
get :builder_partial_test
|
||||
assert_equal "<test>\n <hello/>\n</test>\n", @response.body
|
||||
end
|
||||
|
||||
def test_enum_rjs_test
|
||||
ActiveSupport::SecureRandom.stubs(:base64).returns("asdf")
|
||||
get :enum_rjs_test
|
||||
body = %{
|
||||
$$(".product").each(function(value, index) {
|
||||
new Effect.Highlight(element,{});
|
||||
new Effect.Highlight(value,{});
|
||||
Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}});
|
||||
new Draggable(value, {});
|
||||
});
|
||||
}.gsub(/^ /, '').strip
|
||||
assert_equal body, @response.body
|
||||
end
|
||||
|
||||
# :ported:
|
||||
def test_layout_rendering
|
||||
get :layout_test
|
||||
assert_equal "<html>Hello world!</html>", @response.body
|
||||
@@ -1114,29 +929,10 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal "Goodbye, Local David", @response.body
|
||||
end
|
||||
|
||||
def test_render_in_an_rjs_template_should_pick_html_templates_when_available
|
||||
[:js, "js"].each do |format|
|
||||
assert_nothing_raised do
|
||||
get :render_implicit_html_template, :format => format
|
||||
assert_equal %(document.write("Hello world\\n");), @response.body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template
|
||||
[:js, "js"].each do |format|
|
||||
assert_nothing_raised do
|
||||
get :render_explicit_html_template, :format => format
|
||||
assert_equal %(document.write("Hello world\\n");), @response.body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_implicitly_render_html_template_from_xhr_request
|
||||
pending do
|
||||
xhr :get, :render_implicit_html_template_from_xhr_request
|
||||
assert_equal "XHR!\nHello HTML!", @response.body
|
||||
end
|
||||
pending
|
||||
# xhr :get, :render_implicit_html_template_from_xhr_request
|
||||
# assert_equal "XHR!\nHello HTML!", @response.body
|
||||
end
|
||||
|
||||
def test_should_implicitly_render_js_template_without_layout
|
||||
@@ -1151,11 +947,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal 'formatted html erb', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_formatted_xml_erb_template
|
||||
get :formatted_xml_erb, :format => :xml
|
||||
assert_equal '<test>passed formatted xml erb</test>', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_formatted_html_erb_template
|
||||
get :formatted_xml_erb
|
||||
assert_equal '<test>passed formatted html erb</test>', @response.body
|
||||
@@ -1167,31 +958,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal '<test>passed formatted html erb</test>', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_xml_but_keep_custom_content_type
|
||||
get :render_xml_with_custom_content_type
|
||||
assert_equal "application/atomsvc+xml", @response.content_type
|
||||
end
|
||||
|
||||
def test_render_with_default_from_accept_header
|
||||
xhr :get, :greeting
|
||||
assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
|
||||
end
|
||||
|
||||
def test_render_rjs_with_default
|
||||
get :delete_with_js
|
||||
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
||||
end
|
||||
|
||||
def test_render_rjs_template_explicitly
|
||||
get :render_js_with_explicit_template
|
||||
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
||||
end
|
||||
|
||||
def test_rendering_rjs_action_explicitly
|
||||
get :render_js_with_explicit_action_template
|
||||
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
||||
end
|
||||
|
||||
def test_layout_test_with_different_layout
|
||||
get :layout_test_with_different_layout
|
||||
assert_equal "<html>Hello world!</html>", @response.body
|
||||
@@ -1299,28 +1065,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal "The secret is area51\n", @response.body
|
||||
end
|
||||
|
||||
def test_update_page
|
||||
get :update_page
|
||||
assert_template nil
|
||||
assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type']
|
||||
assert_equal 2, @response.body.split($/).length
|
||||
end
|
||||
|
||||
def test_update_page_with_instance_variables
|
||||
get :update_page_with_instance_variables
|
||||
assert_template nil
|
||||
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
|
||||
assert_match /balance/, @response.body
|
||||
assert_match /\$37/, @response.body
|
||||
end
|
||||
|
||||
def test_update_page_with_view_method
|
||||
get :update_page_with_view_method
|
||||
assert_template nil
|
||||
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
|
||||
assert_match /2 people/, @response.body
|
||||
end
|
||||
|
||||
def test_yield_content_for
|
||||
assert_not_deprecated { get :yield_content_for }
|
||||
assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
|
||||
@@ -1391,31 +1135,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
def test_rendering_with_location_should_set_header
|
||||
get :render_with_location
|
||||
assert_equal "http://example.com", @response.headers["Location"]
|
||||
end
|
||||
|
||||
def test_rendering_xml_should_call_to_xml_if_possible
|
||||
get :render_with_to_xml
|
||||
assert_equal "<i-am-xml/>", @response.body
|
||||
end
|
||||
|
||||
def test_rendering_with_object_location_should_set_header_with_url_for
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.resources :customers
|
||||
map.connect ':controller/:action/:id'
|
||||
end
|
||||
|
||||
get :render_with_object_location
|
||||
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
|
||||
end
|
||||
|
||||
def test_should_use_implicit_content_type
|
||||
get :implicit_content_type, :format => 'atom'
|
||||
assert_equal Mime::ATOM, @response.content_type
|
||||
end
|
||||
|
||||
def test_using_layout_around_block
|
||||
get :render_using_layout_around_block
|
||||
assert_equal "Before (David)\nInside from block\nAfter", @response.body
|
||||
@@ -1446,26 +1165,6 @@ class RenderTest < ActionController::TestCase
|
||||
assert_equal 'partial html', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_html_formatted_partial_with_rjs
|
||||
xhr :get, :partial_as_rjs
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_should_render_html_formatted_partial_with_rjs_and_js_format
|
||||
xhr :get, :respond_to_partial_as_rjs
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_should_render_js_partial
|
||||
xhr :get, :partial, :format => 'js'
|
||||
assert_equal 'partial js', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_with_alternate_default_render
|
||||
xhr :get, :render_alternate_default
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_partial_only_with_layout
|
||||
get :partial_only_with_layout
|
||||
assert_equal "<html>only partial</html>", @response.body
|
||||
@@ -1647,7 +1346,7 @@ class EtagRenderTest < ActionController::TestCase
|
||||
def test_render_against_etag_request_should_304_when_match
|
||||
@request.if_none_match = etag_for("hello david")
|
||||
get :render_hello_world_from_variable
|
||||
assert_equal 304, @response.status
|
||||
assert_equal 304, @response.status.to_i
|
||||
assert @response.body.empty?
|
||||
end
|
||||
|
||||
|
||||
81
actionpack/test/controller/render_xml_test.rb
Normal file
81
actionpack/test/controller/render_xml_test.rb
Normal file
@@ -0,0 +1,81 @@
|
||||
require 'abstract_unit'
|
||||
require 'controller/fake_models'
|
||||
require 'pathname'
|
||||
|
||||
class TestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
def render_with_location
|
||||
render :xml => "<hello/>", :location => "http://example.com", :status => 201
|
||||
end
|
||||
|
||||
def render_with_object_location
|
||||
customer = Customer.new("Some guy", 1)
|
||||
render :xml => "<customer/>", :location => customer_url(customer), :status => :created
|
||||
end
|
||||
|
||||
def render_with_to_xml
|
||||
to_xmlable = Class.new do
|
||||
def to_xml
|
||||
"<i-am-xml/>"
|
||||
end
|
||||
end.new
|
||||
|
||||
render :xml => to_xmlable
|
||||
end
|
||||
|
||||
def formatted_xml_erb
|
||||
end
|
||||
|
||||
def render_xml_with_custom_content_type
|
||||
render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
|
||||
end
|
||||
end
|
||||
|
||||
class RenderTest < ActionController::TestCase
|
||||
tests TestController
|
||||
|
||||
def setup
|
||||
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
||||
# a more accurate simulation of what happens in "real life".
|
||||
super
|
||||
@controller.logger = Logger.new(nil)
|
||||
|
||||
@request.host = "www.nextangle.com"
|
||||
end
|
||||
|
||||
def test_rendering_with_location_should_set_header
|
||||
get :render_with_location
|
||||
assert_equal "http://example.com", @response.headers["Location"]
|
||||
end
|
||||
|
||||
def test_rendering_xml_should_call_to_xml_if_possible
|
||||
get :render_with_to_xml
|
||||
assert_equal "<i-am-xml/>", @response.body
|
||||
end
|
||||
|
||||
def test_rendering_with_object_location_should_set_header_with_url_for
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.resources :customers
|
||||
map.connect ':controller/:action/:id'
|
||||
end
|
||||
|
||||
get :render_with_object_location
|
||||
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
|
||||
end
|
||||
|
||||
def test_should_render_formatted_xml_erb_template
|
||||
get :formatted_xml_erb, :format => :xml
|
||||
assert_equal '<test>passed formatted xml erb</test>', @response.body
|
||||
end
|
||||
|
||||
def test_should_render_xml_but_keep_custom_content_type
|
||||
get :render_xml_with_custom_content_type
|
||||
assert_equal "application/atomsvc+xml", @response.content_type
|
||||
end
|
||||
|
||||
def test_should_use_implicit_content_type
|
||||
get :implicit_content_type, :format => 'atom'
|
||||
assert_equal Mime::ATOM, @response.content_type
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,19 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
module ActionDispatch
|
||||
class ShowExceptions
|
||||
private
|
||||
def public_path
|
||||
"#{FIXTURE_LOAD_PATH}/public"
|
||||
end
|
||||
|
||||
# Silence logger
|
||||
def logger
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class RescueController < ActionController::Base
|
||||
class NotAuthorized < StandardError
|
||||
end
|
||||
|
||||
@@ -6,6 +6,11 @@ module ActionDispatch
|
||||
def public_path
|
||||
"#{FIXTURE_LOAD_PATH}/public"
|
||||
end
|
||||
|
||||
# Silence logger
|
||||
def logger
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
1
actionpack/test/new_base/redirect_test.rb
Normal file
1
actionpack/test/new_base/redirect_test.rb
Normal file
@@ -0,0 +1 @@
|
||||
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
|
||||
@@ -92,7 +92,7 @@ module RenderAction
|
||||
|
||||
test "raises an exception when requesting a layout and none exist" do
|
||||
assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do
|
||||
get "/render_action/basic/hello_world_with_layout"
|
||||
get "/render_action/basic/hello_world_with_layout", {}, "action_dispatch.show_exceptions" => false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -117,7 +117,9 @@ module RenderAction
|
||||
describe "rendering a normal template with full path with layout => 'greetings'"
|
||||
|
||||
test "raises an exception when requesting a layout that does not exist" do
|
||||
assert_raise(ActionView::MissingTemplate) { get "/render_action/basic/hello_world_with_custom_layout" }
|
||||
assert_raise(ActionView::MissingTemplate) do
|
||||
get "/render_action/basic/hello_world_with_custom_layout", {}, "action_dispatch.show_exceptions" => false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -131,8 +133,10 @@ module RenderActionWithApplicationLayout
|
||||
# Set the view path to an application view structure with layouts
|
||||
self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new(
|
||||
"render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!",
|
||||
"render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Omg'",
|
||||
"layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI",
|
||||
"layouts/greetings.html.erb" => "Greetings <%= yield %> Bai"
|
||||
"layouts/greetings.html.erb" => "Greetings <%= yield %> Bai",
|
||||
"layouts/builder.html.builder" => "xml.html do\n xml << yield\nend"
|
||||
)]
|
||||
|
||||
def hello_world
|
||||
@@ -154,6 +158,10 @@ module RenderActionWithApplicationLayout
|
||||
def hello_world_with_custom_layout
|
||||
render :action => "hello_world", :layout => "greetings"
|
||||
end
|
||||
|
||||
def with_builder_and_layout
|
||||
render :action => "hello", :layout => "builder"
|
||||
end
|
||||
end
|
||||
|
||||
class TestDefaultLayout < SimpleRouteCase
|
||||
@@ -199,6 +207,15 @@ module RenderActionWithApplicationLayout
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
class TestLayout < SimpleRouteCase
|
||||
testing BasicController
|
||||
|
||||
test "builder works with layouts" do
|
||||
get :with_builder_and_layout
|
||||
assert_response "<html>\n<p>Omg</p>\n</html>\n"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module RenderActionWithControllerLayout
|
||||
|
||||
110
actionpack/test/new_base/render_file_test.rb
Normal file
110
actionpack/test/new_base/render_file_test.rb
Normal file
@@ -0,0 +1,110 @@
|
||||
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
|
||||
|
||||
module RenderFile
|
||||
|
||||
class BasicController < ActionController::Base
|
||||
self.view_paths = "."
|
||||
|
||||
def index
|
||||
render :file => File.join(File.dirname(__FILE__), *%w[.. fixtures test hello_world])
|
||||
end
|
||||
|
||||
def with_instance_variables
|
||||
@secret = 'in the sauce'
|
||||
render :file => File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
|
||||
end
|
||||
|
||||
def without_file_key
|
||||
render File.join(File.dirname(__FILE__), *%w[.. fixtures test hello_world])
|
||||
end
|
||||
|
||||
def without_file_key_with_instance_variable
|
||||
@secret = 'in the sauce'
|
||||
render File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
|
||||
end
|
||||
|
||||
def relative_path
|
||||
@secret = 'in the sauce'
|
||||
render :file => '../fixtures/test/render_file_with_ivar'
|
||||
end
|
||||
|
||||
def relative_path_with_dot
|
||||
@secret = 'in the sauce'
|
||||
render :file => '../fixtures/test/dot.directory/render_file_with_ivar'
|
||||
end
|
||||
|
||||
def pathname
|
||||
@secret = 'in the sauce'
|
||||
render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. fixtures test dot.directory render_file_with_ivar.erb])
|
||||
end
|
||||
|
||||
def with_locals
|
||||
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
|
||||
render :file => path, :locals => {:secret => 'in the sauce'}
|
||||
end
|
||||
|
||||
def without_file_key_with_locals
|
||||
path = File.expand_path('../fixtures/test/render_file_with_locals.erb')
|
||||
render path, :locals => {:secret => 'in the sauce'}
|
||||
end
|
||||
end
|
||||
|
||||
class TestBasic < SimpleRouteCase
|
||||
testing RenderFile::BasicController
|
||||
|
||||
def setup
|
||||
@old_pwd = Dir.pwd
|
||||
Dir.chdir(File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
def teardown
|
||||
Dir.chdir(@old_pwd)
|
||||
end
|
||||
|
||||
test "rendering simple template" do
|
||||
get :index
|
||||
assert_response "Hello world!"
|
||||
end
|
||||
|
||||
test "rendering template with ivar" do
|
||||
get :with_instance_variables
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
|
||||
test "rendering path without specifying the :file key" do
|
||||
get :without_file_key
|
||||
assert_response "Hello world!"
|
||||
end
|
||||
|
||||
test "rendering path without specifying the :file key with ivar" do
|
||||
get :without_file_key_with_instance_variable
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
|
||||
test "rendering a relative path" do
|
||||
get :relative_path
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
|
||||
test "rendering a relative path with dot" do
|
||||
get :relative_path_with_dot
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
|
||||
test "rendering a Pathname" do
|
||||
get :pathname
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
|
||||
test "rendering file with locals" do
|
||||
get :with_locals
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
|
||||
test "rendering path without specifying the :file key with locals" do
|
||||
get :without_file_key_with_locals
|
||||
assert_response "The secret is in the sauce\n"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -6,7 +6,8 @@ module ControllerLayouts
|
||||
self.view_paths = [ActionView::Template::FixturePath.new(
|
||||
"layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI",
|
||||
"layouts/override.html.erb" => "Override! <%= yield %>",
|
||||
"basic.html.erb" => "Hello world!"
|
||||
"basic.html.erb" => "Hello world!",
|
||||
"controller_layouts/implicit/layout_false.html.erb" => "hai(layout_false.html.erb)"
|
||||
)]
|
||||
|
||||
def index
|
||||
@@ -17,6 +18,10 @@ module ControllerLayouts
|
||||
render :template => "basic", :layout => "override"
|
||||
end
|
||||
|
||||
def layout_false
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
def builder_override
|
||||
|
||||
end
|
||||
@@ -56,4 +61,13 @@ module ControllerLayouts
|
||||
get "/controller_layouts/implicit/override"
|
||||
assert_body "Override! Hello world!"
|
||||
end
|
||||
|
||||
class TestLayoutOptions < SimpleRouteCase
|
||||
testing ControllerLayouts::ImplicitController
|
||||
|
||||
test "rendering with :layout => false leaves out the implicit layout" do
|
||||
get :layout_false
|
||||
assert_response "hai(layout_false.html.erb)"
|
||||
end
|
||||
end
|
||||
end
|
||||
27
actionpack/test/new_base/render_partial_test.rb
Normal file
27
actionpack/test/new_base/render_partial_test.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
|
||||
|
||||
module RenderPartial
|
||||
|
||||
class BasicController < ActionController::Base
|
||||
|
||||
self.view_paths = [ActionView::Template::FixturePath.new(
|
||||
"render_partial/basic/_basic.html.erb" => "OMG!",
|
||||
"render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>"
|
||||
)]
|
||||
|
||||
def changing
|
||||
@test_unchanged = 'hello'
|
||||
render :action => "basic"
|
||||
end
|
||||
end
|
||||
|
||||
class TestPartial < SimpleRouteCase
|
||||
testing BasicController
|
||||
|
||||
test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do
|
||||
get :changing
|
||||
assert_response("goodbyeOMG!goodbye")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -4,14 +4,19 @@ module RenderTemplate
|
||||
class WithoutLayoutController < ActionController::Base
|
||||
|
||||
self.view_paths = [ActionView::Template::FixturePath.new(
|
||||
"test/basic.html.erb" => "Hello from basic.html.erb",
|
||||
"shared.html.erb" => "Elastica",
|
||||
"locals.html.erb" => "The secret is <%= secret %>"
|
||||
"test/basic.html.erb" => "Hello from basic.html.erb",
|
||||
"shared.html.erb" => "Elastica",
|
||||
"locals.html.erb" => "The secret is <%= secret %>",
|
||||
"xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend"
|
||||
)]
|
||||
|
||||
def index
|
||||
render :template => "test/basic"
|
||||
end
|
||||
|
||||
def index_without_key
|
||||
render "test/basic"
|
||||
end
|
||||
|
||||
def in_top_directory
|
||||
render :template => 'shared'
|
||||
@@ -21,41 +26,56 @@ module RenderTemplate
|
||||
render :template => '/shared'
|
||||
end
|
||||
|
||||
def in_top_directory_with_slash_without_key
|
||||
render '/shared'
|
||||
end
|
||||
|
||||
def with_locals
|
||||
render :template => "locals", :locals => { :secret => 'area51' }
|
||||
end
|
||||
|
||||
def builder_template
|
||||
render :template => "xml_template"
|
||||
end
|
||||
end
|
||||
|
||||
class TestWithoutLayout < SimpleRouteCase
|
||||
describe "rendering a normal template with full path without layout"
|
||||
testing RenderTemplate::WithoutLayoutController
|
||||
|
||||
get "/render_template/without_layout"
|
||||
assert_body "Hello from basic.html.erb"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
class TestTemplateRenderInTopDirectory < SimpleRouteCase
|
||||
describe "rendering a template not in a subdirectory"
|
||||
test "rendering a normal template with full path without layout" do
|
||||
get :index
|
||||
assert_response "Hello from basic.html.erb"
|
||||
end
|
||||
|
||||
get "/render_template/without_layout/in_top_directory"
|
||||
assert_body "Elastica"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
class TestTemplateRenderInTopDirectoryWithSlash < SimpleRouteCase
|
||||
describe "rendering a template not in a subdirectory with a leading slash"
|
||||
test "rendering a normal template with full path without layout without key" do
|
||||
get :index_without_key
|
||||
assert_response "Hello from basic.html.erb"
|
||||
end
|
||||
|
||||
get "/render_template/without_layout/in_top_directory_with_slash"
|
||||
assert_body "Elastica"
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
class TestTemplateRenderWithLocals < SimpleRouteCase
|
||||
describe "rendering a template with local variables"
|
||||
test "rendering a template not in a subdirectory" do
|
||||
get :in_top_directory
|
||||
assert_response "Elastica"
|
||||
end
|
||||
|
||||
get "/render_template/without_layout/with_locals"
|
||||
assert_body "The secret is area51"
|
||||
assert_status 200
|
||||
test "rendering a template not in a subdirectory with a leading slash" do
|
||||
get :in_top_directory_with_slash
|
||||
assert_response "Elastica"
|
||||
end
|
||||
|
||||
test "rendering a template not in a subdirectory with a leading slash without key" do
|
||||
get :in_top_directory_with_slash_without_key
|
||||
assert_response "Elastica"
|
||||
end
|
||||
|
||||
test "rendering a template with local variables" do
|
||||
get :with_locals
|
||||
assert_response "The secret is area51"
|
||||
end
|
||||
|
||||
test "rendering a builder template" do
|
||||
get :builder_template
|
||||
assert_response "<html>\n <p>Hello</p>\n</html>\n"
|
||||
end
|
||||
end
|
||||
|
||||
class WithLayoutController < ::ApplicationController
|
||||
|
||||
@@ -48,7 +48,7 @@ module Render
|
||||
|
||||
test "raises an exception" do
|
||||
assert_raises(AbstractController::DoubleRenderError) do
|
||||
get "/render/double_render"
|
||||
get "/render/double_render", {}, "action_dispatch.show_exceptions" => false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -58,13 +58,13 @@ module Render
|
||||
|
||||
test "raises an exception when a method of Object is called" do
|
||||
assert_raises(AbstractController::ActionNotFound) do
|
||||
get "/render/blank_render/clone"
|
||||
get "/render/blank_render/clone", {}, "action_dispatch.show_exceptions" => false
|
||||
end
|
||||
end
|
||||
|
||||
test "raises an exception when a private method is called" do
|
||||
assert_raises(AbstractController::ActionNotFound) do
|
||||
get "/render/blank_render/secretz"
|
||||
get "/render/blank_render/secretz", {}, "action_dispatch.show_exceptions" => false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
11
actionpack/test/new_base/render_xml_test.rb
Normal file
11
actionpack/test/new_base/render_xml_test.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
|
||||
|
||||
module RenderXml
|
||||
|
||||
# This has no layout and it works
|
||||
class BasicController < ActionController::Base
|
||||
self.view_paths = [ActionView::Template::FixturePath.new(
|
||||
"render_xml/basic/with_render_erb" => "Hello world!"
|
||||
)]
|
||||
end
|
||||
end
|
||||
@@ -46,7 +46,7 @@ class Rack::TestCase < ActiveSupport::TestCase
|
||||
ActionController::Routing.use_controllers!(controllers)
|
||||
|
||||
# Move into a bootloader
|
||||
AbstractController::Base.subclasses.each do |klass|
|
||||
ActionController::Base.subclasses.each do |klass|
|
||||
klass = klass.constantize
|
||||
next unless klass < AbstractController::Layouts
|
||||
klass.class_eval do
|
||||
@@ -59,12 +59,28 @@ class Rack::TestCase < ActiveSupport::TestCase
|
||||
@app ||= ActionController::Dispatcher.new
|
||||
end
|
||||
|
||||
def self.testing(klass = nil)
|
||||
if klass
|
||||
@testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
|
||||
else
|
||||
@testing
|
||||
end
|
||||
end
|
||||
|
||||
def self.get(url)
|
||||
setup do |test|
|
||||
test.get url
|
||||
end
|
||||
end
|
||||
|
||||
def get(thing, *args)
|
||||
if thing.is_a?(Symbol)
|
||||
super("#{self.class.testing}/#{thing}")
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def assert_body(body)
|
||||
assert_equal body, Array.wrap(last_response.body).join
|
||||
end
|
||||
@@ -85,6 +101,14 @@ class Rack::TestCase < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def assert_response(body, status = 200, headers = {})
|
||||
assert_body body
|
||||
assert_status status
|
||||
headers.each do |header, value|
|
||||
assert_header header, value
|
||||
end
|
||||
end
|
||||
|
||||
def assert_content_type(type)
|
||||
assert_equal type, last_response.headers["Content-Type"]
|
||||
end
|
||||
|
||||
@@ -80,6 +80,14 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
)
|
||||
end
|
||||
|
||||
def test_string_options_for_select
|
||||
options = "<option value=\"Denmark\">Denmark</option><option value=\"USA\">USA</option><option value=\"Sweden\">Sweden</option>"
|
||||
assert_dom_equal(
|
||||
options,
|
||||
options_for_select(options)
|
||||
)
|
||||
end
|
||||
|
||||
def test_array_options_for_select
|
||||
assert_dom_equal(
|
||||
"<option value=\"<Denmark>\"><Denmark></option>\n<option value=\"USA\">USA</option>\n<option value=\"Sweden\">Sweden</option>",
|
||||
@@ -324,6 +332,20 @@ class FormOptionsHelperTest < ActionView::TestCase
|
||||
)
|
||||
end
|
||||
|
||||
def test_select_under_fields_for_with_string_and_given_prompt
|
||||
@post = Post.new
|
||||
options = "<option value=\"abe\">abe</option><option value=\"mus\">mus</option><option value=\"hest\">hest</option>"
|
||||
|
||||
fields_for :post, @post do |f|
|
||||
concat f.select(:category, options, :prompt => 'The prompt')
|
||||
end
|
||||
|
||||
assert_dom_equal(
|
||||
"<select id=\"post_category\" name=\"post[category]\"><option value=\"\">The prompt</option>\n#{options}</select>",
|
||||
output_buffer
|
||||
)
|
||||
end
|
||||
|
||||
def test_select_with_blank
|
||||
@post = Post.new
|
||||
@post.category = "<mus>"
|
||||
|
||||
@@ -118,6 +118,10 @@ class NumberHelperTest < ActionView::TestCase
|
||||
assert_equal '1.01 KB', number_to_human_size(1.0123.kilobytes, :precision => 2)
|
||||
assert_equal '1.01 KB', number_to_human_size(1.0100.kilobytes, :precision => 4)
|
||||
assert_equal '10 KB', number_to_human_size(10.000.kilobytes, :precision => 4)
|
||||
assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 0)
|
||||
assert_equal '500 MB', number_to_human_size(524288000, :precision=>0)
|
||||
assert_equal '40 KB', number_to_human_size(41010, :precision => 0)
|
||||
assert_equal '40 KB', number_to_human_size(41100, :precision => 0)
|
||||
end
|
||||
|
||||
def test_number_to_human_size_with_custom_delimiter_and_separator
|
||||
|
||||
@@ -401,6 +401,13 @@ class TextHelperTest < ActionView::TestCase
|
||||
auto_link("Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com.",
|
||||
:link => :all, :html => { :class => "menu", :target => "_blank" })
|
||||
end
|
||||
|
||||
def test_auto_link_with_multiple_trailing_punctuations
|
||||
url = "http://youtube.com"
|
||||
url_result = generate_result(url)
|
||||
assert_equal url_result, auto_link(url)
|
||||
assert_equal "(link: #{url_result}).", auto_link("(link: #{url}).")
|
||||
end
|
||||
|
||||
def test_cycle_class
|
||||
value = Cycle.new("one", 2, "3")
|
||||
|
||||
@@ -11,6 +11,12 @@ Rake::TestTask.new do |t|
|
||||
t.verbose = true
|
||||
t.warning = true
|
||||
end
|
||||
task :isolated_test do
|
||||
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
|
||||
Dir.glob("test/**/*_test.rb").all? do |file|
|
||||
system(ruby, '-Ilib:test', file)
|
||||
end or raise "Failures"
|
||||
end
|
||||
|
||||
# Generate the RDoc documentation
|
||||
Rake::RDocTask.new do |rdoc|
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'test_helper'
|
||||
require 'active_model/state_machine/event'
|
||||
|
||||
class EventTest < ActiveModel::TestCase
|
||||
def setup
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'test_helper'
|
||||
require 'active_model/state_machine/state_transition'
|
||||
|
||||
class StateTransitionTest < ActiveModel::TestCase
|
||||
test 'should set from, to, and opts attr readers' do
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
*Edge*
|
||||
|
||||
* Implement #many? for NamedScope and AssociationCollection using #size. #1500 [Chris Kampmeier]
|
||||
|
||||
* Added :touch option to belongs_to associations that will touch the parent record when the current record is saved or destroyed [DHH]
|
||||
|
||||
* Added ActiveRecord::Base#touch to update the updated_at/on attributes (or another specified timestamp) with the current time [DHH]
|
||||
|
||||
@@ -32,21 +32,32 @@ desc 'Run mysql, sqlite, and postgresql tests'
|
||||
task :test => defined?(JRUBY_VERSION) ?
|
||||
%w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
|
||||
%w(test_mysql test_sqlite3 test_postgresql)
|
||||
task :isolated_test => defined?(JRUBY_VERSION) ?
|
||||
%w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) :
|
||||
%w(isolated_test_mysql isolated_test_sqlite3 isolated_test_postgresql)
|
||||
|
||||
for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb )
|
||||
%w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
|
||||
Rake::TestTask.new("test_#{adapter}") { |t|
|
||||
if adapter =~ /jdbc/
|
||||
t.libs << "test" << "test/connections/jdbc_#{adapter}"
|
||||
else
|
||||
t.libs << "test" << "test/connections/native_#{adapter}"
|
||||
end
|
||||
connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}"
|
||||
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
|
||||
t.libs << "test" << connection_path
|
||||
t.test_files=Dir.glob( "test/cases/**/*_test{,_#{adapter_short}}.rb" ).sort
|
||||
t.verbose = true
|
||||
}
|
||||
|
||||
task "isolated_test_#{adapter}" do
|
||||
connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}"
|
||||
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
|
||||
puts [adapter, adapter_short, connection_path].inspect
|
||||
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
|
||||
Dir["test/cases/**/*_test{,_#{adapter_short}}.rb"].all? do |file|
|
||||
system(ruby, "-Ilib:test:#{connection_path}", file)
|
||||
end or raise "Failures"
|
||||
end
|
||||
|
||||
namespace adapter do
|
||||
task :test => "test_#{adapter}"
|
||||
task :isolated_test => "isolated_test_#{adapter}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
14
activerecord/examples/simple.rb
Normal file
14
activerecord/examples/simple.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
||||
require 'active_record'
|
||||
|
||||
class Person < ActiveRecord::Base
|
||||
establish_connection :adapter => 'sqlite3', :database => 'foobar.db'
|
||||
connection.create_table table_name, :force => true do |t|
|
||||
t.string :name
|
||||
end
|
||||
end
|
||||
|
||||
bob = Person.create!(:name => 'bob')
|
||||
puts Person.all.inspect
|
||||
bob.destroy
|
||||
puts Person.all.inspect
|
||||
@@ -24,7 +24,9 @@
|
||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||
$:.unshift(activesupport_path) if File.directory?(activesupport_path)
|
||||
require 'active_support'
|
||||
require 'active_support/core/all'
|
||||
|
||||
# TODO: Figure out what parts of AS are *actually* required and use those
|
||||
require 'active_support/core_ext'
|
||||
|
||||
$:.unshift(File.dirname(__FILE__) + '/../../arel/lib')
|
||||
require 'arel'
|
||||
@@ -78,5 +80,4 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
require 'active_record/i18n_interpolation_deprecation'
|
||||
I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
|
||||
module ActiveRecord
|
||||
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
|
||||
def initialize(reflection)
|
||||
@@ -1674,7 +1676,7 @@ module ActiveRecord
|
||||
|
||||
def tables_in_string(string)
|
||||
return [] if string.blank?
|
||||
string.scan(/([\.a-zA-Z_]+).?\./).flatten
|
||||
string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten
|
||||
end
|
||||
|
||||
def tables_in_hash(hash)
|
||||
|
||||
@@ -302,6 +302,15 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the collection has more than 1 record. Equivalent to collection.size > 1.
|
||||
def many?
|
||||
if block_given?
|
||||
method_missing(:many?) { |*block_args| yield(*block_args) }
|
||||
else
|
||||
size > 1
|
||||
end
|
||||
end
|
||||
|
||||
def uniq(collection = self)
|
||||
seen = Set.new
|
||||
collection.inject([]) do |kept, record|
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user