From 8a4e77b4200946ba4ed42fe5927a7400a846063a Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 27 Apr 2009 18:21:26 -0700 Subject: OMG, a lot of work --- actionpack/Rakefile | 11 +- .../lib/action_controller/abstract/layouts.rb | 5 +- .../lib/action_controller/abstract/renderer.rb | 2 + .../lib/action_controller/dispatch/dispatcher.rb | 2 +- .../lib/action_controller/dispatch/middlewares.rb | 2 +- actionpack/lib/action_controller/new_base.rb | 11 +- actionpack/lib/action_controller/new_base/base.rb | 2 + .../action_controller/new_base/compatibility.rb | 12 +++ .../abstract_controller_test.rb | 22 ++-- .../test/abstract_controller/layouts_test.rb | 2 +- actionpack/test/controller/render_test.rb | 3 + actionpack/test/lib/fixture_template.rb | 115 ++++++++++++++++----- actionpack/test/new_base/base_test.rb | 8 +- actionpack/test/new_base/render_action_test.rb | 8 +- .../test/new_base/render_implicit_action_test.rb | 30 ++++-- actionpack/test/new_base/render_layout_test.rb | 4 +- actionpack/test/new_base/render_template_test.rb | 39 ++++--- actionpack/test/new_base/render_text_test.rb | 4 +- actionpack/test/new_base/test_helper.rb | 14 ++- 19 files changed, 210 insertions(+), 86 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/compatibility.rb (limited to 'actionpack') diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 300c2ebf81..18610ed773 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -23,14 +23,14 @@ task :default => [ :test ] # Run the unit tests desc "Run all unit tests" -task :test => [:test_action_pack, :test_active_record_integration] +task :test => [:test_action_pack, :test_active_record_integration, :test_new_base] Rake::TestTask.new(:test_action_pack) do |t| t.libs << "test" # make sure we include the tests in alphabetical order as on some systems # this will not happen automatically and the tests (as a whole) will error - t.test_files = Dir.glob( "test/[cdft]*/**/*_test.rb" ).sort + t.test_files = Dir.glob( "test/{controller,dispatch,template}/**/*_test.rb" ).sort t.verbose = true #t.warning = true @@ -43,6 +43,13 @@ Rake::TestTask.new(:test_active_record_integration) do |t| t.verbose = true end +desc 'New Controller Tests' +Rake::TestTask.new(:test_new_base) do |t| + t.libs << "test" + t.test_files = Dir.glob("test/{abstract_controller,new_base}/*_test.rb") + t.verbose = true +end + # Genereate the RDoc documentation diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 0039e67c5a..315d6151e9 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -50,6 +50,7 @@ module AbstractController end def _render_template(template, options) + # layout = options[:_layout].is_a?(ActionView::Template) ? options[:_layout] : _layout_for_name(options[:_layout]) _action_view._render_template_with_layout(template, options[:_layout]) end @@ -67,10 +68,10 @@ module AbstractController def _default_layout(require_layout = false) if require_layout && !_layout - raise ArgumentError, + raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end - + begin layout = _layout_for_name(_layout) rescue NameError => e diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index e31accbbfc..37da2398ec 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -27,9 +27,11 @@ module AbstractController # # :api: plugin def render_to_body(options = {}) + options = {:_template_name => options} if options.is_a?(String) name = options[:_template_name] || action_name template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) + _render_template(template, options) end diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb index bb9d8bd063..af2da8bfe5 100644 --- a/actionpack/lib/action_controller/dispatch/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb @@ -79,7 +79,7 @@ module ActionController run_callbacks :before_dispatch Routing::Routes.call(env) rescue Exception => exception - if controller ||= (::ApplicationController rescue Base) + if !env["rack.test"] && controller ||= (::ApplicationController rescue Base) controller.call_with_exception(env, exception).to_a else raise exception diff --git a/actionpack/lib/action_controller/dispatch/middlewares.rb b/actionpack/lib/action_controller/dispatch/middlewares.rb index b5adbae746..d87c0f9706 100644 --- a/actionpack/lib/action_controller/dispatch/middlewares.rb +++ b/actionpack/lib/action_controller/dispatch/middlewares.rb @@ -9,4 +9,4 @@ use lambda { ActionController::Base.session_store }, use "ActionDispatch::ParamsParser" use "Rack::MethodOverride" -use "Rack::Head" +use "Rack::Head" \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 7c65f1cdc1..51d9c05a1a 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,7 +1,8 @@ module ActionController - autoload :AbstractBase, "action_controller/new_base/base" - autoload :HideActions, "action_controller/new_base/hide_actions" - autoload :Layouts, "action_controller/new_base/layouts" - autoload :Renderer, "action_controller/new_base/renderer" - autoload :UrlFor, "action_controller/new_base/url_for" + autoload :AbstractBase, "action_controller/new_base/base" + autoload :HideActions, "action_controller/new_base/hide_actions" + autoload :Layouts, "action_controller/new_base/layouts" + autoload :Rails2Compatibility, "action_controller/new_base/compatibility" + autoload :Renderer, "action_controller/new_base/renderer" + autoload :UrlFor, "action_controller/new_base/url_for" end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 08e7a1a0e7..75fe012aed 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -50,6 +50,8 @@ module ActionController @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new process(@_request.parameters[:action]) + @_response.prepare! + self end # :api: private diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb new file mode 100644 index 0000000000..8682493c8e --- /dev/null +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -0,0 +1,12 @@ +module ActionController + module Rails2Compatibility + + def render_to_body(options) + if options.is_a?(Hash) && options.key?(:template) + options[:template].sub!(/^\//, '') + end + super + end + + end +end \ No newline at end of file diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index 331797afcf..cf6fb5140d 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -58,11 +58,11 @@ module AbstractController end def rendering_to_body - render_to_body "naked_render.erb" + self.response_body = render_to_body :_template_name => "naked_render.erb" end def rendering_to_string - render_to_string "naked_render.erb" + self.response_body = render_to_string :_template_name => "naked_render.erb" end end @@ -136,6 +136,11 @@ module AbstractController class WithLayouts < PrefixedViews use Layouts + def self.inherited(klass) + klass._write_layout_method + super + end + private def self.layout(formats) begin @@ -147,13 +152,9 @@ module AbstractController end end end - - def _layout - self.class.layout(formats) - end - + def render_to_body(options = {}) - options[:_layout] = options[:layout] || _layout + options[:_layout] = options[:layout] || _default_layout super end end @@ -175,11 +176,6 @@ module AbstractController result = Me4.process(:index) assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_obj[:body] end - - test "it can fall back to the application layout" do - result = Me5.process(:index) - assert_equal "Application Enter : Hello from me5/index.erb : Exit", result.response_obj[:body] - end end # respond_to_action?(action_name) diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb index 3d4570bfef..078e0037a8 100644 --- a/actionpack/test/abstract_controller/layouts_test.rb +++ b/actionpack/test/abstract_controller/layouts_test.rb @@ -8,7 +8,7 @@ module AbstractControllerTests use AbstractController::Renderer use AbstractController::Layouts - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/hello.erb" => "With String <%= yield %>", "layouts/hello_override.erb" => "With Override <%= yield %>", "layouts/abstract_controller_tests/layouts/with_string_implied_child.erb" => diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 023bf0eeaa..a97e8ac5c1 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -755,6 +755,7 @@ class RenderTest < ActionController::TestCase @request.host = "www.nextangle.com" end + # :ported: def test_simple_show get :hello_world assert_response 200 @@ -763,11 +764,13 @@ class RenderTest < ActionController::TestCase assert_equal "Hello world!", @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" diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index 26f6ec2d0c..e43e329a9e 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -1,35 +1,104 @@ module ActionView #:nodoc: - class FixtureTemplate < Template - class FixturePath < Template::Path - def initialize(hash = {}) - @hash = {} - - hash.each do |k, v| - @hash[k.sub(/\.\w+$/, '')] = FixtureTemplate.new(v, k.split("/").last, self) +class Template + class FixturePath < Path + def initialize(hash = {}, options = {}) + super(options) + @hash = hash + end + + def find_templates(name, details, prefix, partial) + if regexp = details_to_regexp(name, details, prefix, partial) + cached(regexp) do + templates = [] + @hash.select { |k,v| k =~ regexp }.each do |path, source| + templates << Template.new(source, path, *path_to_details(path)) + end + templates end - - super("fixtures://root") - end - - def find_template(path) - @hash[path] end end - def initialize(body, *args) - @body = body - super(*args) + private + + def formats_regexp + @formats_regexp ||= begin + formats = Mime::SET.map { |m| m.symbol } + '(?:' + formats.map { |l| "\\.#{Regexp.escape(l.to_s)}" }.join('|') + ')?' + end end - def source - @body + def handler_regexp + e = TemplateHandlers.extensions.map{|h| "\\.#{Regexp.escape(h.to_s)}"}.join("|") + "(?:#{e})?" end - private - - def find_full_path(path, load_paths) - return '/', path + def details_to_regexp(name, details, prefix, partial) + path = "" + path << "#{prefix}/" unless prefix.empty? + path << (partial ? "_#{name}" : name) + + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '(?:' + exts.map {|e| "\\.#{Regexp.escape(e.to_s)}"}.join('|') + ')?' + else + k == :formats ? formats_regexp : '' + end + end + + %r'#{Regexp.escape(path)}#{extensions}#{handler_regexp}' + end + + # TODO: fix me + # :api: plugin + def path_to_details(path) + # [:erb, :format => :html, :locale => :en, :partial => true/false] + if m = path.match(%r'(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') + partial = m[1] == '_' + details = (m[2]||"").split('.').reject { |e| e.empty? } + handler = Template.handler_class_for_extension(m[3]) + + format = Mime[details.last] && details.pop.to_sym + locale = details.last && details.pop.to_sym + + return handler, :format => format, :locale => locale, :partial => partial + end end - end + + + # class FixtureTemplate < Template + # class FixturePath < Template::Path + # def initialize(hash = {}) + # @hash = {} + # + # hash.each do |k, v| + # @hash[k.sub(/\.\w+$/, '')] = FixtureTemplate.new(v, k.split("/").last, self) + # end + # + # super("fixtures://root") + # end + # + # def find_template(path) + # @hash[path] + # end + # end + # + # def initialize(body, *args) + # @body = body + # super(*args) + # end + # + # def source + # @body + # end + # + # private + # + # def find_full_path(path, load_paths) + # return '/', path + # end + # + # end +end end \ No newline at end of file diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb index 4f46cb6492..b0e87b4f5b 100644 --- a/actionpack/test/new_base/base_test.rb +++ b/actionpack/test/new_base/base_test.rb @@ -34,11 +34,11 @@ module HappyPath end test "sets the content type" do - assert_content_type Mime::HTML + assert_content_type "text/html; charset=utf-8" end test "sets the content length" do - assert_header "Content-Length", 7 + assert_header "Content-Length", "7" end end @@ -52,7 +52,7 @@ module HappyPath end test "setting the body manually sets the content length" do - assert_header "Content-Length", 7 + assert_header "Content-Length", "7" end end @@ -65,7 +65,7 @@ module HappyPath end test "updating the response body updates the content length" do - assert_header "Content-Length", 8 + assert_header "Content-Length", "8" end end end diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb index 2bfb374a31..37b83fb681 100644 --- a/actionpack/test/new_base/render_action_test.rb +++ b/actionpack/test/new_base/render_action_test.rb @@ -5,7 +5,7 @@ module RenderAction # This has no layout and it works class BasicController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "render_action/basic/hello_world.html.erb" => "Hello world!" )] @@ -129,7 +129,7 @@ module RenderActionWithApplicationLayout class BasicController < ::ApplicationController # Set the view path to an application view structure with layouts - self.view_paths = self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( "render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!", "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai" @@ -204,7 +204,7 @@ end module RenderActionWithControllerLayout class BasicController < ActionController::Base2 - self.view_paths = self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( "render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!", "layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" )] @@ -267,7 +267,7 @@ end module RenderActionWithBothLayouts class BasicController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new({ + self.view_paths = [ActionView::Template::FixturePath.new({ "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!", "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/new_base/render_implicit_action_test.rb index 798505b539..0a10c070c3 100644 --- a/actionpack/test/new_base/render_implicit_action_test.rb +++ b/actionpack/test/new_base/render_implicit_action_test.rb @@ -1,16 +1,28 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") -module HappyPath - - class RenderImplicitActionController < ActionController::Base2 - # No actions yet, they are implicit +module RenderImplicitAction + class SimpleController < ::ApplicationController + self.view_paths = [ActionView::Template::FixturePath.new( + "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", + "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated" + )] + + def hello_world() end end - class TestRendersActionImplicitly < SimpleRouteCase - - test "renders action implicitly" do - assert true - end + class TestImplicitRender < SimpleRouteCase + describe "render a simple action with new explicit call to render" + + get "/render_implicit_action/simple/hello_world" + assert_body "Hello world!" + assert_status 200 + end + class TestImplicitWithSpecialCharactersRender < SimpleRouteCase + describe "render an action with a missing method and has special characters" + + get "/render_implicit_action/simple/hyphen-ated" + assert_body "Hello hyphen-ated!" + assert_status 200 end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb index facf67ea85..07ea2f191e 100644 --- a/actionpack/test/new_base/render_layout_test.rb +++ b/actionpack/test/new_base/render_layout_test.rb @@ -3,7 +3,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module ControllerLayouts class ImplicitController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", "basic.html.erb" => "Hello world!" )] @@ -23,7 +23,7 @@ module ControllerLayouts class ImplicitNameController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI", "basic.html.erb" => "Hello world!" )] diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index c6c0269b40..fd0519159e 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -4,7 +4,7 @@ module HappyPath class RenderTemplateWithoutLayoutController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica" )] @@ -13,10 +13,6 @@ module HappyPath render :template => "test/basic" end - def render_hello_world_with_forward_slash - render :template => "/test/basic" - end - def render_template_in_top_directory render :template => 'shared' end @@ -34,14 +30,6 @@ module HappyPath assert_status 200 end - class TestTemplateRenderWithForwardSlash < SimpleRouteCase - describe "rendering a normal template with full path starting with a leading slash" - - get "/happy_path/render_template_without_layout/render_hello_world_with_forward_slash" - assert_body "Hello from basic.html.erb" - assert_status 200 - end - class TestTemplateRenderInTopDirectory < SimpleRouteCase describe "rendering a template not in a subdirectory" @@ -60,7 +48,7 @@ module HappyPath class RenderTemplateWithLayoutController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica", "layouts/application.html.erb" => "<%= yield %>, I'm here!", @@ -127,7 +115,26 @@ module HappyPath assert_body "Hello from basic.html.erb, I wish thee well." assert_status 200 end - - +end + +module Compatibility + class RenderTemplateWithoutLayoutController < ActionController::CompatibleBase2 + self.view_paths = [ActionView::Template::FixturePath.new( + "test/basic.html.erb" => "Hello from basic.html.erb", + "shared.html.erb" => "Elastica" + )] + + def render_hello_world_with_forward_slash + render :template => "/test/basic" + end + end + + class TestTemplateRenderWithForwardSlash < SimpleRouteCase + describe "rendering a normal template with full path starting with a leading slash" + + get "/compatibility/render_template_without_layout/render_hello_world_with_forward_slash" + assert_body "Hello from basic.html.erb" + assert_status 200 + end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index a20ca5fb8c..3c11524d1d 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -6,7 +6,7 @@ end module HappyPath class RenderTextWithoutLayoutsController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new] + self.view_paths = [ActionView::Template::FixturePath.new] def render_hello_world render :text => "hello david" @@ -14,7 +14,7 @@ module HappyPath end class RenderTextWithLayoutsController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "<%= yield %>, I'm here!", "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well." )] diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index d29449ddc1..091fb77f9f 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -24,6 +24,14 @@ require 'pp' # require 'pp' early to prevent hidden_methods from not picking up require 'rubygems' require 'rack/test' +module Rails + def self.env + x = Object.new + def x.test?() true end + x + end +end + module ActionController class Base2 < AbstractBase use AbstractController::Callbacks @@ -54,6 +62,10 @@ module ActionController CORE_METHODS = self.public_instance_methods end + + class CompatibleBase2 < Base2 + use ActionController::Rails2Compatibility + end end # Temporary base class @@ -91,7 +103,7 @@ class Rack::TestCase < ActiveSupport::TestCase end def assert_body(body) - assert_equal [body], last_response.body + assert_equal body, last_response.body end def self.assert_body(body) -- cgit v1.2.3