aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-06-02 12:36:36 -0300
committerEmilio Tagua <miloops@gmail.com>2009-06-02 12:36:36 -0300
commitfd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90 (patch)
tree89f6b8eeae81ba9e9f3c43667b234b64a776e649 /actionpack
parent5255a81b808c2c947d58df979e6436b1fe1d8157 (diff)
parent196f780e30fcece25e4d09c12f9b9f7374ebed29 (diff)
downloadrails-fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90.tar.gz
rails-fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90.tar.bz2
rails-fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90.zip
Merge commit 'rails/master'
Conflicts: activerecord/lib/active_record.rb
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG3
-rw-r--r--actionpack/Rakefile15
-rw-r--r--actionpack/examples/minimal.rb17
-rw-r--r--actionpack/lib/action_controller/abstract.rb2
-rw-r--r--actionpack/lib/action_controller/abstract/base.rb38
-rw-r--r--actionpack/lib/action_controller/abstract/benchmarker.rb10
-rw-r--r--actionpack/lib/action_controller/abstract/callbacks.rb27
-rw-r--r--actionpack/lib/action_controller/abstract/exceptions.rb4
-rw-r--r--actionpack/lib/action_controller/abstract/helpers.rb13
-rw-r--r--actionpack/lib/action_controller/abstract/layouts.rb29
-rw-r--r--actionpack/lib/action_controller/abstract/logger.rb14
-rw-r--r--actionpack/lib/action_controller/abstract/renderer.rb32
-rw-r--r--actionpack/lib/action_controller/base/chained/filters.rb7
-rw-r--r--actionpack/lib/action_controller/base/chained/flash.rb85
-rw-r--r--actionpack/lib/action_controller/base/cookies.rb2
-rw-r--r--actionpack/lib/action_controller/base/filter_parameter_logging.rb8
-rw-r--r--actionpack/lib/action_controller/base/helpers.rb2
-rw-r--r--actionpack/lib/action_controller/base/request_forgery_protection.rb4
-rw-r--r--actionpack/lib/action_controller/base/streaming.rb4
-rw-r--r--actionpack/lib/action_controller/base/verification.rb4
-rw-r--r--actionpack/lib/action_controller/caching.rb2
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb2
-rw-r--r--actionpack/lib/action_controller/new_base.rb3
-rw-r--r--actionpack/lib/action_controller/new_base/base.rb23
-rw-r--r--actionpack/lib/action_controller/new_base/compatibility.rb62
-rw-r--r--actionpack/lib/action_controller/new_base/conditional_get.rb32
-rw-r--r--actionpack/lib/action_controller/new_base/helpers.rb53
-rw-r--r--actionpack/lib/action_controller/new_base/hide_actions.rb48
-rw-r--r--actionpack/lib/action_controller/new_base/http.rb80
-rw-r--r--actionpack/lib/action_controller/new_base/layouts.rb44
-rw-r--r--actionpack/lib/action_controller/new_base/rack_convenience.rb33
-rw-r--r--actionpack/lib/action_controller/new_base/redirector.rb8
-rw-r--r--actionpack/lib/action_controller/new_base/render_options.rb58
-rw-r--r--actionpack/lib/action_controller/new_base/renderer.rb96
-rw-r--r--actionpack/lib/action_controller/new_base/rescuable.rb31
-rw-r--r--actionpack/lib/action_controller/new_base/session.rb4
-rw-r--r--actionpack/lib/action_controller/new_base/testing.rb7
-rw-r--r--actionpack/lib/action_controller/new_base/url_for.rb10
-rw-r--r--actionpack/lib/action_controller/routing/resources.rb3
-rw-r--r--actionpack/lib/action_controller/routing/segments.rb2
-rw-r--r--actionpack/lib/action_controller/testing/integration.rb2
-rw-r--r--actionpack/lib/action_controller/testing/process2.rb3
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb16
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb2
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb13
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb3
-rw-r--r--actionpack/lib/action_view/render/partials.rb2
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb8
-rw-r--r--actionpack/lib/action_view/template/template.rb20
-rw-r--r--actionpack/test/controller/cookie_test.rb6
-rw-r--r--actionpack/test/controller/filters_test.rb102
-rw-r--r--actionpack/test/controller/flash_test.rb22
-rw-r--r--actionpack/test/controller/routing_test.rb13
-rw-r--r--actionpack/test/controller/view_paths_test.rb4
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb4
-rw-r--r--actionpack/test/fixtures/test/utf8.html.erb4
-rw-r--r--actionpack/test/fixtures/test/utf8_magic.html.erb5
-rw-r--r--actionpack/test/template/body_parts_test.rb5
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb6
-rw-r--r--actionpack/test/template/output_buffer_test.rb75
-rw-r--r--actionpack/test/template/render_test.rb25
62 files changed, 761 insertions, 503 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index e3ad19558e..e758983d7a 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,8 @@
*Edge*
+* Ruby 1.9: ERB template encoding using a magic comment at the top of the file. [Jeremy Kemper]
+ <%# encoding: utf-8 %>
+
* Change integration test helpers to accept Rack environment instead of just HTTP Headers [Pratik Naik]
Before : get '/path', {}, 'Accept' => 'text/javascript'
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index 9ce897aae8..5f5614e58f 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -59,24 +59,21 @@ end
desc 'Old Controller Tests on New Base'
Rake::TestTask.new(:test_new_base_on_old_tests) do |t|
t.libs << "test/new_base" << "test/lib"
- # layout
- # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort +
+ t.verbose = true
# ==== Not ported
# * filters
- # * integration
- # * test
- # * view_paths
- t.test_files = %w(
+
+ t.test_files = Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + %w(
action_pack_assertions addresses_render assert_select
base benchmark caching capture content_type cookie dispatcher
filter_params flash helper http_basic_authentication
- http_digest_authentication layout logging mime_responds
+ http_digest_authentication integration layout logging mime_responds
record_identifier redirect render render_js render_json
render_other render_xml request_forgery_protection rescue
- resources routing selector send_file url_rewriter verification webservice
+ resources routing selector send_file test url_rewriter
+ verification view_paths webservice
).map { |name| "test/controller/#{name}_test.rb" }
- t.verbose = true
end
# Genereate the RDoc documentation
diff --git a/actionpack/examples/minimal.rb b/actionpack/examples/minimal.rb
index e2d112648c..9eb92cd8e7 100644
--- a/actionpack/examples/minimal.rb
+++ b/actionpack/examples/minimal.rb
@@ -24,10 +24,12 @@ class Runner
out.puts '---'
end
- def self.run(app, n)
+ def self.run(app, n, label = nil)
+ puts '=' * label.size, label, '=' * label.size if label
env = { 'n' => n, 'rack.input' => StringIO.new(''), 'rack.errors' => $stdout }
t = Benchmark.realtime { new(app).call(env) }
- puts "%d ms / %d req = %d usec/req" % [10**3 * t, n, 10**6 * t / n]
+ puts "%d ms / %d req = %.1f usec/req" % [10**3 * t, n, 10**6 * t / n]
+ puts
end
end
@@ -38,16 +40,19 @@ class BasePostController < ActionController::Base
def index
render :text => ''
end
-
- Runner.run(action(:index), N)
end
+OK = [200, {}, []]
+MetalPostController = lambda { OK }
+
if ActionController.const_defined?(:Http)
class HttpPostController < ActionController::Http
def index
self.response_body = ''
end
-
- Runner.run(action(:index), N)
end
end
+
+Runner.run(MetalPostController, N, 'metal')
+Runner.run(HttpPostController.action(:index), N, 'http') if defined? HttpPostController
+Runner.run(BasePostController.action(:index), N, 'base')
diff --git a/actionpack/lib/action_controller/abstract.rb b/actionpack/lib/action_controller/abstract.rb
index d6b7a44f5f..f46b91627f 100644
--- a/actionpack/lib/action_controller/abstract.rb
+++ b/actionpack/lib/action_controller/abstract.rb
@@ -11,4 +11,4 @@ module AbstractController
autoload :Renderer, "action_controller/abstract/renderer"
# === Exceptions
autoload :ActionNotFound, "action_controller/abstract/exceptions"
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb
index 0e4803388a..87083a4d79 100644
--- a/actionpack/lib/action_controller/abstract/base.rb
+++ b/actionpack/lib/action_controller/abstract/base.rb
@@ -2,28 +2,27 @@ 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
-
+ end
+
class Base
-
attr_internal :response_body
attr_internal :response_obj
attr_internal :action_name
class << self
- attr_reader :abstract
-
+ attr_reader :abstract
+
def abstract!
@abstract = true
end
-
+
alias_method :abstract?, :abstract
def inherited(klass)
@@ -34,13 +33,13 @@ module AbstractController
def subclasses
@subclasses ||= []
end
-
+
def internal_methods
controller = self
controller = controller.superclass until controller.abstract?
controller.public_instance_methods(true)
end
-
+
def process(action)
new.process(action.to_s)
end
@@ -48,7 +47,7 @@ module AbstractController
def hidden_actions
[]
end
-
+
def action_methods
@action_methods ||=
# All public instance methods of this class, including ancestors
@@ -61,13 +60,13 @@ module AbstractController
hidden_actions
end
end
-
+
abstract!
-
+
def initialize
self.response_obj = {}
end
-
+
def process(action)
@_action_name = action_name = action.to_s
@@ -78,26 +77,27 @@ module AbstractController
process_action(action_name)
self
end
-
+
private
-
def action_methods
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(method_name)
- send(method_name)
+ send_action(method_name)
end
+ alias send_action send
+
def _handle_action_missing
action_missing(@_action_name)
end
@@ -112,4 +112,4 @@ module AbstractController
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/benchmarker.rb b/actionpack/lib/action_controller/abstract/benchmarker.rb
index 9f5889c704..07294cede3 100644
--- a/actionpack/lib/action_controller/abstract/benchmarker.rb
+++ b/actionpack/lib/action_controller/abstract/benchmarker.rb
@@ -1,9 +1,9 @@
module AbstractController
module Benchmarker
- extend ActiveSupport::DependencyModule
-
- depends_on Logger
-
+ extend ActiveSupport::Concern
+
+ include Logger
+
module ClassMethods
def benchmark(title, log_level = ::Logger::DEBUG, use_silence = true)
if logger && logger.level >= log_level
@@ -25,4 +25,4 @@ module AbstractController
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb
index e4f9dd3112..affe053bac 100644
--- a/actionpack/lib/action_controller/abstract/callbacks.rb
+++ b/actionpack/lib/action_controller/abstract/callbacks.rb
@@ -1,8 +1,8 @@
module AbstractController
module Callbacks
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
- depends_on ActiveSupport::NewCallbacks
+ include ActiveSupport::NewCallbacks
included do
define_callbacks :process_action, "response_body"
@@ -13,7 +13,7 @@ module AbstractController
super
end
end
-
+
module ClassMethods
def _normalize_callback_options(options)
if only = options[:only]
@@ -21,11 +21,17 @@ module AbstractController
options[:per_key] = {:if => only}
end
if except = options[:except]
- except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
+ except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
options[:per_key] = {:unless => except}
end
end
-
+
+ def skip_filter(*names, &blk)
+ skip_before_filter(*names, &blk)
+ skip_after_filter(*names, &blk)
+ skip_around_filter(*names, &blk)
+ end
+
[:before, :after, :around].each do |filter|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{filter}_filter(*names, &blk)
@@ -37,6 +43,15 @@ module AbstractController
end
end
+ def prepend_#{filter}_filter(*names, &blk)
+ options = names.last.is_a?(Hash) ? names.pop : {}
+ _normalize_callback_options(options)
+ names.push(blk) if block_given?
+ names.each do |name|
+ process_action_callback(:#{filter}, name, options.merge(:prepend => true))
+ end
+ end
+
def skip_#{filter}_filter(*names, &blk)
options = names.last.is_a?(Hash) ? names.pop : {}
_normalize_callback_options(options)
@@ -51,4 +66,4 @@ module AbstractController
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/exceptions.rb b/actionpack/lib/action_controller/abstract/exceptions.rb
index ec4680629b..2f6c55f068 100644
--- a/actionpack/lib/action_controller/abstract/exceptions.rb
+++ b/actionpack/lib/action_controller/abstract/exceptions.rb
@@ -1,3 +1,3 @@
module AbstractController
- class ActionNotFound < StandardError ; end
-end \ No newline at end of file
+ class ActionNotFound < StandardError; end
+end
diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb
index 41decfd0c7..0a2776de9c 100644
--- a/actionpack/lib/action_controller/abstract/helpers.rb
+++ b/actionpack/lib/action_controller/abstract/helpers.rb
@@ -1,8 +1,8 @@
module AbstractController
module Helpers
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
- depends_on Renderer
+ include Renderer
included do
extlib_inheritable_accessor :master_helper_module
@@ -16,12 +16,12 @@ module AbstractController
av
end
end
-
+
module ClassMethods
def inherited(klass)
klass.master_helper_module = Module.new
klass.master_helper_module.__send__ :include, master_helper_module
-
+
super
end
@@ -57,7 +57,7 @@ module AbstractController
ruby_eval
end
end
-
+
def helper(*args, &block)
args.flatten.each do |arg|
case arg
@@ -68,6 +68,5 @@ module AbstractController
master_helper_module.module_eval(&block) if block_given?
end
end
-
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb
index 3d6810bda9..273063f74b 100644
--- a/actionpack/lib/action_controller/abstract/layouts.rb
+++ b/actionpack/lib/action_controller/abstract/layouts.rb
@@ -1,8 +1,8 @@
module AbstractController
module Layouts
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
- depends_on Renderer
+ include Renderer
included do
extlib_inheritable_accessor :_layout_conditions
@@ -17,18 +17,18 @@ module AbstractController
conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
self._layout_conditions = conditions
-
+
@_layout = layout || false # Converts nil to false
_write_layout_method
end
-
+
def _implied_layout_name
name.underscore
end
-
+
# Takes the specified layout and creates a _layout method to be called
# by _default_layout
- #
+ #
# If the specified layout is a:
# String:: return the string
# Symbol:: call the method specified by the symbol
@@ -57,11 +57,12 @@ module AbstractController
end
end
end
-
+
private
-
- def _layout(details) end # This will be overwritten
-
+ # This will be overwritten
+ def _layout(details)
+ end
+
# :api: plugin
# ====
# Override this to mutate the inbound layout name
@@ -69,7 +70,7 @@ module AbstractController
unless [String, FalseClass, NilClass].include?(name.class)
raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
end
-
+
name && view_paths.find_by_parts(name, details, _layout_prefix(name))
end
@@ -77,7 +78,7 @@ module AbstractController
def _layout_prefix(name)
"layouts"
end
-
+
def _default_layout(require_layout = false, details = {:formats => formats})
if require_layout && _action_has_layout? && !_layout(details)
raise ArgumentError,
@@ -87,7 +88,7 @@ module AbstractController
begin
_layout_for_name(_layout(details), details) if _action_has_layout?
rescue NameError => e
- raise NoMethodError,
+ raise NoMethodError,
"You specified #{@_layout.inspect} as the layout, but no such method was found"
end
end
@@ -103,4 +104,4 @@ module AbstractController
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/logger.rb b/actionpack/lib/action_controller/abstract/logger.rb
index 980ede0bed..d6fa843485 100644
--- a/actionpack/lib/action_controller/abstract/logger.rb
+++ b/actionpack/lib/action_controller/abstract/logger.rb
@@ -3,13 +3,13 @@ require 'active_support/core_ext/logger'
module AbstractController
module Logger
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
class DelayedLog
def initialize(&blk)
@blk = blk
end
-
+
def to_s
@blk.call
end
@@ -19,10 +19,10 @@ module AbstractController
included do
cattr_accessor :logger
end
-
+
def process(action)
ret = super
-
+
if logger
log = DelayedLog.new do
"\n\nProcessing #{self.class.name}\##{action_name} " \
@@ -32,14 +32,14 @@ module AbstractController
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
diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb
index d7c68549e1..dd58c7cb64 100644
--- a/actionpack/lib/action_controller/abstract/renderer.rb
+++ b/actionpack/lib/action_controller/abstract/renderer.rb
@@ -2,9 +2,9 @@ require "action_controller/abstract/logger"
module AbstractController
module Renderer
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
- depends_on AbstractController::Logger
+ include AbstractController::Logger
included do
attr_internal :formats
@@ -15,22 +15,22 @@ module AbstractController
end
def _action_view
- @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
+ @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
end
-
+
def render(*args)
if response_body
raise AbstractController::DoubleRenderError, "OMG"
end
-
+
self.response_body = render_to_body(*args)
end
-
+
# Raw rendering of a template to a Rack-compatible body.
# ====
# @option _prefix<String> The template's path prefix
# @option _layout<String> The relative path to the layout template to use
- #
+ #
# :api: plugin
def render_to_body(options = {})
# TODO: Refactor so we can just use the normal template logic for this
@@ -46,7 +46,7 @@ module AbstractController
# ====
# @option _prefix<String> The template's path prefix
# @option _layout<String> The relative path to the layout template to use
- #
+ #
# :api: plugin
def render_to_string(options = {})
AbstractController::Renderer.body_to_s(render_to_body(options))
@@ -55,8 +55,10 @@ module AbstractController
def _render_template(options)
_action_view._render_template_from_controller(options[:_template], options[:_layout], options, options[:_partial])
end
-
- def view_paths() _view_paths end
+
+ def view_paths()
+ _view_paths
+ end
# Return a string representation of a Rack-compatible response body.
def self.body_to_s(body)
@@ -71,7 +73,6 @@ module AbstractController
end
private
-
def _determine_template(options)
name = (options[:_template_name] || action_name).to_s
@@ -81,15 +82,18 @@ module AbstractController
end
module ClassMethods
-
def append_view_path(path)
self.view_paths << path
end
-
+
+ def prepend_view_path(path)
+ self.view_paths.unshift(path)
+ end
+
def view_paths
self._view_paths
end
-
+
def view_paths=(paths)
self._view_paths = paths.is_a?(ActionView::PathSet) ?
paths : ActionView::Base.process_view_paths(paths)
diff --git a/actionpack/lib/action_controller/base/chained/filters.rb b/actionpack/lib/action_controller/base/chained/filters.rb
index e121c0129d..f528dd0686 100644
--- a/actionpack/lib/action_controller/base/chained/filters.rb
+++ b/actionpack/lib/action_controller/base/chained/filters.rb
@@ -1,11 +1,6 @@
module ActionController #:nodoc:
module Filters #:nodoc:
- def self.included(base)
- base.class_eval do
- extend ClassMethods
- include ActionController::Filters::InstanceMethods
- end
- end
+ extend ActiveSupport::Concern
class FilterChain < ActiveSupport::Callbacks::CallbackChain #:nodoc:
def append_filter_to_chain(filters, filter_type, &block)
diff --git a/actionpack/lib/action_controller/base/chained/flash.rb b/actionpack/lib/action_controller/base/chained/flash.rb
index 6bd482d85a..42c6e430ca 100644
--- a/actionpack/lib/action_controller/base/chained/flash.rb
+++ b/actionpack/lib/action_controller/base/chained/flash.rb
@@ -26,11 +26,11 @@ module ActionController #:nodoc:
#
# See docs on the FlashHash class for more details about the flash.
module Flash
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
- depends_on Session if defined?(ActionController::Http)
-
+ include Session if defined?(ActionController::Http)
+
included do
# TODO : Remove the defined? check when new base is the main base
if defined?(ActionController::Http)
@@ -129,65 +129,68 @@ module ActionController #:nodoc:
(@used.keys - keys).each{ |k| @used.delete(k) }
end
+ def store(session, key = "flash")
+ return if self.empty?
+ session[key] = self
+ end
+
private
# Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
# use() # marks the entire flash as used
# use('msg') # marks the "msg" entry as used
# use(nil, false) # marks the entire flash as unused (keeps it around for one more action)
# use('msg', false) # marks the "msg" entry as unused (keeps it around for one more action)
- def use(k=nil, v=true)
- unless k.nil?
- @used[k] = v
- else
- keys.each{ |key| use(key, v) }
- end
+ # Returns the single value for the key you asked to be marked (un)used or the FlashHash itself
+ # if no key is passed.
+ def use(key = nil, used = true)
+ Array(key || keys).each { |k| @used[k] = used }
+ return key ? self[key] : self
end
end
module InstanceMethodsForBase #:nodoc:
protected
+ def perform_action_with_flash
+ perform_action_without_flash
+ if defined? @_flash
+ @_flash.store(session)
+ remove_instance_variable(:@_flash)
+ end
+ end
- def perform_action_with_flash
- perform_action_without_flash
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
-
- def reset_session_with_flash
- reset_session_without_flash
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
+ def reset_session_with_flash
+ reset_session_without_flash
+ remove_instance_variable(:@_flash) if defined?(@_flash)
+ end
end
module InstanceMethodsForNewBase #:nodoc:
protected
+ def process_action(method_name)
+ super
+ if defined? @_flash
+ @_flash.store(session)
+ remove_instance_variable(:@_flash)
+ end
+ end
- def reset_session
- super
- remove_flash_instance_variable
- end
-
- def process_action(method_name)
- super
- remove_flash_instance_variable
- end
-
- def remove_flash_instance_variable
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
+ def reset_session
+ super
+ remove_instance_variable(:@_flash) if defined?(@_flash)
+ end
end
protected
+ # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
+ # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
+ # to put a new one.
+ def flash #:doc:
+ if !defined?(@_flash)
+ @_flash = session["flash"] || FlashHash.new
+ @_flash.sweep
+ end
- # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
- # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
- # to put a new one.
- def flash #:doc:
- unless defined?(@_flash)
- @_flash = session["flash"] ||= FlashHash.new
- @_flash.sweep
+ @_flash
end
-
- @_flash
- end
end
end
diff --git a/actionpack/lib/action_controller/base/cookies.rb b/actionpack/lib/action_controller/base/cookies.rb
index ca380e98d0..d4806623c3 100644
--- a/actionpack/lib/action_controller/base/cookies.rb
+++ b/actionpack/lib/action_controller/base/cookies.rb
@@ -51,7 +51,7 @@ module ActionController #:nodoc:
protected
# Returns the cookie container, which operates as described above.
def cookies
- CookieJar.new(self)
+ @cookies ||= CookieJar.new(self)
end
end
diff --git a/actionpack/lib/action_controller/base/filter_parameter_logging.rb b/actionpack/lib/action_controller/base/filter_parameter_logging.rb
index f5a678ca03..8370ba6fc0 100644
--- a/actionpack/lib/action_controller/base/filter_parameter_logging.rb
+++ b/actionpack/lib/action_controller/base/filter_parameter_logging.rb
@@ -1,16 +1,14 @@
module ActionController
module FilterParameterLogging
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
if defined?(ActionController::Http)
- depends_on AbstractController::Logger
+ include AbstractController::Logger
end
included do
- if defined?(ActionController::Http)
- include InstanceMethodsForNewBase
- end
+ include InstanceMethodsForNewBase
end
module ClassMethods
diff --git a/actionpack/lib/action_controller/base/helpers.rb b/actionpack/lib/action_controller/base/helpers.rb
index 96fa7896a9..f74158bc13 100644
--- a/actionpack/lib/action_controller/base/helpers.rb
+++ b/actionpack/lib/action_controller/base/helpers.rb
@@ -3,7 +3,7 @@ require 'active_support/dependencies'
# FIXME: helper { ... } is broken on Ruby 1.9
module ActionController #:nodoc:
module Helpers #:nodoc:
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
included do
# Initialize the base module to aggregate its helpers.
diff --git a/actionpack/lib/action_controller/base/request_forgery_protection.rb b/actionpack/lib/action_controller/base/request_forgery_protection.rb
index 0a0e20e1f1..a470c8eec1 100644
--- a/actionpack/lib/action_controller/base/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/base/request_forgery_protection.rb
@@ -3,11 +3,11 @@ module ActionController #:nodoc:
end
module RequestForgeryProtection
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
if defined?(ActionController::Http)
- depends_on AbstractController::Helpers, Session
+ include AbstractController::Helpers, Session
end
included do
diff --git a/actionpack/lib/action_controller/base/streaming.rb b/actionpack/lib/action_controller/base/streaming.rb
index 5872ba99a2..73d4bde6c1 100644
--- a/actionpack/lib/action_controller/base/streaming.rb
+++ b/actionpack/lib/action_controller/base/streaming.rb
@@ -2,11 +2,11 @@ module ActionController #:nodoc:
# Methods for sending arbitrary data and for streaming files to the browser,
# instead of rendering.
module Streaming
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
if defined?(ActionController::Http)
- depends_on ActionController::Renderer
+ include ActionController::Renderer
end
DEFAULT_SEND_FILE_OPTIONS = {
diff --git a/actionpack/lib/action_controller/base/verification.rb b/actionpack/lib/action_controller/base/verification.rb
index 3fa5a105b1..d87b348ed4 100644
--- a/actionpack/lib/action_controller/base/verification.rb
+++ b/actionpack/lib/action_controller/base/verification.rb
@@ -1,10 +1,10 @@
module ActionController #:nodoc:
module Verification #:nodoc:
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
if defined?(ActionController::Http)
- depends_on AbstractController::Callbacks, Session, Flash, Renderer
+ include AbstractController::Callbacks, Session, Flash, Renderer
end
# This module provides a class-level method for specifying that certain
diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb
index 2f2eec10f6..38cf1da6a8 100644
--- a/actionpack/lib/action_controller/caching.rb
+++ b/actionpack/lib/action_controller/caching.rb
@@ -24,7 +24,7 @@ module ActionController #:nodoc:
# ActionController::Base.cache_store = :mem_cache_store, "localhost"
# ActionController::Base.cache_store = MyOwnStore.new("parameter")
module Caching
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
autoload :Actions, 'action_controller/caching/actions'
autoload :Fragments, 'action_controller/caching/fragments'
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 3646ff1af9..54148b55d8 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -93,7 +93,7 @@ module ActionController #:nodoc:
# TODO: Remove once New Base is merged
if defined?(ActionController::Http)
- def around_process_action(controller)
+ def filter(controller)
should_continue = before(controller)
yield if should_continue
after(controller)
diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb
index 276be50614..df256985ac 100644
--- a/actionpack/lib/action_controller/new_base.rb
+++ b/actionpack/lib/action_controller/new_base.rb
@@ -4,6 +4,7 @@ module ActionController
autoload :HideActions, "action_controller/new_base/hide_actions"
autoload :Http, "action_controller/new_base/http"
autoload :Layouts, "action_controller/new_base/layouts"
+ autoload :RackConvenience, "action_controller/new_base/rack_convenience"
autoload :Rails2Compatibility, "action_controller/new_base/compatibility"
autoload :Redirector, "action_controller/new_base/redirector"
autoload :Renderer, "action_controller/new_base/renderer"
@@ -40,5 +41,7 @@ module ActionController
require 'action_controller/routing'
end
+autoload :HTML, 'action_controller/vendor/html-scanner'
+
require 'action_dispatch'
require 'action_view'
diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb
index ffe608ade4..d7b65d37fa 100644
--- a/actionpack/lib/action_controller/new_base/base.rb
+++ b/actionpack/lib/action_controller/new_base/base.rb
@@ -1,7 +1,7 @@
module ActionController
class Base < Http
abstract!
-
+
include AbstractController::Benchmarker
include AbstractController::Callbacks
include AbstractController::Logger
@@ -14,6 +14,7 @@ module ActionController
include ActionController::Renderers::All
include ActionController::Layouts
include ActionController::ConditionalGet
+ include ActionController::RackConvenience
# Legacy modules
include SessionManagement
@@ -38,9 +39,9 @@ module ActionController
# TODO: Extract into its own module
# This should be moved together with other normalizing behavior
module ImplicitRender
- def process_action(method_name)
+ def send_action(method_name)
ret = super
- default_render if response_body.nil?
+ default_render unless performed?
ret
end
@@ -65,31 +66,31 @@ module ActionController
::ActionController::Base.subclasses << klass.to_s
super
end
-
+
def self.subclasses
@subclasses ||= []
end
-
+
def self.app_loaded!
@subclasses.each do |subclass|
subclass.constantize._write_layout_method
end
end
-
+
def _normalize_options(action = nil, options = {}, &blk)
if action.is_a?(Hash)
- options, action = action, nil
+ options, action = action, nil
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
+ end
options.merge! key => action
elsif action
options.merge! :partial => action
end
-
+
if options.key?(:action) && options[:action].to_s.index("/")
options[:template] = options.delete(:action)
end
@@ -139,7 +140,7 @@ module ActionController
#
# 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.
+ # behavior for this case by rescuing RedirectBackError.
def redirect_to(options = {}, response_status = {}) #:doc:
raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
@@ -165,7 +166,7 @@ module ActionController
else
url_for(options)
end
-
+
super(url, status)
end
end
diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb
index 4245ba982b..f278c2da14 100644
--- a/actionpack/lib/action_controller/new_base/compatibility.rb
+++ b/actionpack/lib/action_controller/new_base/compatibility.rb
@@ -1,6 +1,6 @@
module ActionController
module Rails2Compatibility
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
class ::ActionController::ActionControllerError < StandardError #:nodoc:
end
@@ -9,43 +9,43 @@ module ActionController
included do
::ActionController::UnknownAction = ::AbstractController::ActionNotFound
::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError
-
+
cattr_accessor :session_options
self.session_options = {}
-
+
cattr_accessor :allow_concurrency
self.allow_concurrency = false
-
+
cattr_accessor :param_parsers
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.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
-
+
cattr_accessor :default_charset
self.default_charset = "utf-8"
-
+
# 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)
-
+
# 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
@@ -61,19 +61,29 @@ module ActionController
# and images to a dedicated asset server away from the main web server. Example:
# ActionController::Base.asset_host = "http://assets.example.com"
cattr_accessor :asset_host
+
+ cattr_accessor :ip_spoofing_check
+ self.ip_spoofing_check = true
end
-
+
# For old tests
def initialize_template_class(*) end
def assign_shortcuts(*) end
# TODO: Remove this after we flip
def template
- _action_view
+ @template ||= _action_view
+ end
+
+ def process_action(*)
+ template
+ super
end
module ClassMethods
- def consider_all_requests_local() end
+ def consider_all_requests_local
+ end
+
def rescue_action(env)
raise env["action_dispatch.rescue.exception"]
end
@@ -84,16 +94,11 @@ module ActionController
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!(/^\//, '')
end
-
+
options[:text] = nil if options[:nothing] == true
body = super
@@ -107,8 +112,8 @@ module ActionController
def method_for_action(action_name)
super || (respond_to?(:method_missing) && "_handle_method_missing")
- end
-
+ end
+
def _layout_prefix(name)
super unless name =~ /\blayouts/
end
@@ -116,5 +121,18 @@ module ActionController
def performed?
response_body
end
+
+ # ==== Request only view path switching ====
+ def append_view_path(path)
+ view_paths.push(*path)
+ end
+
+ def prepend_view_path(path)
+ view_paths.unshift(*path)
+ end
+
+ def view_paths
+ _action_view.view_paths
+ end
end
end
diff --git a/actionpack/lib/action_controller/new_base/conditional_get.rb b/actionpack/lib/action_controller/new_base/conditional_get.rb
index 116ce34494..d287ec4994 100644
--- a/actionpack/lib/action_controller/new_base/conditional_get.rb
+++ b/actionpack/lib/action_controller/new_base/conditional_get.rb
@@ -1,12 +1,15 @@
module ActionController
module ConditionalGet
-
+ extend ActiveSupport::Concern
+
+ include RackConvenience
+
# Sets the etag, last_modified, or both on the response and renders a
# "304 Not Modified" response if the request is already fresh.
#
# Parameters:
# * <tt>:etag</tt>
- # * <tt>:last_modified</tt>
+ # * <tt>:last_modified</tt>
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
#
# Example:
@@ -18,14 +21,14 @@ module ActionController
#
# This will render the show template if the request isn't sending a matching etag or
# If-Modified-Since header and just a "304 Not Modified" response if there's a match.
- #
+ #
def fresh_when(options)
options.assert_valid_keys(:etag, :last_modified, :public)
response.etag = options[:etag] if options[:etag]
response.last_modified = options[:last_modified] if options[:last_modified]
-
- if options[:public]
+
+ if options[:public]
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
cache_control.delete("private")
cache_control.delete("no-cache")
@@ -36,8 +39,8 @@ module ActionController
if request.fresh?(response)
head :not_modified
end
- end
-
+ end
+
# Return a response that has no content (merely headers). The options
# argument is interpreted to be a hash of header names and values.
# This allows you to easily return a response that consists only of
@@ -64,8 +67,8 @@ module ActionController
end
render :nothing => true, :status => status
- end
-
+ end
+
# Sets the etag and/or last_modified on the response and checks it against
# the client request. If the request doesn't match the options provided, the
# request is considered stale and should be generated from scratch. Otherwise,
@@ -73,7 +76,7 @@ module ActionController
#
# Parameters:
# * <tt>:etag</tt>
- # * <tt>:last_modified</tt>
+ # * <tt>:last_modified</tt>
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
#
# Example:
@@ -92,7 +95,7 @@ module ActionController
fresh_when(options)
!request.fresh?(response)
end
-
+
# Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a "private" instruction, so that
# intermediate caches shouldn't cache the response.
#
@@ -114,10 +117,10 @@ module ActionController
else
cache_control << "private"
end
-
+
# This allows for additional headers to be passed through like 'max-stale' => 5.hours
cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
-
+
response.headers["Cache-Control"] = cache_control.join(', ')
end
@@ -126,6 +129,5 @@ module ActionController
def expires_now #:doc:
response.headers["Cache-Control"] = "no-cache"
end
-
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/new_base/helpers.rb b/actionpack/lib/action_controller/new_base/helpers.rb
index e00c3c338b..e8000be87b 100644
--- a/actionpack/lib/action_controller/new_base/helpers.rb
+++ b/actionpack/lib/action_controller/new_base/helpers.rb
@@ -4,9 +4,9 @@ require 'active_support/dependencies'
module ActionController
module Helpers
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
- depends_on AbstractController::Helpers
+ include AbstractController::Helpers
included do
# Set the default directory for helpers
@@ -24,10 +24,10 @@ module ActionController
#
# * <tt>*args</tt>: One or more modules, strings or symbols, or the special symbol <tt>:all</tt>.
# * <tt>&block</tt>: A block defining helper methods.
- #
+ #
# ==== Examples
- # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
- # and include the module in the template class. The second form illustrates how to include custom helpers
+ # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
+ # and include the module in the template class. The second form illustrates how to include custom helpers
# when working with namespaced controllers, or other cases where the file containing the helper definition is not
# in one of Rails' standard load paths:
# helper :foo # => requires 'foo_helper' and includes FooHelper
@@ -40,17 +40,17 @@ module ActionController
# <tt>ActionController::Base.helpers_dir</tt> (defaults to <tt>app/helpers/**/*.rb</tt> under RAILS_ROOT).
# helper :all
#
- # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
+ # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
# to the template.
# # One line
# helper { def hello() "Hello, world!" end }
# # Multi-line
# helper do
- # def foo(bar)
- # "#{bar} is the very best"
+ # def foo(bar)
+ # "#{bar} is the very best"
# end
# end
- #
+ #
# Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
# +symbols+, +strings+, +modules+ and blocks.
# helper(:three, BlindHelper) { def mice() 'mice' end }
@@ -106,25 +106,24 @@ module ActionController
end
private
-
- def default_helper_module!
- unless name.blank?
- module_name = name.sub(/Controller$|$/, 'Helper')
- module_path = module_name.split('::').map { |m| m.underscore }.join('/')
- require_dependency module_path
- helper module_name.constantize
+ def default_helper_module!
+ unless name.blank?
+ module_name = name.sub(/Controller$|$/, 'Helper')
+ module_path = module_name.split('::').map { |m| m.underscore }.join('/')
+ require_dependency module_path
+ helper module_name.constantize
+ end
+ rescue MissingSourceFile => e
+ raise unless e.is_missing? module_path
+ rescue NameError => e
+ raise unless e.missing_name? module_name
end
- rescue MissingSourceFile => e
- raise unless e.is_missing? module_path
- rescue NameError => e
- raise unless e.missing_name? module_name
- end
- # Extract helper names from files in app/helpers/**/*.rb
- def all_application_helpers
- extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/
- Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
- end
- end # ClassMethods
+ # Extract helper names from files in app/helpers/**/*.rb
+ def all_application_helpers
+ extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/
+ Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
+ end
+ end
end
end
diff --git a/actionpack/lib/action_controller/new_base/hide_actions.rb b/actionpack/lib/action_controller/new_base/hide_actions.rb
index a29b09a893..b45e520bee 100644
--- a/actionpack/lib/action_controller/new_base/hide_actions.rb
+++ b/actionpack/lib/action_controller/new_base/hide_actions.rb
@@ -1,33 +1,39 @@
module ActionController
module HideActions
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
included do
extlib_inheritable_accessor :hidden_actions
self.hidden_actions ||= Set.new
end
- def action_methods() self.class.action_names end
- def action_names() action_methods end
-
- private
-
- def action_method?(action_name)
- !hidden_actions.include?(action_name) && super
+ def action_methods
+ self.class.action_names
end
-
- module ClassMethods
- def hide_action(*args)
- args.each do |arg|
- self.hidden_actions << arg.to_s
- end
- end
-
- def action_methods
- @action_names ||= Set.new(super.reject {|name| self.hidden_actions.include?(name.to_s)})
- end
- def self.action_names() action_methods end
+ def action_names
+ action_methods
end
+
+ private
+ def action_method?(action_name)
+ !hidden_actions.include?(action_name) && super
+ end
+
+ module ClassMethods
+ def hide_action(*args)
+ args.each do |arg|
+ self.hidden_actions << arg.to_s
+ end
+ end
+
+ def action_methods
+ @action_names ||= Set.new(super.reject {|name| self.hidden_actions.include?(name.to_s)})
+ end
+
+ def self.action_names
+ action_methods
+ end
+ end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb
index 2525e221a6..c96aaaa865 100644
--- a/actionpack/lib/action_controller/new_base/http.rb
+++ b/actionpack/lib/action_controller/new_base/http.rb
@@ -4,9 +4,9 @@ require 'active_support/core_ext/module/delegation'
module ActionController
class Http < AbstractController::Base
abstract!
-
+
# :api: public
- attr_internal :request, :response, :params
+ attr_internal :params, :env
# :api: public
def self.controller_name
@@ -14,54 +14,78 @@ module ActionController
end
# :api: public
- def controller_name() self.class.controller_name end
+ def controller_name
+ self.class.controller_name
+ end
- # :api: public
+ # :api: public
def self.controller_path
@controller_path ||= self.name.sub(/Controller$/, '').underscore
end
-
- # :api: public
- def controller_path() self.class.controller_path end
-
- # :api: private
- def self.action_names() action_methods end
-
+
+ # :api: public
+ def controller_path
+ self.class.controller_path
+ end
+
+ # :api: private
+ def self.action_names
+ action_methods
+ end
+
# :api: private
- def action_names() action_methods end
-
+ def action_names
+ action_methods
+ end
+
# :api: plugin
def self.call(env)
controller = new
controller.call(env).to_rack
end
-
- delegate :headers, :to => "@_response"
- def params
- @_params ||= @_request.parameters
+ # The details below can be overridden to support a specific
+ # Request and Response object. The default ActionController::Base
+ # implementation includes RackConvenience, which makes a request
+ # and response object available. You might wish to control the
+ # environment and response manually for performance reasons.
+
+ attr_internal :status, :headers, :content_type
+
+ def initialize(*)
+ @_headers = {}
+ super
+ end
+
+ # Basic implements for content_type=, location=, and headers are
+ # provided to reduce the dependency on the RackConvenience module
+ # in Renderer and Redirector.
+
+ def content_type=(type)
+ headers["Content-Type"] = type.to_s
end
-
+
+ def location=(url)
+ headers["Location"] = url
+ end
+
# :api: private
def call(name, env)
- @_request = ActionDispatch::Request.new(env)
- @_response = ActionDispatch::Response.new
- @_response.request = request
+ @_env = env
process(name)
to_rack
end
-
+
+ # :api: private
+ def to_rack
+ [status, headers, response_body]
+ end
+
def self.action(name)
@actions ||= {}
@actions[name.to_s] ||= proc do |env|
new.call(name, env)
end
end
-
- # :api: private
- def to_rack
- @_response.prepare!
- @_response.to_a
- end
end
end
diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb
index 35068db770..0ff71587d6 100644
--- a/actionpack/lib/action_controller/new_base/layouts.rb
+++ b/actionpack/lib/action_controller/new_base/layouts.rb
@@ -1,36 +1,34 @@
module ActionController
module Layouts
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
+
+ include ActionController::Renderer
+ include AbstractController::Layouts
- depends_on ActionController::Renderer
- depends_on AbstractController::Layouts
-
module ClassMethods
def _implied_layout_name
controller_path
end
end
-
- private
- def _determine_template(options)
- super
- if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout)
- options[:_layout] = _layout_for_option(options.key?(:layout) ? options[:layout] : :none, options[:_template].details)
+ private
+ def _determine_template(options)
+ super
+ if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout)
+ options[:_layout] = _layout_for_option(options.key?(:layout) ? options[:layout] : :none, options[:_template].details)
+ end
end
- end
-
- def _layout_for_option(name, details)
- case name
- when String then _layout_for_name(name, details)
- when true then _default_layout(true, details)
- when :none then _default_layout(false, details)
- when false, nil then nil
- else
- raise ArgumentError,
- "String, true, or false, expected for `layout'; you passed #{name.inspect}"
+
+ def _layout_for_option(name, details)
+ case name
+ when String then _layout_for_name(name, details)
+ when true then _default_layout(true, details)
+ when :none then _default_layout(false, details)
+ when false, nil then nil
+ else
+ raise ArgumentError,
+ "String, true, or false, expected for `layout'; you passed #{name.inspect}"
+ end
end
- end
-
end
end
diff --git a/actionpack/lib/action_controller/new_base/rack_convenience.rb b/actionpack/lib/action_controller/new_base/rack_convenience.rb
new file mode 100644
index 0000000000..5dfa7d12f3
--- /dev/null
+++ b/actionpack/lib/action_controller/new_base/rack_convenience.rb
@@ -0,0 +1,33 @@
+module ActionController
+ module RackConvenience
+ extend ActiveSupport::Concern
+
+ included do
+ delegate :headers, :status=, :location=,
+ :status, :location, :content_type, :to => "@_response"
+ attr_internal :request, :response
+ end
+
+ def call(name, env)
+ @_request = ActionDispatch::Request.new(env)
+ @_response = ActionDispatch::Response.new
+ @_response.request = request
+ super
+ end
+
+ def params
+ @_params ||= @_request.parameters
+ end
+
+ # :api: private
+ def to_rack
+ @_response.prepare!
+ @_response.to_a
+ end
+
+ def response_body=(body)
+ response.body = body if response
+ super
+ end
+ end
+end
diff --git a/actionpack/lib/action_controller/new_base/redirector.rb b/actionpack/lib/action_controller/new_base/redirector.rb
index ff7b74341c..20060b001f 100644
--- a/actionpack/lib/action_controller/new_base/redirector.rb
+++ b/actionpack/lib/action_controller/new_base/redirector.rb
@@ -6,14 +6,14 @@ module ActionController
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.status = status
+ self.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 \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb
index 581a92cb7b..fc9a02626f 100644
--- a/actionpack/lib/action_controller/new_base/render_options.rb
+++ b/actionpack/lib/action_controller/new_base/render_options.rb
@@ -1,12 +1,12 @@
module ActionController
module RenderOptions
- extend ActiveSupport::DependencyModule
-
+ extend ActiveSupport::Concern
+
included do
extlib_inheritable_accessor :_renderers
self._renderers = []
end
-
+
module ClassMethods
def _write_render_options
renderers = _renderers.map do |r|
@@ -17,33 +17,31 @@ module ActionController
end
RUBY_EVAL
end
-
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def _handle_render_options(options)
#{renderers.join}
end
RUBY_EVAL
end
-
+
def _add_render_option(name)
_renderers << name
_write_render_options
end
end
-
+
def render_to_body(options)
_handle_render_options(options) || super
end
end
-
- module RenderOption
- extend ActiveSupport::DependencyModule
- included do
- extend ActiveSupport::DependencyModule
- depends_on ::ActionController::RenderOptions
+ module RenderOption #:nodoc:
+ def self.extended(base)
+ base.extend ActiveSupport::Concern
+ base.send :include, ::ActionController::RenderOptions
- def self.register_renderer(name)
+ def base.register_renderer(name)
included { _add_render_option(name) }
end
end
@@ -51,57 +49,55 @@ module ActionController
module Renderers
module Json
- include RenderOption
+ extend RenderOption
register_renderer :json
-
+
def _render_json(json, options)
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
- response.content_type ||= Mime::JSON
+ self.content_type ||= Mime::JSON
self.response_body = json
- end
+ end
end
module Js
- include RenderOption
+ extend RenderOption
register_renderer :js
def _render_js(js, options)
- response.content_type ||= Mime::JS
+ self.content_type ||= Mime::JS
self.response_body = js
end
end
module Xml
- include RenderOption
+ extend RenderOption
register_renderer :xml
def _render_xml(xml, options)
- response.content_type ||= Mime::XML
+ self.content_type ||= Mime::XML
self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
end
end
- module Rjs
- include RenderOption
+ module RJS
+ extend RenderOption
register_renderer :update
def _render_update(proc, options)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(_action_view, &proc)
- response.content_type = Mime::JS
+ self.content_type = Mime::JS
self.response_body = generator.to_s
end
end
module All
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
- included do
- include ::ActionController::Renderers::Json
- include ::ActionController::Renderers::Js
- include ::ActionController::Renderers::Xml
- include ::ActionController::Renderers::Rjs
- end
+ include ActionController::Renderers::Json
+ include ActionController::Renderers::Js
+ include ActionController::Renderers::Xml
+ include ActionController::Renderers::RJS
end
end
end
diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb
index 987751a601..2fab501302 100644
--- a/actionpack/lib/action_controller/new_base/renderer.rb
+++ b/actionpack/lib/action_controller/new_base/renderer.rb
@@ -1,23 +1,18 @@
module ActionController
module Renderer
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
+
+ include AbstractController::Renderer
- depends_on AbstractController::Renderer
-
def process_action(*)
self.formats = request.formats.map {|x| x.to_sym}
super
end
-
- def response_body=(body)
- response.body = body if response
- super
- end
def render(options)
super
options[:_template] ||= _action_view._partial
- response.content_type ||= begin
+ self.content_type ||= begin
mime = options[:_template].mime_type
formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first)
end
@@ -26,7 +21,7 @@ module ActionController
def render_to_body(options)
_process_options(options)
-
+
if options.key?(:partial)
_render_partial(options[:partial], options)
end
@@ -34,51 +29,50 @@ module ActionController
super
end
- private
+ private
+ def _prefix
+ controller_path
+ end
- def _prefix
- controller_path
- end
+ def _determine_template(options)
+ if options.key?(:text)
+ options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first)
+ elsif options.key?(:inline)
+ handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
+ template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
+ 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)
+ options[:_template_name] = (options[:action] || action_name).to_s
+ options[:_prefix] = _prefix
+ end
- def _determine_template(options)
- if options.key?(:text)
- options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first)
- elsif options.key?(:inline)
- handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
- template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
- 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)
- options[:_template_name] = (options[:action] || action_name).to_s
- options[:_prefix] = _prefix
+ super
end
-
- super
- 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
+ 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, location = options.values_at(:status, :content_type, :location)
+ self.status = status if status
+ self.content_type = content_type if content_type
+ self.headers["Location"] = url_for(location) if location
end
-
- options[:_partial] = options[:object] || true
- end
-
- def _process_options(options)
- status, content_type, location = options.values_at(:status, :content_type, :location)
- response.status = status if status
- response.content_type = content_type if content_type
- response.headers["Location"] = url_for(location) if location
- end
end
end
diff --git a/actionpack/lib/action_controller/new_base/rescuable.rb b/actionpack/lib/action_controller/new_base/rescuable.rb
index 29ffe19d5f..029e643d93 100644
--- a/actionpack/lib/action_controller/new_base/rescuable.rb
+++ b/actionpack/lib/action_controller/new_base/rescuable.rb
@@ -15,7 +15,7 @@ module ActionController #:nodoc:
# behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
# and <tt>rescue_action_locally</tt> methods.
module Rescue
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
included do
include ActiveSupport::Rescuable
@@ -32,22 +32,21 @@ module ActionController #:nodoc:
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
+ 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 _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
+ def process_action(*)
+ super
+ rescue Exception => exception
+ self.rescued_exception = exception
+ _rescue_action
+ end
end
end
diff --git a/actionpack/lib/action_controller/new_base/session.rb b/actionpack/lib/action_controller/new_base/session.rb
index a8715555fb..bcedd6e1c7 100644
--- a/actionpack/lib/action_controller/new_base/session.rb
+++ b/actionpack/lib/action_controller/new_base/session.rb
@@ -1,5 +1,9 @@
module ActionController
module Session
+ extend ActiveSupport::Concern
+
+ include RackConvenience
+
def session
@_request.session
end
diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb
index 78051a6252..a4a1116d9e 100644
--- a/actionpack/lib/action_controller/new_base/testing.rb
+++ b/actionpack/lib/action_controller/new_base/testing.rb
@@ -1,6 +1,8 @@
module ActionController
module Testing
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
+
+ include RackConvenience
# OMG MEGA HAX
def process_with_new_base_test(request, response)
@@ -13,7 +15,7 @@ module ActionController
set_test_assigns
ret
end
-
+
def set_test_assigns
@assigns = {}
(instance_variable_names - self.class.protected_instance_variables).each do |var|
@@ -33,6 +35,5 @@ module ActionController
_process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
end
end
-
end
end
diff --git a/actionpack/lib/action_controller/new_base/url_for.rb b/actionpack/lib/action_controller/new_base/url_for.rb
index 94de9fab50..7119c14cd3 100644
--- a/actionpack/lib/action_controller/new_base/url_for.rb
+++ b/actionpack/lib/action_controller/new_base/url_for.rb
@@ -1,5 +1,9 @@
module ActionController
module UrlFor
+ extend ActiveSupport::Concern
+
+ include RackConvenience
+
def process_action(*)
initialize_current_url
super
@@ -21,7 +25,7 @@ module ActionController
# by this method.
def default_url_options(options = nil)
end
-
+
def rewrite_options(options) #:nodoc:
if defaults = default_url_options(options)
defaults.merge(options)
@@ -29,7 +33,7 @@ module ActionController
options
end
end
-
+
def url_for(options = {})
options ||= {}
case options
@@ -42,4 +46,4 @@ module ActionController
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/routing/resources.rb b/actionpack/lib/action_controller/routing/resources.rb
index 86abb7b2f4..05c782d226 100644
--- a/actionpack/lib/action_controller/routing/resources.rb
+++ b/actionpack/lib/action_controller/routing/resources.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/object/try'
+
module ActionController
# == Overview
#
diff --git a/actionpack/lib/action_controller/routing/segments.rb b/actionpack/lib/action_controller/routing/segments.rb
index 4f936d51d2..2603855476 100644
--- a/actionpack/lib/action_controller/routing/segments.rb
+++ b/actionpack/lib/action_controller/routing/segments.rb
@@ -1,7 +1,7 @@
module ActionController
module Routing
class Segment #:nodoc:
- RESERVED_PCHAR = ':@&=+$,;'
+ RESERVED_PCHAR = ':@&=+$,;%'
SAFE_PCHAR = "#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}"
if RUBY_VERSION >= '1.9'
UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false).freeze
diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb
index cc157816e2..af4ccb7837 100644
--- a/actionpack/lib/action_controller/testing/integration.rb
+++ b/actionpack/lib/action_controller/testing/integration.rb
@@ -301,7 +301,7 @@ module ActionController
# A module used to extend ActionController::Base, so that integration tests
# can capture the controller used to satisfy a request.
module ControllerCapture #:nodoc:
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
included do
alias_method_chain :initialize, :capture
diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb
index 677dd41781..1c6fd2d80a 100644
--- a/actionpack/lib/action_controller/testing/process2.rb
+++ b/actionpack/lib/action_controller/testing/process2.rb
@@ -51,9 +51,10 @@ 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)
+ build_request_uri(action, parameters)
# Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
@controller.process_with_new_base_test(@request, @response)
@response
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
index a992f7d912..51e0868995 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -1,3 +1,6 @@
+require 'set'
+require 'active_support/core_ext/class/inheritable_attributes'
+
module HTML
class Sanitizer
def sanitize(text, options = {})
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index 4d598669c7..bfff307669 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -10,7 +10,8 @@ module ActionDispatch
@@rescue_responses = Hash.new(:internal_server_error)
@@rescue_responses.update({
'ActionController::RoutingError' => :not_found,
- 'ActionController::UnknownAction' => :not_found,
+ # TODO: Clean this up after the switch
+ ActionController::UnknownAction.name => :not_found,
'ActiveRecord::RecordNotFound' => :not_found,
'ActiveRecord::StaleObjectError' => :conflict,
'ActiveRecord::RecordInvalid' => :unprocessable_entity,
@@ -23,14 +24,17 @@ module ActionDispatch
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'
+ 'ActionView::MissingTemplate' => 'missing_template',
+ 'ActionController::RoutingError' => 'routing_error',
+ ActionController::UnknownAction.name => 'unknown_action',
+ 'ActionView::TemplateError' => 'template_error'
})
FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'},
- ['<html><body><h1>500 Internal Server Error</h1></body></html>']]
+ ["<html><body><h1>500 Internal Server Error</h1>" <<
+ "If you are the administrator of this website, then please read this web " <<
+ "application's log file and/or the web server's log file to find out what " <<
+ "went wrong.</body></html>"]]
def initialize(app, consider_all_requests_local = false)
@app = app
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 89d1a49403..e6d6b5a3ef 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/hash/diff'
+
module ActionDispatch
module Assertions
# Suite of assertions to test routes generated by Rails and the handling of requests made to them.
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 9e39536653..b4197479a0 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -124,7 +124,11 @@ module ActionView
# Use an alternate output buffer for the duration of the block.
# Defaults to a new empty string.
- def with_output_buffer(buf = '') #:nodoc:
+ def with_output_buffer(buf = nil) #:nodoc:
+ unless buf
+ buf = ''
+ buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding)
+ end
self.output_buffer, old_buffer = buf, output_buffer
yield
output_buffer
@@ -134,9 +138,12 @@ module ActionView
# Add the output buffer to the response body and start a new one.
def flush_output_buffer #:nodoc:
- if output_buffer && output_buffer != ''
+ if output_buffer && !output_buffer.empty?
response.body_parts << output_buffer
- self.output_buffer = ''
+ new = ''
+ new.force_encoding(output_buffer.encoding) if new.respond_to?(:force_encoding)
+ self.output_buffer = new
+ nil
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index daf38fe3da..c96b1fc8d2 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -353,7 +353,8 @@ module ActionView
disable_with << ";#{options.delete('onclick')}" if options['onclick']
options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
- options["onclick"] << "else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }"
+ options["onclick"] << "else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';"
+ options["onclick"] << "hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }"
options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index f2429e8cef..eacf117bea 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -171,7 +171,7 @@ module ActionView
# <% end %>
module Partials
extend ActiveSupport::Memoizable
- extend ActiveSupport::DependencyModule
+ extend ActiveSupport::Concern
included do
attr_accessor :_partial
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index 95f11d6490..21272ef089 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -16,11 +16,9 @@ module ActionView
self.default_format = Mime::HTML
def compile(template)
- src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src
-
- # Ruby 1.9 prepends an encoding to the source. However this is
- # useless because you can only set an encoding on the first line
- RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
+ magic = $1 if template.source =~ /\A(<%#.*coding:\s*(\S+)\s*-?%>)/
+ erb = "#{magic}<% __in_erb_template=true %>#{template.source}"
+ ::ERB.new(erb, nil, erb_trim_mode, '@output_buffer').src
end
end
end
diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb
index f61dd591a5..e7ea42c2eb 100644
--- a/actionpack/lib/action_view/template/template.rb
+++ b/actionpack/lib/action_view/template/template.rb
@@ -52,16 +52,30 @@ module ActionView
locals_code = locals.keys.map! { |key| "#{key} = local_assigns[:#{key}];" }.join
+ code = @handler.call(self)
+ if code.sub!(/\A(#.*coding.*)\n/, '')
+ encoding_comment = $1
+ elsif defined?(Encoding) && Encoding.respond_to?(:default_external)
+ encoding_comment = "#coding:#{Encoding.default_external}"
+ end
+
source = <<-end_src
def #{method_name}(local_assigns)
- old_output_buffer = output_buffer;#{locals_code};#{@handler.call(self)}
+ old_output_buffer = output_buffer;#{locals_code};#{code}
ensure
self.output_buffer = old_output_buffer
end
end_src
+ if encoding_comment
+ source = "#{encoding_comment}\n#{source}"
+ line = -1
+ else
+ line = 0
+ end
+
begin
- ActionView::Base::CompiledTemplates.module_eval(source, identifier, 0)
+ ActionView::Base::CompiledTemplates.module_eval(source, identifier, line)
method_name
rescue Exception => e # errors from template code
if logger = (view && view.logger)
@@ -79,4 +93,4 @@ module ActionView
"_render_template_#{@identifier.hash}_#{__id__}_#{locals.keys.hash}".gsub('-', "_")
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb
index 39d0017dd8..7199da3441 100644
--- a/actionpack/test/controller/cookie_test.rb
+++ b/actionpack/test/controller/cookie_test.rb
@@ -123,6 +123,12 @@ class CookieTest < ActionController::TestCase
assert_cookie_header "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT"
end
+ def test_cookies_persist_throughout_request
+ get :authenticate
+ cookies = @controller.send(:cookies)
+ assert_equal 'david', cookies['user_name']
+ end
+
private
def assert_cookie_header(expected)
header = @response.headers["Set-Cookie"]
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index bdcc24b371..df0a9dbfb0 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -1,10 +1,32 @@
require 'abstract_unit'
+require 'active_support/core_ext/symbol'
-class << ActionController::Base
- %w(append_around_filter prepend_after_filter prepend_around_filter prepend_before_filter skip_after_filter skip_before_filter skip_filter).each do |pending|
- define_method(pending) do |*args|
- $stderr.puts "#{pending} unimplemented: #{args.inspect}"
- end unless method_defined?(pending)
+class ActionController::Base
+ class << self
+ %w(append_around_filter prepend_after_filter prepend_around_filter prepend_before_filter skip_after_filter skip_before_filter skip_filter).each do |pending|
+ define_method(pending) do |*args|
+ $stderr.puts "#{pending} unimplemented: #{args.inspect}"
+ end unless method_defined?(pending)
+ end
+
+ if defined?(ActionController::Http)
+ def before_filters
+ filters = _process_action_callbacks.select { |c| c.kind == :before }
+ filters.map! { |c| c.instance_variable_get(:@raw_filter) }
+ end
+ end
+ end
+
+ if defined?(ActionController::Http)
+ def assigns(key = nil)
+ assigns = {}
+ instance_variable_names.each do |ivar|
+ next if ActionController::Base.protected_instance_variables.include?(ivar)
+ assigns[ivar[1..-1]] = instance_variable_get(ivar)
+ end
+
+ key.nil? ? assigns : assigns[key.to_s]
+ end
end
end
@@ -209,24 +231,29 @@ class FilterTest < ActionController::TestCase
end
class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
- before_filter :conditional_in_parent, :only => [:show, :another_action]
- after_filter :conditional_in_parent, :only => [:show, :another_action]
+ before_filter :conditional_in_parent_before, :only => [:show, :another_action]
+ after_filter :conditional_in_parent_after, :only => [:show, :another_action]
private
- def conditional_in_parent
+ def conditional_in_parent_before
@ran_filter ||= []
- @ran_filter << 'conditional_in_parent'
+ @ran_filter << 'conditional_in_parent_before'
+ end
+
+ def conditional_in_parent_after
+ @ran_filter ||= []
+ @ran_filter << 'conditional_in_parent_after'
end
end
class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
- skip_before_filter :conditional_in_parent, :only => :another_action
- skip_after_filter :conditional_in_parent, :only => :another_action
+ skip_before_filter :conditional_in_parent_before, :only => :another_action
+ skip_after_filter :conditional_in_parent_after, :only => :another_action
end
class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
- skip_before_filter :conditional_in_parent, :only => :show
+ skip_before_filter :conditional_in_parent_before, :only => :show
end
class ProcController < PrependingController
@@ -571,11 +598,22 @@ class FilterTest < ActionController::TestCase
assert_equal "before and after", assigns["execution_log"]
end
- def test_prepending_and_appending_around_filter
- controller = test_process(MixedFilterController)
- assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
- " after appended aroundfilter after aroundfilter after procfilter ",
- MixedFilterController.execution_log
+ for_tag(:old_base) do
+ def test_prepending_and_appending_around_filter
+ controller = test_process(MixedFilterController)
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
+ " after appended aroundfilter after aroundfilter after procfilter ",
+ MixedFilterController.execution_log
+ end
+ end
+
+ for_tag(:new_base) do
+ def test_prepending_and_appending_around_filter
+ controller = test_process(MixedFilterController)
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
+ " after appended aroundfilter after procfilter after aroundfilter ",
+ MixedFilterController.execution_log
+ end
end
def test_rendering_breaks_filtering_chain
@@ -600,7 +638,7 @@ class FilterTest < ActionController::TestCase
%w(foo bar baz).each do |action|
request = ActionController::TestRequest.new
request.query_parameters[:choose] = action
- response = DynamicDispatchController.action.call(request.env).last
+ response = DynamicDispatchController.action(action).call(request.env).last
assert_equal action, response.body
end
end
@@ -636,18 +674,18 @@ class FilterTest < ActionController::TestCase
def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
test_process(ChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent conditional_in_parent ), assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter']
test_process(ChildOfConditionalParentController, 'another_action')
assert_nil assigns['ran_filter']
end
def test_condition_skipping_of_filters_when_siblings_also_have_conditions
test_process(ChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent conditional_in_parent ), assigns['ran_filter'], "1"
+ assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter']
test_process(AnotherChildOfConditionalParentController)
- assert_equal nil, assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_after ), assigns['ran_filter']
test_process(ChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent conditional_in_parent ), assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter']
end
def test_changing_the_requirements
@@ -801,7 +839,9 @@ class ControllerWithAllTypesOfFilters < PostsController
end
class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
+ $vbf = true
skip_filter :around_again
+ $vbf = false
skip_filter :after
end
@@ -864,9 +904,18 @@ class YieldingAroundFiltersTest < ActionController::TestCase
end
end
- def test_filter_order_with_all_filter_types
- test_process(ControllerWithAllTypesOfFilters,'no_raise')
- assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after', assigns['ran_filter'].join(' ')
+ for_tag(:old_base) do
+ def test_filter_order_with_all_filter_types
+ test_process(ControllerWithAllTypesOfFilters,'no_raise')
+ assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after', assigns['ran_filter'].join(' ')
+ end
+ end
+
+ for_tag(:new_base) do
+ def test_filter_order_with_all_filter_types
+ test_process(ControllerWithAllTypesOfFilters,'no_raise')
+ assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)', assigns['ran_filter'].join(' ')
+ end
end
def test_filter_order_with_skip_filter_method
@@ -879,7 +928,6 @@ class YieldingAroundFiltersTest < ActionController::TestCase
response = test_process(controller, 'fail_1')
assert_equal ' ', response.body
assert_equal 1, controller.instance_variable_get(:@try)
- assert controller.instance_variable_get(:@before_filter_chain_aborted)
end
def test_second_filter_in_multiple_before_filter_chain_halts
@@ -887,7 +935,6 @@ class YieldingAroundFiltersTest < ActionController::TestCase
response = test_process(controller, 'fail_2')
assert_equal ' ', response.body
assert_equal 2, controller.instance_variable_get(:@try)
- assert controller.instance_variable_get(:@before_filter_chain_aborted)
end
def test_last_filter_in_multiple_before_filter_chain_halts
@@ -895,7 +942,6 @@ class YieldingAroundFiltersTest < ActionController::TestCase
response = test_process(controller, 'fail_3')
assert_equal ' ', response.body
assert_equal 3, controller.instance_variable_get(:@try)
- assert controller.instance_variable_get(:@before_filter_chain_aborted)
end
protected
diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb
index 84e27d7779..c448f36cb3 100644
--- a/actionpack/test/controller/flash_test.rb
+++ b/actionpack/test/controller/flash_test.rb
@@ -122,7 +122,7 @@ class FlashTest < ActionController::TestCase
assert_nil assigns["flash_copy"]["that"], "On second flash"
assert_equal "hello again", assigns["flash_copy"]["this"], "On second flash"
end
-
+
def test_flash_after_reset_session
get :use_flash_after_reset_session
assert_equal "hello", assigns["flashy_that"]
@@ -130,6 +130,11 @@ class FlashTest < ActionController::TestCase
assert_nil assigns["flashy_that_reset"]
end
+ def test_does_not_set_the_session_if_the_flash_is_empty
+ get :std_action
+ assert_nil session["flash"]
+ end
+
def test_sweep_after_halted_filter_chain
get :std_action
assert_nil assigns["flash_copy"]["foo"]
@@ -140,4 +145,19 @@ class FlashTest < ActionController::TestCase
get :std_action
assert_nil assigns["flash_copy"]["foo"]
end
+
+ def test_keep_and_discard_return_values
+ flash = ActionController::Flash::FlashHash.new
+ flash.update(:foo => :foo_indeed, :bar => :bar_indeed)
+
+ assert_equal(:foo_indeed, flash.discard(:foo)) # valid key passed
+ assert_nil flash.discard(:unknown) # non existant key passed
+ assert_equal({:foo => :foo_indeed, :bar => :bar_indeed}, flash.discard()) # nothing passed
+ assert_equal({:foo => :foo_indeed, :bar => :bar_indeed}, flash.discard(nil)) # nothing passed
+
+ assert_equal(:foo_indeed, flash.keep(:foo)) # valid key passed
+ assert_nil flash.keep(:unknown) # non existant key passed
+ assert_equal({:foo => :foo_indeed, :bar => :bar_indeed}, flash.keep()) # nothing passed
+ assert_equal({:foo => :foo_indeed, :bar => :bar_indeed}, flash.keep(nil)) # nothing passed
+ end
end
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index 11bffdb42e..6b08a04b10 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -90,6 +90,11 @@ class StaticSegmentTest < Test::Unit::TestCase
assert_equal 'Hello World', s.interpolation_chunk
end
+ def test_value_should_not_be_double_unescaped
+ s = ROUTING::StaticSegment.new('%D0%9A%D0%B0%D1%80%D1%82%D0%B0') # Карта
+ assert_equal '%D0%9A%D0%B0%D1%80%D1%82%D0%B0', s.interpolation_chunk
+ end
+
def test_regexp_chunk_should_escape_specials
s = ROUTING::StaticSegment.new('Hello*World')
assert_equal 'Hello\*World', s.regexp_chunk
@@ -644,9 +649,8 @@ class RoutingTest < Test::Unit::TestCase
ActionController::Routing.use_controllers! nil
- silence_warnings do
- Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
- end
+ Object.send(:remove_const, :RAILS_ROOT) if defined?(::RAILS_ROOT)
+ Object.const_set(:RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
ActionController::Routing.controller_paths = [
RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib'
@@ -2482,7 +2486,8 @@ end
class RouteLoadingTest < Test::Unit::TestCase
def setup
routes.instance_variable_set '@routes_last_modified', nil
- silence_warnings { Object.const_set :RAILS_ROOT, '.' }
+ Object.remove_const(:RAILS_ROOT) if defined?(::RAILS_ROOT)
+ Object.const_set :RAILS_ROOT, '.'
routes.add_configuration_file(File.join(RAILS_ROOT, 'config', 'routes.rb'))
@stat = stub_everything
diff --git a/actionpack/test/controller/view_paths_test.rb b/actionpack/test/controller/view_paths_test.rb
index 0ac10634b2..c732d1c910 100644
--- a/actionpack/test/controller/view_paths_test.rb
+++ b/actionpack/test/controller/view_paths_test.rb
@@ -22,7 +22,7 @@ class ViewLoadPathsTest < ActionController::TestCase
end
def setup
- TestController.view_paths = nil
+ # TestController.view_paths = nil
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@@ -48,7 +48,7 @@ class ViewLoadPathsTest < ActionController::TestCase
def assert_paths(*paths)
controller = paths.first.is_a?(Class) ? paths.shift : @controller
- assert_equal expand(paths), controller.view_paths.map(&:to_s)
+ assert_equal expand(paths), controller.view_paths.map { |p| p.to_s }
end
def test_template_load_path_was_set_correctly
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index 0c0c087340..ce1973853e 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -61,7 +61,7 @@ class ShowExceptionsTest < ActionController::IntegrationTest
get "/not_found"
assert_response 404
- assert_match /ActionController::UnknownAction/, body
+ assert_match /#{ActionController::UnknownAction.name}/, body
get "/method_not_allowed"
assert_response 405
@@ -99,7 +99,7 @@ class ShowExceptionsTest < ActionController::IntegrationTest
get "/not_found"
assert_response 404
- assert_match /ActionController::UnknownAction/, body
+ assert_match /#{ActionController::UnknownAction.name}/, body
get "/method_not_allowed"
assert_response 405
diff --git a/actionpack/test/fixtures/test/utf8.html.erb b/actionpack/test/fixtures/test/utf8.html.erb
index 0b4d19aa0e..14fe12debc 100644
--- a/actionpack/test/fixtures/test/utf8.html.erb
+++ b/actionpack/test/fixtures/test/utf8.html.erb
@@ -1,2 +1,4 @@
Русский текст
-日本語のテキスト \ No newline at end of file
+<%= "日".encoding %>
+<%= @output_buffer.encoding %>
+<%= __ENCODING__ %>
diff --git a/actionpack/test/fixtures/test/utf8_magic.html.erb b/actionpack/test/fixtures/test/utf8_magic.html.erb
new file mode 100644
index 0000000000..58cd03b439
--- /dev/null
+++ b/actionpack/test/fixtures/test/utf8_magic.html.erb
@@ -0,0 +1,5 @@
+<%# encoding: utf-8 -%>
+Русский текст
+<%= "日".encoding %>
+<%= @output_buffer.encoding %>
+<%= __ENCODING__ %>
diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb
index e17092a452..4e7aa63f96 100644
--- a/actionpack/test/template/body_parts_test.rb
+++ b/actionpack/test/template/body_parts_test.rb
@@ -4,6 +4,9 @@ class BodyPartsTest < ActionController::TestCase
RENDERINGS = [Object.new, Object.new, Object.new]
class TestController < ActionController::Base
+ def performed?
+ defined?(ActionController::Http) ? true : super
+ end
def index
RENDERINGS.each do |rendering|
@template.punctuate_body! rendering
@@ -16,7 +19,7 @@ class BodyPartsTest < ActionController::TestCase
def test_body_parts
get :index
- pending do
+ pending(:old_base) do
# TestProcess buffers body_parts into body
# TODO: Rewrite test w/o going through process
assert_equal RENDERINGS, @response.body_parts
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index ea0be4a27a..5ca4d4d6ea 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -253,14 +253,14 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag
assert_dom_equal(
- %(<input name='commit' type='submit' value='Save' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';alert('hello!');result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" />),
+ %(<input name='commit' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';alert('hello!');result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')")
)
end
def test_submit_tag_with_no_onclick_options
assert_dom_equal(
- %(<input name='commit' type='submit' value='Save' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" />),
+ %(<input name='commit' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
submit_tag("Save", :disable_with => "Saving...")
)
end
@@ -274,7 +274,7 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag_with_confirmation_and_with_disable_with
assert_dom_equal(
- %(<input name="commit" type="submit" value="Save" onclick="if (!confirm('Are you sure?')) return false; if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" />),
+ %(<input name="commit" onclick="if (!confirm('Are you sure?')) return false; if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
)
end
diff --git a/actionpack/test/template/output_buffer_test.rb b/actionpack/test/template/output_buffer_test.rb
index 171cfb63e1..36bbaf9099 100644
--- a/actionpack/test/template/output_buffer_test.rb
+++ b/actionpack/test/template/output_buffer_test.rb
@@ -9,33 +9,52 @@ class OutputBufferTest < ActionController::TestCase
tests TestController
- def test_flush_output_buffer
- pending
- # TODO: This tests needs to be rewritten due
- # The @response is not the same response object assigned
- # to the @controller.template
-
- # Start with the default body parts
- # ---
- # get :index
- # assert_equal ['foo'], @response.body_parts
- # assert_nil @controller.template.output_buffer
- #
- # # Nil output buffer is skipped
- # @controller.template.flush_output_buffer
- # assert_nil @controller.template.output_buffer
- # assert_equal ['foo'], @response.body_parts
- #
- # # Empty output buffer is skipped
- # @controller.template.output_buffer = ''
- # @controller.template.flush_output_buffer
- # assert_equal '', @controller.template.output_buffer
- # assert_equal ['foo'], @response.body_parts
- #
- # # Flushing appends the output buffer to the body parts
- # @controller.template.output_buffer = 'bar'
- # @controller.template.flush_output_buffer
- # assert_equal '', @controller.template.output_buffer
- # assert_equal ['foo', 'bar'], @response.body_parts
+ def setup
+ get :index
+ assert_equal ['foo'], body_parts
end
+
+ test 'output buffer is nil after rendering' do
+ assert_nil output_buffer
+ end
+
+ test 'flushing ignores nil output buffer' do
+ @controller.template.flush_output_buffer
+ assert_nil output_buffer
+ assert_equal ['foo'], body_parts
+ end
+
+ test 'flushing ignores empty output buffer' do
+ @controller.template.output_buffer = ''
+ @controller.template.flush_output_buffer
+ assert_equal '', output_buffer
+ assert_equal ['foo'], body_parts
+ end
+
+ test 'flushing appends the output buffer to the body parts' do
+ @controller.template.output_buffer = 'bar'
+ @controller.template.flush_output_buffer
+ assert_equal '', output_buffer
+ assert_equal ['foo', 'bar'], body_parts
+ end
+
+ if '1.9'.respond_to?(:force_encoding)
+ test 'flushing preserves output buffer encoding' do
+ original_buffer = ' '.force_encoding(Encoding::EUC_JP)
+ @controller.template.output_buffer = original_buffer
+ @controller.template.flush_output_buffer
+ assert_equal ['foo', original_buffer], body_parts
+ assert_not_equal original_buffer, output_buffer
+ assert_equal Encoding::EUC_JP, output_buffer.encoding
+ end
+ end
+
+ protected
+ def output_buffer
+ @controller.template.output_buffer
+ end
+
+ def body_parts
+ @controller.template.response.body_parts
+ end
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 71291f009c..20cd4cc1d4 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -247,10 +247,27 @@ module RenderTestCases
end
if '1.9'.respond_to?(:force_encoding)
- def test_render_utf8_template
- result = @view.render(:file => "test/utf8.html.erb", :layouts => "layouts/yield")
- assert_equal "Русский текст\n日本語のテキスト", result
- assert_equal Encoding::UTF_8, result.encoding
+ def test_render_utf8_template_with_magic_comment
+ with_external_encoding Encoding::ASCII_8BIT do
+ result = @view.render(:file => "test/utf8_magic.html.erb", :layouts => "layouts/yield")
+ assert_equal "Русский текст\nUTF-8\nUTF-8\nUTF-8\n", result
+ assert_equal Encoding::UTF_8, result.encoding
+ end
+ end
+
+ def test_render_utf8_template_with_default_external_encoding
+ with_external_encoding Encoding::UTF_8 do
+ result = @view.render(:file => "test/utf8.html.erb", :layouts => "layouts/yield")
+ assert_equal "Русский текст\nUTF-8\nUTF-8\nUTF-8\n", result
+ assert_equal Encoding::UTF_8, result.encoding
+ end
+ end
+
+ def with_external_encoding(encoding)
+ old, Encoding.default_external = Encoding.default_external, encoding
+ yield
+ ensure
+ Encoding.default_external = old
end
end
end