bldr 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +1 -2
- data/Gemfile +1 -0
- data/HISTORY.md +11 -1
- data/MIT-LICENSE +1 -1
- data/README.md +72 -2
- data/bldr.gemspec +3 -3
- data/lib/bldr/node.rb +43 -11
- data/lib/bldr/template.rb +3 -0
- data/lib/bldr/version.rb +1 -1
- data/lib/sinatra/bldr.rb +5 -3
- data/spec/fixtures/ivar.bldr +3 -0
- data/spec/fixtures/nested_ivars.bldr +5 -0
- data/spec/fixtures/nested_objects.json.bldr +2 -2
- data/spec/functional/tilt_template_spec.rb +191 -93
- data/spec/integration/sinatra_spec.rb +21 -1
- data/spec/models/song.rb +6 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/node_spec.rb +501 -490
- metadata +20 -14
    
        data/.travis.yml
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    
    
        data/HISTORY.md
    CHANGED
    
    | @@ -1,3 +1,13 @@ | |
| 1 | 
            +
            ## 0.7.0 (2013-xx-xx)
         | 
| 2 | 
            +
            * Support for inherited instance variables
         | 
| 3 | 
            +
            * Breaking change: Node#attribute block syntax no longer inherits
         | 
| 4 | 
            +
              context from current_object. See 941608e7 for more
         | 
| 5 | 
            +
            * Breaking change: Drop ruby 1.8 support
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## 0.6.1 (2013-02-18) -- yanked
         | 
| 8 | 
            +
            * Feature: Add the ability to access instance variables set in sinatra
         | 
| 9 | 
            +
              actions in bldr templates.
         | 
| 10 | 
            +
             | 
| 1 11 | 
             
            ## 0.6.0 (2012-xx-xx)
         | 
| 2 12 | 
             
            * Feature: Add the ability to pass-through objects directly to `object` and
         | 
| 3 13 | 
             
              `collection` DSL methods
         | 
| @@ -21,4 +31,4 @@ | |
| 21 31 | 
             
            * Add new `attribute` inferred object syntax (@ihunter)
         | 
| 22 32 |  | 
| 23 33 | 
             
            ## 0.1.2 (2011-09-08)
         | 
| 24 | 
            -
            * Return an empty collection when a nil value is passed to `collection` method
         | 
