bldr 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: