bldr 0.7.0 → 1.0.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/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  .rspec
2
2
  Gemfile.lock
3
3
  pkg
4
+ /log
5
+ coverage
data/Gemfile CHANGED
@@ -1,10 +1,12 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'coveralls', require: false
5
6
  gem "rake"
6
7
 
7
8
  group :test do
9
+ gem 'rails', '~>3.2'
8
10
  gem "rspec", ">= 2.6.0"
9
11
  gem 'debugger', :platform => :mri_19
10
12
  end
data/HISTORY.md CHANGED
@@ -1,7 +1,8 @@
1
- ## 0.7.0 (2013-xx-xx)
2
- * Support for inherited instance variables
1
+ ## 0.7.0 (2013-02-24)
2
+ * Full support for instance variables
3
3
  * Breaking change: Node#attribute block syntax no longer inherits
4
4
  context from current_object. See 941608e7 for more
5
+ * Block variables for `object` and `collection` methods
5
6
  * Breaking change: Drop ruby 1.8 support
6
7
 
7
8
  ## 0.6.1 (2013-02-18) -- yanked
data/README.md CHANGED
@@ -3,11 +3,67 @@
3
3
 
4
4
  # Bldr
5
5
 
6
- Bldr is a minimalist templating library that provides a simple DSL for generating
7
- json documents from ruby objects. It currently supports Sinatra out of
8
- the box -- Rails 3 support is planned for the near future.
6
+ Bldr is a minimalist templating DSL that provides a simple syntax for generating
7
+ json documents from ruby objects. Bldr supports Sinatra and Rails
8
+ 3.2.
9
9
 
10
- If you would like to contribute, pull requests with specs are warmly accepted :)
10
+ Bldr enables to quickly generate json documents from ruby with a
11
+ simple and intuitive DSL.
12
+
13
+ ```ruby
14
+ # app/views/posts/index.json.bldr
15
+
16
+ collection @posts do |post|
17
+ attributes :title, :body, :created_at, :slug
18
+
19
+ object :author => post.author do |author|
20
+ attribute(:name) { author.display_name }
21
+ end
22
+
23
+ collection :comments => post.comments do |comment|
24
+ attribute :spamminess
25
+ attribute :created_at
26
+ attribute(:body) do
27
+ xss_filter(comment.body)
28
+ end
29
+ end
30
+ end
31
+ ```
32
+
33
+ This would output the following json document:
34
+
35
+ ```json
36
+ [
37
+ {
38
+ "title": "Some title",
39
+ "body": "blah blah",
40
+ "slug": "some-title",
41
+ "created_at": "2013-04-11T15:46:17-07:00",
42
+ "author": {
43
+ "name": "Joe Author"
44
+ },
45
+ "comments": [
46
+ {
47
+ "spamminess": 1.0,
48
+ "created_at": "2013-04-11T15:46:17-07:00",
49
+ "body": "a comment"
50
+ }
51
+ ]
52
+ }
53
+ ]
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ Bldr is a very concise DSL, containing only four core methods:
59
+
60
+ * `object`
61
+ * `collection`
62
+ * `attribute`
63
+ * `attributes`
64
+
65
+ These four methods provide a great deal of power and flexibility in describing
66
+ json responses.
11
67
 
12
68
  ## Why
13
69
 
@@ -15,18 +71,29 @@ If you're building an API, `Model#to_json` just doesn't cut it. Besides the JSON
15
71
  representation of your models arguably being a presentation concern, trying
16
72
  to cram all of this logic into an `#as_json` method quickly turns into pure chaos.
17
73
 
