From f27360af04f11506d7081b2bd46c9ea0413a910c Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Sun, 3 Jan 2016 22:13:59 -0600 Subject: Add ActionController:Renderers test To complement actionpack/test/controller/metal/renderers_test.rb --- .../lib/action_controller/metal/renderers.rb | 9 +++ actionpack/test/controller/render_other_test.rb | 24 ------ actionpack/test/controller/renderers_test.rb | 90 ++++++++++++++++++++++ 3 files changed, 99 insertions(+), 24 deletions(-) delete mode 100644 actionpack/test/controller/render_other_test.rb create mode 100644 actionpack/test/controller/renderers_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index 1f77f9ecaa..f171c4d172 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -11,6 +11,7 @@ module ActionController Renderers.remove(key) end + # See Responder#api_behavior class MissingRenderer < LoadError def initialize(format) super "No renderer defined for format: #{format}" @@ -67,6 +68,11 @@ module ActionController alias use_renderer use_renderers end + # Called by +render+ in AbstractController::Renderering + # which sets the return value as the +response_body+. + # + # If no renderer is found, +super+ returns control to + # ActionView::Rendering.render_to_body, if present. def render_to_body(options) _render_to_body_with_renderer(options) || super end @@ -137,6 +143,9 @@ module ActionController remove_method(method_name) if method_defined?(method_name) end + # Used in ActionController::Base + # and ActionController::API to include all + # renderers by default. module All extend ActiveSupport::Concern include Renderers diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb deleted file mode 100644 index 1f5215ac55..0000000000 --- a/actionpack/test/controller/render_other_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'abstract_unit' - - -class RenderOtherTest < ActionController::TestCase - class TestController < ActionController::Base - def render_simon_says - render :simon => "foo" - end - end - - tests TestController - - def test_using_custom_render_option - ActionController.add_renderer :simon do |says, options| - self.content_type = Mime[:text] - self.response_body = "Simon says: #{says}" - end - - get :render_simon_says - assert_equal "Simon says: foo", @response.body - ensure - ActionController.remove_renderer :simon - end -end diff --git a/actionpack/test/controller/renderers_test.rb b/actionpack/test/controller/renderers_test.rb new file mode 100644 index 0000000000..e6c2e4636e --- /dev/null +++ b/actionpack/test/controller/renderers_test.rb @@ -0,0 +1,90 @@ +require 'abstract_unit' +require 'controller/fake_models' +require 'active_support/logger' + +class RenderersTest < ActionController::TestCase + class XmlRenderable + def to_xml(options) + options[:root] ||= "i-am-xml" + "<#{options[:root]}/>" + end + end + class JsonRenderable + def as_json(options={}) + hash = { :a => :b, :c => :d, :e => :f } + hash.except!(*options[:except]) if options[:except] + hash + end + + def to_json(options = {}) + super :except => [:c, :e] + end + end + class CsvRenderable + def to_csv + "c,s,v" + end + end + class TestController < ActionController::Base + + def render_simon_says + render :simon => "foo" + end + + def respond_to_mime + respond_to do |type| + type.json do + render json: JsonRenderable.new + end + type.js { render json: 'JS', callback: 'alert' } + type.csv { render csv: CsvRenderable.new } + type.xml { render xml: XmlRenderable.new } + type.html { render body: "HTML" } + type.rss { render body: "RSS" } + type.all { render body: "Nothing" } + type.any(:js, :xml) { render body: "Either JS or XML" } + end + end + end + + 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) + end + + def test_using_custom_render_option + ActionController.add_renderer :simon do |says, options| + self.content_type = Mime[:text] + self.response_body = "Simon says: #{says}" + end + + get :render_simon_says + assert_equal "Simon says: foo", @response.body + ensure + ActionController.remove_renderer :simon + end + + def test_raises_missing_template_no_renderer + assert_raise ActionView::MissingTemplate do + get :respond_to_mime, format: 'csv' + end + assert_equal Mime[:csv], @response.content_type + assert_equal "", @response.body + end + + def test_adding_csv_rendering_via_renderers_add + ActionController::Renderers.add :csv do |value, options| + send_data value.to_csv, type: Mime[:csv] + end + @request.accept = "text/csv" + get :respond_to_mime, format: 'csv' + assert_equal Mime[:csv], @response.content_type + assert_equal "c,s,v", @response.body + ensure + ActionController::Renderers.remove :csv + end +end -- cgit v1.2.3 From f2b3b4019a292d5488bda096a35a70849db585a5 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Sun, 3 Jan 2016 22:54:42 -0600 Subject: Group related methods together --- .../lib/action_controller/metal/renderers.rb | 134 ++++++++++----------- 1 file changed, 67 insertions(+), 67 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index f171c4d172..d5e7a8ffb4 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -21,11 +21,78 @@ module ActionController module Renderers extend ActiveSupport::Concern + # A Set containing renderer names that correspond to available renderer procs. + # Default values are :json, :js, :xml. + RENDERERS = Set.new + included do class_attribute :_renderers self._renderers = Set.new.freeze end + # Used in ActionController::Base + # and ActionController::API to include all + # renderers by default. + module All + extend ActiveSupport::Concern + include Renderers + + included do + self._renderers = RENDERERS + end + end + + # Adds a new renderer to call within controller actions. + # A renderer is invoked by passing its name as an option to + # AbstractController::Rendering#render. To create a renderer + # pass it a name and a block. The block takes two arguments, the first + # is the value paired with its key and the second is the remaining + # hash of options passed to +render+. + # + # Create a csv renderer: + # + # ActionController::Renderers.add :csv do |obj, options| + # filename = options[:filename] || 'data' + # str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s + # send_data str, type: Mime[:csv], + # disposition: "attachment; filename=#{filename}.csv" + # end + # + # Note that we used Mime[:csv] for the csv mime type as it comes with Rails. + # For a custom renderer, you'll need to register a mime type with + # Mime::Type.register. + # + # To use the csv renderer in a controller action: + # + # def show + # @csvable = Csvable.find(params[:id]) + # respond_to do |format| + # format.html + # format.csv { render csv: @csvable, filename: @csvable.name } + # end + # end + # To use renderers and their mime types in more concise ways, see + # ActionController::MimeResponds::ClassMethods.respond_to + def self.add(key, &block) + define_method(_render_with_renderer_method_name(key), &block) + RENDERERS << key.to_sym + end + + # This method is the opposite of add method. + # + # To remove a csv renderer: + # + # ActionController::Renderers.remove(:csv) + def self.remove(key) + RENDERERS.delete(key.to_sym) + method_name = _render_with_renderer_method_name(key) + remove_method(method_name) if method_defined?(method_name) + end + + def self._render_with_renderer_method_name(key) + "_render_with_renderer_#{key}" + end + module ClassMethods # Adds, by name, a renderer or renderers to the +_renderers+ available @@ -88,73 +155,6 @@ module ActionController nil end - # A Set containing renderer names that correspond to available renderer procs. - # Default values are :json, :js, :xml. - RENDERERS = Set.new - - def self._render_with_renderer_method_name(key) - "_render_with_renderer_#{key}" - end - - # Adds a new renderer to call within controller actions. - # A renderer is invoked by passing its name as an option to - # AbstractController::Rendering#render. To create a renderer - # pass it a name and a block. The block takes two arguments, the first - # is the value paired with its key and the second is the remaining - # hash of options passed to +render+. - # - # Create a csv renderer: - # - # ActionController::Renderers.add :csv do |obj, options| - # filename = options[:filename] || 'data' - # str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s - # send_data str, type: Mime[:csv], - # disposition: "attachment; filename=#{filename}.csv" - # end - # - # Note that we used Mime[:csv] for the csv mime type as it comes with Rails. - # For a custom renderer, you'll need to register a mime type with - # Mime::Type.register. - # - # To use the csv renderer in a controller action: - # - # def show - # @csvable = Csvable.find(params[:id]) - # respond_to do |format| - # format.html - # format.csv { render csv: @csvable, filename: @csvable.name } - # end - # end - # To use renderers and their mime types in more concise ways, see - # ActionController::MimeResponds::ClassMethods.respond_to - def self.add(key, &block) - define_method(_render_with_renderer_method_name(key), &block) - RENDERERS << key.to_sym - end - - # This method is the opposite of add method. - # - # To remove a csv renderer: - # - # ActionController::Renderers.remove(:csv) - def self.remove(key) - RENDERERS.delete(key.to_sym) - method_name = _render_with_renderer_method_name(key) - remove_method(method_name) if method_defined?(method_name) - end - - # Used in ActionController::Base - # and ActionController::API to include all - # renderers by default. - module All - extend ActiveSupport::Concern - include Renderers - - included do - self._renderers = RENDERERS - end - end - add :json do |json, options| json = json.to_json(options) unless json.kind_of?(String) -- cgit v1.2.3