aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/actionmailer.gemspec1
-rw-r--r--actionmailer/lib/action_mailer.rb1
-rw-r--r--actionmailer/lib/action_mailer/base.rb6
-rw-r--r--actionmailer/lib/action_mailer/log_subscriber.rb2
-rw-r--r--actionmailer/test/abstract_unit.rb8
-rw-r--r--actionmailer/test/i18n_with_controller_test.rb4
-rw-r--r--actionpack/CHANGELOG.md9
-rw-r--r--actionpack/actionpack.gemspec6
-rw-r--r--actionpack/lib/abstract_controller.rb3
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb138
-rw-r--r--actionpack/lib/action_controller.rb10
-rw-r--r--actionpack/lib/action_controller/base.rb18
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb42
-rw-r--r--actionpack/lib/action_controller/metal/streaming.rb38
-rw-r--r--actionpack/lib/action_controller/railtie.rb1
-rw-r--r--actionpack/test/abstract_unit.rb33
-rw-r--r--actionpack/test/controller/assert_select_test.rb3
-rw-r--r--actionpack/test/controller/mime/respond_with_test.rb1
-rw-r--r--actionpack/test/controller/render_test.rb1406
l---------actionpack/test/fixtures/layout_tests/layouts/symlinked1
-rw-r--r--actionpack/test/lib/controller/fake_models.rb6
-rw-r--r--actionview/Rakefile37
-rw-r--r--actionview/lib/action_view.rb4
-rw-r--r--actionview/lib/action_view/base.rb4
-rw-r--r--actionview/lib/action_view/helpers/record_tag_helper.rb2
-rw-r--r--actionview/lib/action_view/layouts.rb (renamed from actionpack/lib/abstract_controller/layouts.rb)5
-rw-r--r--actionview/lib/action_view/log_subscriber.rb2
-rw-r--r--actionview/lib/action_view/railtie.rb13
-rw-r--r--actionview/lib/action_view/rendering.rb162
-rw-r--r--actionview/lib/action_view/view_paths.rb (renamed from actionpack/lib/abstract_controller/view_paths.rb)2
-rw-r--r--actionview/test/abstract_unit.rb58
-rw-r--r--actionview/test/actionpack/abstract/abstract_controller_test.rb (renamed from actionpack/test/abstract/abstract_controller_test.rb)3
-rw-r--r--actionview/test/actionpack/abstract/helper_test.rb (renamed from actionpack/test/abstract/helper_test.rb)7
-rw-r--r--actionview/test/actionpack/abstract/layouts_test.rb (renamed from actionpack/test/abstract/layouts_test.rb)3
-rw-r--r--actionview/test/actionpack/abstract/render_test.rb (renamed from actionpack/test/abstract/render_test.rb)1
-rw-r--r--actionview/test/actionpack/abstract/views/abstract_controller/testing/me3/formatted.html.erb (renamed from actionpack/test/abstract/views/abstract_controller/testing/me3/formatted.html.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/abstract_controller/testing/me3/index.erb (renamed from actionpack/test/abstract/views/abstract_controller/testing/me3/index.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/abstract_controller/testing/me4/index.erb (renamed from actionpack/test/abstract/views/abstract_controller/testing/me4/index.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/abstract_controller/testing/me5/index.erb (renamed from actionpack/test/abstract/views/abstract_controller/testing/me5/index.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/action_with_ivars.erb (renamed from actionpack/test/abstract/views/action_with_ivars.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/helper_test.erb (renamed from actionpack/test/abstract/views/helper_test.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/index.erb (renamed from actionpack/test/abstract/views/index.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/layouts/abstract_controller/testing/me4.erb (renamed from actionpack/test/abstract/views/layouts/abstract_controller/testing/me4.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/layouts/application.erb (renamed from actionpack/test/abstract/views/layouts/application.erb)0
-rw-r--r--actionview/test/actionpack/abstract/views/naked_render.erb (renamed from actionpack/test/abstract/views/naked_render.erb)0
-rw-r--r--actionview/test/actionpack/controller/capture_test.rb (renamed from actionpack/test/controller/capture_test.rb)2
-rw-r--r--actionview/test/actionpack/controller/layout_test.rb (renamed from actionpack/test/controller/layout_test.rb)6
-rw-r--r--actionview/test/actionpack/controller/render_test.rb1337
-rw-r--r--actionview/test/fixtures/actionpack/bad_customers/_bad_customer.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/customers/_customer.html.erb (renamed from actionpack/test/fixtures/customers/_customer.html.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/fun/games/_form.erb (renamed from actionpack/test/fixtures/fun/games/_form.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/fun/games/hello_world.erb (renamed from actionpack/test/fixtures/fun/games/hello_world.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/good_customers/_good_customer.html.erb (renamed from actionpack/test/fixtures/good_customers/_good_customer.html.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/hello.html (renamed from actionpack/test/fixtures/hello.html)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb (renamed from actionpack/test/fixtures/layout_tests/alt/layouts/alt.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/layouts/controller_name_space/nested.erb (renamed from actionpack/test/fixtures/layout_tests/layouts/controller_name_space/nested.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/layouts/item.erb (renamed from actionpack/test/fixtures/layout_tests/layouts/item.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/layouts/layout_test.erb (renamed from actionpack/test/fixtures/layout_tests/layouts/layout_test.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/layouts/multiple_extensions.html.erb (renamed from actionpack/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/layouts/symlinked/symlinked_layout.erb5
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/layouts/third_party_template_library.mab (renamed from actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/views/goodbye.erb (renamed from actionpack/test/fixtures/layout_tests/views/goodbye.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/views/hello.erb (renamed from actionpack/test/fixtures/layout_tests/views/hello.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/layouts/_column.html.erb2
-rw-r--r--actionview/test/fixtures/actionpack/layouts/_customers.erb1
-rw-r--r--actionview/test/fixtures/actionpack/layouts/_partial_and_yield.erb2
-rw-r--r--actionview/test/fixtures/actionpack/layouts/_yield_only.erb1
-rw-r--r--actionview/test/fixtures/actionpack/layouts/_yield_with_params.erb1
-rw-r--r--actionview/test/fixtures/actionpack/layouts/block_with_layout.erb3
-rw-r--r--actionview/test/fixtures/actionpack/layouts/builder.builder3
-rw-r--r--actionview/test/fixtures/actionpack/layouts/partial_with_layout.erb3
-rw-r--r--actionview/test/fixtures/actionpack/layouts/standard.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/layouts/streaming.erb4
-rw-r--r--actionview/test/fixtures/actionpack/layouts/talk_from_action.erb2
-rw-r--r--actionview/test/fixtures/actionpack/layouts/with_html_partial.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/layouts/xhr.html.erb2
-rw-r--r--actionview/test/fixtures/actionpack/layouts/yield.erb2
-rw-r--r--actionview/test/fixtures/actionpack/layouts/yield_with_render_inline_inside.erb2
-rw-r--r--actionview/test/fixtures/actionpack/layouts/yield_with_render_partial_inside.erb2
-rw-r--r--actionview/test/fixtures/actionpack/quiz/questions/_question.html.erb (renamed from actionpack/test/fixtures/quiz/questions/_question.html.erb)0
-rw-r--r--actionview/test/fixtures/actionpack/shared.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_changing_priority.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_changing_priority.json.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_counter.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_customer.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_customer_counter.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_customer_counter_with_as.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_customer_greeting.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_customer_with_var.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_directory/_partial_with_locales.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_first_json_partial.json.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_form.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_hash_greeting.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_hash_object.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/_hello.builder1
-rw-r--r--actionview/test/fixtures/actionpack/test/_json_change_priority.json.erb0
-rw-r--r--actionview/test/fixtures/actionpack/test/_labelling_form.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_layout_for_partial.html.erb3
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial.js.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial_for_use_in_layout.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial_html_erb.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial_name_local_variable.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial_only.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial_only_html.html1
-rw-r--r--actionview/test/fixtures/actionpack/test/_partial_with_partial.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/_person.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/_raise_indentation.html.erb13
-rw-r--r--actionview/test/fixtures/actionpack/test/_second_json_partial.json.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/action_talk_to_layout.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/calling_partial_with_layout.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/capturing.erb4
-rw-r--r--actionview/test/fixtures/actionpack/test/change_priority.html.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/content_for.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/content_for_concatenated.erb3
-rw-r--r--actionview/test/fixtures/actionpack/test/content_for_with_parameter.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/dot.directory/render_file_with_ivar.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/formatted_html_erb.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder1
-rw-r--r--actionview/test/fixtures/actionpack/test/formatted_xml_erb.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/formatted_xml_erb.xml.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/greeting.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/greeting.xml.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hello,world.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hello.builder4
-rw-r--r--actionview/test/fixtures/actionpack/test/hello/hello.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hello_world.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hello_world_container.builder3
-rw-r--r--actionview/test/fixtures/actionpack/test/hello_world_from_rxml.builder3
-rw-r--r--actionview/test/fixtures/actionpack/test/hello_world_with_layout_false.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hello_world_with_partial.html.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/hello_xml_world.builder11
-rw-r--r--actionview/test/fixtures/actionpack/test/html_template.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hyphen-ated.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/implicit_content_type.atom.builder2
-rw-r--r--actionview/test/fixtures/actionpack/test/list.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder4
-rw-r--r--actionview/test/fixtures/actionpack/test/potential_conflicts.erb4
-rw-r--r--actionview/test/fixtures/actionpack/test/proper_block_detection.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_file_from_template.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_file_with_ivar.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_file_with_locals.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_file_with_locals_and_default.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.da.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_implicit_js_template_without_layout.js.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_partial_inside_directory.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_to_string_test.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/render_two_partials.html.erb2
-rw-r--r--actionview/test/fixtures/actionpack/test/using_layout_around_block.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/with_html_partial.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/with_partial.html.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/with_partial.text.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/with_xml_template.html.erb1
-rw-r--r--actionview/test/fixtures/helpers/abc_helper.rb5
-rw-r--r--actionview/test/fixtures/helpers/fun/games_helper.rb5
-rw-r--r--actionview/test/fixtures/helpers/fun/pdf_helper.rb5
-rw-r--r--actionview/test/fixtures/helpers/helpery_test_helper.rb5
-rw-r--r--actionview/test/fixtures/helpers/just_me_helper.rb3
-rw-r--r--actionview/test/fixtures/helpers/me_too_helper.rb3
-rw-r--r--actionview/test/fixtures/helpers_missing/invalid_require_helper.rb (renamed from actionpack/test/fixtures/helpers_missing/invalid_require_helper.rb)0
-rw-r--r--actionview/test/fixtures/override/test/hello_world.erb (renamed from actionpack/test/fixtures/override/test/hello_world.erb)0
-rw-r--r--actionview/test/fixtures/override2/layouts/test/sub.erb (renamed from actionpack/test/fixtures/override2/layouts/test/sub.erb)0
-rw-r--r--actionview/test/lib/controller/view_paths_test.rb (renamed from actionpack/test/controller/view_paths_test.rb)0
-rw-r--r--actionview/test/template/lookup_context_test.rb2
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb5
-rw-r--r--activerecord/lib/active_record/fixtures.rb9
-rw-r--r--activerecord/lib/active_record/migration.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb8
-rw-r--r--activerecord/test/cases/fixtures_test.rb14
-rw-r--r--activesupport/lib/active_support/deprecation.rb2
-rw-r--r--guides/assets/images/akshaysurve.jpgbin0 -> 3444 bytes
-rw-r--r--guides/rails_guides.rb19
-rw-r--r--guides/source/active_record_basics.md2
-rw-r--r--guides/source/credits.html.erb4
-rw-r--r--railties/lib/rails/all.rb1
-rw-r--r--railties/lib/rails/generators/app_base.rb5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb1
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/application.rb1
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/abstract_unit.rb1
-rw-r--r--railties/test/application/basic_rendering_test.rb62
-rw-r--r--railties/test/application/url_generation_test.rb1
-rw-r--r--railties/test/generators/app_generator_test.rb5
-rw-r--r--railties/test/generators/generators_test_helper.rb1
-rw-r--r--railties/test/isolation/abstract_unit.rb7
-rw-r--r--railties/test/rails_info_controller_test.rb2
190 files changed, 2131 insertions, 1606 deletions
diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec
index c56b6979ef..9b25feaf75 100644
--- a/actionmailer/actionmailer.gemspec
+++ b/actionmailer/actionmailer.gemspec
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
s.requirements << 'none'
s.add_dependency 'actionpack', version
+ s.add_dependency 'actionview', version
s.add_dependency 'mail', '~> 2.5.4'
end
diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb
index c45124be80..5b6960c8fc 100644
--- a/actionmailer/lib/action_mailer.rb
+++ b/actionmailer/lib/action_mailer.rb
@@ -22,7 +22,6 @@
#++
require 'abstract_controller'
-require 'action_view'
require 'action_mailer/version'
# Common Active Support usage in Action Mailer
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index cc3a412221..ada86fbc4f 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -3,6 +3,7 @@ require 'action_mailer/collector'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/anonymous'
+
require 'action_mailer/log_subscriber'
module ActionMailer
@@ -361,11 +362,12 @@ module ActionMailer
# <tt>delivery_method :test</tt>. Most useful for unit and functional testing.
class Base < AbstractController::Base
include DeliveryMethods
+
abstract!
- include AbstractController::Logger
include AbstractController::Rendering
- include AbstractController::Layouts
+
+ include AbstractController::Logger
include AbstractController::Helpers
include AbstractController::Translation
include AbstractController::AssetPaths
diff --git a/actionmailer/lib/action_mailer/log_subscriber.rb b/actionmailer/lib/action_mailer/log_subscriber.rb
index c108156792..8467d45986 100644
--- a/actionmailer/lib/action_mailer/log_subscriber.rb
+++ b/actionmailer/lib/action_mailer/log_subscriber.rb
@@ -1,3 +1,5 @@
+require 'active_support/log_subscriber'
+
module ActionMailer
# Implements the ActiveSupport::LogSubscriber for logging notifications when
# email is delivered and received.
diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb
index ed8cf72cd0..aa18c512c7 100644
--- a/actionmailer/test/abstract_unit.rb
+++ b/actionmailer/test/abstract_unit.rb
@@ -11,11 +11,11 @@ end
require 'active_support/testing/autorun'
require 'action_mailer'
require 'action_mailer/test_case'
+require 'mail'
-silence_warnings do
- # These external dependencies have warnings :/
- require 'mail'
-end
+# Emulate AV railtie
+require 'action_view'
+ActionMailer::Base.send(:include, ActionView::Layouts)
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
diff --git a/actionmailer/test/i18n_with_controller_test.rb b/actionmailer/test/i18n_with_controller_test.rb
index a3e93c9c31..ab5eaaa9d5 100644
--- a/actionmailer/test/i18n_with_controller_test.rb
+++ b/actionmailer/test/i18n_with_controller_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'action_view'
require 'action_controller'
class I18nTestMailer < ActionMailer::Base
@@ -14,6 +15,9 @@ class I18nTestMailer < ActionMailer::Base
end
end
+# Emulate AV railtie
+ActionController::Base.superclass.send(:include, ActionView::Layouts)
+
class TestController < ActionController::Base
def send_mail
I18nTestMailer.mail_with_i18n_subject("test@localhost").deliver
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 6e8ba88b77..e7621270dd 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,12 @@
+* Introduce `BasicRendering` which is the most basic rendering implementation. It
+ allows to `render :text` and `render :nothing` without need of having ActionView.
+
+ *Łukasz Strzałkowski*
+
+* Separate ActionView completely from ActionPack.
+
+ *Łukasz Strzałkowski*
+
* Development mode exceptions are rendered in text format in case of XHR request.
*Kir Shatrov*
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index e3aa84ba0f..b4315c1f57 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -20,11 +20,11 @@ Gem::Specification.new do |s|
s.requirements << 'none'
s.add_dependency 'activesupport', version
- s.add_dependency 'actionview', version
s.add_dependency 'rack', '~> 1.5.2'
s.add_dependency 'rack-test', '~> 0.6.2'
- s.add_development_dependency 'activemodel', version
- s.add_development_dependency 'tzinfo', '~> 0.3.37'
+ s.add_development_dependency 'actionview', version
+ s.add_development_dependency 'activemodel', version
+ s.add_development_dependency 'tzinfo', '~> 0.3.37'
end
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index 867a7954e0..fe9802e395 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -10,12 +10,11 @@ module AbstractController
autoload :Base
autoload :Callbacks
autoload :Collector
+ autoload :DoubleRenderError, "abstract_controller/rendering"
autoload :Helpers
- autoload :Layouts
autoload :Logger
autoload :Rendering
autoload :Translation
autoload :AssetPaths
- autoload :ViewPaths
autoload :UrlFor
end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 3f34add790..5a5c47eb3b 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -1,5 +1,5 @@
-require "abstract_controller/base"
-require "action_view"
+require 'active_support/concern'
+require 'active_support/core_ext/class/attribute'
module AbstractController
class DoubleRenderError < Error
@@ -10,91 +10,16 @@ module AbstractController
end
end
- # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request,
- # it will trigger the lookup_context and consequently expire the cache.
- class I18nProxy < ::I18n::Config #:nodoc:
- attr_reader :original_config, :lookup_context
-
- def initialize(original_config, lookup_context)
- original_config = original_config.original_config if original_config.respond_to?(:original_config)
- @original_config, @lookup_context = original_config, lookup_context
- end
-
- def locale
- @original_config.locale
- end
-
- def locale=(value)
- @lookup_context.locale = value
- end
- end
-
module Rendering
extend ActiveSupport::Concern
- include AbstractController::ViewPaths
included do
class_attribute :protected_instance_variables
self.protected_instance_variables = []
end
- # Overwrite process to setup I18n proxy.
- def process(*) #:nodoc:
- old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
- super
- ensure
- I18n.config = old_config
- end
-
- module ClassMethods
- def view_context_class
- @view_context_class ||= begin
- routes = respond_to?(:_routes) && _routes
- helpers = respond_to?(:_helpers) && _helpers
-
- Class.new(ActionView::Base) do
- if routes
- include routes.url_helpers
- include routes.mounted_helpers
- end
-
- if helpers
- include helpers
- end
- end
- end
- end
- end
-
- attr_internal_writer :view_context_class
-
- def view_context_class
- @_view_context_class ||= self.class.view_context_class
- end
-
- # An instance of a view class. The default view class is ActionView::Base
- #
- # The view class must have the following methods:
- # View.new[lookup_context, assigns, controller]
- # Create a new ActionView instance for a controller
- # View#render[options]
- # Returns String with the rendered template
- #
- # Override this method in a module to change the default behavior.
- def view_context
- view_context_class.new(view_renderer, view_assigns, self)
- end
-
- # Returns an object that is able to render templates.
- def view_renderer
- @_view_renderer ||= ActionView::Renderer.new(lookup_context)
- end
-
- # Normalize arguments, options and then delegates render_to_body and
- # sticks the result in self.response_body.
- def render(*args, &block)
- options = _normalize_render(*args, &block)
- self.response_body = render_to_body(options)
+ def default_protected_instance_vars
+ [:@_action_name, :@_response_body, :@_formats, :@_prefixes, :@_config]
end
# Raw rendering of a template to a string.
@@ -109,28 +34,23 @@ module AbstractController
# overridden in order to still return a string.
# :api: plugin
def render_to_string(*args, &block)
- options = _normalize_render(*args, &block)
- render_to_body(options)
end
# Raw rendering of a template.
# :api: plugin
def render_to_body(options = {})
- _process_options(options)
- _render_template(options)
end
- # Find and renders a template based on the options given.
- # :api: private
- def _render_template(options) #:nodoc:
- lookup_context.rendered_format = nil if options[:formats]
- view_renderer.render(view_context, options)
+ # Normalize arguments, options and then delegates render_to_body and
+ # sticks the result in self.response_body.
+ # :api: public
+ def render(*args, &block)
end
- DEFAULT_PROTECTED_INSTANCE_VARIABLES = [
- :@_action_name, :@_response_body, :@_formats, :@_prefixes, :@_config,
- :@_view_context_class, :@_view_renderer, :@_lookup_context
- ]
+ # Return Content-Type of rendered content
+ # :api: public
+ def rendered_format
+ end
# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
@@ -139,58 +59,28 @@ module AbstractController
hash = {}
variables = instance_variables
variables -= protected_instance_variables
- variables -= DEFAULT_PROTECTED_INSTANCE_VARIABLES
+ variables -= default_protected_instance_vars
variables.each { |name| hash[name[1..-1]] = instance_variable_get(name) }
hash
end
- private
-
- # Normalize args and options.
- # :api: private
- def _normalize_render(*args, &block)
- options = _normalize_args(*args, &block)
- _normalize_options(options)
- options
- end
-
# Normalize args by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :file => "foo/bar".
# :api: plugin
def _normalize_args(action=nil, options={})
- case action
- when NilClass
- when Hash
- options = action
- when String, Symbol
- action = action.to_s
- key = action.include?(?/) ? :file : :action
- options[key] = action
- else
- options[:partial] = action
- end
-
options
end
# Normalize options.
# :api: plugin
def _normalize_options(options)
- if options[:partial] == true
- options[:partial] = action_name
- end
-
- if (options.keys & [:partial, :file, :template]).empty?
- options[:prefixes] ||= _prefixes
- end
-
- options[:template] ||= (options[:action] || action_name).to_s
options
end
# Process extra options.
# :api: plugin
def _process_options(options)
+ options
end
end
end
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index cc03da4904..d6b1908ccb 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -13,6 +13,7 @@ module ActionController
autoload :Middleware
autoload_under "metal" do
+ autoload :BasicRendering, 'action_controller/metal/rendering'
autoload :Compatibility
autoload :ConditionalGet
autoload :Cookies
@@ -46,18 +47,9 @@ module ActionController
def self.eager_load!
super
ActionController::Caching.eager_load!
- HTML.eager_load!
end
end
-# All of these simply register additional autoloads
-require 'action_view'
-require 'action_view/vendor/html-scanner'
-
-ActiveSupport.on_load(:action_view) do
- ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
-end
-
# Common Active Support usage in Action Controller
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/load_error'
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 67d261db77..9941c06201 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -2,6 +2,21 @@ require "action_controller/log_subscriber"
require "action_controller/metal/params_wrapper"
module ActionController
+ # The <tt>metal</tt> anonymous class was introduced to solve issue with including modules in <tt>ActionController::Base</tt>.
+ # Modules needes to be included in particluar order. First wee need to have <tt>AbstractController::Rendering</tt> included,
+ # next we should include actuall implementation which would be for example <tt>ActionView::Rendering</tt> and after that
+ # <tt>ActionController::Rendering</tt>. This order must be preserved and as we want to have middle module included dynamicaly
+ # <tt>metal</tt> class was introduced. It has <tt>AbstractController::Rendering</tt> included and is parent class of
+ # <tt>ActionController::Base</tt> which includes <tt>ActionController::Rendering</tt>. If we include <tt>ActionView::Rendering</tt>
+ # beetween them to perserve the required order, we can simply do this by:
+ #
+ # ActionController::Base.superclass.send(:include, ActionView::Rendering)
+ #
+ metal = Class.new(Metal) do
+ include AbstractController::Rendering
+ include ActionController::BasicRendering
+ end
+
# Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
# on request and then either it renders a template or redirects to another action. An action is defined as a public method
# on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
@@ -160,7 +175,7 @@ module ActionController
# render action: "overthere" # won't be called if monkeys is nil
# end
#
- class Base < Metal
+ class Base < metal
abstract!
# We document the request and response methods here because albeit they are
@@ -200,7 +215,6 @@ module ActionController
end
MODULES = [
- AbstractController::Layouts,
AbstractController::Translation,
AbstractController::AssetPaths,
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index bea6b88f91..21224b9c3b 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -1,8 +1,38 @@
module ActionController
- module Rendering
+ # Basic rendering implements the most minimal rendering layer.
+ # It only supports rendering :text and :nothing. Passing any other option will
+ # result in `UnsupportedOperationError` exception. For more functionality like
+ # different formats, layouts etc. you should use `ActionView` gem.
+ module BasicRendering
extend ActiveSupport::Concern
- include AbstractController::Rendering
+ # Render text or nothing (empty string) to response_body
+ # :api: public
+ def render(*args, &block)
+ super(*args, &block)
+ opts = args.first
+ if opts.has_key?(:text) && opts[:text].present?
+ self.response_body = opts[:text]
+ elsif opts.has_key?(:nothing) && opts[:nothing]
+ self.response_body = " "
+ else
+ raise UnsupportedOperationError
+ end
+ end
+
+ def rendered_format
+ Mime::TEXT
+ end
+
+ class UnsupportedOperationError < StandardError
+ def initialize
+ super "Unsupported render operation. BasicRendering supports only :text and :nothing options. For more, you need to include ActionView."
+ end
+ end
+ end
+
+ module Rendering
+ extend ActiveSupport::Concern
# Before processing, set the request formats in current controller formats.
def process_action(*) #:nodoc:
@@ -12,17 +42,17 @@ module ActionController
# Check for double render errors and set the content_type after rendering.
def render(*args) #:nodoc:
- raise ::AbstractController::DoubleRenderError if response_body
+ raise ::AbstractController::DoubleRenderError if self.response_body
super
- self.content_type ||= Mime[lookup_context.rendered_format].to_s
- response_body
+ self.content_type ||= rendered_format.to_s
+ self.response_body
end
# Overwrite render_to_string because body can now be set to a rack body.
def render_to_string(*)
if self.response_body = super
string = ""
- response_body.each { |r| string << r }
+ self.response_body.each { |r| string << r }
string
end
ensure
diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb
index 73e9b5660d..62d5931b45 100644
--- a/actionpack/lib/action_controller/metal/streaming.rb
+++ b/actionpack/lib/action_controller/metal/streaming.rb
@@ -193,31 +193,29 @@ module ActionController #:nodoc:
module Streaming
extend ActiveSupport::Concern
- include AbstractController::Rendering
-
protected
- # Set proper cache control and transfer encoding when streaming
- def _process_options(options) #:nodoc:
- super
- if options[:stream]
- if env["HTTP_VERSION"] == "HTTP/1.0"
- options.delete(:stream)
- else
- headers["Cache-Control"] ||= "no-cache"
- headers["Transfer-Encoding"] = "chunked"
- headers.delete("Content-Length")
+ # Set proper cache control and transfer encoding when streaming
+ def _process_options(options) #:nodoc:
+ super
+ if options[:stream]
+ if env["HTTP_VERSION"] == "HTTP/1.0"
+ options.delete(:stream)
+ else
+ headers["Cache-Control"] ||= "no-cache"
+ headers["Transfer-Encoding"] = "chunked"
+ headers.delete("Content-Length")
+ end
end
end
- end
- # Call render_body if we are streaming instead of usual +render+.
- def _render_template(options) #:nodoc:
- if options.delete(:stream)
- Rack::Chunked::Body.new view_renderer.render_body(view_context, options)
- else
- super
+ # Call render_body if we are streaming instead of usual +render+.
+ def _render_template(options) #:nodoc:
+ if options.delete(:stream)
+ Rack::Chunked::Body.new view_renderer.render_body(view_context, options)
+ else
+ super
+ end
end
- end
end
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 5379547c57..0833e65d23 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -1,7 +1,6 @@
require "rails"
require "action_controller"
require "action_dispatch/railtie"
-require "action_view/railtie"
require "abstract_controller/railties/routes_helpers"
require "action_controller/railties/helpers"
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 8213997f4e..a0d90f7eee 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -64,28 +64,6 @@ module RackTestUtils
extend self
end
-module RenderERBUtils
- def view
- @view ||= begin
- path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH)
- view_paths = ActionView::PathSet.new([path])
- ActionView::Base.new(view_paths)
- end
- end
-
- def render_erb(string)
- @virtual_path = nil
-
- template = ActionView::Template.new(
- string.strip,
- "test template",
- ActionView::Template::Handlers::ERB,
- {})
-
- template.render(self, {}).strip
- end
-end
-
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
module ActionDispatch
@@ -268,6 +246,8 @@ class Rack::TestCase < ActionDispatch::IntegrationTest
end
end
+ActionController::Base.superclass.send(:include, ActionView::Layouts)
+
module ActionController
class Base
include ActionController::Testing
@@ -290,15 +270,8 @@ module ActionController
end
end
-class ::ApplicationController < ActionController::Base
-end
-module ActionView
- class TestCase
- # Must repeat the setup because AV::TestCase is a duplication
- # of AC::TestCase
- include ActionDispatch::SharedRoutes
- end
+class ::ApplicationController < ActionController::Base
end
class Workshop
diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb
index 3d667f0a2f..114bbf3c22 100644
--- a/actionpack/test/controller/assert_select_test.rb
+++ b/actionpack/test/controller/assert_select_test.rb
@@ -8,6 +8,9 @@ require 'abstract_unit'
require 'controller/fake_controllers'
require 'action_mailer'
+require 'action_view'
+
+ActionMailer::Base.send(:include, ActionView::Layouts)
ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH
class AssertSelectTest < ActionController::TestCase
diff --git a/actionpack/test/controller/mime/respond_with_test.rb b/actionpack/test/controller/mime/respond_with_test.rb
index 29ddbff8d4..76af9e3414 100644
--- a/actionpack/test/controller/mime/respond_with_test.rb
+++ b/actionpack/test/controller/mime/respond_with_test.rb
@@ -337,6 +337,7 @@ class RespondWithControllerTest < ActionController::TestCase
errors = { :name => :invalid }
Customer.any_instance.stubs(:errors).returns(errors)
put :using_resource
+
assert_equal "text/html", @response.content_type
assert_equal 200, @response.status
assert_equal "Edit world!\n", @response.body
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index fd835795c0..f41287381a 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -2,26 +2,6 @@ require 'abstract_unit'
require 'controller/fake_models'
require 'pathname'
-module Fun
- class GamesController < ActionController::Base
- # :ported:
- def hello_world
- end
-
- def nested_partial_with_form_builder
- render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {})
- end
- end
-end
-
-module Quiz
- class QuestionsController < ActionController::Base
- def new
- render :partial => Quiz::Question.new("Namespaced Partial")
- end
- end
-end
-
class TestControllerWithExtraEtags < ActionController::Base
etag { nil }
etag { 'ab' }
@@ -58,10 +38,6 @@ class TestController < ActionController::Base
def hello_world
end
- def hello_world_file
- render :file => File.expand_path("../../fixtures/hello", __FILE__), :formats => [:html]
- end
-
def conditional_hello
if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123])
render :action => 'hello_world'
@@ -147,327 +123,10 @@ class TestController < ActionController::Base
fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ])
end
- # :ported:
- def render_hello_world
- render :template => "test/hello_world"
- end
-
- def render_hello_world_with_last_modified_set
- response.last_modified = Date.new(2008, 10, 10).to_time
- render :template => "test/hello_world"
- end
-
- # :ported: compatibility
- def render_hello_world_with_forward_slash
- render :template => "/test/hello_world"
- end
-
- # :ported:
- def render_template_in_top_directory
- render :template => 'shared'
- end
-
- # :deprecated:
- def render_template_in_top_directory_with_slash
- render :template => '/shared'
- end
-
- # :ported:
- def render_hello_world_from_variable
- @person = "david"
- render :text => "hello #{@person}"
- end
-
- # :ported:
- def render_action_hello_world
- render :action => "hello_world"
- end
-
- def render_action_upcased_hello_world
- render :action => "Hello_world"
- end
-
- def render_action_hello_world_as_string
- render "hello_world"
- end
-
- def render_action_hello_world_with_symbol
- render :action => :hello_world
- end
-
- # :ported:
- def render_text_hello_world
- render :text => "hello world"
- end
-
- # :ported:
- def render_text_hello_world_with_layout
- @variable_for_layout = ", I am here!"
- render :text => "hello world", :layout => true
- end
-
- def hello_world_with_layout_false
- render :layout => false
- end
-
- # :ported:
- def render_file_with_instance_variables
- @secret = 'in the sauce'
- path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar')
- render :file => path
- end
-
- # :ported:
- def render_file_as_string_with_instance_variables
- @secret = 'in the sauce'
- path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar'))
- render path
- end
-
- # :ported:
- def render_file_not_using_full_path
- @secret = 'in the sauce'
- render :file => 'test/render_file_with_ivar'
- end
-
- def render_file_not_using_full_path_with_dot_in_path
- @secret = 'in the sauce'
- render :file => 'test/dot.directory/render_file_with_ivar'
- end
-
- def render_file_using_pathname
- @secret = 'in the sauce'
- render :file => Pathname.new(File.dirname(__FILE__)).join('..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar')
- end
-
- def render_file_from_template
- @secret = 'in the sauce'
- @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar'))
- end
-
- def render_file_with_locals
- path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals')
- render :file => path, :locals => {:secret => 'in the sauce'}
- end
-
- def render_file_as_string_with_locals
- path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals'))
- render path, :locals => {:secret => 'in the sauce'}
- end
-
- def accessing_request_in_template
- render :inline => "Hello: <%= request.host %>"
- end
-
- def accessing_logger_in_template
- render :inline => "<%= logger.class %>"
- end
-
- def accessing_action_name_in_template
- render :inline => "<%= action_name %>"
- end
-
- def accessing_controller_name_in_template
- render :inline => "<%= controller_name %>"
- end
-
- # :ported:
- def render_custom_code
- render :text => "hello world", :status => 404
- end
-
- # :ported:
- def render_text_with_nil
- render :text => nil
- end
-
- # :ported:
- def render_text_with_false
- render :text => false
- end
-
- def render_text_with_resource
- render :text => Customer.new("David")
- end
-
- # :ported:
- def render_nothing_with_appendix
- render :text => "appended"
- end
-
- # This test is testing 3 things:
- # render :file in AV :ported:
- # render :template in AC :ported:
- # setting content type
- def render_xml_hello
- @name = "David"
- render :template => "test/hello"
- end
-
- def render_xml_hello_as_string_template
- @name = "David"
- render "test/hello"
- end
-
- def render_line_offset
- render :inline => '<% raise %>', :locals => {:foo => 'bar'}
- end
-
def heading
head :ok
end
- def greeting
- # let's just rely on the template
- end
-
- # :ported:
- def blank_response
- render :text => ' '
- end
-
- # :ported:
- def layout_test
- render :action => "hello_world"
- end
-
- # :ported:
- def builder_layout_test
- @name = nil
- render :action => "hello", :layout => "layouts/builder"
- end
-
- # :move: test this in Action View
- def builder_partial_test
- render :action => "hello_world_container"
- end
-
- # :ported:
- def partials_list
- @test_unchanged = 'hello'
- @customers = [ Customer.new("david"), Customer.new("mary") ]
- render :action => "list"
- end
-
- def partial_only
- render :partial => true
- end
-
- def hello_in_a_string
- @customers = [ Customer.new("david"), Customer.new("mary") ]
- render :text => "How's there? " + render_to_string(:template => "test/list")
- end
-
- def accessing_params_in_template
- render :inline => "Hello: <%= params[:name] %>"
- end
-
- def accessing_local_assigns_in_inline_template
- name = params[:local_name]
- render :inline => "<%= 'Goodbye, ' + local_name %>",
- :locals => { :local_name => name }
- end
-
- def render_implicit_html_template_from_xhr_request
- end
-
- def render_implicit_js_template_without_layout
- end
-
- def formatted_html_erb
- end
-
- def formatted_xml_erb
- end
-
- def render_to_string_test
- @foo = render_to_string :inline => "this is a test"
- end
-
- def default_render
- @alternate_default_render ||= nil
- if @alternate_default_render
- @alternate_default_render.call
- else
- super
- end
- end
-
- def render_action_hello_world_as_symbol
- render :action => :hello_world
- end
-
- def layout_test_with_different_layout
- render :action => "hello_world", :layout => "standard"
- end
-
- def layout_test_with_different_layout_and_string_action
- render "hello_world", :layout => "standard"
- end
-
- def layout_test_with_different_layout_and_symbol_action
- render :hello_world, :layout => "standard"
- end
-
- def rendering_without_layout
- render :action => "hello_world", :layout => false
- end
-
- def layout_overriding_layout
- render :action => "hello_world", :layout => "standard"
- end
-
- def rendering_nothing_on_layout
- render :nothing => true
- end
-
- def render_to_string_with_assigns
- @before = "i'm before the render"
- render_to_string :text => "foo"
- @after = "i'm after the render"
- render :template => "test/hello_world"
- end
-
- def render_to_string_with_exception
- render_to_string :file => "exception that will not be caught - this will certainly not work"
- end
-
- def render_to_string_with_caught_exception
- @before = "i'm before the render"
- begin
- render_to_string :file => "exception that will be caught- hope my future instance vars still work!"
- rescue
- end
- @after = "i'm after the render"
- render :template => "test/hello_world"
- end
-
- def accessing_params_in_template_with_layout
- render :layout => true, :inline => "Hello: <%= params[:name] %>"
- end
-
- # :ported:
- def render_with_explicit_template
- render :template => "test/hello_world"
- end
-
- def render_with_explicit_unescaped_template
- render :template => "test/h*llo_world"
- end
-
- def render_with_explicit_escaped_template
- render :template => "test/hello,world"
- end
-
- def render_with_explicit_string_template
- render "test/hello_world"
- end
-
- # :ported:
- def render_with_explicit_template_with_locals
- render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' }
- end
-
# :ported:
def double_render
render :text => "hello"
@@ -508,25 +167,6 @@ class TestController < ActionController::Base
render :template => "test/hello_world_from_rxml", :handlers => [:builder]
end
- def action_talk_to_layout
- # Action template sets variable that's picked up by layout
- end
-
- # :addressed:
- def render_text_with_assigns
- @hello = "world"
- render :text => "foo"
- end
-
- def yield_content_for
- render :action => "content_for", :layout => "yield"
- end
-
- def render_content_type_from_body
- response.content_type = Mime::RSS
- render :text => "hello world!"
- end
-
def head_created
head :created
end
@@ -571,162 +211,6 @@ class TestController < ActionController::Base
head :forbidden, :x_custom_header => "something"
end
- def render_using_layout_around_block
- render :action => "using_layout_around_block"
- end
-
- def render_using_layout_around_block_in_main_layout_and_within_content_for_layout
- render :action => "using_layout_around_block", :layout => "layouts/block_with_layout"
- end
-
- def partial_formats_html
- render :partial => 'partial', :formats => [:html]
- end
-
- def partial
- render :partial => 'partial'
- end
-
- def partial_html_erb
- render :partial => 'partial_html_erb'
- end
-
- def render_to_string_with_partial
- @partial_only = render_to_string :partial => "partial_only"
- @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
- render :template => "test/hello_world"
- end
-
- def render_to_string_with_template_and_html_partial
- @text = render_to_string :template => "test/with_partial", :formats => [:text]
- @html = render_to_string :template => "test/with_partial", :formats => [:html]
- render :template => "test/with_html_partial"
- end
-
- def render_to_string_and_render_with_different_formats
- @html = render_to_string :template => "test/with_partial", :formats => [:html]
- render :template => "test/with_partial", :formats => [:text]
- end
-
- def render_template_within_a_template_with_other_format
- render :template => "test/with_xml_template",
- :formats => [:html],
- :layout => "with_html_partial"
- end
-
- def partial_with_counter
- render :partial => "counter", :locals => { :counter_counter => 5 }
- end
-
- def partial_with_locals
- render :partial => "customer", :locals => { :customer => Customer.new("david") }
- end
-
- def partial_with_form_builder
- render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {})
- end
-
- def partial_with_form_builder_subclass
- render :partial => LabellingFormBuilder.new(:post, nil, view_context, {})
- end
-
- def partial_collection
- render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
- end
-
- def partial_collection_with_as
- render :partial => "customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer
- end
-
- def partial_collection_with_counter
- render :partial => "customer_counter", :collection => [ Customer.new("david"), Customer.new("mary") ]
- end
-
- def partial_collection_with_as_and_counter
- render :partial => "customer_counter_with_as", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :client
- end
-
- def partial_collection_with_locals
- render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
- end
-
- def partial_collection_with_spacer
- render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ]
- end
-
- def partial_collection_with_spacer_which_uses_render
- render :partial => "customer", :spacer_template => "partial_with_partial", :collection => [ Customer.new("david"), Customer.new("mary") ]
- end
-
- def partial_collection_shorthand_with_locals
- render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
- end
-
- def partial_collection_shorthand_with_different_types_of_records
- render :partial => [
- BadCustomer.new("mark"),
- GoodCustomer.new("craig"),
- BadCustomer.new("john"),
- GoodCustomer.new("zach"),
- GoodCustomer.new("brandon"),
- BadCustomer.new("dan") ],
- :locals => { :greeting => "Bonjour" }
- end
-
- def empty_partial_collection
- render :partial => "customer", :collection => []
- end
-
- def partial_collection_shorthand_with_different_types_of_records_with_counter
- partial_collection_shorthand_with_different_types_of_records
- end
-
- def missing_partial
- render :partial => 'thisFileIsntHere'
- end
-
- def partial_with_hash_object
- render :partial => "hash_object", :object => {:first_name => "Sam"}
- end
-
- def partial_with_nested_object
- render :partial => "quiz/questions/question", :object => Quiz::Question.new("first")
- end
-
- def partial_with_nested_object_shorthand
- render Quiz::Question.new("first")
- end
-
- def partial_hash_collection
- render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ]
- end
-
- def partial_hash_collection_with_locals
- render :partial => "hash_greeting", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ], :locals => { :greeting => "Hola" }
- end
-
- def partial_with_implicit_local_assignment
- @customer = Customer.new("Marcel")
- render :partial => "customer"
- end
-
- def render_call_to_partial_with_layout
- render :action => "calling_partial_with_layout"
- end
-
- def render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
- render :action => "calling_partial_with_layout", :layout => "layouts/partial_with_layout"
- end
-
- before_action only: :render_with_filters do
- request.format = :xml
- end
-
- # Ensure that the before filter is executed *before* self.formats is set.
- def render_with_filters
- render :action => :formatted_xml_erb
- end
-
private
def set_variable_for_layout
@@ -755,6 +239,8 @@ class TestController < ActionController::Base
end
class MetalTestController < ActionController::Metal
+ include AbstractController::Rendering
+ include ActionView::Rendering
include ActionController::Rendering
def accessing_logger_in_template
@@ -762,788 +248,9 @@ class MetalTestController < ActionController::Metal
end
end
-class RenderTest < ActionController::TestCase
- tests TestController
-
- def setup
- # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
- # a more accurate simulation of what happens in "real life".
- super
- @controller.logger = ActiveSupport::Logger.new(nil)
- ActionView::Base.logger = ActiveSupport::Logger.new(nil)
-
- @request.host = "www.nextangle.com"
- end
-
- # :ported:
- def test_simple_show
- get :hello_world
- assert_response 200
- assert_response :success
- assert_template "test/hello_world"
- assert_equal "<html>Hello world!</html>", @response.body
- end
-
- # :ported:
- def test_renders_default_template_for_missing_action
- get :'hyphen-ated'
- assert_template 'test/hyphen-ated'
- end
-
- # :ported:
- def test_render
- get :render_hello_world
- assert_template "test/hello_world"
- end
-
- def test_line_offset
- get :render_line_offset
- flunk "the action should have raised an exception"
- rescue StandardError => exc
- line = exc.backtrace.first
- assert(line =~ %r{:(\d+):})
- assert_equal "1", $1,
- "The line offset is wrong, perhaps the wrong exception has been raised, exception was: #{exc.inspect}"
- end
-
- # :ported: compatibility
- def test_render_with_forward_slash
- get :render_hello_world_with_forward_slash
- assert_template "test/hello_world"
- end
-
- # :ported:
- def test_render_in_top_directory
- get :render_template_in_top_directory
- assert_template "shared"
- assert_equal "Elastica", @response.body
- end
-
- # :ported:
- def test_render_in_top_directory_with_slash
- get :render_template_in_top_directory_with_slash
- assert_template "shared"
- assert_equal "Elastica", @response.body
- end
-
- # :ported:
- def test_render_from_variable
- get :render_hello_world_from_variable
- assert_equal "hello david", @response.body
- end
-
- # :ported:
- def test_render_action
- get :render_action_hello_world
- assert_template "test/hello_world"
- end
-
- def test_render_action_upcased
- assert_raise ActionView::MissingTemplate do
- get :render_action_upcased_hello_world
- end
- end
-
- # :ported:
- def test_render_action_hello_world_as_string
- get :render_action_hello_world_as_string
- assert_equal "Hello world!", @response.body
- assert_template "test/hello_world"
- end
-
- # :ported:
- def test_render_action_with_symbol
- get :render_action_hello_world_with_symbol
- assert_template "test/hello_world"
- end
-
- # :ported:
- def test_render_text
- get :render_text_hello_world
- assert_equal "hello world", @response.body
- end
-
- # :ported:
- def test_do_with_render_text_and_layout
- get :render_text_hello_world_with_layout
- assert_equal "<html>hello world, I am here!</html>", @response.body
- end
-
- # :ported:
- def test_do_with_render_action_and_layout_false
- get :hello_world_with_layout_false
- assert_equal 'Hello world!', @response.body
- end
-
- # :ported:
- def test_render_file_with_instance_variables
- get :render_file_with_instance_variables
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- def test_render_file
- get :hello_world_file
- assert_equal "Hello world!", @response.body
- end
-
- # :ported:
- def test_render_file_as_string_with_instance_variables
- get :render_file_as_string_with_instance_variables
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
- def test_render_file_not_using_full_path
- get :render_file_not_using_full_path
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
- def test_render_file_not_using_full_path_with_dot_in_path
- get :render_file_not_using_full_path_with_dot_in_path
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
- def test_render_file_using_pathname
- get :render_file_using_pathname
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
- def test_render_file_with_locals
- get :render_file_with_locals
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
- def test_render_file_as_string_with_locals
- get :render_file_as_string_with_locals
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :assessed:
- def test_render_file_from_template
- get :render_file_from_template
- assert_equal "The secret is in the sauce\n", @response.body
- end
-
- # :ported:
- def test_render_custom_code
- get :render_custom_code
- assert_response 404
- assert_response :missing
- assert_equal 'hello world', @response.body
- end
-
- # :ported:
- def test_render_text_with_nil
- get :render_text_with_nil
- assert_response 200
- assert_equal ' ', @response.body
- end
-
- # :ported:
- def test_render_text_with_false
- get :render_text_with_false
- assert_equal 'false', @response.body
- end
-
- # :ported:
- def test_render_nothing_with_appendix
- get :render_nothing_with_appendix
- assert_response 200
- assert_equal 'appended', @response.body
- end
-
- def test_render_text_with_resource
- get :render_text_with_resource
- assert_equal 'name: "David"', @response.body
- end
-
- # :ported:
- def test_attempt_to_access_object_method
- assert_raise(AbstractController::ActionNotFound, "No action responded to [clone]") { get :clone }
- end
-
- # :ported:
- def test_private_methods
- assert_raise(AbstractController::ActionNotFound, "No action responded to [determine_layout]") { get :determine_layout }
- end
-
- # :ported:
- def test_access_to_request_in_view
- get :accessing_request_in_template
- assert_equal "Hello: www.nextangle.com", @response.body
- end
-
- def test_access_to_logger_in_view
- get :accessing_logger_in_template
- assert_equal "ActiveSupport::Logger", @response.body
- end
-
- # :ported:
- def test_access_to_action_name_in_view
- get :accessing_action_name_in_template
- assert_equal "accessing_action_name_in_template", @response.body
- end
-
- # :ported:
- def test_access_to_controller_name_in_view
- get :accessing_controller_name_in_template
- assert_equal "test", @response.body # name is explicitly set in the controller.
- end
-
- # :ported:
- def test_render_xml
- get :render_xml_hello
- assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
- assert_equal "application/xml", @response.content_type
- end
-
- # :ported:
- def test_render_xml_as_string_template
- get :render_xml_hello_as_string_template
- assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
- assert_equal "application/xml", @response.content_type
- end
-
- # :ported:
- def test_render_xml_with_default
- get :greeting
- assert_equal "<p>This is grand!</p>\n", @response.body
- end
-
- # :move: test in AV
- def test_render_xml_with_partial
- get :builder_partial_test
- assert_equal "<test>\n <hello/>\n</test>\n", @response.body
- end
-
- # :ported:
- def test_layout_rendering
- get :layout_test
- assert_equal "<html>Hello world!</html>", @response.body
- end
-
- def test_render_xml_with_layouts
- get :builder_layout_test
- assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
- end
-
- def test_partials_list
- get :partials_list
- assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body
- end
-
- def test_render_to_string
- get :hello_in_a_string
- assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
- end
-
- def test_render_to_string_resets_assigns
- get :render_to_string_test
- assert_equal "The value of foo is: ::this is a test::\n", @response.body
- end
-
- def test_render_to_string_inline
- get :render_to_string_with_inline_and_render
- assert_template "test/hello_world"
- end
-
- # :ported:
- def test_nested_rendering
- @controller = Fun::GamesController.new
- get :hello_world
- assert_equal "Living in a nested world", @response.body
- end
-
- def test_accessing_params_in_template
- get :accessing_params_in_template, :name => "David"
- assert_equal "Hello: David", @response.body
- end
-
- def test_accessing_local_assigns_in_inline_template
- get :accessing_local_assigns_in_inline_template, :local_name => "Local David"
- assert_equal "Goodbye, Local David", @response.body
- assert_equal "text/html", @response.content_type
- end
-
- def test_should_implicitly_render_html_template_from_xhr_request
- xhr :get, :render_implicit_html_template_from_xhr_request
- assert_equal "XHR!\nHello HTML!", @response.body
- end
-
- def test_should_implicitly_render_js_template_without_layout
- get :render_implicit_js_template_without_layout, :format => :js
- assert_no_match %r{<html>}, @response.body
- end
-
- def test_should_render_formatted_template
- get :formatted_html_erb
- assert_equal 'formatted html erb', @response.body
- end
-
- def test_should_render_formatted_html_erb_template
- get :formatted_xml_erb
- assert_equal '<test>passed formatted html erb</test>', @response.body
- end
-
- def test_should_render_formatted_html_erb_template_with_bad_accepts_header
- @request.env["HTTP_ACCEPT"] = "; a=dsf"
- get :formatted_xml_erb
- assert_equal '<test>passed formatted html erb</test>', @response.body
- end
-
- def test_should_render_formatted_html_erb_template_with_faulty_accepts_header
- @request.accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, appliction/x-shockwave-flash, */*"
- get :formatted_xml_erb
- assert_equal '<test>passed formatted html erb</test>', @response.body
- end
-
- def test_layout_test_with_different_layout
- get :layout_test_with_different_layout
- assert_equal "<html>Hello world!</html>", @response.body
- end
-
- def test_layout_test_with_different_layout_and_string_action
- get :layout_test_with_different_layout_and_string_action
- assert_equal "<html>Hello world!</html>", @response.body
- end
-
- def test_layout_test_with_different_layout_and_symbol_action
- get :layout_test_with_different_layout_and_symbol_action
- assert_equal "<html>Hello world!</html>", @response.body
- end
-
- def test_rendering_without_layout
- get :rendering_without_layout
- assert_equal "Hello world!", @response.body
- end
-
- def test_layout_overriding_layout
- get :layout_overriding_layout
- assert_no_match %r{<title>}, @response.body
- end
-
- def test_rendering_nothing_on_layout
- get :rendering_nothing_on_layout
- assert_equal " ", @response.body
- end
-
- def test_render_to_string_doesnt_break_assigns
- get :render_to_string_with_assigns
- assert_equal "i'm before the render", assigns(:before)
- assert_equal "i'm after the render", assigns(:after)
- end
-
- def test_bad_render_to_string_still_throws_exception
- assert_raise(ActionView::MissingTemplate) { get :render_to_string_with_exception }
- end
-
- def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
- assert_nothing_raised { get :render_to_string_with_caught_exception }
- assert_equal "i'm before the render", assigns(:before)
- assert_equal "i'm after the render", assigns(:after)
- end
-
- def test_accessing_params_in_template_with_layout
- get :accessing_params_in_template_with_layout, :name => "David"
- assert_equal "<html>Hello: David</html>", @response.body
- end
-
- def test_render_with_explicit_template
- get :render_with_explicit_template
- assert_response :success
- end
-
- def test_render_with_explicit_unescaped_template
- assert_raise(ActionView::MissingTemplate) { get :render_with_explicit_unescaped_template }
- get :render_with_explicit_escaped_template
- assert_equal "Hello w*rld!", @response.body
- end
-
- def test_render_with_explicit_string_template
- get :render_with_explicit_string_template
- assert_equal "<html>Hello world!</html>", @response.body
- end
-
- def test_render_with_filters
- get :render_with_filters
- assert_equal "<test>passed formatted xml erb</test>", @response.body
- end
-
- # :ported:
- def test_double_render
- assert_raise(AbstractController::DoubleRenderError) { get :double_render }
- end
-
- def test_double_redirect
- assert_raise(AbstractController::DoubleRenderError) { get :double_redirect }
- end
-
- def test_render_and_redirect
- assert_raise(AbstractController::DoubleRenderError) { get :render_and_redirect }
- end
-
- # specify the one exception to double render rule - render_to_string followed by render
- def test_render_to_string_and_render
- get :render_to_string_and_render
- assert_equal("Hi web users! here is some cached stuff", @response.body)
- end
-
- def test_rendering_with_conflicting_local_vars
- get :rendering_with_conflicting_local_vars
- assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body)
- end
-
- def test_action_talk_to_layout
- get :action_talk_to_layout
- assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
- end
-
- # :addressed:
- def test_render_text_with_assigns
- get :render_text_with_assigns
- assert_equal "world", assigns["hello"]
- end
-
- # :ported:
- def test_template_with_locals
- get :render_with_explicit_template_with_locals
- assert_equal "The secret is area51\n", @response.body
- end
-
- def test_yield_content_for
- get :yield_content_for
- assert_equal "<title>Putting stuff in the title!</title>\nGreat stuff!\n", @response.body
- end
-
- def test_overwritting_rendering_relative_file_with_extension
- get :hello_world_from_rxml_using_template
- assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
-
- get :hello_world_from_rxml_using_action
- assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
- end
-
- def test_head_created
- post :head_created
- assert @response.body.blank?
- assert_response :created
- end
-
- def test_head_created_with_application_json_content_type
- post :head_created_with_application_json_content_type
- assert @response.body.blank?
- assert_equal "application/json", @response.header["Content-Type"]
- assert_response :created
- end
-
- def test_head_ok_with_image_png_content_type
- post :head_ok_with_image_png_content_type
- assert @response.body.blank?
- assert_equal "image/png", @response.header["Content-Type"]
- assert_response :ok
- end
-
- def test_head_with_location_header
- get :head_with_location_header
- assert @response.body.blank?
- assert_equal "/foo", @response.headers["Location"]
- assert_response :ok
- end
-
- def test_head_with_location_object
- with_routing do |set|
- set.draw do
- resources :customers
- get ':controller/:action'
- end
-
- get :head_with_location_object
- assert @response.body.blank?
- assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
- assert_response :ok
- end
- end
-
- def test_head_with_custom_header
- get :head_with_custom_header
- assert @response.body.blank?
- assert_equal "something", @response.headers["X-Custom-Header"]
- assert_response :ok
- end
-
- def test_head_with_www_authenticate_header
- get :head_with_www_authenticate_header
- assert @response.body.blank?
- assert_equal "something", @response.headers["WWW-Authenticate"]
- assert_response :ok
- end
-
- def test_head_with_symbolic_status
- get :head_with_symbolic_status, :status => "ok"
- assert_equal 200, @response.status
- assert_response :ok
-
- get :head_with_symbolic_status, :status => "not_found"
- assert_equal 404, @response.status
- assert_response :not_found
-
- get :head_with_symbolic_status, :status => "no_content"
- assert_equal 204, @response.status
- assert !@response.headers.include?('Content-Length')
- assert_response :no_content
-
- Rack::Utils::SYMBOL_TO_STATUS_CODE.each do |status, code|
- get :head_with_symbolic_status, :status => status.to_s
- assert_equal code, @response.response_code
- assert_response status
- end
- end
-
- def test_head_with_integer_status
- Rack::Utils::HTTP_STATUS_CODES.each do |code, message|
- get :head_with_integer_status, :status => code.to_s
- assert_equal message, @response.message
- end
- end
-
- def test_head_with_string_status
- get :head_with_string_status, :status => "404 Eat Dirt"
- assert_equal 404, @response.response_code
- assert_equal "Not Found", @response.message
- assert_response :not_found
- end
-
- def test_head_with_status_code_first
- get :head_with_status_code_first
- assert_equal 403, @response.response_code
- assert_equal "Forbidden", @response.message
- assert_equal "something", @response.headers["X-Custom-Header"]
- assert_response :forbidden
- end
-
- def test_using_layout_around_block
- get :render_using_layout_around_block
- assert_equal "Before (David)\nInside from block\nAfter", @response.body
- end
-
- def test_using_layout_around_block_in_main_layout_and_within_content_for_layout
- get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout
- assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body
- end
-
- def test_partial_only
- get :partial_only
- assert_equal "only partial", @response.body
- assert_equal "text/html", @response.content_type
- end
-
- def test_should_render_html_formatted_partial
- get :partial
- assert_equal "partial html", @response.body
- assert_equal "text/html", @response.content_type
- end
-
- def test_render_html_formatted_partial_even_with_other_mime_time_in_accept
- @request.accept = "text/javascript, text/html"
-
- get :partial_html_erb
-
- assert_equal "partial.html.erb", @response.body.strip
- assert_equal "text/html", @response.content_type
- end
-
- def test_should_render_html_partial_with_formats
- get :partial_formats_html
- assert_equal "partial html", @response.body
- assert_equal "text/html", @response.content_type
- end
-
- def test_render_to_string_partial
- get :render_to_string_with_partial
- assert_equal "only partial", assigns(:partial_only)
- assert_equal "Hello: david", assigns(:partial_with_locals)
- assert_equal "text/html", @response.content_type
- end
-
- def test_render_to_string_with_template_and_html_partial
- get :render_to_string_with_template_and_html_partial
- assert_equal "**only partial**\n", assigns(:text)
- assert_equal "<strong>only partial</strong>\n", assigns(:html)
- assert_equal "<strong>only html partial</strong>\n", @response.body
- assert_equal "text/html", @response.content_type
- end
-
- def test_render_to_string_and_render_with_different_formats
- get :render_to_string_and_render_with_different_formats
- assert_equal "<strong>only partial</strong>\n", assigns(:html)
- assert_equal "**only partial**\n", @response.body
- assert_equal "text/plain", @response.content_type
- end
-
- def test_render_template_within_a_template_with_other_format
- get :render_template_within_a_template_with_other_format
- expected = "only html partial<p>This is grand!</p>"
- assert_equal expected, @response.body.strip
- assert_equal "text/html", @response.content_type
- end
-
- def test_partial_with_counter
- get :partial_with_counter
- assert_equal "5", @response.body
- end
-
- def test_partial_with_locals
- get :partial_with_locals
- assert_equal "Hello: david", @response.body
- end
-
- def test_partial_with_form_builder
- get :partial_with_form_builder
- assert_match(/<label/, @response.body)
- assert_template('test/_form')
- end
-
- def test_partial_with_form_builder_subclass
- get :partial_with_form_builder_subclass
- assert_match(/<label/, @response.body)
- assert_template('test/_labelling_form')
- end
-
- def test_nested_partial_with_form_builder
- @controller = Fun::GamesController.new
- get :nested_partial_with_form_builder
- assert_match(/<label/, @response.body)
- assert_template('fun/games/_form')
- end
-
- def test_namespaced_object_partial
- @controller = Quiz::QuestionsController.new
- get :new
- assert_equal "Namespaced Partial", @response.body
- end
-
- def test_partial_collection
- get :partial_collection
- assert_equal "Hello: davidHello: mary", @response.body
- end
-
- def test_partial_collection_with_as
- get :partial_collection_with_as
- assert_equal "david david davidmary mary mary", @response.body
- end
-
- def test_partial_collection_with_counter
- get :partial_collection_with_counter
- assert_equal "david0mary1", @response.body
- end
-
- def test_partial_collection_with_as_and_counter
- get :partial_collection_with_as_and_counter
- assert_equal "david0mary1", @response.body
- end
-
- def test_partial_collection_with_locals
- get :partial_collection_with_locals
- assert_equal "Bonjour: davidBonjour: mary", @response.body
- end
-
- def test_locals_option_to_assert_template_is_not_supported
- get :partial_collection_with_locals
-
- warning_buffer = StringIO.new
- $stderr = warning_buffer
-
- assert_template partial: 'customer_greeting', locals: { greeting: 'Bonjour' }
- assert_equal "the :locals option to #assert_template is only supported in a ActionView::TestCase\n", warning_buffer.string
- ensure
- $stderr = STDERR
- end
-
- def test_partial_collection_with_spacer
- get :partial_collection_with_spacer
- assert_equal "Hello: davidonly partialHello: mary", @response.body
- assert_template :partial => '_customer'
- end
-
- def test_partial_collection_with_spacer_which_uses_render
- get :partial_collection_with_spacer_which_uses_render
- assert_equal "Hello: davidpartial html\npartial with partial\nHello: mary", @response.body
- assert_template :partial => '_customer'
- end
-
- def test_partial_collection_shorthand_with_locals
- get :partial_collection_shorthand_with_locals
- assert_equal "Bonjour: davidBonjour: mary", @response.body
- assert_template :partial => 'customers/_customer', :count => 2
- assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0
- end
-
- def test_partial_collection_shorthand_with_different_types_of_records
- get :partial_collection_shorthand_with_different_types_of_records
- assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
- assert_template :partial => 'good_customers/_good_customer', :count => 3
- assert_template :partial => 'bad_customers/_bad_customer', :count => 3
- end
-
- def test_empty_partial_collection
- get :empty_partial_collection
- assert_equal " ", @response.body
- assert_template :partial => false
- end
-
- def test_partial_with_hash_object
- get :partial_with_hash_object
- assert_equal "Sam\nmaS\n", @response.body
- end
-
- def test_partial_with_nested_object
- get :partial_with_nested_object
- assert_equal "first", @response.body
- end
-
- def test_partial_with_nested_object_shorthand
- get :partial_with_nested_object_shorthand
- assert_equal "first", @response.body
- end
-
- def test_hash_partial_collection
- get :partial_hash_collection
- assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body
- end
-
- def test_partial_hash_collection_with_locals
- get :partial_hash_collection_with_locals
- assert_equal "Hola: PratikHola: Amy", @response.body
- end
-
- def test_render_missing_partial_template
- assert_raise(ActionView::MissingTemplate) do
- get :missing_partial
- end
- end
-
- def test_render_call_to_partial_with_layout
- get :render_call_to_partial_with_layout
- assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body
- end
-
- def test_render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
- get :render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
- assert_equal "Before (Anthony)\nInside from partial (Anthony)\nAfter\nBefore (David)\nInside from partial (David)\nAfter\nBefore (Ramm)\nInside from partial (Ramm)\nAfter", @response.body
- end
-end
-
class ExpiresInRenderTest < ActionController::TestCase
tests TestController
- def setup
- @request.host = "www.nextangle.com"
- end
-
def test_expires_in_header
get :conditional_hello_with_expires_in
assert_equal "max-age=60, private", @response.headers["Cache-Control"]
@@ -1598,7 +305,6 @@ class LastModifiedRenderTest < ActionController::TestCase
def setup
super
- @request.host = "www.nextangle.com"
@last_modified = Time.now.utc.beginning_of_day.httpdate
end
@@ -1683,7 +389,6 @@ class EtagRenderTest < ActionController::TestCase
def setup
super
- @request.host = "www.nextangle.com"
end
def test_multiple_etags
@@ -1711,7 +416,6 @@ class EtagRenderTest < ActionController::TestCase
end
end
-
class MetalRenderTest < ActionController::TestCase
tests MetalTestController
@@ -1720,3 +424,109 @@ class MetalRenderTest < ActionController::TestCase
assert_equal "NilClass", @response.body
end
end
+
+class HeadRenderTest < ActionController::TestCase
+ tests TestController
+
+ def setup
+ @request.host = "www.nextangle.com"
+ end
+
+ def test_head_created
+ post :head_created
+ assert @response.body.blank?
+ assert_response :created
+ end
+
+ def test_head_created_with_application_json_content_type
+ post :head_created_with_application_json_content_type
+ assert @response.body.blank?
+ assert_equal "application/json", @response.header["Content-Type"]
+ assert_response :created
+ end
+
+ def test_head_ok_with_image_png_content_type
+ post :head_ok_with_image_png_content_type
+ assert @response.body.blank?
+ assert_equal "image/png", @response.header["Content-Type"]
+ assert_response :ok
+ end
+
+ def test_head_with_location_header
+ get :head_with_location_header
+ assert @response.body.blank?
+ assert_equal "/foo", @response.headers["Location"]
+ assert_response :ok
+ end
+
+ def test_head_with_location_object
+ with_routing do |set|
+ set.draw do
+ resources :customers
+ get ':controller/:action'
+ end
+
+ get :head_with_location_object
+ assert @response.body.blank?
+ assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
+ assert_response :ok
+ end
+ end
+
+ def test_head_with_custom_header
+ get :head_with_custom_header
+ assert @response.body.blank?
+ assert_equal "something", @response.headers["X-Custom-Header"]
+ assert_response :ok
+ end
+
+ def test_head_with_www_authenticate_header
+ get :head_with_www_authenticate_header
+ assert @response.body.blank?
+ assert_equal "something", @response.headers["WWW-Authenticate"]
+ assert_response :ok
+ end
+
+ def test_head_with_symbolic_status
+ get :head_with_symbolic_status, :status => "ok"
+ assert_equal 200, @response.status
+ assert_response :ok
+
+ get :head_with_symbolic_status, :status => "not_found"
+ assert_equal 404, @response.status
+ assert_response :not_found
+
+ get :head_with_symbolic_status, :status => "no_content"
+ assert_equal 204, @response.status
+ assert !@response.headers.include?('Content-Length')
+ assert_response :no_content
+
+ Rack::Utils::SYMBOL_TO_STATUS_CODE.each do |status, code|
+ get :head_with_symbolic_status, :status => status.to_s
+ assert_equal code, @response.response_code
+ assert_response status
+ end
+ end
+
+ def test_head_with_integer_status
+ Rack::Utils::HTTP_STATUS_CODES.each do |code, message|
+ get :head_with_integer_status, :status => code.to_s
+ assert_equal message, @response.message
+ end
+ end
+
+ def test_head_with_string_status
+ get :head_with_string_status, :status => "404 Eat Dirt"
+ assert_equal 404, @response.response_code
+ assert_equal "Not Found", @response.message
+ assert_response :not_found
+ end
+
+ def test_head_with_status_code_first
+ get :head_with_status_code_first
+ assert_equal 403, @response.response_code
+ assert_equal "Forbidden", @response.message
+ assert_equal "something", @response.headers["X-Custom-Header"]
+ assert_response :forbidden
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/fixtures/layout_tests/layouts/symlinked b/actionpack/test/fixtures/layout_tests/layouts/symlinked
deleted file mode 120000
index 0ddc1154ab..0000000000
--- a/actionpack/test/fixtures/layout_tests/layouts/symlinked
+++ /dev/null
@@ -1 +0,0 @@
-../../symlink_parent \ No newline at end of file
diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb
index 82f38b5309..38abb16d08 100644
--- a/actionpack/test/lib/controller/fake_models.rb
+++ b/actionpack/test/lib/controller/fake_models.rb
@@ -28,12 +28,6 @@ class Customer < Struct.new(:name, :id)
end
end
-class BadCustomer < Customer
-end
-
-class GoodCustomer < Customer
-end
-
class ValidatedCustomer < Customer
def errors
if name =~ /Sikachu/i
diff --git a/actionview/Rakefile b/actionview/Rakefile
index 8e980df7fc..e1cb4b5be0 100644
--- a/actionview/Rakefile
+++ b/actionview/Rakefile
@@ -7,14 +7,7 @@ task :default => :test
# Run the unit tests
desc "Run all unit tests"
-task :test => [:test_action_view, :test_active_record_integration]
-
-Rake::TestTask.new(:test_action_view) do |t|
- t.libs << 'test'
- t.test_files = Dir.glob('test/template/**/*_test.rb').sort
- t.warning = true
- t.verbose = true
-end
+task :test => ["test:template", "test:integration:action_pack", "test:integration:active_record"]
namespace :test do
task :isolated do
@@ -25,16 +18,28 @@ namespace :test do
Rake::TestTask.new(:template) do |t|
t.libs << 'test'
- t.pattern = 'test/template/**/*.rb'
+ t.test_files = Dir.glob('test/template/**/*_test.rb').sort
+ t.warning = true
+ t.verbose = true
end
-end
-desc 'ActiveRecord Integration Tests'
-Rake::TestTask.new(:test_active_record_integration) do |t|
- t.libs << 'test'
- t.test_files = Dir.glob("test/activerecord/*_test.rb")
- t.warning = true
- t.verbose = true
+ namespace :integration do
+ desc 'ActiveRecord Integration Tests'
+ Rake::TestTask.new(:active_record) do |t|
+ t.libs << 'test'
+ t.test_files = Dir.glob("test/activerecord/*_test.rb")
+ t.warning = true
+ t.verbose = true
+ end
+
+ desc 'ActionPack Integration Tests'
+ Rake::TestTask.new(:action_pack) do |t|
+ t.libs << 'test'
+ t.test_files = Dir.glob("test/actionpack/**/*_test.rb")
+ t.warning = true
+ t.verbose = true
+ end
+ end
end
spec = eval(File.read('actionview.gemspec'))
diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb
index 8def4ba7c5..39c0c6c856 100644
--- a/actionview/lib/action_view.rb
+++ b/actionview/lib/action_view.rb
@@ -34,10 +34,13 @@ module ActionView
autoload :Digestor
autoload :Helpers
autoload :LookupContext
+ autoload :Layouts
autoload :PathSet
autoload :RecordIdentifier
+ autoload :Rendering
autoload :RoutingUrlFor
autoload :Template
+ autoload :ViewPaths
autoload_under "renderer" do
autoload :Renderer
@@ -82,6 +85,7 @@ module ActionView
def self.eager_load!
super
ActionView::Template.eager_load!
+ HTML.eager_load!
end
end
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index 08253de3f4..caade8f43b 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -2,6 +2,10 @@ require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/ordered_options'
require 'action_view/log_subscriber'
+require 'action_view/helpers'
+require 'action_view/context'
+require 'action_view/template'
+require 'action_view/lookup_context'
module ActionView #:nodoc:
# = Action View Base
diff --git a/actionview/lib/action_view/helpers/record_tag_helper.rb b/actionview/lib/action_view/helpers/record_tag_helper.rb
index f767957fa9..77c3e6d394 100644
--- a/actionview/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/record_tag_helper.rb
@@ -1,3 +1,5 @@
+require 'action_view/record_identifier'
+
module ActionView
# = Action View Record Tag Helpers
module Helpers
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionview/lib/action_view/layouts.rb
index 8e7bdf620e..d8de1d95df 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionview/lib/action_view/layouts.rb
@@ -1,6 +1,7 @@
+require "action_view/rendering"
require "active_support/core_ext/module/remove_method"
-module AbstractController
+module ActionView
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
# repeated setups. The inclusion pattern has pages that look like this:
#
@@ -200,7 +201,7 @@ module AbstractController
module Layouts
extend ActiveSupport::Concern
- include Rendering
+ include ActionView::Rendering
included do
class_attribute :_layout, :_layout_conditions, :instance_accessor => false
diff --git a/actionview/lib/action_view/log_subscriber.rb b/actionview/lib/action_view/log_subscriber.rb
index fd9a543e0a..354a136894 100644
--- a/actionview/lib/action_view/log_subscriber.rb
+++ b/actionview/lib/action_view/log_subscriber.rb
@@ -1,3 +1,5 @@
+require 'active_support/log_subscriber'
+
module ActionView
# = Action View Log Subscriber
#
diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb
index e80e0ed9b0..4113448af0 100644
--- a/actionview/lib/action_view/railtie.rb
+++ b/actionview/lib/action_view/railtie.rb
@@ -35,5 +35,18 @@ module ActionView
end
end
end
+
+ initializer "action_view.setup_action_pack", before: :add_view_paths do |app|
+ ActiveSupport.on_load(:action_controller) do
+ ActionController::Base.superclass.send(:include, ActionView::Layouts)
+ ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
+ end
+ end
+
+ initializer "action_view.setup_action_mailer", before: :add_view_paths do |app|
+ ActiveSupport.on_load(:action_mailer) do
+ ActionMailer::Base.send(:include, ActionView::Layouts)
+ end
+ end
end
end
diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb
new file mode 100644
index 0000000000..db9c4ef501
--- /dev/null
+++ b/actionview/lib/action_view/rendering.rb
@@ -0,0 +1,162 @@
+require "action_view/view_paths"
+
+module ActionView
+ # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request,
+ # it will trigger the lookup_context and consequently expire the cache.
+ class I18nProxy < ::I18n::Config #:nodoc:
+ attr_reader :original_config, :lookup_context
+
+ def initialize(original_config, lookup_context)
+ original_config = original_config.original_config if original_config.respond_to?(:original_config)
+ @original_config, @lookup_context = original_config, lookup_context
+ end
+
+ def locale
+ @original_config.locale
+ end
+
+ def locale=(value)
+ @lookup_context.locale = value
+ end
+ end
+
+ module Rendering
+ extend ActiveSupport::Concern
+ include ActionView::ViewPaths
+
+ # Overwrite process to setup I18n proxy.
+ def process(*) #:nodoc:
+ old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
+ super
+ ensure
+ I18n.config = old_config
+ end
+
+ module ClassMethods
+ def view_context_class
+ @view_context_class ||= begin
+ routes = respond_to?(:_routes) && _routes
+ helpers = respond_to?(:_helpers) && _helpers
+
+ Class.new(ActionView::Base) do
+ if routes
+ include routes.url_helpers
+ include routes.mounted_helpers
+ end
+
+ if helpers
+ include helpers
+ end
+ end
+ end
+ end
+ end
+
+ attr_internal_writer :view_context_class
+
+ def view_context_class
+ @_view_context_class ||= self.class.view_context_class
+ end
+
+ # An instance of a view class. The default view class is ActionView::Base
+ #
+ # The view class must have the following methods:
+ # View.new[lookup_context, assigns, controller]
+ # Create a new ActionView instance for a controller
+ # View#render[options]
+ # Returns String with the rendered template
+ #
+ # Override this method in a module to change the default behavior.
+ def view_context
+ view_context_class.new(view_renderer, view_assigns, self)
+ end
+
+ # Returns an object that is able to render templates.
+ # :api: private
+ def view_renderer
+ @_view_renderer ||= ActionView::Renderer.new(lookup_context)
+ end
+
+ # Render template to response_body
+ # :api: public
+ def render(*args, &block)
+ options = _normalize_render(*args, &block)
+ self.response_body = render_to_body(options)
+ end
+
+ # Raw rendering of a template to a string.
+ # :api: public
+ def render_to_string(*args, &block)
+ options = _normalize_render(*args, &block)
+ render_to_body(options)
+ end
+
+ # Raw rendering of a template.
+ # :api: public
+ def render_to_body(options = {})
+ _process_options(options)
+ _render_template(options)
+ end
+
+ # Find and renders a template based on the options given.
+ # :api: private
+ def _render_template(options) #:nodoc:
+ lookup_context.rendered_format = nil if options[:formats]
+ view_renderer.render(view_context, options)
+ end
+
+ def rendered_format
+ Mime[lookup_context.rendered_format]
+ end
+
+ def default_protected_instance_vars
+ super.concat([:@_view_context_class, :@_view_renderer, :@_lookup_context])
+ end
+
+ private
+
+ # Normalize args and options.
+ # :api: private
+ def _normalize_render(*args, &block)
+ options = _normalize_args(*args, &block)
+ _normalize_options(options)
+ options
+ end
+
+ # Normalize args by converting render "foo" to render :action => "foo" and
+ # render "foo/bar" to render :file => "foo/bar".
+ # :api: private
+ def _normalize_args(action=nil, options={})
+ options = super(action, options)
+ case action
+ when NilClass
+ when Hash
+ options = action
+ when String, Symbol
+ action = action.to_s
+ key = action.include?(?/) ? :file : :action
+ options[key] = action
+ else
+ options[:partial] = action
+ end
+
+ options
+ end
+
+ # Normalize options.
+ # :api: private
+ def _normalize_options(options)
+ options = super(options)
+ if options[:partial] == true
+ options[:partial] = action_name
+ end
+
+ if (options.keys & [:partial, :file, :template]).empty?
+ options[:prefixes] ||= _prefixes
+ end
+
+ options[:template] ||= (options[:action] || action_name).to_s
+ options
+ end
+ end
+end
diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionview/lib/action_view/view_paths.rb
index c08b3a0e2a..6c349feb1d 100644
--- a/actionpack/lib/abstract_controller/view_paths.rb
+++ b/actionview/lib/action_view/view_paths.rb
@@ -1,6 +1,6 @@
require 'action_view/base'
-module AbstractController
+module ActionView
module ViewPaths
extend ActiveSupport::Concern
diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb
index 8213997f4e..6623b47e83 100644
--- a/actionview/test/abstract_unit.rb
+++ b/actionview/test/abstract_unit.rb
@@ -24,7 +24,6 @@ require 'action_dispatch'
require 'active_support/dependencies'
require 'active_model'
require 'active_record'
-require 'action_controller/caching'
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
@@ -268,6 +267,10 @@ class Rack::TestCase < ActionDispatch::IntegrationTest
end
end
+# Emulate AV railtie.
+ActionController::Base.superclass.send(:include, ActionView::Layouts)
+ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
+
module ActionController
class Base
include ActionController::Testing
@@ -290,9 +293,6 @@ module ActionController
end
end
-class ::ApplicationController < ActionController::Base
-end
-
module ActionView
class TestCase
# Must repeat the setup because AV::TestCase is a duplication
@@ -330,53 +330,3 @@ module ActionDispatch
end
end
-module ActionDispatch
- module RoutingVerbs
- def get(uri_or_host, path = nil)
- host = uri_or_host.host unless path
- path ||= uri_or_host.path
-
- params = {'PATH_INFO' => path,
- 'REQUEST_METHOD' => 'GET',
- 'HTTP_HOST' => host}
-
- routes.call(params)[2].join
- end
- end
-end
-
-module RoutingTestHelpers
- def url_for(set, options, recall = nil)
- set.send(:url_for, options.merge(:only_path => true, :_recall => recall))
- end
-end
-
-class ResourcesController < ActionController::Base
- def index() render :nothing => true end
- alias_method :show, :index
-end
-
-class ThreadsController < ResourcesController; end
-class MessagesController < ResourcesController; end
-class CommentsController < ResourcesController; end
-class ReviewsController < ResourcesController; end
-class AuthorsController < ResourcesController; end
-class LogosController < ResourcesController; end
-
-class AccountsController < ResourcesController; end
-class AdminController < ResourcesController; end
-class ProductsController < ResourcesController; end
-class ImagesController < ResourcesController; end
-class PreferencesController < ResourcesController; end
-
-module Backoffice
- class ProductsController < ResourcesController; end
- class TagsController < ResourcesController; end
- class ManufacturersController < ResourcesController; end
- class ImagesController < ResourcesController; end
-
- module Admin
- class ProductsController < ResourcesController; end
- class ImagesController < ResourcesController; end
- end
-end
diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb
index eb9143c8f6..40d3b17131 100644
--- a/actionpack/test/abstract/abstract_controller_test.rb
+++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb
@@ -30,6 +30,7 @@ module AbstractController
# ====
class RenderingController < AbstractController::Base
include AbstractController::Rendering
+ include ActionView::Rendering
def _prefixes
[]
@@ -153,7 +154,7 @@ module AbstractController
# ====
# self._layout is used when defined
class WithLayouts < PrefixedViews
- include AbstractController::Layouts
+ include ActionView::Layouts
private
def self.layout(formats)
diff --git a/actionpack/test/abstract/helper_test.rb b/actionview/test/actionpack/abstract/helper_test.rb
index bc3e34684c..4e05245584 100644
--- a/actionpack/test/abstract/helper_test.rb
+++ b/actionview/test/actionpack/abstract/helper_test.rb
@@ -1,13 +1,14 @@
require 'abstract_unit'
-ActionController::Base.helpers_path = File.expand_path('../../fixtures/helpers', __FILE__)
+ActionController::Base.helpers_path = File.expand_path('../../../fixtures/helpers', __FILE__)
module AbstractController
module Testing
class ControllerWithHelpers < AbstractController::Base
- include AbstractController::Rendering
include AbstractController::Helpers
+ include AbstractController::Rendering
+ include ActionView::Rendering
def with_module
render :inline => "Module <%= included_method %>"
@@ -51,7 +52,7 @@ module AbstractController
class AbstractInvalidHelpers < AbstractHelpers
include ActionController::Helpers
- path = File.join(File.expand_path('../../fixtures', __FILE__), "helpers_missing")
+ path = File.join(File.expand_path('../../../fixtures', __FILE__), "helpers_missing")
$:.unshift(path)
self.helpers_path = path
end
diff --git a/actionpack/test/abstract/layouts_test.rb b/actionview/test/actionpack/abstract/layouts_test.rb
index 4a05c00f8b..c79cb50fd7 100644
--- a/actionpack/test/abstract/layouts_test.rb
+++ b/actionview/test/actionpack/abstract/layouts_test.rb
@@ -6,7 +6,8 @@ module AbstractControllerTests
# Base controller for these tests
class Base < AbstractController::Base
include AbstractController::Rendering
- include AbstractController::Layouts
+ include ActionView::Rendering
+ include ActionView::Layouts
abstract!
diff --git a/actionpack/test/abstract/render_test.rb b/actionview/test/actionpack/abstract/render_test.rb
index b9293d1241..f9d8c916d9 100644
--- a/actionpack/test/abstract/render_test.rb
+++ b/actionview/test/actionpack/abstract/render_test.rb
@@ -5,6 +5,7 @@ module AbstractController
class ControllerRenderer < AbstractController::Base
include AbstractController::Rendering
+ include ActionView::Rendering
def _prefixes
%w[renderer]
diff --git a/actionpack/test/abstract/views/abstract_controller/testing/me3/formatted.html.erb b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me3/formatted.html.erb
index 785bf69191..785bf69191 100644
--- a/actionpack/test/abstract/views/abstract_controller/testing/me3/formatted.html.erb
+++ b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me3/formatted.html.erb
diff --git a/actionpack/test/abstract/views/abstract_controller/testing/me3/index.erb b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me3/index.erb
index f079ad8204..f079ad8204 100644
--- a/actionpack/test/abstract/views/abstract_controller/testing/me3/index.erb
+++ b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me3/index.erb
diff --git a/actionpack/test/abstract/views/abstract_controller/testing/me4/index.erb b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me4/index.erb
index 89dce12bdc..89dce12bdc 100644
--- a/actionpack/test/abstract/views/abstract_controller/testing/me4/index.erb
+++ b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me4/index.erb
diff --git a/actionpack/test/abstract/views/abstract_controller/testing/me5/index.erb b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me5/index.erb
index 84d0b7417e..84d0b7417e 100644
--- a/actionpack/test/abstract/views/abstract_controller/testing/me5/index.erb
+++ b/actionview/test/actionpack/abstract/views/abstract_controller/testing/me5/index.erb
diff --git a/actionpack/test/abstract/views/action_with_ivars.erb b/actionview/test/actionpack/abstract/views/action_with_ivars.erb
index 8d8ae22fd7..8d8ae22fd7 100644
--- a/actionpack/test/abstract/views/action_with_ivars.erb
+++ b/actionview/test/actionpack/abstract/views/action_with_ivars.erb
diff --git a/actionpack/test/abstract/views/helper_test.erb b/actionview/test/actionpack/abstract/views/helper_test.erb
index 8ae45cc195..8ae45cc195 100644
--- a/actionpack/test/abstract/views/helper_test.erb
+++ b/actionview/test/actionpack/abstract/views/helper_test.erb
diff --git a/actionpack/test/abstract/views/index.erb b/actionview/test/actionpack/abstract/views/index.erb
index cc1a8b8c85..cc1a8b8c85 100644
--- a/actionpack/test/abstract/views/index.erb
+++ b/actionview/test/actionpack/abstract/views/index.erb
diff --git a/actionpack/test/abstract/views/layouts/abstract_controller/testing/me4.erb b/actionview/test/actionpack/abstract/views/layouts/abstract_controller/testing/me4.erb
index 172dd56569..172dd56569 100644
--- a/actionpack/test/abstract/views/layouts/abstract_controller/testing/me4.erb
+++ b/actionview/test/actionpack/abstract/views/layouts/abstract_controller/testing/me4.erb
diff --git a/actionpack/test/abstract/views/layouts/application.erb b/actionview/test/actionpack/abstract/views/layouts/application.erb
index 27317140ad..27317140ad 100644
--- a/actionpack/test/abstract/views/layouts/application.erb
+++ b/actionview/test/actionpack/abstract/views/layouts/application.erb
diff --git a/actionpack/test/abstract/views/naked_render.erb b/actionview/test/actionpack/abstract/views/naked_render.erb
index 1b3d03878b..1b3d03878b 100644
--- a/actionpack/test/abstract/views/naked_render.erb
+++ b/actionview/test/actionpack/abstract/views/naked_render.erb
diff --git a/actionpack/test/controller/capture_test.rb b/actionview/test/actionpack/controller/capture_test.rb
index 72263156d9..f8387b27b0 100644
--- a/actionpack/test/controller/capture_test.rb
+++ b/actionview/test/actionpack/controller/capture_test.rb
@@ -2,6 +2,8 @@ require 'abstract_unit'
require 'active_support/logger'
class CaptureController < ActionController::Base
+ self.view_paths = [ File.dirname(__FILE__) + '/../../fixtures/actionpack' ]
+
def self.controller_name; "test"; end
def self.controller_path; "test"; end
diff --git a/actionpack/test/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb
index 34304cf640..5dd23c4b31 100644
--- a/actionpack/test/controller/layout_test.rb
+++ b/actionview/test/actionpack/controller/layout_test.rb
@@ -9,7 +9,7 @@ old_load_paths = ActionController::Base.view_paths
ActionView::Template::register_template_handler :mab,
lambda { |template| template.source.inspect }
-ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ]
+ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../../fixtures/actionpack/layout_tests/' ]
class LayoutTest < ActionController::Base
def self.controller_path; 'views' end
@@ -87,7 +87,7 @@ class StreamingLayoutController < LayoutTest
end
class AbsolutePathLayoutController < LayoutTest
- layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/layouts/layout_test')
+ layout File.expand_path(File.expand_path(__FILE__) + '/../../../fixtures/actionpack/layout_tests/layouts/layout_test')
end
class HasOwnLayoutController < LayoutTest
@@ -108,7 +108,7 @@ end
class PrependsViewPathController < LayoutTest
def hello
- prepend_view_path File.dirname(__FILE__) + '/../fixtures/layout_tests/alt/'
+ prepend_view_path File.dirname(__FILE__) + '/../../fixtures/actionpack/layout_tests/alt/'
render :layout => 'alt'
end
end
diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb
new file mode 100644
index 0000000000..964dccbffb
--- /dev/null
+++ b/actionview/test/actionpack/controller/render_test.rb
@@ -0,0 +1,1337 @@
+require 'abstract_unit'
+require "active_model"
+
+class ApplicationController < ActionController::Base
+ self.view_paths = File.join(FIXTURE_LOAD_PATH, "actionpack")
+end
+
+class Customer < Struct.new(:name, :id)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ undef_method :to_json
+
+ def to_xml(options={})
+ if options[:builder]
+ options[:builder].name name
+ else
+ "<name>#{name}</name>"
+ end
+ end
+
+ def to_js(options={})
+ "name: #{name.inspect}"
+ end
+ alias :to_text :to_js
+
+ def errors
+ []
+ end
+
+ def persisted?
+ id.present?
+ end
+end
+
+module Quiz
+ #Models
+ class Question < Struct.new(:name, :id)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ def persisted?
+ id.present?
+ end
+ end
+
+ class Store < Question; end
+
+ # Controller
+ class QuestionsController < ApplicationController
+ def new
+ render :partial => Quiz::Question.new("Namespaced Partial")
+ end
+ end
+end
+
+class BadCustomer < Customer; end
+class GoodCustomer < Customer; end
+
+module Fun
+ class GamesController < ApplicationController
+ def hello_world; end
+
+ def nested_partial_with_form_builder
+ render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {})
+ end
+ end
+end
+
+class TestController < ApplicationController
+ protect_from_forgery
+
+ before_action :set_variable_for_layout
+
+ class LabellingFormBuilder < ActionView::Helpers::FormBuilder
+ end
+
+ layout :determine_layout
+
+ def name
+ nil
+ end
+
+ private :name
+ helper_method :name
+
+ def hello_world
+ end
+
+ def hello_world_file
+ render :file => File.expand_path("../../../fixtures/actionpack/hello", __FILE__), :formats => [:html]
+ end
+
+ # :ported:
+ def render_hello_world
+ render :template => "test/hello_world"
+ end
+
+ def render_hello_world_with_last_modified_set
+ response.last_modified = Date.new(2008, 10, 10).to_time
+ render :template => "test/hello_world"
+ end
+
+ # :ported: compatibility
+ def render_hello_world_with_forward_slash
+ render :template => "/test/hello_world"
+ end
+
+ # :ported:
+ def render_template_in_top_directory
+ render :template => 'shared'
+ end
+
+ # :deprecated:
+ def render_template_in_top_directory_with_slash
+ render :template => '/shared'
+ end
+
+ # :ported:
+ def render_hello_world_from_variable
+ @person = "david"
+ render :text => "hello #{@person}"
+ end
+
+ # :ported:
+ def render_action_hello_world
+ render :action => "hello_world"
+ end
+
+ def render_action_upcased_hello_world
+ render :action => "Hello_world"
+ end
+
+ def render_action_hello_world_as_string
+ render "hello_world"
+ end
+
+ def render_action_hello_world_with_symbol
+ render :action => :hello_world
+ end
+
+ # :ported:
+ def render_text_hello_world
+ render :text => "hello world"
+ end
+
+ # :ported:
+ def render_text_hello_world_with_layout
+ @variable_for_layout = ", I am here!"
+ render :text => "hello world", :layout => true
+ end
+
+ def hello_world_with_layout_false
+ render :layout => false
+ end
+
+ # :ported:
+ def render_file_with_instance_variables
+ @secret = 'in the sauce'
+ path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar')
+ render :file => path
+ end
+
+ # :ported:
+ def render_file_as_string_with_instance_variables
+ @secret = 'in the sauce'
+ path = File.expand_path(File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar'))
+ render path
+ end
+
+ # :ported:
+ def render_file_not_using_full_path
+ @secret = 'in the sauce'
+ render :file => 'test/render_file_with_ivar'
+ end
+
+ def render_file_not_using_full_path_with_dot_in_path
+ @secret = 'in the sauce'
+ render :file => 'test/dot.directory/render_file_with_ivar'
+ end
+
+ def render_file_using_pathname
+ @secret = 'in the sauce'
+ render :file => Pathname.new(File.dirname(__FILE__)).join('..', '..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar')
+ end
+
+ def render_file_from_template
+ @secret = 'in the sauce'
+ @path = File.expand_path(File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar'))
+ end
+
+ def render_file_with_locals
+ path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals')
+ render :file => path, :locals => {:secret => 'in the sauce'}
+ end
+
+ def render_file_as_string_with_locals
+ path = File.expand_path(File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals'))
+ render path, :locals => {:secret => 'in the sauce'}
+ end
+
+ def accessing_request_in_template
+ render :inline => "Hello: <%= request.host %>"
+ end
+
+ def accessing_logger_in_template
+ render :inline => "<%= logger.class %>"
+ end
+
+ def accessing_action_name_in_template
+ render :inline => "<%= action_name %>"
+ end
+
+ def accessing_controller_name_in_template
+ render :inline => "<%= controller_name %>"
+ end
+
+ # :ported:
+ def render_custom_code
+ render :text => "hello world", :status => 404
+ end
+
+ # :ported:
+ def render_text_with_nil
+ render :text => nil
+ end
+
+ # :ported:
+ def render_text_with_false
+ render :text => false
+ end
+
+ def render_text_with_resource
+ render :text => Customer.new("David")
+ end
+
+ # :ported:
+ def render_nothing_with_appendix
+ render :text => "appended"
+ end
+
+ # This test is testing 3 things:
+ # render :file in AV :ported:
+ # render :template in AC :ported:
+ # setting content type
+ def render_xml_hello
+ @name = "David"
+ render :template => "test/hello"
+ end
+
+ def render_xml_hello_as_string_template
+ @name = "David"
+ render "test/hello"
+ end
+
+ def render_line_offset
+ render :inline => '<% raise %>', :locals => {:foo => 'bar'}
+ end
+
+ def heading
+ head :ok
+ end
+
+ def greeting
+ # let's just rely on the template
+ end
+
+ # :ported:
+ def blank_response
+ render :text => ' '
+ end
+
+ # :ported:
+ def layout_test
+ render :action => "hello_world"
+ end
+
+ # :ported:
+ def builder_layout_test
+ @name = nil
+ render :action => "hello", :layout => "layouts/builder"
+ end
+
+ # :move: test this in Action View
+ def builder_partial_test
+ render :action => "hello_world_container"
+ end
+
+ # :ported:
+ def partials_list
+ @test_unchanged = 'hello'
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
+ render :action => "list"
+ end
+
+ def partial_only
+ render :partial => true
+ end
+
+ def hello_in_a_string
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
+ render :text => "How's there? " + render_to_string(:template => "test/list")
+ end
+
+ def accessing_params_in_template
+ render :inline => "Hello: <%= params[:name] %>"
+ end
+
+ def accessing_local_assigns_in_inline_template
+ name = params[:local_name]
+ render :inline => "<%= 'Goodbye, ' + local_name %>",
+ :locals => { :local_name => name }
+ end
+
+ def render_implicit_html_template_from_xhr_request
+ end
+
+ def render_implicit_js_template_without_layout
+ end
+
+ def formatted_html_erb
+ end
+
+ def formatted_xml_erb
+ end
+
+ def render_to_string_test
+ @foo = render_to_string :inline => "this is a test"
+ end
+
+ def default_render
+ @alternate_default_render ||= nil
+ if @alternate_default_render
+ @alternate_default_render.call
+ else
+ super
+ end
+ end
+
+ def render_action_hello_world_as_symbol
+ render :action => :hello_world
+ end
+
+ def layout_test_with_different_layout
+ render :action => "hello_world", :layout => "standard"
+ end
+
+ def layout_test_with_different_layout_and_string_action
+ render "hello_world", :layout => "standard"
+ end
+
+ def layout_test_with_different_layout_and_symbol_action
+ render :hello_world, :layout => "standard"
+ end
+
+ def rendering_without_layout
+ render :action => "hello_world", :layout => false
+ end
+
+ def layout_overriding_layout
+ render :action => "hello_world", :layout => "standard"
+ end
+
+ def rendering_nothing_on_layout
+ render :nothing => true
+ end
+
+ def render_to_string_with_assigns
+ @before = "i'm before the render"
+ render_to_string :text => "foo"
+ @after = "i'm after the render"
+ render :template => "test/hello_world"
+ end
+
+ def render_to_string_with_exception
+ render_to_string :file => "exception that will not be caught - this will certainly not work"
+ end
+
+ def render_to_string_with_caught_exception
+ @before = "i'm before the render"
+ begin
+ render_to_string :file => "exception that will be caught- hope my future instance vars still work!"
+ rescue
+ end
+ @after = "i'm after the render"
+ render :template => "test/hello_world"
+ end
+
+ def accessing_params_in_template_with_layout
+ render :layout => true, :inline => "Hello: <%= params[:name] %>"
+ end
+
+ # :ported:
+ def render_with_explicit_template
+ render :template => "test/hello_world"
+ end
+
+ def render_with_explicit_unescaped_template
+ render :template => "test/h*llo_world"
+ end
+
+ def render_with_explicit_escaped_template
+ render :template => "test/hello,world"
+ end
+
+ def render_with_explicit_string_template
+ render "test/hello_world"
+ end
+
+ # :ported:
+ def render_with_explicit_template_with_locals
+ render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' }
+ end
+
+ # :ported:
+ def double_render
+ render :text => "hello"
+ render :text => "world"
+ end
+
+ def double_redirect
+ redirect_to :action => "double_render"
+ redirect_to :action => "double_render"
+ end
+
+ def render_and_redirect
+ render :text => "hello"
+ redirect_to :action => "double_render"
+ end
+
+ def render_to_string_and_render
+ @stuff = render_to_string :text => "here is some cached stuff"
+ render :text => "Hi web users! #{@stuff}"
+ end
+
+ def render_to_string_with_inline_and_render
+ render_to_string :inline => "<%= 'dlrow olleh'.reverse %>"
+ render :template => "test/hello_world"
+ end
+
+ def rendering_with_conflicting_local_vars
+ @name = "David"
+ render :action => "potential_conflicts"
+ end
+
+ def hello_world_from_rxml_using_action
+ render :action => "hello_world_from_rxml", :handlers => [:builder]
+ end
+
+ # :deprecated:
+ def hello_world_from_rxml_using_template
+ render :template => "test/hello_world_from_rxml", :handlers => [:builder]
+ end
+
+ def action_talk_to_layout
+ # Action template sets variable that's picked up by layout
+ end
+
+ # :addressed:
+ def render_text_with_assigns
+ @hello = "world"
+ render :text => "foo"
+ end
+
+ def yield_content_for
+ render :action => "content_for", :layout => "yield"
+ end
+
+ def render_content_type_from_body
+ response.content_type = Mime::RSS
+ render :text => "hello world!"
+ end
+
+ def render_using_layout_around_block
+ render :action => "using_layout_around_block"
+ end
+
+ def render_using_layout_around_block_in_main_layout_and_within_content_for_layout
+ render :action => "using_layout_around_block", :layout => "layouts/block_with_layout"
+ end
+
+ def partial_formats_html
+ render :partial => 'partial', :formats => [:html]
+ end
+
+ def partial
+ render :partial => 'partial'
+ end
+
+ def partial_html_erb
+ render :partial => 'partial_html_erb'
+ end
+
+ def render_to_string_with_partial
+ @partial_only = render_to_string :partial => "partial_only"
+ @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
+ render :template => "test/hello_world"
+ end
+
+ def render_to_string_with_template_and_html_partial
+ @text = render_to_string :template => "test/with_partial", :formats => [:text]
+ @html = render_to_string :template => "test/with_partial", :formats => [:html]
+ render :template => "test/with_html_partial"
+ end
+
+ def render_to_string_and_render_with_different_formats
+ @html = render_to_string :template => "test/with_partial", :formats => [:html]
+ render :template => "test/with_partial", :formats => [:text]
+ end
+
+ def render_template_within_a_template_with_other_format
+ render :template => "test/with_xml_template",
+ :formats => [:html],
+ :layout => "with_html_partial"
+ end
+
+ def partial_with_counter
+ render :partial => "counter", :locals => { :counter_counter => 5 }
+ end
+
+ def partial_with_locals
+ render :partial => "customer", :locals => { :customer => Customer.new("david") }
+ end
+
+ def partial_with_form_builder
+ render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {})
+ end
+
+ def partial_with_form_builder_subclass
+ render :partial => LabellingFormBuilder.new(:post, nil, view_context, {})
+ end
+
+ def partial_collection
+ render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
+ end
+
+ def partial_collection_with_as
+ render :partial => "customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer
+ end
+
+ def partial_collection_with_counter
+ render :partial => "customer_counter", :collection => [ Customer.new("david"), Customer.new("mary") ]
+ end
+
+ def partial_collection_with_as_and_counter
+ render :partial => "customer_counter_with_as", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :client
+ end
+
+ def partial_collection_with_locals
+ render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
+ end
+
+ def partial_collection_with_spacer
+ render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ]
+ end
+
+ def partial_collection_with_spacer_which_uses_render
+ render :partial => "customer", :spacer_template => "partial_with_partial", :collection => [ Customer.new("david"), Customer.new("mary") ]
+ end
+
+ def partial_collection_shorthand_with_locals
+ render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
+ end
+
+ def partial_collection_shorthand_with_different_types_of_records
+ render :partial => [
+ BadCustomer.new("mark"),
+ GoodCustomer.new("craig"),
+ BadCustomer.new("john"),
+ GoodCustomer.new("zach"),
+ GoodCustomer.new("brandon"),
+ BadCustomer.new("dan") ],
+ :locals => { :greeting => "Bonjour" }
+ end
+
+ def empty_partial_collection
+ render :partial => "customer", :collection => []
+ end
+
+ def partial_collection_shorthand_with_different_types_of_records_with_counter
+ partial_collection_shorthand_with_different_types_of_records
+ end
+
+ def missing_partial
+ render :partial => 'thisFileIsntHere'
+ end
+
+ def partial_with_hash_object
+ render :partial => "hash_object", :object => {:first_name => "Sam"}
+ end
+
+ def partial_with_nested_object
+ render :partial => "quiz/questions/question", :object => Quiz::Question.new("first")
+ end
+
+ def partial_with_nested_object_shorthand
+ render Quiz::Question.new("first")
+ end
+
+ def partial_hash_collection
+ render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ]
+ end
+
+ def partial_hash_collection_with_locals
+ render :partial => "hash_greeting", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ], :locals => { :greeting => "Hola" }
+ end
+
+ def partial_with_implicit_local_assignment
+ @customer = Customer.new("Marcel")
+ render :partial => "customer"
+ end
+
+ def render_call_to_partial_with_layout
+ render :action => "calling_partial_with_layout"
+ end
+
+ def render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
+ render :action => "calling_partial_with_layout", :layout => "layouts/partial_with_layout"
+ end
+
+ before_action only: :render_with_filters do
+ request.format = :xml
+ end
+
+ # Ensure that the before filter is executed *before* self.formats is set.
+ def render_with_filters
+ render :action => :formatted_xml_erb
+ end
+
+ private
+
+ def set_variable_for_layout
+ @variable_for_layout = nil
+ end
+
+ def determine_layout
+ case action_name
+ when "hello_world", "layout_test", "rendering_without_layout",
+ "rendering_nothing_on_layout", "render_text_hello_world",
+ "render_text_hello_world_with_layout",
+ "hello_world_with_layout_false",
+ "partial_only", "accessing_params_in_template",
+ "accessing_params_in_template_with_layout",
+ "render_with_explicit_template",
+ "render_with_explicit_string_template",
+ "update_page", "update_page_with_instance_variables"
+
+ "layouts/standard"
+ when "action_talk_to_layout", "layout_overriding_layout"
+ "layouts/talk_from_action"
+ when "render_implicit_html_template_from_xhr_request"
+ (request.xhr? ? 'layouts/xhr' : 'layouts/standard')
+ end
+ end
+end
+
+class RenderTest < ActionController::TestCase
+ tests TestController
+
+ def setup
+ # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
+ # a more accurate simulation of what happens in "real life".
+ super
+ @controller.logger = ActiveSupport::Logger.new(nil)
+ ActionView::Base.logger = ActiveSupport::Logger.new(nil)
+
+ @request.host = "www.nextangle.com"
+ end
+
+ def teardown
+ ActionView::Base.logger = nil
+ end
+
+ # :ported:
+ def test_simple_show
+ get :hello_world
+ assert_response 200
+ assert_response :success
+ assert_template "test/hello_world"
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ # :ported:
+ def test_renders_default_template_for_missing_action
+ get :'hyphen-ated'
+ assert_template 'test/hyphen-ated'
+ end
+
+ # :ported:
+ def test_render
+ get :render_hello_world
+ assert_template "test/hello_world"
+ end
+
+ def test_line_offset
+ get :render_line_offset
+ flunk "the action should have raised an exception"
+ rescue StandardError => exc
+ line = exc.backtrace.first
+ assert(line =~ %r{:(\d+):})
+ assert_equal "1", $1,
+ "The line offset is wrong, perhaps the wrong exception has been raised, exception was: #{exc.inspect}"
+ end
+
+ # :ported: compatibility
+ def test_render_with_forward_slash
+ get :render_hello_world_with_forward_slash
+ assert_template "test/hello_world"
+ end
+
+ # :ported:
+ def test_render_in_top_directory
+ get :render_template_in_top_directory
+ assert_template "shared"
+ assert_equal "Elastica", @response.body
+ end
+
+ # :ported:
+ def test_render_in_top_directory_with_slash
+ get :render_template_in_top_directory_with_slash
+ assert_template "shared"
+ assert_equal "Elastica", @response.body
+ end
+
+ # :ported:
+ def test_render_from_variable
+ get :render_hello_world_from_variable
+ assert_equal "hello david", @response.body
+ end
+
+ # :ported:
+ def test_render_action
+ get :render_action_hello_world
+ assert_template "test/hello_world"
+ end
+
+ def test_render_action_upcased
+ assert_raise ActionView::MissingTemplate do
+ get :render_action_upcased_hello_world
+ end
+ end
+
+ # :ported:
+ def test_render_action_hello_world_as_string
+ get :render_action_hello_world_as_string
+ assert_equal "Hello world!", @response.body
+ assert_template "test/hello_world"
+ end
+
+ # :ported:
+ def test_render_action_with_symbol
+ get :render_action_hello_world_with_symbol
+ assert_template "test/hello_world"
+ end
+
+ # :ported:
+ def test_render_text
+ get :render_text_hello_world
+ assert_equal "hello world", @response.body
+ end
+
+ # :ported:
+ def test_do_with_render_text_and_layout
+ get :render_text_hello_world_with_layout
+ assert_equal "<html>hello world, I am here!</html>", @response.body
+ end
+
+ # :ported:
+ def test_do_with_render_action_and_layout_false
+ get :hello_world_with_layout_false
+ assert_equal 'Hello world!', @response.body
+ end
+
+ # :ported:
+ def test_render_file_with_instance_variables
+ get :render_file_with_instance_variables
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ def test_render_file
+ get :hello_world_file
+ assert_equal "Hello world!", @response.body
+ end
+
+ # :ported:
+ def test_render_file_as_string_with_instance_variables
+ get :render_file_as_string_with_instance_variables
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :ported:
+ def test_render_file_not_using_full_path
+ get :render_file_not_using_full_path
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :ported:
+ def test_render_file_not_using_full_path_with_dot_in_path
+ get :render_file_not_using_full_path_with_dot_in_path
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :ported:
+ def test_render_file_using_pathname
+ get :render_file_using_pathname
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :ported:
+ def test_render_file_with_locals
+ get :render_file_with_locals
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :ported:
+ def test_render_file_as_string_with_locals
+ get :render_file_as_string_with_locals
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :assessed:
+ def test_render_file_from_template
+ get :render_file_from_template
+ assert_equal "The secret is in the sauce\n", @response.body
+ end
+
+ # :ported:
+ def test_render_custom_code
+ get :render_custom_code
+ assert_response 404
+ assert_response :missing
+ assert_equal 'hello world', @response.body
+ end
+
+ # :ported:
+ def test_render_text_with_nil
+ get :render_text_with_nil
+ assert_response 200
+ assert_equal ' ', @response.body
+ end
+
+ # :ported:
+ def test_render_text_with_false
+ get :render_text_with_false
+ assert_equal 'false', @response.body
+ end
+
+ # :ported:
+ def test_render_nothing_with_appendix
+ get :render_nothing_with_appendix
+ assert_response 200
+ assert_equal 'appended', @response.body
+ end
+
+ def test_render_text_with_resource
+ get :render_text_with_resource
+ assert_equal 'name: "David"', @response.body
+ end
+
+ # :ported:
+ def test_attempt_to_access_object_method
+ assert_raise(AbstractController::ActionNotFound, "No action responded to [clone]") { get :clone }
+ end
+
+ # :ported:
+ def test_private_methods
+ assert_raise(AbstractController::ActionNotFound, "No action responded to [determine_layout]") { get :determine_layout }
+ end
+
+ # :ported:
+ def test_access_to_request_in_view
+ get :accessing_request_in_template
+ assert_equal "Hello: www.nextangle.com", @response.body
+ end
+
+ def test_access_to_logger_in_view
+ get :accessing_logger_in_template
+ assert_equal "ActiveSupport::Logger", @response.body
+ end
+
+ # :ported:
+ def test_access_to_action_name_in_view
+ get :accessing_action_name_in_template
+ assert_equal "accessing_action_name_in_template", @response.body
+ end
+
+ # :ported:
+ def test_access_to_controller_name_in_view
+ get :accessing_controller_name_in_template
+ assert_equal "test", @response.body # name is explicitly set in the controller.
+ end
+
+ # :ported:
+ def test_render_xml
+ get :render_xml_hello
+ assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
+ assert_equal "application/xml", @response.content_type
+ end
+
+ # :ported:
+ def test_render_xml_as_string_template
+ get :render_xml_hello_as_string_template
+ assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
+ assert_equal "application/xml", @response.content_type
+ end
+
+ # :ported:
+ def test_render_xml_with_default
+ get :greeting
+ assert_equal "<p>This is grand!</p>\n", @response.body
+ end
+
+ # :move: test in AV
+ def test_render_xml_with_partial
+ get :builder_partial_test
+ assert_equal "<test>\n <hello/>\n</test>\n", @response.body
+ end
+
+ # :ported:
+ def test_layout_rendering
+ get :layout_test
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_render_xml_with_layouts
+ get :builder_layout_test
+ assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
+ end
+
+ def test_partials_list
+ get :partials_list
+ assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body
+ end
+
+ def test_render_to_string
+ get :hello_in_a_string
+ assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
+ end
+
+ def test_render_to_string_resets_assigns
+ get :render_to_string_test
+ assert_equal "The value of foo is: ::this is a test::\n", @response.body
+ end
+
+ def test_render_to_string_inline
+ get :render_to_string_with_inline_and_render
+ assert_template "test/hello_world"
+ end
+
+ # :ported:
+ def test_nested_rendering
+ @controller = Fun::GamesController.new
+ get :hello_world
+ assert_equal "Living in a nested world", @response.body
+ end
+
+ def test_accessing_params_in_template
+ get :accessing_params_in_template, :name => "David"
+ assert_equal "Hello: David", @response.body
+ end
+
+ def test_accessing_local_assigns_in_inline_template
+ get :accessing_local_assigns_in_inline_template, :local_name => "Local David"
+ assert_equal "Goodbye, Local David", @response.body
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_should_implicitly_render_html_template_from_xhr_request
+ xhr :get, :render_implicit_html_template_from_xhr_request
+ assert_equal "XHR!\nHello HTML!", @response.body
+ end
+
+ def test_should_implicitly_render_js_template_without_layout
+ get :render_implicit_js_template_without_layout, :format => :js
+ assert_no_match %r{<html>}, @response.body
+ end
+
+ def test_should_render_formatted_template
+ get :formatted_html_erb
+ assert_equal 'formatted html erb', @response.body
+ end
+
+ def test_should_render_formatted_html_erb_template
+ get :formatted_xml_erb
+ assert_equal '<test>passed formatted html erb</test>', @response.body
+ end
+
+ def test_should_render_formatted_html_erb_template_with_bad_accepts_header
+ @request.env["HTTP_ACCEPT"] = "; a=dsf"
+ get :formatted_xml_erb
+ assert_equal '<test>passed formatted html erb</test>', @response.body
+ end
+
+ def test_should_render_formatted_html_erb_template_with_faulty_accepts_header
+ @request.accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, appliction/x-shockwave-flash, */*"
+ get :formatted_xml_erb
+ assert_equal '<test>passed formatted html erb</test>', @response.body
+ end
+
+ def test_layout_test_with_different_layout
+ get :layout_test_with_different_layout
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_layout_test_with_different_layout_and_string_action
+ get :layout_test_with_different_layout_and_string_action
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_layout_test_with_different_layout_and_symbol_action
+ get :layout_test_with_different_layout_and_symbol_action
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_rendering_without_layout
+ get :rendering_without_layout
+ assert_equal "Hello world!", @response.body
+ end
+
+ def test_layout_overriding_layout
+ get :layout_overriding_layout
+ assert_no_match %r{<title>}, @response.body
+ end
+
+ def test_rendering_nothing_on_layout
+ get :rendering_nothing_on_layout
+ assert_equal " ", @response.body
+ end
+
+ def test_render_to_string_doesnt_break_assigns
+ get :render_to_string_with_assigns
+ assert_equal "i'm before the render", assigns(:before)
+ assert_equal "i'm after the render", assigns(:after)
+ end
+
+ def test_bad_render_to_string_still_throws_exception
+ assert_raise(ActionView::MissingTemplate) { get :render_to_string_with_exception }
+ end
+
+ def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
+ assert_nothing_raised { get :render_to_string_with_caught_exception }
+ assert_equal "i'm before the render", assigns(:before)
+ assert_equal "i'm after the render", assigns(:after)
+ end
+
+ def test_accessing_params_in_template_with_layout
+ get :accessing_params_in_template_with_layout, :name => "David"
+ assert_equal "<html>Hello: David</html>", @response.body
+ end
+
+ def test_render_with_explicit_template
+ get :render_with_explicit_template
+ assert_response :success
+ end
+
+ def test_render_with_explicit_unescaped_template
+ assert_raise(ActionView::MissingTemplate) { get :render_with_explicit_unescaped_template }
+ get :render_with_explicit_escaped_template
+ assert_equal "Hello w*rld!", @response.body
+ end
+
+ def test_render_with_explicit_string_template
+ get :render_with_explicit_string_template
+ assert_equal "<html>Hello world!</html>", @response.body
+ end
+
+ def test_render_with_filters
+ get :render_with_filters
+ assert_equal "<test>passed formatted xml erb</test>", @response.body
+ end
+
+ # :ported:
+ def test_double_render
+ assert_raise(AbstractController::DoubleRenderError) { get :double_render }
+ end
+
+ def test_double_redirect
+ assert_raise(AbstractController::DoubleRenderError) { get :double_redirect }
+ end
+
+ def test_render_and_redirect
+ assert_raise(AbstractController::DoubleRenderError) { get :render_and_redirect }
+ end
+
+ # specify the one exception to double render rule - render_to_string followed by render
+ def test_render_to_string_and_render
+ get :render_to_string_and_render
+ assert_equal("Hi web users! here is some cached stuff", @response.body)
+ end
+
+ def test_rendering_with_conflicting_local_vars
+ get :rendering_with_conflicting_local_vars
+ assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body)
+ end
+
+ def test_action_talk_to_layout
+ get :action_talk_to_layout
+ assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
+ end
+
+ # :addressed:
+ def test_render_text_with_assigns
+ get :render_text_with_assigns
+ assert_equal "world", assigns["hello"]
+ end
+
+ # :ported:
+ def test_template_with_locals
+ get :render_with_explicit_template_with_locals
+ assert_equal "The secret is area51\n", @response.body
+ end
+
+ def test_yield_content_for
+ get :yield_content_for
+ assert_equal "<title>Putting stuff in the title!</title>\nGreat stuff!\n", @response.body
+ end
+
+ def test_overwritting_rendering_relative_file_with_extension
+ get :hello_world_from_rxml_using_template
+ assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
+
+ get :hello_world_from_rxml_using_action
+ assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
+ end
+
+ def test_using_layout_around_block
+ get :render_using_layout_around_block
+ assert_equal "Before (David)\nInside from block\nAfter", @response.body
+ end
+
+ def test_using_layout_around_block_in_main_layout_and_within_content_for_layout
+ get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout
+ assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body
+ end
+
+ def test_partial_only
+ get :partial_only
+ assert_equal "only partial", @response.body
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_should_render_html_formatted_partial
+ get :partial
+ assert_equal "partial html", @response.body
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_render_html_formatted_partial_even_with_other_mime_time_in_accept
+ @request.accept = "text/javascript, text/html"
+
+ get :partial_html_erb
+
+ assert_equal "partial.html.erb", @response.body.strip
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_should_render_html_partial_with_formats
+ get :partial_formats_html
+ assert_equal "partial html", @response.body
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_render_to_string_partial
+ get :render_to_string_with_partial
+ assert_equal "only partial", assigns(:partial_only)
+ assert_equal "Hello: david", assigns(:partial_with_locals)
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_render_to_string_with_template_and_html_partial
+ get :render_to_string_with_template_and_html_partial
+ assert_equal "**only partial**\n", assigns(:text)
+ assert_equal "<strong>only partial</strong>\n", assigns(:html)
+ assert_equal "<strong>only html partial</strong>\n", @response.body
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_render_to_string_and_render_with_different_formats
+ get :render_to_string_and_render_with_different_formats
+ assert_equal "<strong>only partial</strong>\n", assigns(:html)
+ assert_equal "**only partial**\n", @response.body
+ assert_equal "text/plain", @response.content_type
+ end
+
+ def test_render_template_within_a_template_with_other_format
+ get :render_template_within_a_template_with_other_format
+ expected = "only html partial<p>This is grand!</p>"
+ assert_equal expected, @response.body.strip
+ assert_equal "text/html", @response.content_type
+ end
+
+ def test_partial_with_counter
+ get :partial_with_counter
+ assert_equal "5", @response.body
+ end
+
+ def test_partial_with_locals
+ get :partial_with_locals
+ assert_equal "Hello: david", @response.body
+ end
+
+ def test_partial_with_form_builder
+ get :partial_with_form_builder
+ assert_match(/<label/, @response.body)
+ assert_template('test/_form')
+ end
+
+ def test_partial_with_form_builder_subclass
+ get :partial_with_form_builder_subclass
+ assert_match(/<label/, @response.body)
+ assert_template('test/_labelling_form')
+ end
+
+ def test_nested_partial_with_form_builder
+ @controller = Fun::GamesController.new
+ get :nested_partial_with_form_builder
+ assert_match(/<label/, @response.body)
+ assert_template('fun/games/_form')
+ end
+
+ def test_namespaced_object_partial
+ @controller = Quiz::QuestionsController.new
+ get :new
+ assert_equal "Namespaced Partial", @response.body
+ end
+
+ def test_partial_collection
+ get :partial_collection
+ assert_equal "Hello: davidHello: mary", @response.body
+ end
+
+ def test_partial_collection_with_as
+ get :partial_collection_with_as
+ assert_equal "david david davidmary mary mary", @response.body
+ end
+
+ def test_partial_collection_with_counter
+ get :partial_collection_with_counter
+ assert_equal "david0mary1", @response.body
+ end
+
+ def test_partial_collection_with_as_and_counter
+ get :partial_collection_with_as_and_counter
+ assert_equal "david0mary1", @response.body
+ end
+
+ def test_partial_collection_with_locals
+ get :partial_collection_with_locals
+ assert_equal "Bonjour: davidBonjour: mary", @response.body
+ end
+
+ def test_locals_option_to_assert_template_is_not_supported
+ get :partial_collection_with_locals
+
+ warning_buffer = StringIO.new
+ $stderr = warning_buffer
+
+ assert_template partial: 'customer_greeting', locals: { greeting: 'Bonjour' }
+ assert_equal "the :locals option to #assert_template is only supported in a ActionView::TestCase\n", warning_buffer.string
+ ensure
+ $stderr = STDERR
+ end
+
+ def test_partial_collection_with_spacer
+ get :partial_collection_with_spacer
+ assert_equal "Hello: davidonly partialHello: mary", @response.body
+ assert_template :partial => '_customer'
+ end
+
+ def test_partial_collection_with_spacer_which_uses_render
+ get :partial_collection_with_spacer_which_uses_render
+ assert_equal "Hello: davidpartial html\npartial with partial\nHello: mary", @response.body
+ assert_template :partial => '_customer'
+ end
+
+ def test_partial_collection_shorthand_with_locals
+ get :partial_collection_shorthand_with_locals
+ assert_equal "Bonjour: davidBonjour: mary", @response.body
+ assert_template :partial => 'customers/_customer', :count => 2
+ assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0
+ end
+
+ def test_partial_collection_shorthand_with_different_types_of_records
+ get :partial_collection_shorthand_with_different_types_of_records
+ assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
+ assert_template :partial => 'good_customers/_good_customer', :count => 3
+ assert_template :partial => 'bad_customers/_bad_customer', :count => 3
+ end
+
+ def test_empty_partial_collection
+ get :empty_partial_collection
+ assert_equal " ", @response.body
+ assert_template :partial => false
+ end
+
+ def test_partial_with_hash_object
+ get :partial_with_hash_object
+ assert_equal "Sam\nmaS\n", @response.body
+ end
+
+ def test_partial_with_nested_object
+ get :partial_with_nested_object
+ assert_equal "first", @response.body
+ end
+
+ def test_partial_with_nested_object_shorthand
+ get :partial_with_nested_object_shorthand
+ assert_equal "first", @response.body
+ end
+
+ def test_hash_partial_collection
+ get :partial_hash_collection
+ assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body
+ end
+
+ def test_partial_hash_collection_with_locals
+ get :partial_hash_collection_with_locals
+ assert_equal "Hola: PratikHola: Amy", @response.body
+ end
+
+ def test_render_missing_partial_template
+ assert_raise(ActionView::MissingTemplate) do
+ get :missing_partial
+ end
+ end
+
+ def test_render_call_to_partial_with_layout
+ get :render_call_to_partial_with_layout
+ assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body
+ end
+
+ def test_render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
+ get :render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
+ assert_equal "Before (Anthony)\nInside from partial (Anthony)\nAfter\nBefore (David)\nInside from partial (David)\nAfter\nBefore (Ramm)\nInside from partial (Ramm)\nAfter", @response.body
+ end
+end
+
diff --git a/actionview/test/fixtures/actionpack/bad_customers/_bad_customer.html.erb b/actionview/test/fixtures/actionpack/bad_customers/_bad_customer.html.erb
new file mode 100644
index 0000000000..d22af431ec
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/bad_customers/_bad_customer.html.erb
@@ -0,0 +1 @@
+<%= greeting %> bad customer: <%= bad_customer.name %><%= bad_customer_counter %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/customers/_customer.html.erb b/actionview/test/fixtures/actionpack/customers/_customer.html.erb
index 483571e22a..483571e22a 100644
--- a/actionpack/test/fixtures/customers/_customer.html.erb
+++ b/actionview/test/fixtures/actionpack/customers/_customer.html.erb
diff --git a/actionpack/test/fixtures/fun/games/_form.erb b/actionview/test/fixtures/actionpack/fun/games/_form.erb
index 01107f1cb2..01107f1cb2 100644
--- a/actionpack/test/fixtures/fun/games/_form.erb
+++ b/actionview/test/fixtures/actionpack/fun/games/_form.erb
diff --git a/actionpack/test/fixtures/fun/games/hello_world.erb b/actionview/test/fixtures/actionpack/fun/games/hello_world.erb
index 1ebfbe2539..1ebfbe2539 100644
--- a/actionpack/test/fixtures/fun/games/hello_world.erb
+++ b/actionview/test/fixtures/actionpack/fun/games/hello_world.erb
diff --git a/actionpack/test/fixtures/good_customers/_good_customer.html.erb b/actionview/test/fixtures/actionpack/good_customers/_good_customer.html.erb
index a2d97ebc6d..a2d97ebc6d 100644
--- a/actionpack/test/fixtures/good_customers/_good_customer.html.erb
+++ b/actionview/test/fixtures/actionpack/good_customers/_good_customer.html.erb
diff --git a/actionpack/test/fixtures/hello.html b/actionview/test/fixtures/actionpack/hello.html
index 6769dd60bd..6769dd60bd 100644
--- a/actionpack/test/fixtures/hello.html
+++ b/actionview/test/fixtures/actionpack/hello.html
diff --git a/actionpack/test/fixtures/layout_tests/alt/layouts/alt.erb b/actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb
index e69de29bb2..e69de29bb2 100644
--- a/actionpack/test/fixtures/layout_tests/alt/layouts/alt.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb
diff --git a/actionpack/test/fixtures/layout_tests/layouts/controller_name_space/nested.erb b/actionview/test/fixtures/actionpack/layout_tests/layouts/controller_name_space/nested.erb
index 121bc079a1..121bc079a1 100644
--- a/actionpack/test/fixtures/layout_tests/layouts/controller_name_space/nested.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/layouts/controller_name_space/nested.erb
diff --git a/actionpack/test/fixtures/layout_tests/layouts/item.erb b/actionview/test/fixtures/actionpack/layout_tests/layouts/item.erb
index 60f04d77d5..60f04d77d5 100644
--- a/actionpack/test/fixtures/layout_tests/layouts/item.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/layouts/item.erb
diff --git a/actionpack/test/fixtures/layout_tests/layouts/layout_test.erb b/actionview/test/fixtures/actionpack/layout_tests/layouts/layout_test.erb
index b74ac0840d..b74ac0840d 100644
--- a/actionpack/test/fixtures/layout_tests/layouts/layout_test.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/layouts/layout_test.erb
diff --git a/actionpack/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb b/actionview/test/fixtures/actionpack/layout_tests/layouts/multiple_extensions.html.erb
index 3b65e54f9c..3b65e54f9c 100644
--- a/actionpack/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/layouts/multiple_extensions.html.erb
diff --git a/actionview/test/fixtures/actionpack/layout_tests/layouts/symlinked/symlinked_layout.erb b/actionview/test/fixtures/actionpack/layout_tests/layouts/symlinked/symlinked_layout.erb
new file mode 100644
index 0000000000..bda57d0fae
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layout_tests/layouts/symlinked/symlinked_layout.erb
@@ -0,0 +1,5 @@
+This is my layout
+
+<%= yield %>
+
+End.
diff --git a/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab b/actionview/test/fixtures/actionpack/layout_tests/layouts/third_party_template_library.mab
index fcee620d82..fcee620d82 100644
--- a/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab
+++ b/actionview/test/fixtures/actionpack/layout_tests/layouts/third_party_template_library.mab
diff --git a/actionpack/test/fixtures/layout_tests/views/goodbye.erb b/actionview/test/fixtures/actionpack/layout_tests/views/goodbye.erb
index 4ee911188e..4ee911188e 100644
--- a/actionpack/test/fixtures/layout_tests/views/goodbye.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/views/goodbye.erb
diff --git a/actionpack/test/fixtures/layout_tests/views/hello.erb b/actionview/test/fixtures/actionpack/layout_tests/views/hello.erb
index 4ee911188e..4ee911188e 100644
--- a/actionpack/test/fixtures/layout_tests/views/hello.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/views/hello.erb
diff --git a/actionview/test/fixtures/actionpack/layouts/_column.html.erb b/actionview/test/fixtures/actionpack/layouts/_column.html.erb
new file mode 100644
index 0000000000..96db002b8a
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/_column.html.erb
@@ -0,0 +1,2 @@
+<div id="column"><%= yield :column %></div>
+<div id="content"><%= yield %></div> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/_customers.erb b/actionview/test/fixtures/actionpack/layouts/_customers.erb
new file mode 100644
index 0000000000..ae63f13cd3
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/_customers.erb
@@ -0,0 +1 @@
+<title><%= yield Struct.new(:name).new("David") %></title> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/_partial_and_yield.erb b/actionview/test/fixtures/actionpack/layouts/_partial_and_yield.erb
new file mode 100644
index 0000000000..74cc428ffa
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/_partial_and_yield.erb
@@ -0,0 +1,2 @@
+<%= render :partial => 'test/partial' %>
+<%= yield %>
diff --git a/actionview/test/fixtures/actionpack/layouts/_yield_only.erb b/actionview/test/fixtures/actionpack/layouts/_yield_only.erb
new file mode 100644
index 0000000000..37f0bddbd7
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/_yield_only.erb
@@ -0,0 +1 @@
+<%= yield %>
diff --git a/actionview/test/fixtures/actionpack/layouts/_yield_with_params.erb b/actionview/test/fixtures/actionpack/layouts/_yield_with_params.erb
new file mode 100644
index 0000000000..68e6557fb8
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/_yield_with_params.erb
@@ -0,0 +1 @@
+<%= yield 'Yield!' %>
diff --git a/actionview/test/fixtures/actionpack/layouts/block_with_layout.erb b/actionview/test/fixtures/actionpack/layouts/block_with_layout.erb
new file mode 100644
index 0000000000..73ac833e52
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/block_with_layout.erb
@@ -0,0 +1,3 @@
+<%= render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% "Return value should be discarded" %><% end %>
+<%= yield %>
+<%= render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %>
diff --git a/actionview/test/fixtures/actionpack/layouts/builder.builder b/actionview/test/fixtures/actionpack/layouts/builder.builder
new file mode 100644
index 0000000000..7c7d4b2dd1
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/builder.builder
@@ -0,0 +1,3 @@
+xml.wrapper do
+ xml << yield
+end \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/partial_with_layout.erb b/actionview/test/fixtures/actionpack/layouts/partial_with_layout.erb
new file mode 100644
index 0000000000..a0349d731e
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/partial_with_layout.erb
@@ -0,0 +1,3 @@
+<%= render( :layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => {:name => 'Anthony' } ) %>
+<%= yield %>
+<%= render( :layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => {:name => 'Ramm' } ) %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/standard.html.erb b/actionview/test/fixtures/actionpack/layouts/standard.html.erb
new file mode 100644
index 0000000000..5e6c24fe39
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/standard.html.erb
@@ -0,0 +1 @@
+<html><%= yield %><%= @variable_for_layout %></html> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/streaming.erb b/actionview/test/fixtures/actionpack/layouts/streaming.erb
new file mode 100644
index 0000000000..d3f896a6ca
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/streaming.erb
@@ -0,0 +1,4 @@
+<%= yield :header -%>
+<%= yield -%>
+<%= yield :footer -%>
+<%= yield(:unknown).presence || "." -%> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/talk_from_action.erb b/actionview/test/fixtures/actionpack/layouts/talk_from_action.erb
new file mode 100644
index 0000000000..bf53fdb785
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/talk_from_action.erb
@@ -0,0 +1,2 @@
+<title><%= @title || yield(:title) %></title>
+<%= yield -%> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/with_html_partial.html.erb b/actionview/test/fixtures/actionpack/layouts/with_html_partial.html.erb
new file mode 100644
index 0000000000..fd2896aeaa
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/with_html_partial.html.erb
@@ -0,0 +1 @@
+<%= render :partial => "partial_only_html" %><%= yield %>
diff --git a/actionview/test/fixtures/actionpack/layouts/xhr.html.erb b/actionview/test/fixtures/actionpack/layouts/xhr.html.erb
new file mode 100644
index 0000000000..85285324ec
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/xhr.html.erb
@@ -0,0 +1,2 @@
+XHR!
+<%= yield %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/layouts/yield.erb b/actionview/test/fixtures/actionpack/layouts/yield.erb
new file mode 100644
index 0000000000..482dc9022e
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/yield.erb
@@ -0,0 +1,2 @@
+<title><%= yield :title %></title>
+<%= yield %>
diff --git a/actionview/test/fixtures/actionpack/layouts/yield_with_render_inline_inside.erb b/actionview/test/fixtures/actionpack/layouts/yield_with_render_inline_inside.erb
new file mode 100644
index 0000000000..7298d79690
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/yield_with_render_inline_inside.erb
@@ -0,0 +1,2 @@
+<%= render :inline => 'welcome' %>
+<%= yield %>
diff --git a/actionview/test/fixtures/actionpack/layouts/yield_with_render_partial_inside.erb b/actionview/test/fixtures/actionpack/layouts/yield_with_render_partial_inside.erb
new file mode 100644
index 0000000000..74cc428ffa
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/layouts/yield_with_render_partial_inside.erb
@@ -0,0 +1,2 @@
+<%= render :partial => 'test/partial' %>
+<%= yield %>
diff --git a/actionpack/test/fixtures/quiz/questions/_question.html.erb b/actionview/test/fixtures/actionpack/quiz/questions/_question.html.erb
index fb4dcfee64..fb4dcfee64 100644
--- a/actionpack/test/fixtures/quiz/questions/_question.html.erb
+++ b/actionview/test/fixtures/actionpack/quiz/questions/_question.html.erb
diff --git a/actionview/test/fixtures/actionpack/shared.html.erb b/actionview/test/fixtures/actionpack/shared.html.erb
new file mode 100644
index 0000000000..af262fc9f8
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/shared.html.erb
@@ -0,0 +1 @@
+Elastica \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_changing_priority.html.erb b/actionview/test/fixtures/actionpack/test/_changing_priority.html.erb
new file mode 100644
index 0000000000..3225efc49a
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_changing_priority.html.erb
@@ -0,0 +1 @@
+HTML \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_changing_priority.json.erb b/actionview/test/fixtures/actionpack/test/_changing_priority.json.erb
new file mode 100644
index 0000000000..7fa41dce66
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_changing_priority.json.erb
@@ -0,0 +1 @@
+JSON \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_counter.html.erb b/actionview/test/fixtures/actionpack/test/_counter.html.erb
new file mode 100644
index 0000000000..fd245bfc70
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_counter.html.erb
@@ -0,0 +1 @@
+<%= counter_counter %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_customer.erb b/actionview/test/fixtures/actionpack/test/_customer.erb
new file mode 100644
index 0000000000..d8220afeda
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_customer.erb
@@ -0,0 +1 @@
+Hello: <%= customer.name rescue "Anonymous" %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_customer_counter.erb b/actionview/test/fixtures/actionpack/test/_customer_counter.erb
new file mode 100644
index 0000000000..3435979dba
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_customer_counter.erb
@@ -0,0 +1 @@
+<%= customer_counter.name %><%= customer_counter_counter %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_customer_counter_with_as.erb b/actionview/test/fixtures/actionpack/test/_customer_counter_with_as.erb
new file mode 100644
index 0000000000..1241eb604d
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_customer_counter_with_as.erb
@@ -0,0 +1 @@
+<%= client.name %><%= client_counter %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_customer_greeting.erb b/actionview/test/fixtures/actionpack/test/_customer_greeting.erb
new file mode 100644
index 0000000000..6acbcb20c4
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_customer_greeting.erb
@@ -0,0 +1 @@
+<%= greeting %>: <%= customer_greeting.name %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_customer_with_var.erb b/actionview/test/fixtures/actionpack/test/_customer_with_var.erb
new file mode 100644
index 0000000000..00047dd20e
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_customer_with_var.erb
@@ -0,0 +1 @@
+<%= customer.name %> <%= customer.name %> <%= customer.name %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_directory/_partial_with_locales.html.erb b/actionview/test/fixtures/actionpack/test/_directory/_partial_with_locales.html.erb
new file mode 100644
index 0000000000..1cc8d41475
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_directory/_partial_with_locales.html.erb
@@ -0,0 +1 @@
+Hello <%= name %>
diff --git a/actionview/test/fixtures/actionpack/test/_first_json_partial.json.erb b/actionview/test/fixtures/actionpack/test/_first_json_partial.json.erb
new file mode 100644
index 0000000000..790ee896db
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_first_json_partial.json.erb
@@ -0,0 +1 @@
+<%= render :partial => "test/second_json_partial" %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_form.erb b/actionview/test/fixtures/actionpack/test/_form.erb
new file mode 100644
index 0000000000..01107f1cb2
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_form.erb
@@ -0,0 +1 @@
+<%= form.label :title %>
diff --git a/actionview/test/fixtures/actionpack/test/_hash_greeting.erb b/actionview/test/fixtures/actionpack/test/_hash_greeting.erb
new file mode 100644
index 0000000000..fc54a36f2a
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_hash_greeting.erb
@@ -0,0 +1 @@
+<%= greeting %>: <%= hash_greeting[:first_name] %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_hash_object.erb b/actionview/test/fixtures/actionpack/test/_hash_object.erb
new file mode 100644
index 0000000000..34a92c6a56
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_hash_object.erb
@@ -0,0 +1,2 @@
+<%= hash_object[:first_name] %>
+<%= hash_object[:first_name].reverse %>
diff --git a/actionview/test/fixtures/actionpack/test/_hello.builder b/actionview/test/fixtures/actionpack/test/_hello.builder
new file mode 100644
index 0000000000..ef52f632d1
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_hello.builder
@@ -0,0 +1 @@
+xm.hello \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_json_change_priority.json.erb b/actionview/test/fixtures/actionpack/test/_json_change_priority.json.erb
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_json_change_priority.json.erb
diff --git a/actionview/test/fixtures/actionpack/test/_labelling_form.erb b/actionview/test/fixtures/actionpack/test/_labelling_form.erb
new file mode 100644
index 0000000000..1b95763165
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_labelling_form.erb
@@ -0,0 +1 @@
+<%= labelling_form.label :title %>
diff --git a/actionview/test/fixtures/actionpack/test/_layout_for_partial.html.erb b/actionview/test/fixtures/actionpack/test/_layout_for_partial.html.erb
new file mode 100644
index 0000000000..666efadbb6
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_layout_for_partial.html.erb
@@ -0,0 +1,3 @@
+Before (<%= name %>)
+<%= yield %>
+After \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial.erb b/actionview/test/fixtures/actionpack/test/_partial.erb
new file mode 100644
index 0000000000..e466dcbd8e
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial.erb
@@ -0,0 +1 @@
+invalid \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial.html.erb b/actionview/test/fixtures/actionpack/test/_partial.html.erb
new file mode 100644
index 0000000000..e39f6c9827
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial.html.erb
@@ -0,0 +1 @@
+partial html \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial.js.erb b/actionview/test/fixtures/actionpack/test/_partial.js.erb
new file mode 100644
index 0000000000..b350cdd7ef
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial.js.erb
@@ -0,0 +1 @@
+partial js \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial_for_use_in_layout.html.erb b/actionview/test/fixtures/actionpack/test/_partial_for_use_in_layout.html.erb
new file mode 100644
index 0000000000..3a03a64e31
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial_for_use_in_layout.html.erb
@@ -0,0 +1 @@
+Inside from partial (<%= name %>) \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial_html_erb.html.erb b/actionview/test/fixtures/actionpack/test/_partial_html_erb.html.erb
new file mode 100644
index 0000000000..4b54875782
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial_html_erb.html.erb
@@ -0,0 +1 @@
+<%= "partial.html.erb" %>
diff --git a/actionview/test/fixtures/actionpack/test/_partial_name_local_variable.erb b/actionview/test/fixtures/actionpack/test/_partial_name_local_variable.erb
new file mode 100644
index 0000000000..cc3a91c89f
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial_name_local_variable.erb
@@ -0,0 +1 @@
+<%= partial_name_local_variable %>
diff --git a/actionview/test/fixtures/actionpack/test/_partial_only.erb b/actionview/test/fixtures/actionpack/test/_partial_only.erb
new file mode 100644
index 0000000000..a44b3eed40
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial_only.erb
@@ -0,0 +1 @@
+only partial \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial_only_html.html b/actionview/test/fixtures/actionpack/test/_partial_only_html.html
new file mode 100644
index 0000000000..d2d630bd40
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial_only_html.html
@@ -0,0 +1 @@
+only html partial \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_partial_with_partial.erb b/actionview/test/fixtures/actionpack/test/_partial_with_partial.erb
new file mode 100644
index 0000000000..ee0d5037b6
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_partial_with_partial.erb
@@ -0,0 +1,2 @@
+<%= render 'test/partial' %>
+partial with partial
diff --git a/actionview/test/fixtures/actionpack/test/_person.erb b/actionview/test/fixtures/actionpack/test/_person.erb
new file mode 100644
index 0000000000..b2e5688956
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_person.erb
@@ -0,0 +1,2 @@
+Second: <%= name %>
+Third: <%= @name %>
diff --git a/actionview/test/fixtures/actionpack/test/_raise_indentation.html.erb b/actionview/test/fixtures/actionpack/test/_raise_indentation.html.erb
new file mode 100644
index 0000000000..f9a93728fe
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_raise_indentation.html.erb
@@ -0,0 +1,13 @@
+<p>First paragraph</p>
+<p>Second paragraph</p>
+<p>Third paragraph</p>
+<p>Fourth paragraph</p>
+<p>Fifth paragraph</p>
+<p>Sixth paragraph</p>
+<p>Seventh paragraph</p>
+<p>Eight paragraph</p>
+<p>Ninth paragraph</p>
+<p>Tenth paragraph</p>
+<%= raise "error here!" %>
+<p>Eleventh paragraph</p>
+<p>Twelfth paragraph</p> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/_second_json_partial.json.erb b/actionview/test/fixtures/actionpack/test/_second_json_partial.json.erb
new file mode 100644
index 0000000000..5ebb7f1afd
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/_second_json_partial.json.erb
@@ -0,0 +1 @@
+Third level \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/action_talk_to_layout.erb b/actionview/test/fixtures/actionpack/test/action_talk_to_layout.erb
new file mode 100644
index 0000000000..36e896daa8
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/action_talk_to_layout.erb
@@ -0,0 +1,2 @@
+<% @title = "Talking to the layout" -%>
+Action was here! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/calling_partial_with_layout.html.erb b/actionview/test/fixtures/actionpack/test/calling_partial_with_layout.html.erb
new file mode 100644
index 0000000000..ac44bc0d81
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/calling_partial_with_layout.html.erb
@@ -0,0 +1 @@
+<%= render(:layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => { :name => "David" }) %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/capturing.erb b/actionview/test/fixtures/actionpack/test/capturing.erb
new file mode 100644
index 0000000000..1addaa40d9
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/capturing.erb
@@ -0,0 +1,4 @@
+<% days = capture do %>
+ Dreamy days
+<% end %>
+<%= days %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/change_priority.html.erb b/actionview/test/fixtures/actionpack/test/change_priority.html.erb
new file mode 100644
index 0000000000..5618977d05
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/change_priority.html.erb
@@ -0,0 +1,2 @@
+<%= render :partial => "test/json_change_priority", formats: :json %>
+HTML Template, but <%= render :partial => "test/changing_priority" %> partial \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/content_for.erb b/actionview/test/fixtures/actionpack/test/content_for.erb
new file mode 100644
index 0000000000..1fb829f54c
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/content_for.erb
@@ -0,0 +1 @@
+<% content_for :title do -%>Putting stuff in the title!<% end -%>Great stuff! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/content_for_concatenated.erb b/actionview/test/fixtures/actionpack/test/content_for_concatenated.erb
new file mode 100644
index 0000000000..e65f629574
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/content_for_concatenated.erb
@@ -0,0 +1,3 @@
+<% content_for :title, "Putting stuff "
+ content_for :title, "in the title!" -%>
+Great stuff! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/content_for_with_parameter.erb b/actionview/test/fixtures/actionpack/test/content_for_with_parameter.erb
new file mode 100644
index 0000000000..aeb6f73ce0
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/content_for_with_parameter.erb
@@ -0,0 +1,2 @@
+<% content_for :title, "Putting stuff in the title!" -%>
+Great stuff! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/dot.directory/render_file_with_ivar.erb b/actionview/test/fixtures/actionpack/test/dot.directory/render_file_with_ivar.erb
new file mode 100644
index 0000000000..8b8a449236
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/dot.directory/render_file_with_ivar.erb
@@ -0,0 +1 @@
+The secret is <%= @secret %>
diff --git a/actionview/test/fixtures/actionpack/test/formatted_html_erb.html.erb b/actionview/test/fixtures/actionpack/test/formatted_html_erb.html.erb
new file mode 100644
index 0000000000..1c64efabd8
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/formatted_html_erb.html.erb
@@ -0,0 +1 @@
+formatted html erb \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder
new file mode 100644
index 0000000000..14fd3549fb
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder
@@ -0,0 +1 @@
+xml.test 'failed' \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/formatted_xml_erb.html.erb b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.html.erb
new file mode 100644
index 0000000000..0c855a604b
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.html.erb
@@ -0,0 +1 @@
+<test>passed formatted html erb</test> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/formatted_xml_erb.xml.erb b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.xml.erb
new file mode 100644
index 0000000000..6ca09d5304
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.xml.erb
@@ -0,0 +1 @@
+<test>passed formatted xml erb</test> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/greeting.html.erb b/actionview/test/fixtures/actionpack/test/greeting.html.erb
new file mode 100644
index 0000000000..62fb0293f0
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/greeting.html.erb
@@ -0,0 +1 @@
+<p>This is grand!</p>
diff --git a/actionview/test/fixtures/actionpack/test/greeting.xml.erb b/actionview/test/fixtures/actionpack/test/greeting.xml.erb
new file mode 100644
index 0000000000..62fb0293f0
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/greeting.xml.erb
@@ -0,0 +1 @@
+<p>This is grand!</p>
diff --git a/actionview/test/fixtures/actionpack/test/hello,world.erb b/actionview/test/fixtures/actionpack/test/hello,world.erb
new file mode 100644
index 0000000000..bc8fa5e0ca
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello,world.erb
@@ -0,0 +1 @@
+Hello w*rld! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hello.builder b/actionview/test/fixtures/actionpack/test/hello.builder
new file mode 100644
index 0000000000..a471553941
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello.builder
@@ -0,0 +1,4 @@
+xml.html do
+ xml.p "Hello #{@name}"
+ xml << render(:file => "test/greeting")
+end \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hello/hello.erb b/actionview/test/fixtures/actionpack/test/hello/hello.erb
new file mode 100644
index 0000000000..6769dd60bd
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello/hello.erb
@@ -0,0 +1 @@
+Hello world! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hello_world.erb b/actionview/test/fixtures/actionpack/test/hello_world.erb
new file mode 100644
index 0000000000..6769dd60bd
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello_world.erb
@@ -0,0 +1 @@
+Hello world! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hello_world_container.builder b/actionview/test/fixtures/actionpack/test/hello_world_container.builder
new file mode 100644
index 0000000000..e48d75c405
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello_world_container.builder
@@ -0,0 +1,3 @@
+xml.test do
+ render :partial => 'hello', :locals => { :xm => xml }
+end \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hello_world_from_rxml.builder b/actionview/test/fixtures/actionpack/test/hello_world_from_rxml.builder
new file mode 100644
index 0000000000..619a97ba96
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello_world_from_rxml.builder
@@ -0,0 +1,3 @@
+xml.html do
+ xml.p "Hello"
+end
diff --git a/actionview/test/fixtures/actionpack/test/hello_world_with_layout_false.erb b/actionview/test/fixtures/actionpack/test/hello_world_with_layout_false.erb
new file mode 100644
index 0000000000..6769dd60bd
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello_world_with_layout_false.erb
@@ -0,0 +1 @@
+Hello world! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hello_world_with_partial.html.erb b/actionview/test/fixtures/actionpack/test/hello_world_with_partial.html.erb
new file mode 100644
index 0000000000..ec31545356
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello_world_with_partial.html.erb
@@ -0,0 +1,2 @@
+Hello world!
+<%= render '/test/partial' %>
diff --git a/actionview/test/fixtures/actionpack/test/hello_xml_world.builder b/actionview/test/fixtures/actionpack/test/hello_xml_world.builder
new file mode 100644
index 0000000000..e7081b89fe
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hello_xml_world.builder
@@ -0,0 +1,11 @@
+xml.html do
+ xml.head do
+ xml.title "Hello World"
+ end
+
+ xml.body do
+ xml.p "abes"
+ xml.p "monks"
+ xml.p "wiseguys"
+ end
+end \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/html_template.html.erb b/actionview/test/fixtures/actionpack/test/html_template.html.erb
new file mode 100644
index 0000000000..1bbc2b7f09
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/html_template.html.erb
@@ -0,0 +1 @@
+<%= render :partial => "test/first_json_partial", formats: :json %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/hyphen-ated.erb b/actionview/test/fixtures/actionpack/test/hyphen-ated.erb
new file mode 100644
index 0000000000..cd0875583a
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/hyphen-ated.erb
@@ -0,0 +1 @@
+Hello world!
diff --git a/actionview/test/fixtures/actionpack/test/implicit_content_type.atom.builder b/actionview/test/fixtures/actionpack/test/implicit_content_type.atom.builder
new file mode 100644
index 0000000000..2fcb32d247
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/implicit_content_type.atom.builder
@@ -0,0 +1,2 @@
+xml.atom do
+end
diff --git a/actionview/test/fixtures/actionpack/test/list.erb b/actionview/test/fixtures/actionpack/test/list.erb
new file mode 100644
index 0000000000..0a4bda58ee
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/list.erb
@@ -0,0 +1 @@
+<%= @test_unchanged = 'goodbye' %><%= render :partial => 'customer', :collection => @customers %><%= @test_unchanged %>
diff --git a/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder b/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder
new file mode 100644
index 0000000000..d539a425a4
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder
@@ -0,0 +1,4 @@
+content_for :title do
+ 'Putting stuff in the title!'
+end
+xml << "Great stuff!"
diff --git a/actionview/test/fixtures/actionpack/test/potential_conflicts.erb b/actionview/test/fixtures/actionpack/test/potential_conflicts.erb
new file mode 100644
index 0000000000..a5e964e359
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/potential_conflicts.erb
@@ -0,0 +1,4 @@
+First: <%= @name %>
+<%= render :partial => "person", :locals => { :name => "Stephan" } -%>
+Fourth: <%= @name %>
+Fifth: <%= name %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/proper_block_detection.erb b/actionview/test/fixtures/actionpack/test/proper_block_detection.erb
new file mode 100644
index 0000000000..b55efbb25d
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/proper_block_detection.erb
@@ -0,0 +1 @@
+<%= @todo %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/render_file_from_template.html.erb b/actionview/test/fixtures/actionpack/test/render_file_from_template.html.erb
new file mode 100644
index 0000000000..fde9f4bb64
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_file_from_template.html.erb
@@ -0,0 +1 @@
+<%= render :file => @path %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/render_file_with_ivar.erb b/actionview/test/fixtures/actionpack/test/render_file_with_ivar.erb
new file mode 100644
index 0000000000..8b8a449236
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_file_with_ivar.erb
@@ -0,0 +1 @@
+The secret is <%= @secret %>
diff --git a/actionview/test/fixtures/actionpack/test/render_file_with_locals.erb b/actionview/test/fixtures/actionpack/test/render_file_with_locals.erb
new file mode 100644
index 0000000000..ebe09faee6
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_file_with_locals.erb
@@ -0,0 +1 @@
+The secret is <%= secret %>
diff --git a/actionview/test/fixtures/actionpack/test/render_file_with_locals_and_default.erb b/actionview/test/fixtures/actionpack/test/render_file_with_locals_and_default.erb
new file mode 100644
index 0000000000..9b4900acc5
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_file_with_locals_and_default.erb
@@ -0,0 +1 @@
+<%= secret ||= 'one' %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.da.html.erb b/actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.da.html.erb
new file mode 100644
index 0000000000..0740b2d07c
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.da.html.erb
@@ -0,0 +1 @@
+Hey HTML!
diff --git a/actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.html.erb b/actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.html.erb
new file mode 100644
index 0000000000..4a11845cfe
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_implicit_html_template_from_xhr_request.html.erb
@@ -0,0 +1 @@
+Hello HTML! \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/render_implicit_js_template_without_layout.js.erb b/actionview/test/fixtures/actionpack/test/render_implicit_js_template_without_layout.js.erb
new file mode 100644
index 0000000000..892ae5eca2
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_implicit_js_template_without_layout.js.erb
@@ -0,0 +1 @@
+alert('hello'); \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/render_partial_inside_directory.html.erb b/actionview/test/fixtures/actionpack/test/render_partial_inside_directory.html.erb
new file mode 100644
index 0000000000..1461b95186
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_partial_inside_directory.html.erb
@@ -0,0 +1 @@
+<%= render partial: 'test/_directory/partial_with_locales', locals: {'name' => 'Jane'} %>
diff --git a/actionview/test/fixtures/actionpack/test/render_to_string_test.erb b/actionview/test/fixtures/actionpack/test/render_to_string_test.erb
new file mode 100644
index 0000000000..6e267e8634
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_to_string_test.erb
@@ -0,0 +1 @@
+The value of foo is: ::<%= @foo %>::
diff --git a/actionview/test/fixtures/actionpack/test/render_two_partials.html.erb b/actionview/test/fixtures/actionpack/test/render_two_partials.html.erb
new file mode 100644
index 0000000000..3db6025860
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/render_two_partials.html.erb
@@ -0,0 +1,2 @@
+<%= render :partial => 'partial', :locals => {'first' => '1'} %>
+<%= render :partial => 'partial', :locals => {'second' => '2'} %>
diff --git a/actionview/test/fixtures/actionpack/test/using_layout_around_block.html.erb b/actionview/test/fixtures/actionpack/test/using_layout_around_block.html.erb
new file mode 100644
index 0000000000..3d6661df9a
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/using_layout_around_block.html.erb
@@ -0,0 +1 @@
+<%= render(:layout => "layout_for_partial", :locals => { :name => "David" }) do %>Inside from block<% end %> \ No newline at end of file
diff --git a/actionview/test/fixtures/actionpack/test/with_html_partial.html.erb b/actionview/test/fixtures/actionpack/test/with_html_partial.html.erb
new file mode 100644
index 0000000000..d84d909d64
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/with_html_partial.html.erb
@@ -0,0 +1 @@
+<strong><%= render :partial => "partial_only_html" %></strong>
diff --git a/actionview/test/fixtures/actionpack/test/with_partial.html.erb b/actionview/test/fixtures/actionpack/test/with_partial.html.erb
new file mode 100644
index 0000000000..7502364cf5
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/with_partial.html.erb
@@ -0,0 +1 @@
+<strong><%= render :partial => "partial_only" %></strong>
diff --git a/actionview/test/fixtures/actionpack/test/with_partial.text.erb b/actionview/test/fixtures/actionpack/test/with_partial.text.erb
new file mode 100644
index 0000000000..5f068ebf27
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/with_partial.text.erb
@@ -0,0 +1 @@
+**<%= render :partial => "partial_only" %>**
diff --git a/actionview/test/fixtures/actionpack/test/with_xml_template.html.erb b/actionview/test/fixtures/actionpack/test/with_xml_template.html.erb
new file mode 100644
index 0000000000..e54a7cd001
--- /dev/null
+++ b/actionview/test/fixtures/actionpack/test/with_xml_template.html.erb
@@ -0,0 +1 @@
+<%= render :template => "test/greeting", :formats => :xml %>
diff --git a/actionview/test/fixtures/helpers/abc_helper.rb b/actionview/test/fixtures/helpers/abc_helper.rb
new file mode 100644
index 0000000000..7104ff3730
--- /dev/null
+++ b/actionview/test/fixtures/helpers/abc_helper.rb
@@ -0,0 +1,5 @@
+module AbcHelper
+ def bare_a() end
+ def bare_b() end
+ def bare_c() end
+end
diff --git a/actionview/test/fixtures/helpers/fun/games_helper.rb b/actionview/test/fixtures/helpers/fun/games_helper.rb
new file mode 100644
index 0000000000..3b7adce086
--- /dev/null
+++ b/actionview/test/fixtures/helpers/fun/games_helper.rb
@@ -0,0 +1,5 @@
+module Fun
+ module GamesHelper
+ def stratego() "Iz guuut!" end
+ end
+end \ No newline at end of file
diff --git a/actionview/test/fixtures/helpers/fun/pdf_helper.rb b/actionview/test/fixtures/helpers/fun/pdf_helper.rb
new file mode 100644
index 0000000000..0171be8500
--- /dev/null
+++ b/actionview/test/fixtures/helpers/fun/pdf_helper.rb
@@ -0,0 +1,5 @@
+module Fun
+ module PdfHelper
+ def foobar() 'baz' end
+ end
+end
diff --git a/actionview/test/fixtures/helpers/helpery_test_helper.rb b/actionview/test/fixtures/helpers/helpery_test_helper.rb
new file mode 100644
index 0000000000..a4f2951efa
--- /dev/null
+++ b/actionview/test/fixtures/helpers/helpery_test_helper.rb
@@ -0,0 +1,5 @@
+module HelperyTestHelper
+ def helpery_test
+ "Default"
+ end
+end
diff --git a/actionview/test/fixtures/helpers/just_me_helper.rb b/actionview/test/fixtures/helpers/just_me_helper.rb
new file mode 100644
index 0000000000..b140a7b9b4
--- /dev/null
+++ b/actionview/test/fixtures/helpers/just_me_helper.rb
@@ -0,0 +1,3 @@
+module JustMeHelper
+ def me() "mine!" end
+end \ No newline at end of file
diff --git a/actionview/test/fixtures/helpers/me_too_helper.rb b/actionview/test/fixtures/helpers/me_too_helper.rb
new file mode 100644
index 0000000000..ce56042143
--- /dev/null
+++ b/actionview/test/fixtures/helpers/me_too_helper.rb
@@ -0,0 +1,3 @@
+module MeTooHelper
+ def me() "me too!" end
+end \ No newline at end of file
diff --git a/actionpack/test/fixtures/helpers_missing/invalid_require_helper.rb b/actionview/test/fixtures/helpers_missing/invalid_require_helper.rb
index d8801e54d5..d8801e54d5 100644
--- a/actionpack/test/fixtures/helpers_missing/invalid_require_helper.rb
+++ b/actionview/test/fixtures/helpers_missing/invalid_require_helper.rb
diff --git a/actionpack/test/fixtures/override/test/hello_world.erb b/actionview/test/fixtures/override/test/hello_world.erb
index 3e308d3d86..3e308d3d86 100644
--- a/actionpack/test/fixtures/override/test/hello_world.erb
+++ b/actionview/test/fixtures/override/test/hello_world.erb
diff --git a/actionpack/test/fixtures/override2/layouts/test/sub.erb b/actionview/test/fixtures/override2/layouts/test/sub.erb
index 3863d5a8ef..3863d5a8ef 100644
--- a/actionpack/test/fixtures/override2/layouts/test/sub.erb
+++ b/actionview/test/fixtures/override2/layouts/test/sub.erb
diff --git a/actionpack/test/controller/view_paths_test.rb b/actionview/test/lib/controller/view_paths_test.rb
index c6e7a523b9..c6e7a523b9 100644
--- a/actionpack/test/controller/view_paths_test.rb
+++ b/actionview/test/lib/controller/view_paths_test.rb
diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb
index 073bd14783..203ad6d910 100644
--- a/actionview/test/template/lookup_context_test.rb
+++ b/actionview/test/template/lookup_context_test.rb
@@ -68,7 +68,7 @@ class LookupContextTest < ActiveSupport::TestCase
test "delegates changing the locale to the I18n configuration object if it contains a lookup_context object" do
begin
- I18n.config = AbstractController::I18nProxy.new(I18n.config, @lookup_context)
+ I18n.config = ActionView::I18nProxy.new(I18n.config, @lookup_context)
@lookup_context.locale = :pt
assert_equal :pt, I18n.locale
assert_equal :pt, @lookup_context.locale
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 98d2fa62d7..a485feaf47 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
+* PostgreSQL adapter recognizes negative money values formatted with
+ parentheses (eg. `($1.25) # => -1.25`)).
+ Fixes #11899.
+
+ * Yves Senn*
+
* Stop interpreting SQL 'string' columns as :string type because there is no
common STRING datatype in SQL.
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index c8fa4ef9af..552a22d28a 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -51,7 +51,6 @@ module ActiveRecord
return value unless column
case column.type
- when :binary then value
when :integer then value.to_i
when :float then value.to_f
else
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 58c6235059..dab876af14 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -34,12 +34,17 @@ module ActiveRecord
class Money < Type
def type_cast(value)
return if value.nil?
+ return value unless String === value
# Because money output is formatted according to the locale, there are two
# cases to consider (note the decimal separators):
# (1) $12,345,678.12
# (2) $12.345.678,12
+ # Negative values are represented as follows:
+ # (3) -$2.55
+ # (4) ($2.55)
+ value.sub!(/^\((.+)\)$/, '-\1') # (4)
case value
when /^-?\D+[\d,]+\.\d{2}$/ # (1)
value.gsub!(/[^-\d.]/, '')
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index eb89e3875f..a7a40ca72b 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -455,7 +455,7 @@ module ActiveRecord
fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
connection,
fs_name,
- class_names[fs_name] || default_fixture_model_name(fs_name),
+ class_names[fs_name] || (default_fixture_model_name(fs_name).safe_constantize),
::File.join(fixtures_directory, fs_name))
end
@@ -504,11 +504,14 @@ module ActiveRecord
@name = name
@path = path
+ if class_name.is_a?(String)
+ ActiveSupport::Deprecation.warn("The ability to pass in strings as a class name will be removed in Rails 4.2, consider using the class itself instead.")
+ end
+
if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
@model_class = class_name
else
- ActiveSupport::Deprecation.warn("The ability to pass in strings as a class name will be removed in Rails 4.1, consider using the class itself instead.")
- @model_class = class_name.constantize rescue nil
+ @model_class = class_name.safe_constantize if class_name
end
@connection = ( model_class.respond_to?(:connection) ?
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 888e8771ce..a1ad4f6255 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -828,7 +828,7 @@ module ActiveRecord
end
def proper_table_name(name, options = {})
- ActiveSupport::Deprecation.warn "ActiveRecord::Migrator.proper_table_name is deprecated and will be removed in Rails 4.1. Use the proper_table_name instance method on ActiveRecord::Migration instead"
+ ActiveSupport::Deprecation.warn "ActiveRecord::Migrator.proper_table_name is deprecated and will be removed in Rails 4.2. Use the proper_table_name instance method on ActiveRecord::Migration instead"
options = {
table_name_prefix: ActiveRecord::Base.table_name_prefix,
table_name_suffix: ActiveRecord::Base.table_name_suffix
diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
index 75b6f4f8ce..3dbab08a99 100644
--- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
@@ -298,6 +298,14 @@ _SQL
assert_equal(-567.89, @second_money.wealth)
end
+ def test_money_type_cast
+ column = PostgresqlMoney.columns.find { |c| c.name == 'wealth' }
+ assert_equal(12345678.12, column.type_cast("$12,345,678.12"))
+ assert_equal(12345678.12, column.type_cast("$12.345.678,12"))
+ assert_equal(-1.15, column.type_cast("-$1.15"))
+ assert_equal(-2.25, column.type_cast("($2.25)"))
+ end
+
def test_create_tstzrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT')
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index c07c9c3b74..afbe65062d 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -190,11 +190,11 @@ class FixturesTest < ActiveRecord::TestCase
end
def test_empty_yaml_fixture
- assert_not_nil ActiveRecord::FixtureSet.new( Account.connection, "accounts", 'Account', FIXTURES_ROOT + "/naked/yml/accounts")
+ assert_not_nil ActiveRecord::FixtureSet.new( Account.connection, "accounts", Account, FIXTURES_ROOT + "/naked/yml/accounts")
end
def test_empty_yaml_fixture_with_a_comment_in_it
- assert_not_nil ActiveRecord::FixtureSet.new( Account.connection, "companies", 'Company', FIXTURES_ROOT + "/naked/yml/companies")
+ assert_not_nil ActiveRecord::FixtureSet.new( Account.connection, "companies", Company, FIXTURES_ROOT + "/naked/yml/companies")
end
def test_nonexistent_fixture_file
@@ -204,19 +204,19 @@ class FixturesTest < ActiveRecord::TestCase
assert Dir[nonexistent_fixture_path+"*"].empty?
assert_raise(Errno::ENOENT) do
- ActiveRecord::FixtureSet.new( Account.connection, "companies", 'Company', nonexistent_fixture_path)
+ ActiveRecord::FixtureSet.new( Account.connection, "companies", Company, nonexistent_fixture_path)
end
end
def test_dirty_dirty_yaml_file
assert_raise(ActiveRecord::Fixture::FormatError) do
- ActiveRecord::FixtureSet.new( Account.connection, "courses", 'Course', FIXTURES_ROOT + "/naked/yml/courses")
+ ActiveRecord::FixtureSet.new( Account.connection, "courses", Course, FIXTURES_ROOT + "/naked/yml/courses")
end
end
def test_omap_fixtures
assert_nothing_raised do
- fixtures = ActiveRecord::FixtureSet.new(Account.connection, 'categories', 'Category', FIXTURES_ROOT + "/categories_ordered")
+ fixtures = ActiveRecord::FixtureSet.new(Account.connection, 'categories', Category, FIXTURES_ROOT + "/categories_ordered")
fixtures.each.with_index do |(name, fixture), i|
assert_equal "fixture_no_#{i}", name
@@ -449,7 +449,7 @@ class OverRideFixtureMethodTest < ActiveRecord::TestCase
end
class CheckSetTableNameFixturesTest < ActiveRecord::TestCase
- set_fixture_class :funny_jokes => 'Joke'
+ set_fixture_class :funny_jokes => Joke
fixtures :funny_jokes
# Set to false to blow away fixtures cache and ensure our fixtures are loaded
# and thus takes into account our set_fixture_class
@@ -532,7 +532,7 @@ class InvalidTableNameFixturesTest < ActiveRecord::TestCase
end
class CheckEscapedYamlFixturesTest < ActiveRecord::TestCase
- set_fixture_class :funny_jokes => 'Joke'
+ set_fixture_class :funny_jokes => Joke
fixtures :funny_jokes
# Set to false to blow away fixtures cache and ensure our fixtures are loaded
# and thus takes into account our set_fixture_class
diff --git a/activesupport/lib/active_support/deprecation.rb b/activesupport/lib/active_support/deprecation.rb
index 0281c9222e..ab16977bda 100644
--- a/activesupport/lib/active_support/deprecation.rb
+++ b/activesupport/lib/active_support/deprecation.rb
@@ -32,7 +32,7 @@ module ActiveSupport
# and the second is a library name
#
# ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
- def initialize(deprecation_horizon = '4.1', gem_name = 'Rails')
+ def initialize(deprecation_horizon = '4.2', gem_name = 'Rails')
self.gem_name = gem_name
self.deprecation_horizon = deprecation_horizon
# By default, warnings are not silenced and debugging is off.
diff --git a/guides/assets/images/akshaysurve.jpg b/guides/assets/images/akshaysurve.jpg
new file mode 100644
index 0000000000..cfc3333958
--- /dev/null
+++ b/guides/assets/images/akshaysurve.jpg
Binary files differ
diff --git a/guides/rails_guides.rb b/guides/rails_guides.rb
index ce409868ca..33975718c9 100644
--- a/guides/rails_guides.rb
+++ b/guides/rails_guides.rb
@@ -39,6 +39,25 @@ ERROR
exit 1
end
+begin
+ require 'nokogiri'
+rescue LoadError
+ # This can happen if doc:guides is executed in an application.
+ $stderr.puts('Generating guides requires Nokogiri.')
+ $stderr.puts(<<ERROR) if bundler?
+Please add
+
+ gem 'nokogiri'
+
+to the Gemfile, run
+
+ bundle install
+
+and try again.
+ERROR
+ exit 1
+end
+
require 'rails_guides/markdown'
require "rails_guides/generator"
RailsGuides::Generator.new.generate
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index bff60efc33..a80c3b6c8e 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -181,7 +181,7 @@ definition:
```ruby
class FunnyJoke < ActiveSupport::TestCase
- set_fixture_class funny_jokes: 'Joke'
+ set_fixture_class funny_jokes: Joke
fixtures :funny_jokes
...
end
diff --git a/guides/source/credits.html.erb b/guides/source/credits.html.erb
index 10dd8178fb..5beae9c29b 100644
--- a/guides/source/credits.html.erb
+++ b/guides/source/credits.html.erb
@@ -74,3 +74,7 @@ Oscar Del Ben is a software engineer at <a href="http://www.wildfireapp.com/">Wi
<%= author('Heiko Webers', 'hawe') do %>
Heiko Webers is the founder of <a href="http://www.bauland42.de">bauland42</a>, a German web application security consulting and development company focused on Ruby on Rails. He blogs at the <a href="http://www.rorsecurity.info">Ruby on Rails Security Project</a>. After 10 years of desktop application development, Heiko has rarely looked back.
<% end %>
+
+<%= author('Akshay Surve', 'startupjockey', 'akshaysurve.jpg') do %>
+ Akshay Surve is the Founder at <a href="http://www.deltax.com">DeltaX</a>, hackathon specialist, a midnight code junkie and ocassionally writes prose. You can connect with him on <a href="https://twitter.com/akshaysurve">Twitter</a>, <a href="http://www.linkedin.com/in/akshaysurve">Linkedin</a>, <a href="http://www.akshaysurve.com/">Personal Blog</a> or <a href="http://www.quora.com/Akshay-Surve">Quora</a>.
+<% end %>
diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb
index 6c9c53fc69..2e83c0fe14 100644
--- a/railties/lib/rails/all.rb
+++ b/railties/lib/rails/all.rb
@@ -3,6 +3,7 @@ require "rails"
%w(
active_record
action_controller
+ action_view
action_mailer
rails/test_unit
sprockets
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 675ada7ed0..fb495c918c 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -37,6 +37,9 @@ module Rails
class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
desc: 'Skip Active Record files'
+ class_option :skip_action_view, type: :boolean, aliases: '-V', default: false,
+ desc: 'Skip Action View files'
+
class_option :skip_sprockets, type: :boolean, aliases: '-S', default: false,
desc: 'Skip Sprockets files'
@@ -123,7 +126,7 @@ module Rails
end
def include_all_railties?
- !options[:skip_active_record] && !options[:skip_test_unit] && !options[:skip_sprockets]
+ !options[:skip_active_record] && !options[:skip_action_view] && !options[:skip_test_unit] && !options[:skip_sprockets]
end
def comment_if(value)
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 4d474d5267..ac41a0cadb 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -8,6 +8,7 @@ require "active_model/railtie"
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
+<%= comment_if :skip_action_view %>require "action_view/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
index 310c975262..5508829f6b 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
@@ -7,6 +7,7 @@ require 'rails/all'
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
+<%= comment_if :skip_action_view %>require "action_view/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index 45968052a8..56b8736800 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -28,4 +28,6 @@ Gem::Specification.new do |s|
s.add_dependency 'rake', '>= 0.8.7'
s.add_dependency 'thor', '>= 0.18.1', '< 2.0'
+
+ s.add_development_dependency 'actionview', version
end
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index 491faf4af9..643cc6b0ee 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -8,6 +8,7 @@ require 'fileutils'
require 'active_support'
require 'action_controller'
+require 'action_view'
require 'rails/all'
module TestApp
diff --git a/railties/test/application/basic_rendering_test.rb b/railties/test/application/basic_rendering_test.rb
new file mode 100644
index 0000000000..00ba433a05
--- /dev/null
+++ b/railties/test/application/basic_rendering_test.rb
@@ -0,0 +1,62 @@
+require 'isolation/abstract_unit'
+require 'rack/test'
+
+module ApplicationTests
+ class BasicRenderingTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
+
+ def setup
+ build_app
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ test "Rendering without ActionView" do
+ gsub_app_file 'config/application.rb', "require 'rails/all'", <<-RUBY
+ require "active_model/railtie"
+ require "action_controller/railtie"
+ RUBY
+
+ # Turn off ActionView and jquery-rails (it depends on AV)
+ $:.reject! {|path| path =~ /(actionview|jquery\-rails)/ }
+ boot_rails
+
+ app_file 'app/controllers/pages_controller.rb', <<-RUBY
+ class PagesController < ApplicationController
+ def render_hello_world
+ render text: "Hello World!"
+ end
+
+ def render_nothing
+ render nothing: true
+ end
+
+ def no_render; end
+
+ def raise_error
+ render foo: "bar"
+ end
+ end
+ RUBY
+
+ get '/pages/render_hello_world'
+ assert_equal 200, last_response.status
+ assert_equal "Hello World!", last_response.body
+ assert_equal "text/plain; charset=utf-8", last_response.content_type
+
+ get '/pages/render_nothing'
+ assert_equal 200, last_response.status
+ assert_equal " ", last_response.body
+ assert_equal "text/plain; charset=utf-8", last_response.content_type
+
+ get '/pages/no_render'
+ assert_equal 500, last_response.status
+
+ get '/pages/raise_error'
+ assert_equal 500, last_response.status
+ end
+ end
+end
diff --git a/railties/test/application/url_generation_test.rb b/railties/test/application/url_generation_test.rb
index 2767779719..efbc853d7b 100644
--- a/railties/test/application/url_generation_test.rb
+++ b/railties/test/application/url_generation_test.rb
@@ -12,6 +12,7 @@ module ApplicationTests
boot_rails
require "rails"
require "action_controller/railtie"
+ require "action_view/railtie"
class MyApp < Rails::Application
config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 42b6275932..2f0dfc7d3e 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -222,6 +222,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generator_if_skip_action_view_is_given
+ run_generator [destination_root, "--skip-action-view"]
+ assert_file "config/application.rb", /#\s+require\s+["']action_view\/railtie["']/
+ end
+
def test_generator_if_skip_sprockets_is_given
run_generator [destination_root, "--skip-sprockets"]
assert_file "config/application.rb" do |content|
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index 7fdd54fc30..32a3d072c9 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -16,6 +16,7 @@ Rails.application.load_generators
require 'active_record'
require 'action_dispatch'
+require 'action_view'
module GeneratorsTestHelper
def self.included(base)
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index a3295a6e69..913e2b5e29 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -135,6 +135,7 @@ module TestHelpers
def make_basic_app
require "rails"
require "action_controller/railtie"
+ require "action_view/railtie"
app = Class.new(Rails::Application)
app.config.eager_load = false
@@ -242,6 +243,12 @@ module TestHelpers
end
end
+ def gsub_app_file(path, regexp, *args, &block)
+ path = "#{app_path}/#{path}"
+ content = File.read(path).gsub(regexp, *args, &block)
+ File.open(path, 'wb') { |f| f.write(content) }
+ end
+
def remove_file(path)
FileUtils.rm_rf "#{app_path}/#{path}"
end
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index a9b237d0a5..e45a5228a1 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -1,5 +1,7 @@
require 'abstract_unit'
+ActionController::Base.superclass.send(:include, ActionView::Layouts)
+
module ActionController
class Base
include ActionController::Testing