18
- There are other json templating libraries available -- [rabl](http://github.com/nesquena/rabl) being the most popular -- but I wasn't satisfied with any of the DSL's, so I created Bldr.
74
+ There are other json templating libraries available such as
75
+ [rabl](https://github.com/nesquena/rabl) or [json_builder](https://github.com/dewski/json_builder).
76
+ Bldr is in the same vein as these libraries, but with a simpler synxtax.
19
77
 
20
- ## Features
78
+ ## Usage & Examples
21
79
 
22
- * Simple json templating DSL
23
- * Uses Tilt's built-in rendering and template caching for better performance
24
- * Partials
80
+ See [Examples on the wiki](https://github.com/ajsharp/bldr/wiki/Documentation-&-Examples)
81
+ for documentation and usage examples.
25
82
 
26
83
  ## Installation
27
84
 
28
- There are two ways to use Bldr in your Sinatra app, depending on whether
29
- you are using Sinatra's classic or module application style:
85
+ In your gemfile:
86
+
87
+ ```ruby
88
+ gem 'bldr'
89
+ ```
90
+
91
+ ## Configuration
92
+
93
+ No additional configuration is required for rails applications.
94
+
95
+ For sinatra apps, dependening on whether you're using a modular or classic
96
+ application style, do one of the following:
30
97
 
31
98
  ```ruby
32
99
 
@@ -48,10 +115,6 @@ class MyApp < Sinatra::Base
48
115
  end
49
116
  ```
50
117
 
51
- ## Usage
52
-
53
- See the [Documentation & Examples](https://github.com/ajsharp/bldr/wiki/Documentation-&-Examples) page on the wiki.
54
-
55
118
  ## Deprecations & Breaking Changes
56
119
 
57
120
  ### 0.7.0: current_object deprecation
@@ -123,16 +186,24 @@ See [941608e](https://github.com/ajsharp/bldr/commit/d0bfbd8) and [d0bfbd8](http
123
186
 
124
187
  ## Editor Syntax Support
125
188
 
126
- To get proper syntax highlighting in vim, add this line to your .vimrc:
189
+ ### Vim
190
+
191
+ Add this line to your .vimrc:
127
192
 
128
193
  ```
129
194
  au BufRead,BufNewFile *.bldr set filetype=ruby
130
195
  ```
131
196
 
197
+ ### Emacs
198
+
199
+ Add this to your `~/.emacs.d/init.el`:
200
+
201
+ ```
202
+ (add-to-list 'auto-mode-alist '("\\.bldr$" . ruby-mode))
203
+ ```
204
+
132
205
  ## TODO
133
206
 
134
- * Rails 3 support. An attempt for this was made for this but was reverted in e1cfd7fcbe130b316d95773d8c73ece4e247200e. Feel free to take a shot.
135
- * Replace current_object with a block param for collection methods
136
207
  * XML support
137
208
 
138
209
  ## Acknowledgements
@@ -0,0 +1,24 @@
1
+ module ActionView::Template::Handlers
2
+ class Bldr
3
+
4
+ # @param [ActionView::Template] template the template instance
5
+ # @return [String] the rendered ruby code string to render the template
6
+ def self.call(template, opts = {})
7
+ source = if template.source.empty?
8
+ File.read(template.identifier)
9
+ else
10
+ template.source
11
+ end
12
+
13
+ %{
14
+ node = ::Bldr::Node.new(nil, parent: self, root: true) {
15
+ #{source}
16
+ }
17
+ MultiJson.encode node.result
18
+ }
19
+ end
20
+
21
+ end
22
+ end
23
+
24
+ ActionView::Template.register_template_handler :bldr, ActionView::Template::Handlers::Bldr
@@ -5,6 +5,7 @@ end
5
5
 
6
6
  require 'multi_json'
7
7
  require 'bldr/node'
8
+ require 'bldr/railtie' if defined?(Rails)
8
9
 
9
10
  if defined?(Tilt)
10
11
  require 'bldr/template'
@@ -1,12 +1,22 @@
1
+ require 'forwardable'
1
2
 
2
3
  module Bldr
3
4
 
4
5
  class Node
6
+ extend Forwardable
5
7
 
8
+ # These do not get copied into child nodes. All other instance variables do.
6
9
  PROTECTED_IVARS = [:@current_object, :@result, :@parent, :@opts, :@views, :@locals]
7
10
 
11
+ # List of bldr public api method. So we don't overwrite them when we do
12
+ # crazy ruby metaprogramming when we build nodes.
13
+ API_METHODS = [:object, :collection, :attribute, :attributes]
14
+
8
15
  attr_reader :current_object, :result, :parent, :opts, :views, :locals
9
16
 
17
+ # @!attribute [r] request params from a rails or sinatra controller
18
+ attr_reader :params
19
+
10
20
  # Initialize a new Node instance.
11
21
  #
12
22
  # @example Building a simple node
@@ -20,6 +30,9 @@ module Bldr
20
30
  #
21
31
  # @param [Object] value an object to serialize.
22
32
  # @param [Hash] opts
33
+ # @option opts [Object] :parent The parent object is used to copy instance variables
34
+ # into each node in the node tree.
35
+ # @option opts [Boolean] :root indicates whether this is the root node or not
23
36
  # @option [Object] opts :parent used to copy instance variables into self
24
37
  def initialize(value = nil, opts = {}, &block)
25
38
  @current_object = value
@@ -27,10 +40,27 @@ module Bldr
27
40
  @parent = opts[:parent]
28
41
  @views = opts[:views]
29
42
  @locals = opts[:locals]
30
- # Storage hash for all descendant nodes
31
- @result = {}
43
+ @result = {} # Storage hash for all descendant nodes
32
44
 
33
- copy_instance_variables_from(opts[:parent]) if opts[:parent]
45
+ # opts[:parent] will only get set to an ActionView::Base instance
46
+ # when rails renders a bldr template. This logic doesn't belong here,
47
+ # and there's a concept to be extracted here.
48
+ #
49
+ # The upshot of initializing the root node like this is that all child
50
+ # nodes will have access to rails helper methods. This is necessary
51
+ # due to the way bldr makes judicious use of instance_eval.
52
+ #
53
+ # @todo refactor this
54
+ if opts[:root] && @parent
55
+ # assign @parent to @view so it will be copied down to each child nod
56
+ # @parent is in PROTECTED_IVARS and won't be copied. This effectively
57
+ # gives all child nodes access to helper methods passed into the parent
58
+ @view = @parent
59
+ end
60
+
61
+ copy_instance_variables(@parent) if @parent
62
+ delegate_helpers if @view
63
+ assign_params if @parent
34
64
 
35
65
  if block_given?
36
66
  if value && block.arity > 0
@@ -94,12 +124,11 @@ module Bldr
94
124
  value = nil
95
125
  end
96
126
 
97
- # Short circuit here if the object passed in pointed
98
- # at a nil value. There's some debate about how this
99
- # should behave by default -- should it build the keyspace,
100
- # pointing a null value, or should it leave the key out.
101
- # With this implementation, it leaves the keyspace out.
102
- return nil if value.nil? and keyed_object?(base)
127
+ # handle nil objects
128
+ if value.nil? && keyed_object?(base)
129
+ merge_result!(key, nil)
130
+ return self
131
+ end
103
132
 
104
133
  node = Node.new(value, opts.merge(:parent => self), &block)
105
134
  merge_result!(key, node.result)
@@ -160,7 +189,7 @@ module Bldr
160
189
  else
161
190
  @result = massage_value(vals)
162
191
  end
163
-
192
+
164
193
  self
165
194
  end
166
195
 
@@ -173,28 +202,7 @@ module Bldr
173
202
  #
174
203
  # @example Attribute aliasing
175
204
  # object :person => dude do
176
- # attributes :surname => :last_name
177
- # end
178
- #
179
- # @example Dynamic attributes (explicit object context)
180
- # object :person => employee do
181
- # collection :colleagues => employee.colleagues do |colleague|
182
- # attribute :isBoss do |colleague|
183
- # employee.works_with?(colleague) && colleague.admin?
184
- # end
185
- # end
186
- # end
187
- #
188
- # @example Dynamic attributes (implicit object context)
189
- # object :person => dude do
190
- # collection :colleagues => employee.colleagues do |colleague|
191
- # attribute :rank do
192
- # # method called on colleague
193
- # if admin? && superior_to?(employee)
194
- # "High Up"
195
- # end
196
- # end
197
- # end
205
+ # attributes :surname => :last_name # invokes dude.last_name
198
206
  # end
199
207
  #
200
208
  # @return [Nil]
@@ -213,25 +221,61 @@ module Bldr
213
221
  self
214
222
  end
215
223
 
216
- def attribute(*args,&block)
224
+ # @example Dynamic attributes
225
+ # object :person => employee do
226
+ # collection :colleagues => employee.colleagues do |colleague|
227
+ # attribute :isBoss do
228
+ # employee.works_with?(colleague) && colleague.admin?
229
+ # end
230
+ # end
231
+ # end
232
+ #
233
+ def attribute(*args, &block)
217
234
  if block_given?
218
- raise(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.") if args.size > 1
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?
235
+ # e.g. attribute(:one, :two) { "value" }
236
+ if args.size > 1
237
+ raise(ArgumentError, "You may only pass one argument to #attribute when using the block syntax.")
238
+ end
239
+
240
+ # e.g.
241
+ # object do
242
+ # attribute { 'value' }
243
+ # end
244
+ if block.arity > 0 && @current_object.nil?
245
+ raise(ArgumentError, "You cannot use a block of arity > 0 if current_object is not present.")
246
+ end
247
+
220
248
  if block.arity > 0
249
+ # object(person: @person) do
250
+ # attribute(:name) { |person| person.name }
251
+ # end
221
252
  merge_result! args.first, block.call(@current_object)
222
253
  else
254
+ # object(person: @person) do
255
+ # attribute(:name) # i.e. @person.name
256
+ # end
223
257
  merge_result! args.first, block.call
224
258
  end
225
259
  else
226
260
  case args.size
227
- when 1 # inferred object
261
+ when 1
262
+ # object do
263
+ # attribute(:name)
264
+ # end
228
265
  raise(ArgumentError, "#attribute can't be used when there is no current_object.") if @current_object.nil?
229
266
  if args[0].is_a?(Hash)
267
+ # object(person: @person) do
268
+ # attribute :key => :display_name # i.e. @person.display_name
269
+ # end
230
270
  merge_result!(args[0].keys.first, @current_object.send(args[0].values.first))
231
271
  else
272
+ # object(person: @person) do
273
+ # attribute :name
274
+ # end
232
275
  merge_result!(args[0], @current_object.send(args[0]))
233
276
  end
234
- when 2 # static property
277
+ when 2
278
+ # attribute :name, @person.name
235
279
  merge_result!(args[0], args[1])
236
280
  else
237
281
  raise(ArgumentError, "You cannot pass more than two arguments to #attribute.")
@@ -246,7 +290,7 @@ module Bldr
246
290
  # object :person => dude do
247
291
  # template "path/to/template"
248
292
  # end
249
- #
293
+ #
250
294
  # @example Using locals
251
295
  # object :person => dude do
252
296
  # template "path/to/template", :locals => {:foo => 'bar'}
@@ -269,13 +313,32 @@ module Bldr
269
313
  # current scope.
270
314
  #
271
315
  # @param [Object] object The object to copy instance variables from.
272
- def copy_instance_variables_from(object)
316
+ def copy_instance_variables(object)
273
317
  ivar_names = (object.instance_variables - PROTECTED_IVARS).map(&:to_s)
274
318
  ivar_names.map do |name|
275
319
  instance_variable_set(name, object.instance_variable_get(name))
276
320
  end
277
321
  end
278
322
 
323
+ # Delegate helper methods on the @view to @view
324
+ def delegate_helpers
325
+ # ActionView::Base instances carry a method called helpers,
326
+ # which is a module that contains helper methods available in a rails
327
+ # controller.
328
+ @_helpers = @view.helpers if @view.respond_to?(:helpers)
329
+
330
+ # Delegate all helper methods, minus those with the same name as any
331
+ # bldr api methods to @view via this object's metaclass
332
+ if @_helpers
333
+ (class << self; self; end).def_delegators :@view, *(@_helpers.instance_methods - API_METHODS)
334
+ end
335
+ end
336
+
337
+ # Assigns the params attribute from the parent.
338
+ def assign_params
339
+ @params = @parent.params if @parent.respond_to?(:params)
340
+ end
341
+
279
342
  # Determines if an object was passed in with a key pointing to it, or if
280
343
  # it was passed in as the "root" of the current object. Essentially, this
281
344
  # checks if `obj` quacks like a hash.
@@ -285,7 +348,7 @@ module Bldr
285
348
  def keyed_object?(obj)
286
349
  obj.respond_to?(:keys)
287
350
  end
288
-
351
+
289
352
  def find_template(template)
290
353
  path = []
291
354
  path << views if views
@@ -312,6 +375,6 @@ module Bldr
312
375
  val
313
376
  end
314
377
  end
315
-
378
+
316
379
  end
317
380
  end
@@ -0,0 +1,9 @@
1
+ module Bldr
2
+ class Railtie < Rails::Railtie
3
+ initializer 'bldr.initialize' do |app|
4
+ ActiveSupport.on_load(:action_view) do
5
+ require 'action_view/template/handlers/bldr'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Bldr
3
- VERSION = '0.7.0'
3
+ VERSION = '1.0.0'
4
4
  end
@@ -0,0 +1,4 @@
1
+
2
+ collection @people do
3
+ attribute :name
4
+ end
@@ -0,0 +1,7 @@
1
+
2
+ attribute(:id) { params[:id] }
3
+ attribute(:name) { @person.name }
4
+
5
+ if params[:use_boss_helper]
6
+ attribute(:boss) { boss?(@person) }
7
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ module Bldr
4
+ describe Node, 'delegating helper methods' do
5
+ before do
6
+ # mock version of a module of methods that would be attached
7
+ # to an ActionView::Base instance
8
+ helpers = Module.new do
9
+ def my_helper
10
+ 'my helper'
11
+ end
12
+
13
+ def helper_with_args_and_block(one, two)
14
+ yield if block_given?
15
+ end
16
+ end
17
+
18
+ # set up a mock ActionView::Base instance
19
+ mock_action_view = Struct.new(:helpers)
20
+ @view = mock_action_view.new(helpers)
21
+ @view.extend(helpers)
22
+
23
+ @node = Node.new(nil, root: true, parent: @view)
24
+ end
25
+
26
+ it 'delegates the methods to the parent object' do
27
+ @view.should_receive(:my_helper)
28
+ @node.my_helper
29
+ end
30
+
31
+ it 'gives access to helper methods to child nodes' do
32
+ node = Node.new(nil, root: true, parent: @view) do
33
+ object(:foo => Object.new) do
34
+ attribute(:bar) { my_helper }
35
+ end
36
+ end
37
+ node.result.should == {foo: {bar: 'my helper'}}
38
+ end
39
+
40
+ it 'assigns opts[:parent] as a @view instance variable' do
41
+ @node.instance_variable_get(:@view).should == @view
42
+ end
43
+
44
+ it 'delegates arguments and blocks to the parent' do
45
+ lam = lambda { }
46
+ @view.should_receive(:helper_with_args_and_block).with(1, 2, lam)
47
+ @node.helper_with_args_and_block(1, 2, lam)
48
+ end
49
+
50
+ it 'defines helper methods on a per-instance basis' do
51
+ @node.methods.should include :my_helper
52
+
53
+ new_parent = Struct.new(nil).new
54
+ Node.new(nil, root: true, parent: new_parent).methods.should_not include :my_helper
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Bldr
4
+ describe Node, 'access to the params hash' do
5
+ let(:params) { {foo: 'bar'} }
6
+ let(:parent) { Struct.new(:params).new(params) }
7
+
8
+ it 'has access in the root node' do
9
+ Node.new(nil, parent: parent) do
10
+ attribute(:foo) { params[:foo] }
11
+ end.result.should == {
12
+ foo: 'bar'
13
+ }
14
+ end
15
+
16
+ it 'has access in child nodes' do
17
+ Node.new(nil, parent: parent) do
18
+ object(:foo) do
19
+ attribute(:baz) { params[:foo] }
20
+ end
21
+ end.result.should == {
22
+ foo: {baz: 'bar'}
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+ require 'rails'
3
+ require 'action_controller/railtie'
4
+ require 'bldr/railtie'
5
+
6
+ describe 'a template for a rails controller' do
7
+ TestRailsApp = Class.new(Rails::Application) do
8
+ routes.append do
9
+ resources :people
10
+ end
11
+
12
+ config.secret_token = "secret"
13
+ config.session_store = :disabled
14
+ config.active_support.deprecation = nil
15
+ config.middleware.delete 'ActionDispatch::Session::CookieStore'
16
+ end
17
+
18
+ class PeopleController < ActionController::Base
19
+ helper_method :boss?
20
+
21
+ # GET /people
22
+ def index
23
+ @people = [Person.new('Dave Chappelle'), Person.new('Chris Rock')]
24
+ render 'spec/fixtures/templates/rails/people/index', handlers: [:bldr], formats: [:json]
25
+ end
26
+
27
+ # GET /people/:id
28
+ def show
29
+ @person = Person.new('Dave Chappelle')
30
+ render 'spec/fixtures/templates/rails/people/show', handlers: [:bldr], formats: [:json]
31
+ end
32
+
33
+ private
34
+ def boss?(person)
35
+ person.name == 'Dave Chappelle'
36
+ end
37
+ end
38
+
39
+ TestRailsApp.initialize!
40
+
41
+ def app
42
+ TestRailsApp.app
43
+ end
44
+
45
+ def get(url)
46
+ Rack::MockRequest.new(app).get(url)
47
+ end
48
+
49
+ def decode(d)
50
+ MultiJson.decode(d)
51
+ end
52
+
53
+ it 'returns 200' do
54
+ get('/people').status.should == 200
55
+ end
56
+
57
+ it 'returns a json response body' do
58
+ decode(get('/people').body).should == [
59
+ {'name' => 'Dave Chappelle'},
60
+ {'name' => 'Chris Rock'}
61
+ ]
62
+ end
63
+
64
+ it 'returns json content type' do
65
+ get('/people').content_type.should =~ %r{application/json}
66
+ end
67
+
68
+ it 'has access to controller helper methods' do
69
+ response = get('/people/123?use_boss_helper=true')
70
+ response.status.should == 200
71
+ decode(response.body).should == {
72
+ 'id' => '123',
73
+ 'name' => 'Dave Chappelle',
74
+ 'boss' => true
75
+ }
76
+ end
77
+
78
+ it 'has access to params' do
79
+ decode(get('/people/123').body).should == {
80
+ 'id' => '123',
81
+ 'name' => 'Dave Chappelle'
82
+ }
83
+ end
84
+ end
@@ -11,6 +11,19 @@ describe "Using Bldr with a sinatra app" do
11
11
  disable :show_exceptions
12
12
  enable :raise_errors
13
13
 
14
+ get '/people/:id' do
15
+ @alex = Person.new("alex", 25)
16
+
17
+ tpl = %{
18
+ object(:person => @alex) do
19
+ attribute(:id) { params['id'] }
20
+ attribute :name
21
+ end
22
+ }
23
+ status 200
24
+ bldr tpl
25
+ end
26
+
14
27
  get '/' do
15
28
  alex = Person.new("alex", 25)
16
29
  tpl = <<-RUBY
@@ -67,6 +80,13 @@ describe "Using Bldr with a sinatra app" do
67
80
  end
68
81
  end
69
82
 
83
+ it 'has access to the params hash in bldr templates' do
84
+ response = Rack::MockRequest.new(TestApp).get('/people/123')
85
+ decode(response.body).should == {
86
+ 'person' => { 'id' => '123', 'name' => 'alex'}
87
+ }
88
+ end
89
+
70
90
  it 'passes ivars through to the template' do
71
91
  response = Rack::MockRequest.new(TestApp).get('/ivar')
72
92
  decode(response.body).should == {'person' => {'name' => 'bert', 'age' => 99}}
@@ -1,4 +1,10 @@
1
1
  require 'rubygems'
2
+
3
+ if ENV['TRAVIS']
4
+ require 'coveralls'
5
+ Coveralls.wear!
6
+ end
7
+
2
8
  require 'rspec'
3
9
 
4
10
  require 'yajl'
@@ -163,6 +163,19 @@ module Bldr
163
163
  end
164
164
 
165
165
  describe Node, "#object" do
166
+ it 'renders the object structure for a nil object' do
167
+ node = Node.new do
168
+ object :person => nil do
169
+ attributes :name
170
+ end
171
+ attribute(:foo) { "bar" }
172
+ end
173
+ node.result.should == {
174
+ person: nil,
175
+ foo: 'bar'
176
+ }
177
+ end
178
+
166
179
  it 'is passes block the block variable to the block' do
167
180
  denver = Person.new('John Denver')
168
181
  node = Node.new do
@@ -231,7 +244,6 @@ module Bldr
231
244
  end
232
245
  end
233
246
 
234
-
235
247
  describe "#attributes" do
236
248
  describe "when an object key is passed a null value" do
237
249
  subject {
@@ -250,13 +262,14 @@ module Bldr
250
262
  }.not_to raise_error(ArgumentError, ERROR_MESSAGES[:attributes_inferred_missing])
251
263
  end
252
264
 
253
- its(:result) { should == {} }
265
+ its(:result) { should == {:person => nil} }
254
266
  end
255
267
 
256
268
  it "renders each argument against the inferred object" do
257
269
  node = wrap { attributes(:name, :age) }
258
270
  node.result.should == {:person => {:name => 'alex', :age => 25}}
259
271
  end
272
+
260
273
  it "renders nil attributes" do
261
274
  node = node_wrap do
262
275
  object :person => Person.new('alex') do
@@ -266,9 +279,7 @@ module Bldr
266
279
 
267
280
  node.result.should == {:person => {:name => 'alex', :age => nil}}
268
281
  end
269
-
270
282
  end
271
-
272
283
  end
273
284
 
274
285
  describe "embedded objects" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bldr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-25 00:00:00.000000000 Z
12
+ date: 2013-05-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -124,8 +124,10 @@ files:
124
124
  - README.md
125
125
  - Rakefile
126
126
  - bldr.gemspec
127
+ - lib/action_view/template/handlers/bldr.rb
127
128
  - lib/bldr.rb
128
129
  - lib/bldr/node.rb
130
+ - lib/bldr/railtie.rb
129
131
  - lib/bldr/template.rb
130
132
  - lib/bldr/version.rb
131
133
  - lib/sinatra/bldr.rb
@@ -140,8 +142,13 @@ files:
140
142
  - spec/fixtures/root_partial.bldr
141
143
  - spec/fixtures/root_template.json.bldr
142
144
  - spec/fixtures/some/include.json.bldr
145
+ - spec/fixtures/templates/rails/people/index.json.bldr
146
+ - spec/fixtures/templates/rails/people/show.json.bldr
143
147
  - spec/functional/handlers_spec.rb
148
+ - spec/functional/helpers_spec.rb
149
+ - spec/functional/params_spec.rb
144
150
  - spec/functional/tilt_template_spec.rb
151
+ - spec/integration/rails_32_spec.rb
145
152
  - spec/integration/sinatra_spec.rb
146
153
  - spec/models/comment.rb
147
154
  - spec/models/person.rb
@@ -170,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
177
  version: '0'
171
178
  requirements: []
172
179
  rubyforge_project: bldr
173
- rubygems_version: 1.8.24
180
+ rubygems_version: 1.8.25
174
181
  signing_key:
175
182
  specification_version: 3
176
183
  summary: Templating library with a simple, minimalist DSL.
@@ -183,8 +190,13 @@ test_files:
183
190
  - spec/fixtures/root_partial.bldr
184
191
  - spec/fixtures/root_template.json.bldr
185
192
  - spec/fixtures/some/include.json.bldr
193
+ - spec/fixtures/templates/rails/people/index.json.bldr
194
+ - spec/fixtures/templates/rails/people/show.json.bldr
186
195
  - spec/functional/handlers_spec.rb
196
+ - spec/functional/helpers_spec.rb
197
+ - spec/functional/params_spec.rb
187
198
  - spec/functional/tilt_template_spec.rb
199
+ - spec/integration/rails_32_spec.rb
188
200
  - spec/integration/sinatra_spec.rb
189
201
  - spec/models/comment.rb
190
202
  - spec/models/person.rb
@@ -193,3 +205,4 @@ test_files:
193
205
  - spec/spec_helper.rb
194
206
  - spec/unit/bldr_spec.rb
195
207
  - spec/unit/node_spec.rb
208
+ has_rdoc: