bldr 0.5.5 → 0.6.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/HISTORY.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.6.0 (2012-xx-xx)
2
+ * Feature: Add the ability to pass-through objects directly to `object` and
3
+ `collection` DSL methods
4
+
5
+ ## 0.5.5 (2012-05-15)
6
+ * Bug: Allow .bldr extensions at the end of partial template names
7
+ * Bug: `#attribute` DSL method returns self, allowing use at top level
8
+
1
9
  ## 0.5.4 (2012-04-24)
2
10
  * Fix bug to allow using `template` method at the root of a bldr template
3
11
  * Add `locals` reader method to allow access to locals passed into a bldr template
@@ -57,45 +57,88 @@ module Bldr
57
57
  # attributes(:url) { url }
58
58
  # end
59
59
  #
60
+ # @example "Pass-through" objects
61
+ # object :person => person do
62
+ # object :hobbies => hobbies
63
+ # end
64
+ #
60
65
  # @param [Hash, Nil] hash a key/value pair indicating the output key name
61
66
  # and the object to serialize.
62
67
  # @param [Proc] block the code block to evaluate
63
68
  #
64
69
  # @return [Bldr::Node] returns self
65
70
  def object(base = nil, &block)
66
- if base.kind_of? Hash
67
- key = base.keys.first
68
- value = base.values.first
71
+ if block_given?
72
+ if keyed_object?(base)
73
+ key = base.keys.first
74
+ value = base.values.first
75
+ else
76
+ key = base
77
+ value = nil
78
+ end
79
+
80
+ # Short circuit here if the object passed in pointed
81
+ # at a nil value. There's some debate about how this
82
+ # should behave by default -- should it build the keyspace,
83
+ # pointing a null value, or should it leave the key out.
84
+ # With this implementation, it leaves the keyspace out.
85
+ return nil if value.nil? and keyed_object?(base)
86
+
87
+ node = Node.new(value, opts.merge(:parent => self), &block)
88
+ merge_result!(key, node.result)
69
89
  else
70
- key = base
71
- value = nil
90
+ merge_result!(nil, base)
72
91
  end
73
92
 
74
- return nil if value.nil? and base.kind_of? Hash
75
- node = Node.new(value, opts.merge(:parent => self), &block)
76
- merge_result!(key, node.result)
77
-
78
93
  self
79
94
  end
80
95
 
96
+ # Build a collection of objects, either passing each object
97
+ # into the block provided, or rendering the collection
98
+ # "pass-through", i.e. exactly as it appears.
99
+ #
100
+ # @example
101
+ # object :person => person do
102
+ # attributes :id, :name, :age
103
+ #
104
+ # collection :friends => person.friends do
105
+ # attributes :name, :age, :friend_count
106
+ # end
107
+ # end
108
+ #
109
+ # @example "Pass-through" collections
110
+ # object :person => person do
111
+ # collection :hobbies => hobbies
112
+ # end
113
+ #
114
+ # @param [Array, Hash] items Either an array of items, or a hash.
115
+ # If an array is passed in, the objects will be rendered at the
116
+ # "top level", i.e. without a key pointing to them.
81
117
  # @return [Bldr::Node] returns self
82
118
  def collection(items, &block)
83
119
 
84
- if items.respond_to?('keys')
120
+ # Does this collection live in a key, or is it top-level?
121
+ if keyed_object?(items)
85
122
  key = items.keys.first
86
123
  values = items.values.to_a.first
87
124
  else
88
125
  key = nil
89
126
  values = items
90
127
  end
91
-
128
+
92
129
  vals = if values
93
- values.map{|item| Node.new(item, opts.merge(:parent => self), &block).result}
94
- else
95
- []
96
- end
130
+ if block_given?
131
+ values.map do |item|
132
+ Node.new(item, opts.merge(:parent => self), &block).result
133
+ end
134
+ else
135
+ values
136
+ end
137
+ else
138
+ []
139
+ end
97
140
 
98
- if items.respond_to?('keys')
141
+ if keyed_object?(items)
99
142
  merge_result! key, vals
100
143
  else
101
144
  @result = massage_value(vals)
@@ -200,6 +243,16 @@ module Bldr
200
243
  end
201
244
 
202
245
  private
