Changeset 1278

Show
Ignore:
Timestamp:
02/19/08 06:13:18 (9 months ago)
Author:
brian
Message:

Make it possible to create a renderer instance prior to any formatter(s)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ruport/branches/brian/exp-renderer-instance/lib/ruport/renderer.rb

    r1262 r1278  
    322322    # sets the data and options, and then does the following process: 
    323323    # 
     324    #   * If a block is given, yield the Renderer instance. 
     325    #   * Check the presence of any required options. 
     326    #   * If a setup() method is defined on the Renderer, call it. 
     327    #   * Create a formatter. 
    324328    #   * If the renderer contains a module Helpers, mix it in to the instance. 
    325     #   * If a block is given, yield the Renderer instance. 
    326     #   * If a setup() method is defined on the Renderer, call it. 
    327329    #   * Call the run() method. 
    328330    #   * If the :file option is set to a file name, appends output to the file. 
     
    331333    # Please see the examples/ directory for custom renderer examples, because 
    332334    # this is not nearly as complicated as it sounds in most cases. 
    333     def render(format, add_options=nil) 
    334       rend = build(format, add_options) { |r| 
    335           yield(r) if block_given?    
    336         r.setup if r.respond_to? :setup 
    337       }   
    338       rend.run 
    339       rend.formatter.save_output(rend.options.file) if rend.options.file 
    340       return rend.formatter.output 
     335    def render(format, add_options={}, &blk) 
     336      rend = new(add_options, &blk) 
     337      rend.as(format) 
    341338    end 
    342339 
     
    354351    end 
    355352 
    356     private 
    357      
    358     # Creates a new instance of the renderer and sets it to use the specified 
    359     # formatter (by name).  If a block is given, the renderer instance is 
    360     # yielded.   
    361     # 
    362     # Returns the renderer instance. 
    363     # 
    364     def build(format, add_options=nil) 
    365       rend = self.new 
    366  
    367       rend.send(:use_formatter, format) 
    368       rend.send(:options=, options.dup) 
    369       if rend.class.const_defined? :Helpers 
    370         rend.formatter.extend(rend.class.const_get(:Helpers)) 
    371       end 
    372       if add_options.kind_of?(Hash) 
    373         d = add_options.delete(:data) 
    374         rend.data = d if d 
    375         add_options.each {|k,v| rend.options.send("#{k}=",v) } 
    376       end 
    377  
    378       yield(rend) if block_given? 
    379       return rend 
    380     end 
    381      
    382353    # Allows you to register a format with the renderer. 
    383354    # 
     
    401372  attr_writer :formatter   
    402373   
    403   # The +data+ that has been passed to the active formatter. 
     374  # The +data+ that will be passed to the formatter. 
    404375  def data 
    405     formatter.data 
    406   end 
    407  
    408   # Sets +data+ attribute on the active formatter. 
     376    @options.data 
     377  end 
     378 
     379  # Sets +data+ to be passed to the formatter. 
    409380  def data=(val) 
    410     formatter.data = val 
    411   end 
    412  
    413   # Renderer::Options object which is shared with the current formatter. 
     381    @options.data = val 
     382  end 
     383 
     384  # Renderer::Options object within this Renderer 
    414385  def options 
    415     yield(formatter.options) if block_given? 
    416     formatter.options 
    417   end 
    418    
     386    yield(@options) if block_given? 
     387    @options 
     388  end 
     389   
     390  # Creates a new instance of the renderer, sets its options, yields self 
     391  # if block given to allow additional initialization. Then validates the 
     392  # presence of required options, and calls the 'setup' method if present. 
     393  # 
     394  # At this point no formatter is involved. This is so that you can 
     395  # get a renderer to perform work, and then afterwards choose which 
     396  # format(s) you want to output this work as. 
     397  # 
     398  def initialize(add_options={}) 
     399    @options = self.class.options.dup 
     400    add_options.each {|k,v| @options.send("#{k}=",v) } 
     401 
     402    yield self if block_given? 
     403 
     404    unless self.class.required_options.nil? 
     405      self.class.required_options.each do |opt| 
     406        if @options.__send__(opt).nil? 
     407          raise RequiredOptionNotSet, "Required option #{opt} not set" 
     408        end 
     409      end 
     410    end 
     411 
     412    setup if respond_to? :setup 
     413  end 
     414 
     415  # Given this existing renderer object, create and run an appropriate 
     416  # formatter. If the :file option is set to a file name, appends output 
     417  # to the file. Return the results of formatter.output 
     418  # 
     419  # If a block is given, yield the renderer to it after the formatter 
     420  # has been created (for backwards compatibility) 
     421  def as(format, add_options={}) 
     422    with_formatter(format, add_options) do |formatter| 
     423      yield formatter if block_given? 
     424      run 
     425      formatter.save_output(formatter.options.file) if formatter.options.file 
     426      return formatter.output 
     427    end 
     428  end 
     429 
    419430  # Call the _run_ method.  You can override this method in your custom 
    420431  # renderer if you need to define other actions. 
     432  # 
     433  # By the time this method is called, the formatter object has been created. 
    421434  def run 
    422435    _run_ 
     
    429442  # 
    430443  def io=(obj) 
    431     options.io=obj     
     444    @options.io=obj     
    432445  end 
    433446 
     
    436449  # If a block is given, it is evaluated in the context of the formatter. 
    437450  def formatter(&block) 
    438     @formatter.instance_eval(&block) if block    
     451    if block 
     452      raise "No formatter instance" unless @formatter 
     453      @formatter.instance_eval(&block) 
     454    end 
    439455    return @formatter 
    440456  end 
     
    453469  private   
    454470 
     471  # Create a formatter then yield to the block. 
     472  def with_formatter(format, add_options={}) 
     473    use_formatter(format) 
     474    formatter.options = @options.dup 
     475    add_options.each {|k,v| formatter.options.send("#{k}=",v) } 
     476 
     477    if self.class.const_defined? :Helpers 
     478      formatter.extend(self.class.const_get(:Helpers)) 
     479    end 
     480 
     481    yield formatter if block_given? 
     482 
     483    return formatter 
     484  end 
     485 
    455486  # Called automatically when the report is rendered. Uses the 
    456487  # data collected from the earlier methods. 
     488  # 
     489  # The formatter must have been created before this method is called 
    457490  def _run_ 
    458     unless self.class.required_options.nil? 
    459       self.class.required_options.each do |opt| 
    460         if options.__send__(opt).nil? 
    461           raise RequiredOptionNotSet, "Required option #{opt} not set" 
    462         end 
    463       end 
    464     end 
    465  
    466     if formatter.respond_to?(:apply_template) && options.template != false 
    467       formatter.apply_template if options.template || 
     491    d = formatter.options.to_hash.delete(:data) 
     492    formatter.data = d if d 
     493 
     494    if formatter.respond_to?(:apply_template) && formatter.options.template != false 
     495      formatter.apply_template if formatter.options.template || 
    468496        Ruport::Formatter::Template.default 
    469497    end 
     
    471499    prepare self.class.first_stage if self.class.first_stage 
    472500               
    473     if formatter.respond_to?(:layout)  && options.layout != false 
     501    if formatter.respond_to?(:layout)  && formatter.options.layout != false 
    474502      formatter.layout do execute_stages end 
    475503    else 
     
    501529 
    502530  def options=(o) 
    503     formatter.options = o 
     531    @options = o 
    504532  end 
    505533   
  • ruport/branches/brian/exp-renderer-instance/test/csv_formatter_test.rb

    r1226 r1278  
    6666    opts = nil 
    6767    table = Table(%w[a b c]) 
    68     table.to_csv( 
     68    rend = table.class.renderer.new( 
     69      :data => table, 
    6970      :template => :simple, 
    7071      :table_format => { 
     
    7576        :show_headings  => true 
    7677      } 
    77     ) do |r| 
    78       opts = r.options 
     78    ) 
     79    rend.as(:csv) do |f| 
     80      opts = f.options 
    7981    end 
    8082     
  • ruport/branches/brian/exp-renderer-instance/test/html_formatter_test.rb

    r1226 r1278  
    6161    opts = nil 
    6262    table = Table(%w[a b c]) 
    63     table.to_html( 
     63    rend = table.class.renderer.new( 
     64      :data => table, 
    6465      :template => :simple, 
    6566      :table_format => { 
     
    7071        :show_headings  => true 
    7172      } 
    72     ) do |r| 
    73       opts = r.options 
     73    ) 
     74    rend.as(:html) do |f| 
     75      opts = f.options 
    7476    end 
    7577     
  • ruport/branches/brian/exp-renderer-instance/test/pdf_formatter_test.rb

    r1236 r1278  
    9393    opts = nil 
    9494    table = Table(%w[a b c]) 
    95     table.to_pdf( 
     95    rend = table.class.renderer.new( 
     96      :data => table, 
    9697      :template => :simple, 
    9798      :page_format => { 
     
    117118        :style  => :inline 
    118119      } 
    119     ) do |r| 
    120       opts = r.options 
     120    ) 
     121    rend.as(:pdf) do |f| 
     122      opts = f.options 
    121123    end 
    122124     
  • ruport/branches/brian/exp-renderer-instance/test/renderer_test.rb

    r1262 r1278  
    102102    def specify_apply_template_should_be_called 
    103103      Ruport::Formatter::Template.create(:stub) 
    104       Table(%w[a b c]).to_csv(:template => :stub) do |r|  
    105        r.formatter.expects(:apply_template) 
     104      table = Table(%w[a b c]) 
     105      rend = table.class.renderer.new(:data => table) 
     106      rend.as(:csv, :template => :stub) do |formatter| 
     107        formatter.expects(:apply_template) 
    106108      end   
    107109    end  
     
    117119    def specify_default_template_should_be_called 
    118120      Ruport::Formatter::Template.create(:default) 
    119       Table(%w[a b c]).to_csv do |r|  
    120         r.formatter.expects(:apply_template) 
    121         assert r.formatter.template == Ruport::Formatter::Template[:default] 
     121      table = Table(%w[a b c]) 
     122      rend = table.class.renderer.new(:data => table) 
     123      rend.as(:csv) do |formatter| 
     124        formatter.expects(:apply_template) 
     125        assert formatter.template == Ruport::Formatter::Template[:default] 
    122126      end   
    123127    end 
     
    126130      Ruport::Formatter::Template.create(:default) 
    127131      Ruport::Formatter::Template.create(:stub) 
    128       Table(%w[a b c]).to_csv(:template => :stub) do |r|  
    129         r.formatter.expects(:apply_template) 
    130         assert r.formatter.template == Ruport::Formatter::Template[:stub] 
     132      table = Table(%w[a b c]) 
     133      rend = table.class.renderer.new(:data => table) 
     134      rend.as(:csv, :template => :stub) do |formatter| 
     135        formatter.expects(:apply_template) 
     136        assert formatter.template == Ruport::Formatter::Template[:stub] 
    131137      end   
    132138    end 
     
    134140    def specify_should_be_able_to_disable_templates 
    135141      Ruport::Formatter::Template.create(:default) 
    136       Table(%w[a b c]).to_csv(:template => false) do |r|  
    137         r.formatter.expects(:apply_template).never 
     142      table = Table(%w[a b c]) 
     143      rend = table.class.renderer.new(:data => table) 
     144      rend.as(:csv, :template => false) do |formatter| 
     145        formatter.expects(:apply_template).never 
    138146      end   
    139147    end 
     
    187195 
    188196    # render mode 
    189     OldSchoolRenderer.render_text do |r| 
    190       assert_kind_of Ruport::Formatter, r.formatter 
    191       assert_kind_of DummyText, r.formatter 
     197    OldSchoolRenderer.new.as(:text) do |formatter| 
     198      assert_kind_of Ruport::Formatter, formatter 
     199      assert_kind_of DummyText, formatter 
    192200    end 
    193201 
     
    239247    assert_equal "header\nbody\nfooter\n", 
    240248      VanillaRenderer.render_text_using_build 
    241     VanillaRenderer.render_text_using_build do |rend
    242       assert rend.formatter.respond_to?(:build_header) 
    243       assert rend.formatter.respond_to?(:build_body) 
    244       assert rend.formatter.respond_to?(:build_footer) 
     249    VanillaRenderer.new.as(:text_using_build) do |formatter
     250      assert formatter.respond_to?(:build_header) 
     251      assert formatter.respond_to?(:build_body) 
     252      assert formatter.respond_to?(:build_footer) 
    245253    end 
    246254  end 
     
    417425 
    418426  def test_renderer_helper_module 
    419     RendererWithHelperModule.render_stub do |r
    420       assert_equal "Hello Dolly", r.formatter.say_hello 
     427    RendererWithHelperModule.new.as(:stub) do |f
     428      assert_equal "Hello Dolly", f.say_hello 
    421429    end 
    422430  end 
     
    516524   
    517525  class RendererForCheckingPassivity < Ruport::Renderer 
     526    add_format DummyText, :stub 
     527 
    518528    def foo 
    519529      "apples" 
     
    523533 
    524534   def setup  
    525      @renderer = RendererForCheckingOptionReaders.new  
    526      @renderer.formatter = Ruport::Formatter.new  
    527       
    528      @passive = RendererForCheckingPassivity.new 
    529      @passive.formatter = Ruport::Formatter.new 
     535     @renderer = RendererForCheckingOptionReaders.new(:foo=>123) 
     536     @passive = RendererForCheckingPassivity.new(:foo=>123) 
    530537   end 
    531538    
    532539   def test_options_are_readable 
     540      assert_equal 123, @renderer.foo 
    533541      @renderer.foo = 5 
    534542      assert_equal 5, @renderer.foo 
     
    539547     assert_equal "apples", @passive.foo 
    540548     assert_equal 5, @passive.options.foo 
    541      assert_equal 5, @passive.formatter.options.foo 
     549     @passive.as(:stub) do |f| 
     550       assert_equal 5, f.options.foo 
     551     end 
    542552   end 
    543553      
  • ruport/branches/brian/exp-renderer-instance/test/text_formatter_test.rb

    r1226 r1278  
    9797    opts = nil 
    9898    table = Table(%w[a b c]) 
    99     table.to_text( 
     99    rend = table.class.renderer.new( 
     100      :data => table, 
    100101      :template => :simple, 
    101102      :table_format => { 
     
    111112        :show_headings  => true 
    112113      } 
    113     ) do |r| 
    114       opts = r.options 
     114    ) 
     115    rend.as(:text) do |f| 
     116      opts = f.options 
    115117    end 
    116118