diff options
author | Piotr Sarnacki <drogus@gmail.com> | 2013-08-26 03:07:30 -0700 |
---|---|---|
committer | Piotr Sarnacki <drogus@gmail.com> | 2013-08-26 03:07:30 -0700 |
commit | c19958015fac7b50f8dedbdf17991c00d6b8bbd4 (patch) | |
tree | 42431a33fd65c954b1242b8ff6116163c9969924 | |
parent | 27dc4fa28ee098d70a11829ad5fa4af0c54e880b (diff) | |
parent | 0d43df7ebf7587f032e3b16c153bf35746878c46 (diff) | |
download | rails-c19958015fac7b50f8dedbdf17991c00d6b8bbd4.tar.gz rails-c19958015fac7b50f8dedbdf17991c00d6b8bbd4.tar.bz2 rails-c19958015fac7b50f8dedbdf17991c00d6b8bbd4.zip |
Merge pull request #11396 from strzalek/extract_renderers
Remove dependency on Action View from Action Pack
This set of changes removes the need of using Action View with Action Pack.
Now you may use controllers without Action View, by rendering `:text` response
or alternatively you can plug in your own rendering logic. This is especially
handy when you're just dealing with APIs and don't need to include entire
Action View just to render simple JSON responses.
178 files changed, 2073 insertions, 1592 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/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 |