| 34 | 
            +
            * Return an empty collection when a nil value is passed to `collection` method
         | 
    
        data/MIT-LICENSE
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            [](https://travis-ci.org/ajsharp/bldr)
         | 
| 2 2 |  | 
| 3 3 |  | 
| 4 4 | 
             
            # Bldr
         | 
| @@ -52,6 +52,75 @@ end | |
| 52 52 |  | 
| 53 53 | 
             
            See the [Documentation & Examples](https://github.com/ajsharp/bldr/wiki/Documentation-&-Examples) page on the wiki.
         | 
| 54 54 |  | 
| 55 | 
            +
            ## Deprecations & Breaking Changes
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            ### 0.7.0: current_object deprecation
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            The use of `current_object` is now deprecated. Instead of referencing `current_object` in bldr templates
         | 
| 60 | 
            +
            use block variables in `object` and `collection` methods:
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            ```ruby
         | 
| 63 | 
            +
            # OLD (deprecated)
         | 
| 64 | 
            +
            collection :people => people do
         | 
| 65 | 
            +
              attribute(:name) { current_object.name }
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            # NEW
         | 
| 69 | 
            +
            collection :people => people do |person|
         | 
| 70 | 
            +
              attribute(:name) { person.name }
         | 
| 71 | 
            +
            end
         | 
| 72 | 
            +
            ```
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            Make use of block variables the same way for the `object` method:
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            ```ruby
         | 
| 77 | 
            +
            # OLD (deprecated)
         | 
| 78 | 
            +
            object :person => person do
         | 
| 79 | 
            +
              attributes :name, :age
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              person = current_object
         | 
| 82 | 
            +
              object :address => person.address do
         | 
| 83 | 
            +
                # current_object here would be assigned to person.address
         | 
| 84 | 
            +
                attribute(:zip) { current_object.zip_code }
         | 
| 85 | 
            +
                attribute(:address_title) { person.display_name }
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
            end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            # NEW
         | 
| 90 | 
            +
            object :person => person do |person|
         | 
| 91 | 
            +
              attributes :name, :age
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              object :adress => person.address do |address|
         | 
| 94 | 
            +
                attribute(:zip) { address.zip_code }
         | 
| 95 | 
            +
                attribute(:address_title) { person.display_name }
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
            end
         | 
| 98 | 
            +
            ```
         | 
| 99 | 
            +
             | 
| 100 | 
            +
            ### 0.7.0: attribute method breaking change
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            One of the forms of the `attribute` method has changed in the 0.7.0 release.
         | 
| 103 | 
            +
            Previously, using the dynamic block form of `attribute`, if you did not pass
         | 
| 104 | 
            +
            in a block variable, the block would be eval'd in context of the `current_object`.
         | 
| 105 | 
            +
            This behavior fails the "principle of least surprise" test.
         | 
| 106 | 
            +
             | 
| 107 | 
            +
            0.7.0 changes this behavior by simply executing the block in context of `Bldr::Node`, which provides
         | 
| 108 | 
            +
            access to instance variables and locals available in that context.
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            ```ruby
         | 
| 111 | 
            +
            # OLD
         | 
| 112 | 
            +
            object :person => person do
         | 
| 113 | 
            +
              attribute(:name) { display_name } # equivalent to doing attribute(:name) { |person| person.display_name }
         | 
| 114 | 
            +
            end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
            # NEW
         | 
| 117 | 
            +
            object :person => @person do
         | 
| 118 | 
            +
              attribute(:name) { @person.display_name }
         | 
| 119 | 
            +
            end
         | 
| 120 | 
            +
            ```
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            See [941608e](https://github.com/ajsharp/bldr/commit/d0bfbd8) and [d0bfbd8](https://github.com/ajsharp/bldr/commit/d0bfbd8) for more info.
         | 
| 123 | 
            +
             | 
| 55 124 | 
             
            ## Editor Syntax Support
         | 
| 56 125 |  | 
| 57 126 | 
             
            To get proper syntax highlighting in vim, add this line to your .vimrc:
         | 
| @@ -75,8 +144,9 @@ au BufRead,BufNewFile *.bldr set filetype=ruby | |
| 75 144 |  | 
| 76 145 | 
             
            * Ian Hunter (@ihunter)
         | 
| 77 146 | 
             
            * Justin Smestad (@jsmestad)
         | 
| 147 | 
            +
            * Adam LaFave (@lafave)
         | 
| 78 148 |  | 
| 79 149 | 
             
            ## Copyright
         | 
| 80 150 |  | 
| 81 | 
            -
            Copyright (c) 2011- | 
| 151 | 
            +
            Copyright (c) 2011-2013 Alex Sharp. See the MIT-LICENSE file for full
         | 
| 82 152 | 
             
            copyright information.
         | 
    
        data/bldr.gemspec
    CHANGED
    
    | @@ -22,8 +22,8 @@ Gem::Specification.new do |s| | |
| 22 22 | 
             
              s.add_dependency 'multi_json'
         | 
| 23 23 |  | 
| 24 24 | 
             
              s.add_development_dependency 'json_pure'
         | 
| 25 | 
            -
              s.add_development_dependency 'sinatra' | 
| 26 | 
            -
              s.add_development_dependency 'tilt' | 
| 25 | 
            +
              s.add_development_dependency 'sinatra'
         | 
| 26 | 
            +
              s.add_development_dependency 'tilt'
         | 
| 27 27 | 
             
              s.add_development_dependency 'yajl-ruby', '>= 1.0'
         | 
| 28 | 
            -
              s.add_development_dependency 'actionpack' | 
| 28 | 
            +
              s.add_development_dependency 'actionpack'
         | 
| 29 29 | 
             
            end
         | 
    
        data/lib/bldr/node.rb
    CHANGED
    
    | @@ -3,6 +3,8 @@ module Bldr | |
| 3 3 |  | 
| 4 4 | 
             
              class Node
         | 
| 5 5 |  | 
| 6 | 
            +
                PROTECTED_IVARS = [:@current_object, :@result, :@parent, :@opts, :@views, :@locals]
         | 
| 7 | 
            +
             | 
| 6 8 | 
             
                attr_reader :current_object, :result, :parent, :opts, :views, :locals
         | 
| 7 9 |  | 
| 8 10 | 
             
                # Initialize a new Node instance.
         | 
| @@ -17,6 +19,8 @@ module Bldr | |
| 17 19 | 
             
                #
         | 
| 18 20 | 
             
                #
         | 
| 19 21 | 
             
                # @param [Object] value an object to serialize.
         | 
| 22 | 
            +
                # @param [Hash] opts
         | 
| 23 | 
            +
                # @option [Object] opts :parent used to copy instance variables into self
         | 
| 20 24 | 
             
                def initialize(value = nil, opts = {}, &block)
         | 
| 21 25 | 
             
                  @current_object = value
         | 
| 22 26 | 
             
                  @opts           = opts
         | 
| @@ -24,11 +28,24 @@ module Bldr | |
| 24 28 | 
             
                  @views          = opts[:views]
         | 
| 25 29 | 
             
                  @locals         = opts[:locals]
         | 
| 26 30 | 
             
                  # Storage hash for all descendant nodes
         | 
| 27 | 
            -
                  @result | 
| 31 | 
            +
                  @result         = {}
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  copy_instance_variables_from(opts[:parent]) if opts[:parent]
         | 
| 28 34 |  | 
| 29 | 
            -
                   | 
| 35 | 
            +
                  if block_given?
         | 
| 36 | 
            +
                    if value && block.arity > 0
         | 
| 37 | 
            +
                      instance_exec(value, &block)
         | 
| 38 | 
            +
                    else
         | 
| 39 | 
            +
                      instance_eval(&block)
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                  end
         | 
| 30 42 | 
             
                end
         | 
| 31 | 
            -
             | 
| 43 | 
            +
             | 
| 44 | 
            +
                def current_object
         | 
| 45 | 
            +
                  warn "[DEPRECATION] `current_object` is deprecated. Please use object or collection block varibles instead."
         | 
| 46 | 
            +
                  @current_object
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 32 49 | 
             
                # Create and render a node.
         | 
| 33 50 | 
             
                #
         | 
| 34 51 | 
             
                # @example A keyed object
         | 
| @@ -182,15 +199,15 @@ module Bldr | |
| 182 199 | 
             
                #
         | 
| 183 200 | 
             
                # @return [Nil]
         | 
| 184 201 | 
             
                def attributes(*args, &block)
         | 
| 185 | 
            -
                  if current_object.nil?
         | 
| 202 | 
            +
                  if @current_object.nil?
         | 
| 186 203 | 
             
                    raise(ArgumentError, "No current_object to apply #attributes to.")
         | 
| 187 204 | 
             
                  end
         | 
| 188 205 |  | 
| 189 206 | 
             
                  args.each do |arg|
         | 
| 190 207 | 
             
                    if arg.is_a?(Hash)
         | 
| 191 | 
            -
                      merge_result!(arg.keys.first, current_object.send(arg.values.first))
         | 
| 208 | 
            +
                      merge_result!(arg.keys.first, @current_object.send(arg.values.first))
         | 
| 192 209 | 
             
                    else
         | 
| 193 | 
            -
                      merge_result!(arg, current_object.send(arg))
         | 
| 210 | 
            +
                      merge_result!(arg, @current_object.send(arg))
         | 
| 194 211 | 
             
                    end
         | 
| 195 212 | 
             
                  end
         | 
| 196 213 | 
             
                  self
         | 
| @@ -199,16 +216,20 @@ module Bldr | |
| 199 216 | 
             
                def attribute(*args,&block)
         | 
| 200 217 | 
             
                  if block_given?
         | 
| 201 218 | 
             
                    raise(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.") if args.size > 1
         | 
| 202 | 
            -
                    raise(ArgumentError, "You cannot use a block of arity > 0 if current_object is not present.") if block.arity > 0 and current_object.nil?
         | 
| 203 | 
            -
                     | 
| 219 | 
            +
                    raise(ArgumentError, "You cannot use a block of arity > 0 if current_object is not present.") if block.arity > 0 and @current_object.nil?
         | 
| 220 | 
            +
                    if block.arity > 0
         | 
| 221 | 
            +
                      merge_result! args.first, block.call(@current_object)
         | 
| 222 | 
            +
                    else
         | 
| 223 | 
            +
                      merge_result! args.first, block.call
         | 
| 224 | 
            +
                    end
         | 
| 204 225 | 
             
                  else
         | 
| 205 226 | 
             
                    case args.size
         | 
| 206 227 | 
             
                    when 1 # inferred object
         | 
| 207 | 
            -
                      raise(ArgumentError, "#attribute can't be used when there is no current_object.") if current_object.nil?
         | 
| 228 | 
            +
                      raise(ArgumentError, "#attribute can't be used when there is no current_object.") if @current_object.nil?
         | 
| 208 229 | 
             
                      if args[0].is_a?(Hash)
         | 
| 209 | 
            -
                        merge_result!(args[0].keys.first, current_object.send(args[0].values.first))
         | 
| 230 | 
            +
                        merge_result!(args[0].keys.first, @current_object.send(args[0].values.first))
         | 
| 210 231 | 
             
                      else
         | 
| 211 | 
            -
                        merge_result!(args[0], current_object.send(args[0]))
         | 
| 232 | 
            +
                        merge_result!(args[0], @current_object.send(args[0]))
         | 
| 212 233 | 
             
                      end
         | 
| 213 234 | 
             
                    when 2 # static property
         | 
| 214 235 | 
             
                      merge_result!(args[0], args[1])
         | 
| @@ -244,6 +265,17 @@ module Bldr | |
| 244 265 |  | 
| 245 266 | 
             
                private
         | 
| 246 267 |  | 
| 268 | 
            +
                # Retrieves all instance variables from an object and sets them in the
         | 
| 269 | 
            +
                #   current scope.
         | 
| 270 | 
            +
                #
         | 
| 271 | 
            +
                # @param [Object] object The object to copy instance variables from.
         | 
| 272 | 
            +
                def copy_instance_variables_from(object)
         | 
| 273 | 
            +
                  ivar_names = (object.instance_variables - PROTECTED_IVARS).map(&:to_s)
         | 
| 274 | 
            +
                  ivar_names.map do |name|
         | 
| 275 | 
            +
                    instance_variable_set(name, object.instance_variable_get(name))
         | 
| 276 | 
            +
                  end
         | 
| 277 | 
            +
                end
         | 
| 278 | 
            +
             | 
| 247 279 | 
             
                # Determines if an object was passed in with a key pointing to it, or if
         | 
| 248 280 | 
             
                # it was passed in as the "root" of the current object. Essentially, this
         | 
| 249 281 | 
             
                # checks if `obj` quacks like a hash.
         | 
    
        data/lib/bldr/template.rb
    CHANGED
    
    | @@ -2,6 +2,7 @@ require 'tilt' | |
| 2 2 |  | 
| 3 3 | 
             
            module Bldr
         | 
| 4 4 |  | 
| 5 | 
            +
              # This class is required for Tilt compatibility
         | 
| 5 6 | 
             
              class Template < Tilt::Template
         | 
| 6 7 |  | 
| 7 8 | 
             
                self.default_mime_type = 'application/json'
         | 
| @@ -14,6 +15,8 @@ module Bldr | |
| 14 15 | 
             
                  defined? ::Bldr
         | 
| 15 16 | 
             
                end
         | 
| 16 17 |  | 
| 18 | 
            +
                # Called at the end of Tilt::Template#initialize.
         | 
| 19 | 
            +
                # Use this method to access or mutate any state available to Tilt::Template
         | 
| 17 20 | 
             
                def prepare
         | 
| 18 21 | 
             
                  # We get NotImplementedError by Tilt when we don't have this method
         | 
| 19 22 | 
             
                end
         | 
    
        data/lib/bldr/version.rb
    CHANGED
    
    
    
        data/lib/sinatra/bldr.rb
    CHANGED
    
    | @@ -4,7 +4,6 @@ module Sinatra | |
| 4 4 |  | 
| 5 5 | 
             
              module Bldr
         | 
| 6 6 | 
             
                module Helpers
         | 
| 7 | 
            -
             | 
| 8 7 | 
             
                  # Wrapper for Tilt's `render` method
         | 
| 9 8 | 
             
                  #
         | 
| 10 9 | 
             
                  # We use this to properly set the scope the template gets rendered
         | 
| @@ -24,10 +23,13 @@ module Sinatra | |
| 24 23 | 
             
                  # @param [Hash] opts a hash of options
         | 
| 25 24 | 
             
                  # @option opts [Hash] :locals a hash of local variables to be used in the template
         | 
| 26 25 | 
             
                  def bldr(template, opts = {}, &block)
         | 
| 26 | 
            +
                    opts[:parent] = self
         | 
| 27 27 | 
             
                    opts[:scope] = ::Bldr::Node.new(nil, opts.merge(:views => (settings.views || "./views")))
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                     | 
| 28 | 
            +
             | 
| 29 | 
            +
                    locals = opts.delete(:locals) || {}
         | 
| 30 | 
            +
             | 
| 30 31 | 
             
                    # @todo add support for alternate formats, like plist
         | 
| 32 | 
            +
                    MultiJson.encode render(:bldr, template, opts, locals, &block).result
         | 
| 31 33 | 
             
                  end
         | 
| 32 34 | 
             
                end
         | 
| 33 35 |  | 
| @@ -1,75 +1,172 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
               | 
| 5 | 
            -
                 | 
| 3 | 
            +
            module Bldr
         | 
| 4 | 
            +
              describe 'local variable access' do
         | 
| 5 | 
            +
                it 'provides access to locals in nested object blocks' do
         | 
| 6 | 
            +
                  Template.new do
         | 
| 7 | 
            +
                      <<-RUBY
         | 
| 8 | 
            +
                        object :person => person do
         | 
| 9 | 
            +
                          attribute(:name) { person.name }
         | 
| 10 | 
            +
                          object :address => Object.new do |address|
         | 
| 11 | 
            +
                            attribute(:display_name) { person.name }
         | 
| 12 | 
            +
                          end
         | 
| 13 | 
            +
                        end
         | 
| 14 | 
            +
                      RUBY
         | 
| 15 | 
            +
                  end.render(Node.new(nil), {person: Person.new('alex')})
         | 
| 16 | 
            +
                  .result
         | 
| 17 | 
            +
                  .should == {:person => {:name => 'alex', :address => {:display_name => 'alex'}}}
         | 
| 18 | 
            +
                end
         | 
| 6 19 | 
             
              end
         | 
| 7 20 |  | 
| 8 | 
            -
               | 
| 9 | 
            -
                 | 
| 10 | 
            -
             | 
| 21 | 
            +
              describe "instance variables" do
         | 
| 22 | 
            +
                let(:ctx) { Object.new }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                describe "collection blocks" do
         | 
| 25 | 
            +
                  it 'has access to instance variables' do
         | 
| 26 | 
            +
                    ctx.instance_variable_set(:@person, Person.new("John Denver"))
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    Template.new do
         | 
| 29 | 
            +
                      <<-RUBY
         | 
| 30 | 
            +
                        collection :artists => [@person] do
         | 
| 31 | 
            +
                          attribute(:name) { @person.name }
         | 
| 32 | 
            +
                        end
         | 
| 33 | 
            +
                      RUBY
         | 
| 34 | 
            +
                    end.render(Node.new(nil, :parent => ctx))
         | 
| 35 | 
            +
                    .result
         | 
| 36 | 
            +
                    .should == {:artists => [{:name => 'John Denver'}]}
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it 'has access to instance variables in included template partials' do
         | 
| 41 | 
            +
                  ctx.instance_variable_set(:@person, Person.new('john denver'))
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  Template.new {
         | 
| 44 | 
            +
                    <<-RUBY
         | 
| 45 | 
            +
                     template('spec/fixtures/ivar.bldr')
         | 
| 46 | 
            +
                    RUBY
         | 
| 47 | 
            +
                  }.render(Node.new(nil, :parent => ctx))
         | 
| 48 | 
            +
                  .result
         | 
| 49 | 
            +
                  .should == {:person => {:name => 'john denver', :age => nil}}
         | 
| 50 | 
            +
                end
         | 
| 11 51 |  | 
| 12 | 
            -
                 | 
| 13 | 
            -
             | 
| 52 | 
            +
                it 'has access to ivars in attribute blocks with no arity' do
         | 
| 53 | 
            +
                  ctx.instance_variable_set(:@person, Person.new('john denver'))
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  Template.new {
         | 
| 56 | 
            +
                    <<-RUBY
         | 
| 57 | 
            +
                     object :person do
         | 
| 58 | 
            +
                       attribute(:name) { @person.name }
         | 
| 59 | 
            +
                     end
         | 
| 60 | 
            +
                    RUBY
         | 
| 61 | 
            +
                  }.render(Node.new(nil, :parent => ctx))
         | 
| 62 | 
            +
                  .result
         | 
| 63 | 
            +
                  .should == {:person => {:name => 'john denver'}}
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                it 'has access to ivars in attribute blocks with arity of 1' do
         | 
| 67 | 
            +
                  ctx.instance_variable_set(:@denver, Person.new('john denver'))
         | 
| 68 | 
            +
                  ctx.instance_variable_set(:@rich, Person.new('charlie rich'))
         | 
| 69 | 
            +
                  Template.new {
         | 
| 70 | 
            +
                    <<-RUBY
         | 
| 71 | 
            +
                     object :person => @denver do
         | 
| 72 | 
            +
                       attribute(:name) { |p| @rich.name }
         | 
| 73 | 
            +
                     end
         | 
| 74 | 
            +
                    RUBY
         | 
| 75 | 
            +
                  }.render(Node.new(nil, :parent => ctx))
         | 
| 76 | 
            +
                  .result
         | 
| 77 | 
            +
                  .should == {:person => {:name => 'charlie rich'}}
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                it 'has access to ivars in nested object blocks' do
         | 
| 81 | 
            +
                  ctx.instance_variable_set(:@batman, Person.new('batman'))
         | 
| 82 | 
            +
                  ctx.instance_variable_set(:@bane, Person.new('bane'))
         | 
| 83 | 
            +
                  Template.new {
         | 
| 84 | 
            +
                    <<-RUBY
         | 
| 85 | 
            +
                     object :hero => @batman do
         | 
| 86 | 
            +
                       attribute(:name) { @batman.name }
         | 
| 87 | 
            +
                       object :nemesis do
         | 
| 88 | 
            +
                         attribute(:name) { @bane.name }
         | 
| 89 | 
            +
                         attribute(:nemesis_name) { @batman.name }
         | 
| 90 | 
            +
                       end
         | 
| 91 | 
            +
                     end
         | 
| 92 | 
            +
                    RUBY
         | 
| 93 | 
            +
                  }.render(Node.new(nil, :parent => ctx))
         | 
| 94 | 
            +
                  .result
         | 
| 95 | 
            +
                  .should == {hero: {name: 'batman', nemesis: {name: 'bane', nemesis_name: 'batman'}}}
         | 
| 96 | 
            +
                end
         | 
| 14 97 | 
             
              end
         | 
| 15 98 |  | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 99 | 
            +
             | 
| 100 | 
            +
              describe "evaluating a tilt template" do
         | 
| 101 | 
            +
                it "registers with Tilt" do
         | 
| 102 | 
            +
                  Tilt['test.bldr'].should == Bldr::Template
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                it "renders a template" do
         | 
| 106 | 
            +
                  alex = Person.new
         | 
| 107 | 
            +
                  alex.name = 'alex'
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  tpl = Bldr::Template.new { "object(:person => alex) { attribute(:name) }" }
         | 
| 110 | 
            +
                  tpl.render(Bldr::Node.new, :alex => alex).result.should == {:person => {:name => 'alex'}}
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                it "allows attribute to be used at the root-level" do
         | 
| 114 | 
            +
                  tpl = Bldr::Template.new {
         | 
| 18 115 | 
             
                  <<-RUBY
         | 
| 19 116 | 
             
                    attribute(:foo) { "bar" }
         | 
| 20 117 | 
             
                  RUBY
         | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 118 | 
            +
                  }
         | 
| 119 | 
            +
                  tpl.render(Bldr::Node.new(nil)).result.should == {:foo => 'bar'}
         | 
| 120 | 
            +
                end
         | 
| 24 121 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 122 | 
            +
                it "works when render two top-level objects" do
         | 
| 123 | 
            +
                  alex = Person.new('alex')
         | 
| 124 | 
            +
                  john = Person.new('john')
         | 
| 28 125 |  | 
| 29 | 
            -
             | 
| 126 | 
            +
                  tpl = Bldr::Template.new {
         | 
| 30 127 | 
             
                  <<-RUBY
         | 
| 31 128 | 
             
                    object(:person_1 => alex) { attribute(:name) }
         | 
| 32 129 | 
             
                    object(:person_2 => john) { attribute(:name) }
         | 
| 33 130 | 
             
                  RUBY
         | 
| 34 | 
            -
             | 
| 131 | 
            +
                  }
         | 
| 35 132 |  | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 133 | 
            +
                  result = tpl.render(Bldr::Node.new, :alex => alex, :john => john).result
         | 
| 134 | 
            +
                  result.should == {
         | 
| 135 | 
            +
                                    :person_1 => {:name => 'alex'},
         | 
| 136 | 
            +
                                    :person_2 => {:name => 'john'}
         | 
| 137 | 
            +
                                   }
         | 
| 138 | 
            +
                end
         | 
| 42 139 |  | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 140 | 
            +
                it "renders nil -> null correctly" do
         | 
| 141 | 
            +
                  alex = Person.new('alex')
         | 
| 142 | 
            +
                  tpl = Bldr::Template.new {
         | 
| 46 143 | 
             
                  <<-RUBY
         | 
| 47 144 | 
             
                    object(:person_1 => alex) { attributes(:age) }
         | 
| 48 145 | 
             
                  RUBY
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 146 | 
            +
                  }
         | 
| 147 | 
            +
                  result = tpl.render(Bldr::Node.new, :alex => alex).result
         | 
| 148 | 
            +
                  result.should == {:person_1 => {:age => nil}}
         | 
| 149 | 
            +
                end
         | 
| 53 150 |  | 
| 54 | 
            -
             | 
| 151 | 
            +
                describe "root Object nodes" do
         | 
| 55 152 |  | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 153 | 
            +
                  let(:alex) { Person.new('alex', 25) }
         | 
| 154 | 
            +
                  let(:ian) { Person.new('ian', 32) }
         | 
| 58 155 |  | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 156 | 
            +
                  it "returns json for a root object" do
         | 
| 157 | 
            +
                    tpl = Bldr::Template.new {
         | 
| 61 158 | 
             
                    <<-RUBY
         | 
| 62 159 | 
             
                      object :person => alex do
         | 
| 63 160 | 
             
                        attributes :name, :age
         | 
| 64 161 | 
             
                      end
         | 
| 65 162 | 
             
                    RUBY
         | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 163 | 
            +
                    }
         | 
| 164 | 
            +
                    result = tpl.render(Bldr::Node.new, :alex => alex, :ian => ian).result
         | 
| 165 | 
            +
                    result.should == {:person => {:name => 'alex', :age => 25}}
         | 
| 166 | 
            +
                  end
         | 
| 70 167 |  | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 168 | 
            +
                  it "returns json for root object templates with nested collections" do
         | 
| 169 | 
            +
                    tpl = Bldr::Template.new {
         | 
| 73 170 | 
             
                    <<-RUBY
         | 
| 74 171 | 
             
                      object :person => alex do
         | 
| 75 172 | 
             
                        attributes :name, :age
         | 
| @@ -79,78 +176,79 @@ describe "evaluating a tilt template" do | |
| 79 176 | 
             
                        end
         | 
| 80 177 | 
             
                      end
         | 
| 81 178 | 
             
                    RUBY
         | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 179 | 
            +
                    }
         | 
| 180 | 
            +
                    result = tpl.render(Bldr::Node.new, :alex => alex, :friends => [ian]).result
         | 
| 181 | 
            +
                    result.should == {
         | 
| 182 | 
            +
                                      :person=> {:name => 'alex', :age => 25, :friends => [{:name => 'ian', :age => 32}]}
         | 
| 183 | 
            +
                                     }
         | 
| 184 | 
            +
                  end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                  it "renders nil -> null correctly" do
         | 
| 187 | 
            +
                    alex = Person.new('alex')
         | 
| 188 | 
            +
                    tpl = Bldr::Template.new {
         | 
| 92 189 | 
             
                    <<-RUBY
         | 
| 93 190 | 
             
                      object :person_1 => alex do
         | 
| 94 191 | 
             
                        attributes(:age)
         | 
| 95 192 | 
             
                      end
         | 
| 96 193 | 
             
                    RUBY
         | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 194 | 
            +
                    }
         | 
| 195 | 
            +
                    result = tpl.render(Bldr::Node.new, :alex => alex).result
         | 
| 196 | 
            +
                    result.should == {:person_1 => {:age => nil}}
         | 
| 197 | 
            +
                  end
         | 
| 101 198 |  | 
| 102 | 
            -
             | 
| 199 | 
            +
                end
         | 
| 103 200 |  | 
| 104 | 
            -
             | 
| 201 | 
            +
                describe "root Collection nodes" do
         | 
| 105 202 |  | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 203 | 
            +
                  let(:alex) { Person.new('alex', 25, [Person.new('bo',33)]) }
         | 
| 204 | 
            +
                  let(:ian) { Person.new('ian', 32, [Person.new('eric',34)]) }
         | 
| 108 205 |  | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 206 | 
            +
                  it "returns json for a root collection template" do
         | 
| 207 | 
            +
                    tpl = Bldr::Template.new {
         | 
| 111 208 | 
             
                    <<-RUBY
         | 
| 112 209 | 
             
                      collection :people => people do
         | 
| 113 210 | 
             
                        attributes :name, :age
         | 
| 114 211 | 
             
                      end
         | 
| 115 212 | 
             
                    RUBY
         | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 213 | 
            +
                    }
         | 
| 214 | 
            +
                    result = tpl.render(Bldr::Node.new, :people => [alex,ian]).result
         | 
| 215 | 
            +
                    result.should == {
         | 
| 216 | 
            +
                                      :people => [{:name => 'alex', :age => 25}, {:name => 'ian', :age => 32}]
         | 
| 217 | 
            +
                                     }
         | 
| 218 | 
            +
                  end
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                  it "returns json for a root collection with embedded collection template" do
         | 
| 221 | 
            +
                    tpl = Bldr::Template.new {
         | 
| 125 222 | 
             
                    <<-RUBY
         | 
| 126 | 
            -
                      collection :people => people do
         | 
| 223 | 
            +
                      collection :people => people do |person|
         | 
| 127 224 | 
             
                        attributes :name, :age
         | 
| 128 | 
            -
                        collection :friends =>  | 
| 225 | 
            +
                        collection :friends => person.friends do
         | 
| 129 226 | 
             
                          attributes :name, :age
         | 
| 130 227 | 
             
                        end
         | 
| 131 228 | 
             
                      end
         | 
| 132 229 | 
             
                    RUBY
         | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 230 | 
            +
                    }
         | 
| 231 | 
            +
                    result = tpl.render(Bldr::Node.new, :people => [alex,ian]).result
         | 
| 232 | 
            +
                    result.should == {
         | 
| 233 | 
            +
                                      :people=> [{
         | 
| 234 | 
            +
                                                  :name => 'alex',
         | 
| 235 | 
            +
                                                  :age => 25,
         | 
| 236 | 
            +
                                                  :friends => [{:name => 'bo', :age => 33}]
         | 
| 237 | 
            +
                                                 },{
         | 
| 238 | 
            +
                                                    :name => 'ian',
         | 
| 239 | 
            +
                                                    :age => 32,
         | 
| 240 | 
            +
                                                    :friends => [{:name => 'eric', :age => 34}]
         | 
| 241 | 
            +
                                                   }]
         | 
| 242 | 
            +
                                     }
         | 
| 243 | 
            +
                  end
         | 
| 147 244 |  | 
| 245 | 
            +
                end
         | 
| 148 246 | 
             
              end
         | 
| 149 | 
            -
            end
         | 
| 150 247 |  | 
| 151 | 
            -
            describe "using a partial template at the root of another template" do
         | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 248 | 
            +
              describe "using a partial template at the root of another template" do
         | 
| 249 | 
            +
                it "works as expected" do
         | 
| 250 | 
            +
                  template = Bldr::Template.new('./spec/fixtures/root_partial.bldr')
         | 
| 251 | 
            +
                  template.render(Bldr::Node.new(nil, :views => './spec')).result.should == {:foo => 'bar'}
         | 
| 252 | 
            +
                end
         | 
| 155 253 | 
             
              end
         | 
| 156 | 
            -
            end
         | 
| 254 | 
            +
            end
         |