rabl 0.5.4 → 0.5.5.a
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/CHANGELOG.md +3 -1
- data/README.md +2 -2
- data/lib/rabl/builder.rb +25 -18
- data/lib/rabl/engine.rb +5 -4
- data/lib/rabl/version.rb +1 -1
- data/test/builder_test.rb +59 -101
- metadata +4 -4
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -34,7 +34,7 @@ gem 'yajl-ruby'
|
|
|
34
34
|
|
|
35
35
|
and run `bundle install` to install the dependency.
|
|
36
36
|
|
|
37
|
-
If you are using **Rails 2.X, Rails 3 or Padrino**, RABL works without configuration.
|
|
37
|
+
If you are using **Rails 2.X, Rails 3.X or Padrino**, RABL works without configuration.
|
|
38
38
|
|
|
39
39
|
With Sinatra, or any other tilt-based framework, simply register:
|
|
40
40
|
|
|
@@ -43,7 +43,7 @@ With Sinatra, or any other tilt-based framework, simply register:
|
|
|
43
43
|
and RABL will be initialized and ready for use. For usage with Sinatra, check out
|
|
44
44
|
the [Sinatra Usage](https://github.com/nesquena/rabl/wiki/Setup-for-Sinatra) guide.
|
|
45
45
|
|
|
46
|
-
**Note:** Users have reported a few rendering issues with Rails 3.
|
|
46
|
+
**Note:** Users have reported a few rendering issues with Rails 3.2.
|
|
47
47
|
The [template handler](https://github.com/nesquena/rabl/blob/master/lib/rabl/template.rb) probably needs
|
|
48
48
|
a patch to properly support Rails 3.2. Hopefully I can get to it soon but patches are welcome.
|
|
49
49
|
|
data/lib/rabl/builder.rb
CHANGED
|
@@ -2,20 +2,28 @@ module Rabl
|
|
|
2
2
|
class Builder
|
|
3
3
|
include Rabl::Helpers
|
|
4
4
|
|
|
5
|
-
# Constructs a new
|
|
5
|
+
# Constructs a new rabl hash based on given object and options
|
|
6
6
|
# options = { :format => "json", :attributes, :root => true,
|
|
7
7
|
# :child_root => true, :node, :child, :glue, :extends }
|
|
8
|
-
def initialize(
|
|
8
|
+
def initialize(options={}, &block)
|
|
9
9
|
@options = options
|
|
10
10
|
@_scope = options[:scope]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Given an object and options, returns the hash representation
|
|
14
|
+
# build(@user, :format => "json", :attributes => { ... })
|
|
15
|
+
def build(data, options={})
|
|
11
16
|
@_data = data
|
|
12
17
|
@_object = data_object(data)
|
|
13
|
-
@_result
|
|
18
|
+
@_result = {}
|
|
19
|
+
compile_hash(options)
|
|
14
20
|
end
|
|
15
21
|
|
|
22
|
+
protected
|
|
23
|
+
|
|
16
24
|
# Returns a hash representation of the data object
|
|
17
|
-
#
|
|
18
|
-
def
|
|
25
|
+
# compile_hash(:root => true)
|
|
26
|
+
def compile_hash(options={})
|
|
19
27
|
# Extends
|
|
20
28
|
@options[:extends].each do |settings|
|
|
21
29
|
extends(settings[:file], settings[:options], &settings[:block])
|
|
@@ -36,23 +44,22 @@ module Rabl
|
|
|
36
44
|
@options[:glue].each do |settings|
|
|
37
45
|
glue(settings[:data], &settings[:block])
|
|
38
46
|
end if @options.has_key?(:glue)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
|
|
48
|
+
# Wrap result in root
|
|
49
|
+
if @options[:root] || options[:root]
|
|
50
|
+
@_root_name ||= data_name(@_data)
|
|
51
|
+
else # no root
|
|
52
|
+
@_root_name = nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Return Results
|
|
56
|
+
@_root_name ? { @_root_name => @_result } : @_result
|
|
42
57
|
end
|
|
43
58
|
|
|
44
59
|
# Indicates an attribute or method should be included in the json output
|
|
45
60
|
# attribute :foo, :as => "bar"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if args.first.is_a?(Hash)
|
|
49
|
-
args.first.each_pair { |k,v| self.attribute(k, :as => v) }
|
|
50
|
-
else # array of attributes
|
|
51
|
-
options = args.extract_options!
|
|
52
|
-
args.each do |attribute|
|
|
53
|
-
@_result[options[:as] || attribute] = @_object.send(attribute) if @_object && @_object.respond_to?(attribute)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
61
|
+
def attribute(name, options={})
|
|
62
|
+
@_result[options[:as] || name] = @_object.send(name) if @_object && @_object.respond_to?(name)
|
|
56
63
|
end
|
|
57
64
|
alias_method :attributes, :attribute
|
|
58
65
|
|
data/lib/rabl/engine.rb
CHANGED
|
@@ -33,14 +33,15 @@ module Rabl
|
|
|
33
33
|
def to_hash(options={})
|
|
34
34
|
options = @_options.merge(options)
|
|
35
35
|
data = data_object(@_data)
|
|
36
|
+
builder = Rabl::Builder.new(options)
|
|
36
37
|
if is_object?(data) || !data # object @user
|
|
37
|
-
|
|
38
|
+
builder.build(@_data, options)
|
|
38
39
|
elsif is_collection?(data) # collection @users
|
|
39
40
|
if options[:root] # only calculate root name if needed
|
|
40
41
|
object_name = data_name(@_data).to_s.singularize # @users => :users
|
|
41
|
-
data.map { |object|
|
|
42
|
-
else
|
|
43
|
-
data.map { |object|
|
|
42
|
+
data.map { |object| builder.build({ object => object_name }, options) }
|
|
43
|
+
else # skip root name
|
|
44
|
+
data.map { |object| builder.build(object, options) }
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
end
|
data/lib/rabl/version.rb
CHANGED
data/test/builder_test.rb
CHANGED
|
@@ -3,19 +3,22 @@ require File.expand_path('../models/user', __FILE__)
|
|
|
3
3
|
|
|
4
4
|
context "Rabl::Builder" do
|
|
5
5
|
|
|
6
|
-
helper(:builder) { |
|
|
7
|
-
helper(:
|
|
8
|
-
helper(:get_hash) { |obj, root| obj.to_hash(:root => root) }
|
|
6
|
+
helper(:builder) { |opt| Rabl::Builder.new(opt) }
|
|
7
|
+
helper(:build_hash) { |obj, opt| builder(opt).build(obj) }
|
|
9
8
|
|
|
10
9
|
setup do
|
|
11
10
|
@users = [User.new, User.new]
|
|
12
11
|
@user = User.new
|
|
13
|
-
builder
|
|
12
|
+
builder({})
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
context "#initialize" do
|
|
17
|
-
asserts_topic.assigns :_object
|
|
18
16
|
asserts_topic.assigns :options
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "#build" do
|
|
20
|
+
setup { b = builder({}); b.build(User.new); b }
|
|
21
|
+
asserts_topic.assigns :_object
|
|
19
22
|
asserts_topic.assigns :_result
|
|
20
23
|
end
|
|
21
24
|
|
|
@@ -23,30 +26,27 @@ context "Rabl::Builder" do
|
|
|
23
26
|
|
|
24
27
|
context "when given a simple object" do
|
|
25
28
|
|
|
26
|
-
setup { builder
|
|
29
|
+
setup { builder({ :attributes => { :name => :name } }) }
|
|
27
30
|
asserts "that the object is set properly" do
|
|
28
|
-
topic.
|
|
29
|
-
get_hash(topic, true)
|
|
31
|
+
topic.build(User.new, :root => true)
|
|
30
32
|
end.equivalent_to({ "user" => { :name => "rabl" } })
|
|
31
33
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
context "when given an object alias" do
|
|
35
37
|
|
|
36
|
-
setup { builder({
|
|
38
|
+
setup { builder({ :attributes => { :name => :name } }) }
|
|
37
39
|
asserts "that the object is set properly" do
|
|
38
|
-
topic.
|
|
39
|
-
get_hash(topic, true)
|
|
40
|
+
topic.build({ User.new => "person" }, :root => true)
|
|
40
41
|
end.equivalent_to({ "person" => { :name => "rabl" } })
|
|
41
42
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
context "when specified with no root" do
|
|
45
46
|
|
|
46
|
-
setup { builder
|
|
47
|
+
setup { builder({ :attributes => { :name => :name } }) }
|
|
47
48
|
asserts "that the object is set properly" do
|
|
48
|
-
topic.
|
|
49
|
-
get_hash(topic, false)
|
|
49
|
+
topic.build(User.new, :root => false)
|
|
50
50
|
end.equivalent_to({ :name => "rabl" })
|
|
51
51
|
|
|
52
52
|
end
|
|
@@ -54,146 +54,104 @@ context "Rabl::Builder" do
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
context "#attribute" do
|
|
57
|
+
asserts "that the node" do
|
|
58
|
+
build_hash @user, :attributes => { :name => :name, :city => :city }
|
|
59
|
+
end.equivalent_to({:name => 'rabl', :city => 'irvine'})
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
topic.attribute :name, :city
|
|
62
|
-
get_result(topic)
|
|
63
|
-
end.equivalent_to({:name => 'rabl', :city => 'irvine'})
|
|
64
|
-
|
|
65
|
-
asserts "that with a non-existent attribute the node" do
|
|
66
|
-
topic.attribute :fake
|
|
67
|
-
get_result(topic)[:fake]
|
|
68
|
-
end.nil
|
|
69
|
-
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
context "when given a Hash" do
|
|
73
|
-
|
|
74
|
-
asserts "that using :as, the node" do
|
|
75
|
-
topic.attribute :city, :as => 'foo'
|
|
76
|
-
get_result(topic)
|
|
77
|
-
end.equals({'foo'=>'irvine'})
|
|
78
|
-
|
|
79
|
-
asserts "with multiple attributes, the node" do
|
|
80
|
-
topic.attributes :city => :a, :age => :b
|
|
81
|
-
get_result(topic)
|
|
82
|
-
end.equivalent_to({:a => 'irvine', :b => 24, 'foo' => 'irvine'})
|
|
83
|
-
|
|
84
|
-
end
|
|
85
|
-
|
|
61
|
+
asserts "that with a non-existent attribute the node" do
|
|
62
|
+
build_hash @user, :attributes => { :fake => :fake }
|
|
63
|
+
end.equals({})
|
|
86
64
|
end
|
|
87
65
|
|
|
88
|
-
context "#code" do
|
|
89
66
|
|
|
67
|
+
context "#node" do
|
|
90
68
|
asserts "that it has node :foo" do
|
|
91
|
-
|
|
92
|
-
get_result(topic)
|
|
69
|
+
build_hash @user, :node => [{ :name => :foo, :options => {}, :block => lambda { |u| "bar" } }]
|
|
93
70
|
end.equivalent_to({:foo => 'bar'})
|
|
94
71
|
|
|
95
72
|
asserts "that using object it has node :boo" do
|
|
96
|
-
|
|
97
|
-
|
|
73
|
+
build_hash @user, :node => [
|
|
74
|
+
{ :name => :foo, :options => {}, :block => lambda { |u| "bar" } },
|
|
75
|
+
{ :name => :baz, :options => {}, :block => lambda { |u| u.city } }
|
|
76
|
+
]
|
|
98
77
|
end.equivalent_to({:foo => 'bar', :baz => 'irvine'})
|
|
99
78
|
end
|
|
100
79
|
|
|
101
80
|
context "#child" do
|
|
102
81
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
end
|
|
82
|
+
asserts "that it generates if no data present" do
|
|
83
|
+
builder(:child => []).build(@user)
|
|
84
|
+
end.equals({})
|
|
106
85
|
|
|
107
86
|
asserts "that it generates with a hash" do
|
|
108
|
-
b = builder @user, {}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
b.child(@user => :user) { attribute :name }
|
|
112
|
-
get_result(b)
|
|
113
|
-
end.equivalent_to({ :user => 'xyz'})
|
|
87
|
+
b = builder(:child => [ { :data => { @user => :user }, :options => { }, :block => lambda { |u| attribute :name } } ])
|
|
88
|
+
b.build(@user)
|
|
89
|
+
end.equivalent_to({ :user => { :name => "rabl" } })
|
|
114
90
|
|
|
115
91
|
asserts "that it generates with a hash alias" do
|
|
116
|
-
b = builder @user, {}
|
|
117
|
-
|
|
118
|
-
b.child(@user => :person) { attribute :name }
|
|
119
|
-
get_result(b)
|
|
92
|
+
b = builder :child => [{ :data => { @user => :person }, :options => {}, :block => lambda { |u| attribute :name } }]
|
|
93
|
+
b.build(@user)
|
|
120
94
|
end.equivalent_to({ :person => { :name => "rabl" } })
|
|
121
95
|
|
|
122
96
|
asserts "that it generates with an object" do
|
|
123
|
-
b = builder @user, {}
|
|
97
|
+
b = builder :child => [{ :data => @user, :options => {}, :block => lambda { |u| attribute :name } }]
|
|
124
98
|
mock(b).data_name(@user) { :user }
|
|
125
|
-
mock(b).object_to_hash(@user,{ :root => false }).returns('xyz').subject
|
|
126
|
-
|
|
127
|
-
b.child(@user) { attribute :name }
|
|
128
|
-
get_result(b)
|
|
99
|
+
mock(b).object_to_hash(@user, { :root => false }).returns('xyz').subject
|
|
100
|
+
b.build(@user)
|
|
129
101
|
end.equivalent_to({ :user => 'xyz'})
|
|
130
102
|
|
|
131
103
|
asserts "that it generates with an collection and child_root" do
|
|
132
|
-
b = builder @
|
|
104
|
+
b = builder :child => [{ :data => @users, :options => {}, :block => lambda { |u| attribute :name } }], :child_root => true
|
|
133
105
|
mock(b).data_name(@users) { :users }
|
|
134
|
-
mock(b).object_to_hash(@users,{ :root => true, :child_root => true }).returns('xyz').subject
|
|
135
|
-
|
|
136
|
-
b.child(@users) { attribute :name }
|
|
137
|
-
get_result(b)
|
|
106
|
+
mock(b).object_to_hash(@users, { :root => true, :child_root => true }).returns('xyz').subject
|
|
107
|
+
b.build(@user)
|
|
138
108
|
end.equivalent_to({ :users => 'xyz'})
|
|
139
109
|
|
|
140
110
|
asserts "that it generates with an collection and no child root" do
|
|
141
|
-
b = builder @
|
|
111
|
+
b = builder :child => [{ :data => @users, :options => {}, :block => lambda { |u| attribute :name } }], :child_root => false
|
|
142
112
|
mock(b).data_name(@users) { :users }
|
|
143
|
-
mock(b).object_to_hash(@users,{ :root => false, :child_root => false }).returns('xyz').subject
|
|
144
|
-
|
|
145
|
-
b.child(@users) { attribute :name }
|
|
146
|
-
get_result(b)
|
|
113
|
+
mock(b).object_to_hash(@users, { :root => false, :child_root => false }).returns('xyz').subject
|
|
114
|
+
b.build(@user)
|
|
147
115
|
end.equivalent_to({ :users => 'xyz'})
|
|
148
116
|
end
|
|
149
117
|
|
|
118
|
+
|
|
150
119
|
context "#glue" do
|
|
151
120
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
end
|
|
121
|
+
asserts "that it generates if no data present" do
|
|
122
|
+
builder(:glue => []).build(@user)
|
|
123
|
+
end.equals({})
|
|
155
124
|
|
|
156
125
|
asserts "that it generates the glue attributes" do
|
|
157
|
-
b = builder @user, {}
|
|
158
|
-
mock(b).object_to_hash(@user,{ :root => false }).returns({:user => 'xyz'}).subject
|
|
159
|
-
|
|
160
|
-
b.glue(@user) { attribute :name }
|
|
161
|
-
get_result(b)
|
|
126
|
+
b = builder :glue => [{ :data => @user, :block => lambda { |u| attribute :name }}]
|
|
127
|
+
mock(b).object_to_hash(@user, { :root => false }).returns({:user => 'xyz'}).subject
|
|
128
|
+
b.build(@user)
|
|
162
129
|
end.equivalent_to({ :user => 'xyz' })
|
|
163
130
|
|
|
164
131
|
asserts "that it appends the glue attributes to result" do
|
|
165
|
-
b = builder @user, {}
|
|
166
|
-
|
|
167
|
-
b.glue(@user) { attribute :name => :user_name }
|
|
168
|
-
get_result(b)
|
|
132
|
+
b = builder :glue => [{ :data => @user, :block => lambda { |u| attribute :name => :user_name }}]
|
|
133
|
+
b.build(@user)
|
|
169
134
|
end.equivalent_to({ :user_name => 'rabl' })
|
|
170
135
|
|
|
171
136
|
asserts "that it does not generate new attributes if no glue attributes are present" do
|
|
172
|
-
b = builder @user, {}
|
|
137
|
+
b = builder :glue => [{ :data => @user, :block => lambda { |u| attribute :name }}]
|
|
173
138
|
mock(b).object_to_hash(@user,{ :root => false }).returns({}).subject
|
|
174
|
-
|
|
175
|
-
b.glue(@user) { attribute :name }
|
|
176
|
-
get_result(b)
|
|
139
|
+
b.build(@user)
|
|
177
140
|
end.equals({})
|
|
178
141
|
end
|
|
179
142
|
|
|
180
143
|
context "#extend" do
|
|
181
144
|
|
|
182
145
|
asserts "that it does not genereate if no data is present" do
|
|
183
|
-
b = builder
|
|
146
|
+
b = builder :extends => [{ :file => 'users/show', :options => {}, :block => lambda { |u| attribute :name }}]
|
|
184
147
|
mock(b).partial('users/show',{ :object => @user}).returns({}).subject
|
|
185
|
-
|
|
186
|
-
b.extends('users/show') { attribute :name }
|
|
187
|
-
get_result(b)
|
|
148
|
+
b.build(@user)
|
|
188
149
|
end.equals({})
|
|
189
150
|
|
|
190
151
|
asserts "that it generates if data is present" do
|
|
191
|
-
b = builder
|
|
192
|
-
mock(b).partial('users/show',{ :object => @user}).returns({:user => 'xyz'}).subject
|
|
193
|
-
|
|
194
|
-
b.extends('users/show') { attribute :name }
|
|
195
|
-
get_result(b)
|
|
152
|
+
b = builder :extends => [{ :file => 'users/show', :options => {}, :block => lambda { |u| attribute :name }}]
|
|
153
|
+
mock(b).partial('users/show', { :object => @user }).returns({:user => 'xyz'}).subject
|
|
154
|
+
b.build(@user)
|
|
196
155
|
end.equivalent_to({:user => 'xyz'})
|
|
197
156
|
end
|
|
198
|
-
|
|
199
157
|
end
|
metadata
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rabl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
prerelease:
|
|
5
|
-
version: 0.5.
|
|
4
|
+
prerelease: 6
|
|
5
|
+
version: 0.5.5.a
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Nathan Esquenazi
|
|
@@ -280,9 +280,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
280
280
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
281
281
|
none: false
|
|
282
282
|
requirements:
|
|
283
|
-
- - "
|
|
283
|
+
- - ">"
|
|
284
284
|
- !ruby/object:Gem::Version
|
|
285
|
-
version:
|
|
285
|
+
version: 1.3.1
|
|
286
286
|
requirements: []
|
|
287
287
|
|
|
288
288
|
rubyforge_project: rabl
|