diff options
author | José Valim <jose.valim@gmail.com> | 2009-08-06 23:48:48 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-08-07 17:17:51 +0200 |
commit | aed135d3e261cbee153a35fcfbeb47e2e02b12e4 (patch) | |
tree | ab3b3ff0b8cbd632f34d938bf1117b075f4813a7 | |
parent | 1fd65c80fcdc6080b9efa27f41dbb7f7d95a17c6 (diff) | |
download | rails-aed135d3e261cbee153a35fcfbeb47e2e02b12e4.tar.gz rails-aed135d3e261cbee153a35fcfbeb47e2e02b12e4.tar.bz2 rails-aed135d3e261cbee153a35fcfbeb47e2e02b12e4.zip |
Renamed presenter to renderer, added some documentation and defined its API.
18 files changed, 294 insertions, 241 deletions
diff --git a/actionpack/examples/very_simple.rb b/actionpack/examples/very_simple.rb index 422c4c3298..6714185172 100644 --- a/actionpack/examples/very_simple.rb +++ b/actionpack/examples/very_simple.rb @@ -6,7 +6,7 @@ require "action_controller" class Kaigi < ActionController::Metal include AbstractController::Callbacks include ActionController::RackConvenience - include ActionController::Renderer + include ActionController::RenderingController include ActionController::Layouts include ActionView::Context @@ -47,4 +47,4 @@ app = Rack::Builder.new do map("/kaigi/alt") { run Kaigi.action(:alt) } end.to_app -Rack::Handler::Mongrel.run app, :Port => 3000
\ No newline at end of file +Rack::Handler::Mongrel.run app, :Port => 3000 diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index f020abaa45..cdeb55b915 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -2,15 +2,15 @@ require "active_support/core_ext/module/attr_internal" require "active_support/core_ext/module/delegation" module AbstractController - autoload :Base, "abstract_controller/base" - autoload :Benchmarker, "abstract_controller/benchmarker" - autoload :Callbacks, "abstract_controller/callbacks" - autoload :Helpers, "abstract_controller/helpers" - autoload :Layouts, "abstract_controller/layouts" - autoload :Logger, "abstract_controller/logger" - autoload :Renderer, "abstract_controller/renderer" + autoload :Base, "abstract_controller/base" + autoload :Benchmarker, "abstract_controller/benchmarker" + autoload :Callbacks, "abstract_controller/callbacks" + autoload :Helpers, "abstract_controller/helpers" + autoload :Layouts, "abstract_controller/layouts" + autoload :Logger, "abstract_controller/logger" + autoload :RenderingController, "abstract_controller/rendering_controller" # === Exceptions - autoload :ActionNotFound, "abstract_controller/exceptions" - autoload :DoubleRenderError, "abstract_controller/exceptions" - autoload :Error, "abstract_controller/exceptions" + autoload :ActionNotFound, "abstract_controller/exceptions" + autoload :DoubleRenderError, "abstract_controller/exceptions" + autoload :Error, "abstract_controller/exceptions" end diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index 5efa37fde3..04eaa02441 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -2,7 +2,7 @@ module AbstractController module Helpers extend ActiveSupport::Concern - include Renderer + include RenderingController included do extlib_inheritable_accessor(:_helpers) { Module.new } diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 038598a3b3..0cb3d166f7 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -2,7 +2,7 @@ module AbstractController module Layouts extend ActiveSupport::Concern - include Renderer + include RenderingController included do extlib_inheritable_accessor(:_layout_conditions) { Hash.new } diff --git a/actionpack/lib/abstract_controller/renderer.rb b/actionpack/lib/abstract_controller/rendering_controller.rb index da57d0ff4d..23cd71e0bd 100644 --- a/actionpack/lib/abstract_controller/renderer.rb +++ b/actionpack/lib/abstract_controller/rendering_controller.rb @@ -1,7 +1,7 @@ require "abstract_controller/logger" module AbstractController - module Renderer + module RenderingController extend ActiveSupport::Concern include AbstractController::Logger @@ -67,7 +67,7 @@ module AbstractController # # :api: plugin def render_to_string(options = {}) - AbstractController::Renderer.body_to_s(render_to_body(options)) + AbstractController::RenderingController.body_to_s(render_to_body(options)) end # Renders the template from an object. diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 22c2c4f499..8343a87936 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -8,8 +8,8 @@ module ActionController autoload :Rails2Compatibility, "action_controller/metal/compatibility" autoload :Redirector, "action_controller/metal/redirector" autoload :Renderer, "action_controller/metal/renderer" + autoload :RenderingController, "action_controller/metal/rendering_controller" autoload :RenderOptions, "action_controller/metal/render_options" - autoload :Renderers, "action_controller/metal/render_options" autoload :Rescue, "action_controller/metal/rescuable" autoload :Testing, "action_controller/metal/testing" autoload :UrlFor, "action_controller/metal/url_for" @@ -69,4 +69,4 @@ require 'active_support/core_ext/load_error' require 'active_support/core_ext/module/attr_internal' require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/name_error' -require 'active_support/inflector'
\ No newline at end of file +require 'active_support/inflector' diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 9d9f735e27..40f4802b74 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -10,8 +10,8 @@ module ActionController include ActionController::HideActions include ActionController::UrlFor include ActionController::Redirector - include ActionController::Renderer - include ActionController::Renderers::All + include ActionController::RenderingController + include ActionController::RenderOptions::All include ActionController::Layouts include ActionController::ConditionalGet include ActionController::RackConvenience diff --git a/actionpack/lib/action_controller/metal/layouts.rb b/actionpack/lib/action_controller/metal/layouts.rb index 365351b421..cac529b1ae 100644 --- a/actionpack/lib/action_controller/metal/layouts.rb +++ b/actionpack/lib/action_controller/metal/layouts.rb @@ -158,7 +158,7 @@ module ActionController module Layouts extend ActiveSupport::Concern - include ActionController::Renderer + include ActionController::RenderingController include AbstractController::Layouts module ClassMethods diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index d43f940774..d823dd424a 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -1,146 +1,4 @@ module ActionController #:nodoc: - - # Presenter is responsible to expose a resource for different mime requests, - # usually depending on the HTTP verb. The presenter is triggered when - # respond_with is called. The simplest case to study is a GET request: - # - # class PeopleController < ApplicationController - # respond_to :html, :xml, :json - # - # def index - # @people = Person.find(:all) - # respond_with(@people) - # end - # end - # - # When a request comes, for example with format :xml, three steps happen: - # - # 1) respond_with searches for a template at people/index.xml; - # - # 2) if the template is not available, it will create a presenter, passing - # the controller and the resource, and invoke :to_xml on it; - # - # 3) if the presenter does not respond_to :to_xml, call to_format on it. - # - # === Builtin HTTP verb semantics - # - # Rails default presenter holds semantics for each HTTP verb. Depending on the - # content type, verb and the resource status, it will behave differently. - # - # Using Rails default presenter, a POST request could be written as: - # - # def create - # @user = User.new(params[:user]) - # flash[:notice] = 'User was successfully created.' if @user.save - # respond_with(@user) - # end - # - # Which is exactly the same as: - # - # def create - # @user = User.new(params[:user]) - # - # respond_to do |format| - # if @user.save - # flash[:notice] = 'User was successfully created.' - # format.html { redirect_to(@user) } - # format.xml { render :xml => @user, :status => :created, :location => @user } - # else - # format.html { render :action => "new" } - # format.xml { render :xml => @user.errors, :status => :unprocessable_entity } - # end - # end - # end - # - # The same happens for PUT and DELETE requests. By default, it accepts just - # :location as parameter, which is used as redirect destination, in both - # POST, PUT, DELETE requests for HTML mime, as in the example below: - # - # def destroy - # @person = Person.find(params[:id]) - # @person.destroy - # respond_with(@person, :location => root_url) - # end - # - # === Nested resources - # - # You can given nested resource as you do in form_for and polymorphic_url. - # Consider the project has many tasks example. The create action for - # TasksController would be like: - # - # def create - # @project = Project.find(params[:project_id]) - # @task = @project.comments.build(params[:task]) - # flash[:notice] = 'Task was successfully created.' if @task.save - # respond_with([@project, @task]) - # end - # - # Given a nested resource, you ensure that the presenter will redirect to - # project_task_url instead of task_url. - # - # Namespaced and singleton resources requires a symbol to be given, as in - # polymorphic urls. If a project has one manager which has many tasks, it - # should be invoked as: - # - # respond_with([@project, :manager, @task]) - # - # Check polymorphic_url documentation for more examples. - # - class Presenter - attr_reader :controller, :request, :format, :resource, :resource_location, :options - - def initialize(controller, resource, options) - @controller = controller - @request = controller.request - @format = controller.formats.first - @resource = resource.is_a?(Array) ? resource.last : resource - @resource_location = options[:location] || resource - @options = options - end - - delegate :head, :render, :redirect_to, :to => :controller - delegate :get?, :post?, :put?, :delete?, :to => :request - - # Undefine :to_json since it's defined on Object - undef_method :to_json - - def to_html - if get? - render - elsif has_errors? - render :action => default_action - else - redirect_to resource_location - end - end - - def to_format - return render unless resourceful? - - if get? - render format => resource - elsif has_errors? - render format => resource.errors, :status => :unprocessable_entity - elsif post? - render format => resource, :status => :created, :location => resource_location - else - head :ok - end - end - - def resourceful? - resource.respond_to?(:"to_#{format}") - end - - def has_errors? - resource.respond_to?(:errors) && !resource.errors.empty? - end - - def default_action - request.post? ? :new : :edit - end - end - module MimeResponds #:nodoc: extend ActiveSupport::Concern @@ -339,10 +197,10 @@ module ActionController #:nodoc: end end - # respond_with wraps a resource around a presenter for default representation. + # respond_with wraps a resource around a renderer for default representation. # First it invokes respond_to, if a response cannot be found (ie. no block # for the request was given and template was not available), it instantiates - # an ActionController::Presenter with the controller and resource. + # an ActionController::Renderer with the controller and resource. # # ==== Example # @@ -363,19 +221,19 @@ module ActionController #:nodoc: # end # end # - # All options given to respond_with are sent to the underlying presenter. + # All options given to respond_with are sent to the underlying renderer, + # except for the option :renderer itself. Since the renderer interface + # is quite simple (it just needs to respond to call), you can even give + # a proc to it. # def respond_with(resource, options={}, &block) respond_to(&block) rescue ActionView::MissingTemplate - presenter = ActionController::Presenter.new(self, resource, options) - format_method = :"to_#{self.formats.first}" + (options.delete(:renderer) || renderer).call(self, resource, options) + end - if presenter.respond_to?(format_method) - presenter.send(format_method) - else - presenter.to_format - end + def renderer + ActionController::Renderer end protected diff --git a/actionpack/lib/action_controller/metal/render_options.rb b/actionpack/lib/action_controller/metal/render_options.rb index c6a965472f..0d69ca10df 100644 --- a/actionpack/lib/action_controller/metal/render_options.rb +++ b/actionpack/lib/action_controller/metal/render_options.rb @@ -47,7 +47,7 @@ module ActionController end end - module Renderers + module RenderOptions module Json extend RenderOption register_renderer :json @@ -94,10 +94,10 @@ module ActionController module All extend ActiveSupport::Concern - include ActionController::Renderers::Json - include ActionController::Renderers::Js - include ActionController::Renderers::Xml - include ActionController::Renderers::RJS + include ActionController::RenderOptions::Json + include ActionController::RenderOptions::Js + include ActionController::RenderOptions::Xml + include ActionController::RenderOptions::RJS end end end diff --git a/actionpack/lib/action_controller/metal/renderer.rb b/actionpack/lib/action_controller/metal/renderer.rb index 31ba7e582a..39ab2407aa 100644 --- a/actionpack/lib/action_controller/metal/renderer.rb +++ b/actionpack/lib/action_controller/metal/renderer.rb @@ -1,66 +1,181 @@ -module ActionController - module Renderer - extend ActiveSupport::Concern +module ActionController #:nodoc: + # Renderer is responsible to expose a resource for different mime requests, + # usually depending on the HTTP verb. The renderer is triggered when + # respond_with is called. The simplest case to study is a GET request: + # + # class PeopleController < ApplicationController + # respond_to :html, :xml, :json + # + # def index + # @people = Person.find(:all) + # respond_with(@people) + # end + # end + # + # When a request comes, for example with format :xml, three steps happen: + # + # 1) respond_with searches for a template at people/index.xml; + # + # 2) if the template is not available, it will create a renderer, passing + # the controller and the resource and invoke :to_xml on it; + # + # 3) if the renderer does not respond_to :to_xml, call to_format on it. + # + # === Builtin HTTP verb semantics + # + # Rails default renderer holds semantics for each HTTP verb. Depending on the + # content type, verb and the resource status, it will behave differently. + # + # Using Rails default renderer, a POST request for creating an object could + # be written as: + # + # def create + # @user = User.new(params[:user]) + # flash[:notice] = 'User was successfully created.' if @user.save + # respond_with(@user) + # end + # + # Which is exactly the same as: + # + # def create + # @user = User.new(params[:user]) + # + # respond_to do |format| + # if @user.save + # flash[:notice] = 'User was successfully created.' + # format.html { redirect_to(@user) } + # format.xml { render :xml => @user, :status => :created, :location => @user } + # else + # format.html { render :action => "new" } + # format.xml { render :xml => @user.errors, :status => :unprocessable_entity } + # end + # end + # end + # + # The same happens for PUT and DELETE requests. + # + # === Nested resources + # + # You can given nested resource as you do in form_for and polymorphic_url. + # Consider the project has many tasks example. The create action for + # TasksController would be like: + # + # def create + # @project = Project.find(params[:project_id]) + # @task = @project.comments.build(params[:task]) + # flash[:notice] = 'Task was successfully created.' if @task.save + # respond_with([@project, @task]) + # end + # + # Giving an array of resources, you ensure that the renderer will redirect to + # project_task_url instead of task_url. + # + # Namespaced and singleton resources requires a symbol to be given, as in + # polymorphic urls. If a project has one manager which has many tasks, it + # should be invoked as: + # + # respond_with([@project, :manager, @task]) + # + # Check polymorphic_url documentation for more examples. + # + class Renderer + attr_reader :controller, :request, :format, :resource, :resource_location, :options - include AbstractController::Renderer + def initialize(controller, resource, options={}) + @controller = controller + @request = controller.request + @format = controller.formats.first + @resource = resource.is_a?(Array) ? resource.last : resource + @resource_location = options[:location] || resource + @options = options + end + + delegate :head, :render, :redirect_to, :to => :controller + delegate :get?, :post?, :put?, :delete?, :to => :request - def process_action(*) - self.formats = request.formats.map {|x| x.to_sym} - super + # Undefine :to_json since it's defined on Object + undef_method :to_json + + # Initializes a new renderer an invoke the proper format. If the format is + # not defined, call to_format. + # + def self.call(*args) + renderer = new(*args) + method = :"to_#{renderer.format}" + renderer.respond_to?(method) ? renderer.send(method) : renderer.to_format end - def render(options) - super - self.content_type ||= begin - mime = options[:_template].mime_type - formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first) - end.to_s - response_body + # HTML format does not render the resource, it always attempt to render a + # template. + # + def to_html + if get? + render + elsif has_errors? + render :action => default_action + else + redirect_to resource_location + end end - def render_to_body(options) - _process_options(options) + # All others formats try to render the resource given instead. For this + # purpose a helper called display as a shortcut to render a resource with + # the current format. + # + def to_format + return render unless resourceful? - if options.key?(:partial) - options[:partial] = action_name if options[:partial] == true - options[:_details] = {:formats => formats} + if get? + display resource + elsif has_errors? + display resource.errors, :status => :unprocessable_entity + elsif post? + display resource, :status => :created, :location => resource_location + else + head :ok end - - super end - private - def _prefix - controller_path - end + protected - def _determine_template(options) - if options.key?(:text) - options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first) - elsif options.key?(:inline) - handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") - template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) - options[:_template] = template - elsif options.key?(:template) - options[:_template_name] = options[:template] - elsif options.key?(:file) - options[:_template_name] = options[:file] - elsif !options.key?(:partial) - options[:_template_name] = (options[:action] || action_name).to_s - options[:_prefix] = _prefix - end + # Checks whether the resource responds to the current format or not. + # + def resourceful? + resource.respond_to?(:"to_#{format}") + end - super - end + # display is just a shortcut to render a resource with the current format. + # + # display @user, :status => :ok + # + # For xml request is equivalent to: + # + # render :xml => @user, :status => :ok + # + # Options sent by the user are also used: + # + # respond_with(@user, :status => :created) + # display(@user, :status => :ok) + # + # Results in: + # + # render :xml => @user, :status => :created + # + def display(resource, given_options={}) + render given_options.merge!(options).merge!(format => resource) + end - def _render_partial(partial, options) - end + # Check if the resource has errors or not. + # + def has_errors? + resource.respond_to?(:errors) && !resource.errors.empty? + end - def _process_options(options) - status, content_type, location = options.values_at(:status, :content_type, :location) - self.status = status if status - self.content_type = content_type if content_type - self.headers["Location"] = url_for(location) if location - end + # By default, render the :edit action for html requests with failure, unless + # the verb is post. + # + def default_action + request.post? ? :new : :edit + end end end diff --git a/actionpack/lib/action_controller/metal/rendering_controller.rb b/actionpack/lib/action_controller/metal/rendering_controller.rb new file mode 100644 index 0000000000..c8922290f3 --- /dev/null +++ b/actionpack/lib/action_controller/metal/rendering_controller.rb @@ -0,0 +1,66 @@ +module ActionController + module RenderingController + extend ActiveSupport::Concern + + include AbstractController::RenderingController + + def process_action(*) + self.formats = request.formats.map {|x| x.to_sym} + super + end + + def render(options) + super + self.content_type ||= begin + mime = options[:_template].mime_type + formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first) + end.to_s + response_body + end + + def render_to_body(options) + _process_options(options) + + if options.key?(:partial) + options[:partial] = action_name if options[:partial] == true + options[:_details] = {:formats => formats} + end + + super + end + + private + def _prefix + controller_path + end + + def _determine_template(options) + if options.key?(:text) + options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first) + elsif options.key?(:inline) + handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") + template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) + options[:_template] = template + elsif options.key?(:template) + options[:_template_name] = options[:template] + elsif options.key?(:file) + options[:_template_name] = options[:file] + elsif !options.key?(:partial) + options[:_template_name] = (options[:action] || action_name).to_s + options[:_prefix] = _prefix + end + + super + end + + def _render_partial(partial, options) + end + + def _process_options(options) + status, content_type, location = options.values_at(:status, :content_type, :location) + self.status = status if status + self.content_type = content_type if content_type + self.headers["Location"] = url_for(location) if location + end + end +end diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb index f0317c6e99..57318e8747 100644 --- a/actionpack/lib/action_controller/metal/streaming.rb +++ b/actionpack/lib/action_controller/metal/streaming.rb @@ -6,7 +6,7 @@ module ActionController #:nodoc: module Streaming extend ActiveSupport::Concern - include ActionController::Renderer + include ActionController::RenderingController DEFAULT_SEND_FILE_OPTIONS = { :type => 'application/octet-stream'.freeze, diff --git a/actionpack/lib/action_controller/metal/verification.rb b/actionpack/lib/action_controller/metal/verification.rb index 951ae1bee1..d3d78e3749 100644 --- a/actionpack/lib/action_controller/metal/verification.rb +++ b/actionpack/lib/action_controller/metal/verification.rb @@ -2,7 +2,7 @@ module ActionController #:nodoc: module Verification #:nodoc: extend ActiveSupport::Concern - include AbstractController::Callbacks, Session, Flash, Renderer + include AbstractController::Callbacks, Session, Flash, RenderingController # This module provides a class-level method for specifying that certain # actions are guarded against being called without certain prerequisites @@ -127,4 +127,4 @@ module ActionController #:nodoc: end end end -end
\ No newline at end of file +end diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index 56ec6a6a31..10b97f4eb4 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -27,7 +27,7 @@ module AbstractController # Test Render mixin # ==== class RenderingController < AbstractController::Base - include Renderer + include ::AbstractController::RenderingController def _prefix() end @@ -65,8 +65,8 @@ module AbstractController self.response_body = render_to_string :_template_name => "naked_render.erb" end end - - class TestRenderer < ActiveSupport::TestCase + + class TestRenderingController < ActiveSupport::TestCase test "rendering templates works" do result = Me2.new.process(:index) assert_equal "Hello from index.erb", result.response_body diff --git a/actionpack/test/abstract_controller/helper_test.rb b/actionpack/test/abstract_controller/helper_test.rb index 0a2535f834..cd6d4ee90e 100644 --- a/actionpack/test/abstract_controller/helper_test.rb +++ b/actionpack/test/abstract_controller/helper_test.rb @@ -4,7 +4,7 @@ module AbstractController module Testing class ControllerWithHelpers < AbstractController::Base - include Renderer + include RenderingController include Helpers def render(string) @@ -40,4 +40,4 @@ module AbstractController end end -end
\ No newline at end of file +end diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb index b28df7743f..42f73faa61 100644 --- a/actionpack/test/abstract_controller/layouts_test.rb +++ b/actionpack/test/abstract_controller/layouts_test.rb @@ -6,7 +6,7 @@ module AbstractControllerTests # Base controller for these tests class Base < AbstractController::Base - include AbstractController::Renderer + include AbstractController::RenderingController include AbstractController::Layouts self.view_paths = [ActionView::FixtureResolver.new( diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 157e837503..00ad90ff68 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -501,8 +501,13 @@ class RespondWithController < ActionController::Base respond_with([Quiz::Store.new("developer?", 11), Customer.new("david", 13)]) end - def using_resource_with_location - respond_with(Customer.new("david", 13), :location => "http://test.host/") + def using_resource_with_status_and_location + respond_with(Customer.new("david", 13), :location => "http://test.host/", :status => :created) + end + + def using_resource_with_renderer + renderer = proc { |c, r, o| c.render :text => "Resource name is #{r.name}" } + respond_with(Customer.new("david", 13), :renderer => renderer) end protected @@ -727,11 +732,20 @@ class RespondWithControllerTest < ActionController::TestCase end end - def test_using_resource_with_location + def test_using_resource_with_status_and_location @request.accept = "text/html" - post :using_resource_with_location + post :using_resource_with_status_and_location assert @response.redirect? assert_equal "http://test.host/", @response.location + + @request.accept = "application/xml" + get :using_resource_with_status_and_location + assert_equal 201, @response.status + end + + def test_using_resource_with_renderer + get :using_resource_with_renderer + assert_equal "Resource name is david", @response.body end def test_not_acceptable |