bldr 0.5.5 → 0.6.0

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