246
+
247
+ # Determines if an object was passed in with a key pointing to it, or if
248
+ # it was passed in as the "root" of the current object. Essentially, this
249
+ # checks if `obj` quacks like a hash.
250
+ #
251
+ # @param [Object] obj
252
+ # @return [Boolean]
253
+ def keyed_object?(obj)
254
+ obj.respond_to?(:keys)
255
+ end
203
256
 
204
257
  def find_template(template)
205
258
  path = []
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Bldr
3
- VERSION = '0.5.5'
3
+ VERSION = '0.6.0'
4
4
  end
@@ -1,6 +1,8 @@
1
+ class Author < Struct.new(:name)
2
+ end
1
3
 
2
4
  class Post
3
- attr_accessor :title, :body, :comments
5
+ attr_accessor :title, :body, :comments, :author
4
6
 
5
7
  def initialize(title = nil, body = nil)
6
8
  @title, @body = title, body
@@ -18,6 +18,15 @@ describe "Node#attributes" do
18
18
  end
19
19
 
20
20
  describe "Node#object" do
21
+ context "rendering an object exactly as it exists" do
22
+ it "renders the object exactly as it appears when passed an object with no block" do
23
+ obj = {'key' => 'val', 'nested' => {'key' => 'val'}}
24
+ node = node_wrap do
25
+ object obj
26
+ end
27
+ node.result.should == obj
28
+ end
29
+ end
21
30
 
22
31
  context "a zero arg root object node" do
23
32
 
@@ -406,6 +415,30 @@ describe "Node#to_json" do
406
415
  end
407
416
 
408
417
  describe "Node#collection" do
418
+ context "when passed an object with no block" do
419
+ it "renders the object exactly as it exists" do
420
+ coll = [{'key' => 'val'}]
421
+ node = node_wrap do
422
+ collection coll
423
+ end
424
+
425
+ node.result.should == coll
426
+ end
427
+
428
+ it "renders complex collection objects correctly" do
429
+ hobbies = [{'name' => "Gym"}, {'name' => "Tan"}, {'name' => "Laundry"}]
430
+
431
+ node = node_wrap do
432
+ object 'person' => Person.new("Alex") do
433
+ attribute :name
434
+ collection 'hobbies' => hobbies
435
+ end
436
+ end
437
+
438
+ node.result.should == {'person' => {:name => "Alex", 'hobbies' => hobbies}}
439
+ end
440
+ end
441
+
409
442
  it "iterates through the collection and renders them as nodes" do
410
443
  node = node_wrap do
411
444
  object :person => Person.new('alex', 26) do
@@ -488,6 +521,28 @@ describe "Node#collection" do
488
521
  }
489
522
  end
490
523
 
524
+ it "renders objects nested in collections properly" do
525
+ post = Post.new 'foo'
526
+ post.author = Author.new('John Doe')
527
+ posts = [post]
528
+
529
+ nodes = node_wrap do
530
+ collection :data => posts do
531
+ attributes :title
532
+
533
+ object :author => current_object.author do
534
+ attributes :name
535
+ end
536
+ end
537
+ end
538
+
539
+ nodes.result.should == {
540
+ :data => [
541
+ {:title => 'foo', :author => {:name => 'John Doe'}}
542
+ ]
543
+ }
544
+ end
545
+
491
546
  it "renders nested collections with dynamic property values correctly" do
492
547
  post1 = Post.new("post 1")
493
548
  post2 = Post.new("post 2")
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.5.5
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-15 00:00:00.000000000 Z
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
16
- requirement: &70314605956260 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70314605956260
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: json_pure
27
- requirement: &70314605955840 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70314605955840
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: sinatra
38
- requirement: &70314605955340 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: 1.2.6
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70314605955340
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.6
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: tilt
49
- requirement: &70314605954840 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: 1.3.2
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70314605954840
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.3.2
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: yajl-ruby
60
- requirement: &70314605954380 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: '1.0'
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70314605954380
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '1.0'
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: actionpack
71
- requirement: &70314605953920 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ~>
@@ -76,7 +101,12 @@ dependencies:
76
101
  version: 3.0.7
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *70314605953920
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 3.0.7
80
110
  description: Provides a simple and intuitive templating DSL for serializing objects
81
111
  to JSON.
82
112
  email:
@@ -137,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
167
  version: '0'
138
168
  requirements: []
139
169
  rubyforge_project: bldr
140
- rubygems_version: 1.8.15
170
+ rubygems_version: 1.8.24
141
171
  signing_key:
142
172
  specification_version: 3
143
173
  summary: Templating library with a simple, minimalist DSL.