rabl 0.5.5.d → 0.5.5.e
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 +2 -1
- data/README.md +43 -3
- data/lib/rabl/configuration.rb +20 -0
- data/lib/rabl/engine.rb +26 -15
- data/lib/rabl/helpers.rb +3 -1
- data/lib/rabl/version.rb +1 -1
- data/rabl.gemspec +3 -2
- data/test/bson_engine_test.rb +331 -0
- metadata +17 -4
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
-
## 0.5.5.a-
|
3
|
+
## 0.5.5.a-e
|
4
4
|
|
5
5
|
* Change engine to only instantiate one builder when rendering a collection
|
6
6
|
* Alias to\_msgpack to to\_mpac
|
7
7
|
* Cache template sources for faster partial lookups (thanks cj)
|
8
|
+
* Adds BSON format support (thanks Antiarchitect)
|
8
9
|
|
9
10
|
## 0.5.4
|
10
11
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# RABL #
|
2
2
|
|
3
|
-
RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON and
|
3
|
+
RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON, XML, MessagePack and BSON. When using the ActiveRecord 'to_json' method, I tend to quickly find myself wanting a more expressive and powerful solution for generating APIs.
|
4
4
|
This is especially frustrating when the JSON representation is complex or doesn't match the exact schema defined in the database.
|
5
5
|
|
6
6
|
I wanted a simple and flexible system for generating my APIs. In particular, I wanted to easily:
|
@@ -101,8 +101,10 @@ Rabl.configure do |config|
|
|
101
101
|
# config.cache_sources = false
|
102
102
|
# config.json_engine = nil # Any multi\_json engines
|
103
103
|
# config.msgpack_engine = nil # Defaults to ::MessagePack
|
104
|
+
# config.bson_engine = nil # Defaults to ::BSON
|
104
105
|
# config.include_json_root = true
|
105
106
|
# config.include_msgpack_root = true
|
107
|
+
# config.include_bson_root = true
|
106
108
|
# config.include_xml_root = false
|
107
109
|
# config.enable_json_callbacks = false
|
108
110
|
# config.xml_options = { :dasherize => true, :skip_types => false }
|
@@ -151,7 +153,41 @@ Rabl.configure do |config|
|
|
151
153
|
end
|
152
154
|
```
|
153
155
|
|
154
|
-
*NOTE*: Attempting to render the msgpack format without either including the msgpack gem
|
156
|
+
*NOTE*: Attempting to render the msgpack format without either including the msgpack gem
|
157
|
+
or setting a `msgpack_engine` will cause an exception to be raised.
|
158
|
+
|
159
|
+
### BSON ###
|
160
|
+
|
161
|
+
Rabl also includes optional support for [BSON](http://bsonspec.org/) serialization format using the [bson gem](https://rubygems.org/gems/bson).
|
162
|
+
To enable, include the bson gem in your project's Gemfile. Then use Rabl as normal with the `bson` format (akin to json and xml formats).
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
# Gemfile
|
166
|
+
gem 'bson', '~> 1.5.2'
|
167
|
+
```
|
168
|
+
To use it with Rails just register bson mime type format.
|
169
|
+
```ruby
|
170
|
+
# config/initializers/mime_types.rb
|
171
|
+
Mime::Type.register "application/bson", :bson
|
172
|
+
```
|
173
|
+
|
174
|
+
One can additionally use a custom BSON implementation by setting the Rabl `bson_engine` configuration attribute.
|
175
|
+
This custom BSON engine must conform to the BSON#serialize method signature.
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
class CustomEncodeEngine
|
179
|
+
def self.serialize string
|
180
|
+
# Custom Encoding by your own engine.
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
Rabl.configure do |config|
|
185
|
+
config.bson_engine = CustomEncodeEngine
|
186
|
+
end
|
187
|
+
```
|
188
|
+
|
189
|
+
*NOTE*: Attempting to render the bson format without either including the bson gem or
|
190
|
+
setting a `bson_engine` will cause an exception to be raised.
|
155
191
|
|
156
192
|
## Usage ##
|
157
193
|
|
@@ -426,16 +462,20 @@ Thanks to [Miso](http://gomiso.com) for allowing me to create this for our appli
|
|
426
462
|
* [Arthur Chiu](https://github.com/achiu) - Core Maintainer, Riot Testing Guru
|
427
463
|
* [Tim Lee](https://github.com/timothy1ee) - RABL is an awesome name and was chosen by the Miso CTO.
|
428
464
|
* [Rick Thomas](https://github.com/rickthomasjr) - Added options for extends and Sinatra testing
|
465
|
+
* [Benjamin Yu](https://github.com/byu) - Added msgpack format support
|
429
466
|
* [Chris Kimpton](https://github.com/kimptoc) - Helping with documentation and wiki
|
430
467
|
* [Marjun](https://github.com/mpagalan) - Added xml option configurations
|
431
468
|
* [Anton Orel](https://github.com/skyeagle) - Added Rails 3.1 compatibility
|
432
469
|
* [Sasha Koss](https://github.com/kossnocorp) - Added multi_json support
|
433
470
|
* [Matthew Schulkind](https://github.com/mschulkind) - Cleanup of configuration and tests
|
434
471
|
* [Luke van der Hoeven](https://github.com/plukevdh) - Support non-ORM objects in templates
|
472
|
+
* [Andrey Voronkov](https://github.com/Antiarchitect) - Added BSON format support
|
435
473
|
|
436
474
|
and many more contributors listed in the [CHANGELOG](https://github.com/nesquena/rabl/blob/master/CHANGELOG.md).
|
437
475
|
|
438
|
-
Want to contribute support for another format?
|
476
|
+
Want to contribute support for another format?
|
477
|
+
Check out the patch for [msgpack support](https://github.com/nesquena/rabl/pull/69) and
|
478
|
+
[BSON support](https://github.com/nesquena/rabl/pull/163).
|
439
479
|
|
440
480
|
Please fork and contribute, any help in making this project better is appreciated!
|
441
481
|
|
data/lib/rabl/configuration.rb
CHANGED
@@ -4,6 +4,12 @@ begin
|
|
4
4
|
rescue LoadError
|
5
5
|
end
|
6
6
|
|
7
|
+
# We load the bson library if it is available.
|
8
|
+
begin
|
9
|
+
require 'bson'
|
10
|
+
rescue LoadError
|
11
|
+
end
|
12
|
+
|
7
13
|
# Load MultiJSON
|
8
14
|
require 'multi_json'
|
9
15
|
|
@@ -13,8 +19,12 @@ module Rabl
|
|
13
19
|
attr_accessor :include_json_root
|
14
20
|
attr_accessor :include_msgpack_root
|
15
21
|
attr_accessor :include_xml_root
|
22
|
+
attr_accessor :include_bson_root
|
16
23
|
attr_accessor :enable_json_callbacks
|
24
|
+
attr_accessor :bson_check_keys
|
25
|
+
attr_accessor :bson_move_id
|
17
26
|
attr_writer :msgpack_engine
|
27
|
+
attr_writer :bson_engine
|
18
28
|
attr_writer :xml_options
|
19
29
|
attr_accessor :cache_sources
|
20
30
|
|
@@ -24,9 +34,13 @@ module Rabl
|
|
24
34
|
@include_json_root = true
|
25
35
|
@include_msgpack_root = true
|
26
36
|
@include_xml_root = false
|
37
|
+
@include_bson_root = true
|
27
38
|
@enable_json_callbacks = false
|
39
|
+
@bson_check_keys = false
|
40
|
+
@bson_move_id = false
|
28
41
|
@json_engine = nil
|
29
42
|
@msgpack_engine = nil
|
43
|
+
@bson_engine = nil
|
30
44
|
@xml_options = {}
|
31
45
|
@cache_sources = false
|
32
46
|
end
|
@@ -49,6 +63,12 @@ module Rabl
|
|
49
63
|
@msgpack_engine || ::MessagePack
|
50
64
|
end
|
51
65
|
|
66
|
+
##
|
67
|
+
# @return the Bson encoder/engine to use.
|
68
|
+
def bson_engine
|
69
|
+
@bson_engine || ::BSON
|
70
|
+
end
|
71
|
+
|
52
72
|
# Allows config options to be read like a hash
|
53
73
|
#
|
54
74
|
# @param [Symbol] option Key for a given attribute
|
data/lib/rabl/engine.rb
CHANGED
@@ -12,7 +12,7 @@ module Rabl
|
|
12
12
|
# Renders the representation based on source, object, scope and locals
|
13
13
|
# Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
|
14
14
|
def render(scope, locals, &block)
|
15
|
-
|
15
|
+
reset_options!
|
16
16
|
@_locals, @_scope = locals, scope
|
17
17
|
self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
|
18
18
|
@_options[:scope] = @_scope
|
@@ -73,6 +73,21 @@ module Rabl
|
|
73
73
|
to_hash(options).to_xml(xml_options)
|
74
74
|
end
|
75
75
|
|
76
|
+
# Returns a bson representation of the data object
|
77
|
+
# to_bson(:root => true)
|
78
|
+
def to_bson(options={})
|
79
|
+
include_root = Rabl.configuration.include_bson_root
|
80
|
+
options = options.reverse_merge(:root => include_root, :child_root => include_root)
|
81
|
+
result = if defined?(@_collection_name)
|
82
|
+
{ @_collection_name => to_hash(options) }
|
83
|
+
elsif is_collection?(@_data) && @_data.is_a?(Array)
|
84
|
+
{ data_name(@_data) => to_hash(options) }
|
85
|
+
else
|
86
|
+
to_hash(options)
|
87
|
+
end
|
88
|
+
Rabl.configuration.bson_engine.serialize(result).to_s
|
89
|
+
end
|
90
|
+
|
76
91
|
# Sets the object to be used as the data source for this template
|
77
92
|
# object(@user)
|
78
93
|
# object @user => :person
|
@@ -93,11 +108,10 @@ module Rabl
|
|
93
108
|
# attribute :foo, :as => "bar"
|
94
109
|
# attribute :foo => :bar
|
95
110
|
def attribute(*args)
|
96
|
-
if args.first.is_a?(Hash)
|
111
|
+
if args.first.is_a?(Hash) # :foo => :bar, :bar => :baz
|
97
112
|
args.first.each_pair { |k,v| self.attribute(k, :as => v) }
|
98
|
-
else # array of attributes
|
113
|
+
else # array of attributes i.e :foo, :bar, :baz
|
99
114
|
options = args.extract_options!
|
100
|
-
@_options[:attributes] ||= {}
|
101
115
|
args.each { |name| @_options[:attributes][name] = options[:as] || name }
|
102
116
|
end
|
103
117
|
end
|
@@ -107,29 +121,25 @@ module Rabl
|
|
107
121
|
# node(:foo) { "bar" }
|
108
122
|
# node(:foo, :if => lambda { ... }) { "bar" }
|
109
123
|
def node(name = nil, options={}, &block)
|
110
|
-
@_options[:node]
|
111
|
-
@_options[:node] << { :name => name, :options => options, :block => block }
|
124
|
+
@_options[:node].push({ :name => name, :options => options, :block => block })
|
112
125
|
end
|
113
126
|
alias_method :code, :node
|
114
127
|
|
115
128
|
# Creates a child node that is included in json output
|
116
129
|
# child(@user) { attribute :full_name }
|
117
130
|
def child(data, options={}, &block)
|
118
|
-
@_options[:child] ||= []
|
119
131
|
@_options[:child].push({ :data => data, :options => options, :block => block })
|
120
132
|
end
|
121
133
|
|
122
134
|
# Glues data from a child node to the json_output
|
123
135
|
# glue(@user) { attribute :full_name => :user_full_name }
|
124
136
|
def glue(data, &block)
|
125
|
-
@_options[:glue] ||= []
|
126
137
|
@_options[:glue].push({ :data => data, :block => block })
|
127
138
|
end
|
128
139
|
|
129
140
|
# Extends an existing rabl template with additional attributes in the block
|
130
141
|
# extends("users/show", :object => @user) { attribute :full_name }
|
131
142
|
def extends(file, options={}, &block)
|
132
|
-
@_options[:extends] ||= []
|
133
143
|
@_options[:extends].push({ :file => file, :options => options, :block => block })
|
134
144
|
end
|
135
145
|
|
@@ -193,12 +203,13 @@ module Rabl
|
|
193
203
|
|
194
204
|
private
|
195
205
|
|
196
|
-
|
197
|
-
|
198
|
-
@_options
|
199
|
-
@_options
|
200
|
-
@_options
|
201
|
-
@_options
|
206
|
+
# Resets the options parsed from a rabl template.
|
207
|
+
def reset_options!
|
208
|
+
@_options[:attributes] = {}
|
209
|
+
@_options[:node] = []
|
210
|
+
@_options[:child] = []
|
211
|
+
@_options[:glue] = []
|
212
|
+
@_options[:extends] = []
|
202
213
|
end
|
203
214
|
end
|
204
215
|
end
|
data/lib/rabl/helpers.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/inflector' # for the sake of pluralizing
|
2
|
+
|
1
3
|
module Rabl
|
2
4
|
module Helpers
|
3
5
|
|
@@ -19,7 +21,7 @@ module Rabl
|
|
19
21
|
return data.values.first if data.is_a?(Hash) # @user => :user
|
20
22
|
data = @_object.send(data) if data.is_a?(Symbol) && @_object # :address
|
21
23
|
if data.respond_to?(:first)
|
22
|
-
data_name(data.first).pluralize if data.first.present?
|
24
|
+
data_name(data.first).to_s.pluralize if data.first.present?
|
23
25
|
else # actual data object
|
24
26
|
object_name = @_collection_name.to_s.singularize if defined? @_collection_name
|
25
27
|
object_name ||= data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase
|
data/lib/rabl/version.rb
CHANGED
data/rabl.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Nathan Esquenazi"]
|
10
10
|
s.email = ["nesquena@gmail.com"]
|
11
11
|
s.homepage = "https://github.com/nesquena/rabl"
|
12
|
-
s.summary = %q{General ruby templating
|
13
|
-
s.description = %q{General ruby templating
|
12
|
+
s.summary = %q{General ruby templating with json, bson, xml and msgpack support}
|
13
|
+
s.description = %q{General ruby templating with json, bson, xml and msgpack support}
|
14
14
|
|
15
15
|
s.rubyforge_project = "rabl"
|
16
16
|
|
@@ -28,4 +28,5 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_development_dependency 'tilt'
|
29
29
|
s.add_development_dependency 'yajl-ruby'
|
30
30
|
s.add_development_dependency 'msgpack', '~> 0.4.5'
|
31
|
+
s.add_development_dependency 'bson', '~> 1.5.2'
|
31
32
|
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
require File.expand_path('../teststrap', __FILE__)
|
2
|
+
require File.expand_path('../../lib/rabl', __FILE__)
|
3
|
+
require File.expand_path('../../lib/rabl/template', __FILE__)
|
4
|
+
require File.expand_path('../models/user', __FILE__)
|
5
|
+
|
6
|
+
context "Rabl::Engine" do
|
7
|
+
|
8
|
+
helper(:rabl) { |t| RablTemplate.new("code", :format => 'bson') { t } }
|
9
|
+
|
10
|
+
context "with bson defaults" do
|
11
|
+
setup do
|
12
|
+
Rabl.configure do |config|
|
13
|
+
# Comment this line out because include_bson_root is default.
|
14
|
+
#config.include_bson_root = true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#object" do
|
19
|
+
|
20
|
+
asserts "that it sets data source" do
|
21
|
+
template = rabl %q{
|
22
|
+
object @user
|
23
|
+
}
|
24
|
+
scope = Object.new
|
25
|
+
scope.instance_variable_set :@user, User.new
|
26
|
+
template.render(scope)
|
27
|
+
end.matches "\x10\x00\x00\x00\x03user\x00\x05\x00\x00\x00\x00\x00"
|
28
|
+
|
29
|
+
asserts "that it can set root node" do
|
30
|
+
template = rabl %q{
|
31
|
+
object @user => :person
|
32
|
+
}
|
33
|
+
scope = Object.new
|
34
|
+
scope.instance_variable_set :@user, User.new
|
35
|
+
template.render(scope).split("").sort
|
36
|
+
end.equals "\x12\x00\x00\x00\x03person\x00\x05\x00\x00\x00\x00\x00".split("").sort
|
37
|
+
end
|
38
|
+
|
39
|
+
context "#collection" do
|
40
|
+
|
41
|
+
asserts "that it sets object to be casted as a simple array" do
|
42
|
+
template = rabl %{
|
43
|
+
collection @users
|
44
|
+
}
|
45
|
+
scope = Object.new
|
46
|
+
scope.instance_variable_set :@users, [User.new, User.new]
|
47
|
+
template.render(scope).split("").sort
|
48
|
+
end.equals "7\x00\x00\x00\x04users\x00+\x00\x00\x00\x030\x00\x10\x00\x00\x00\x03user\x00\x05\x00\x00\x00\x00\x00\x031\x00\x10\x00\x00\x00\x03user\x00\x05\x00\x00\x00\x00\x00\x00\x00".split("").sort
|
49
|
+
|
50
|
+
asserts "that it sets root node for objects" do
|
51
|
+
template = rabl %{
|
52
|
+
collection @users => :people
|
53
|
+
}
|
54
|
+
scope = Object.new
|
55
|
+
scope.instance_variable_set :@users, [User.new, User.new]
|
56
|
+
template.render(scope).split("").sort
|
57
|
+
end.equals "<\x00\x00\x00\x04people\x00/\x00\x00\x00\x030\x00\x12\x00\x00\x00\x03person\x00\x05\x00\x00\x00\x00\x00\x031\x00\x12\x00\x00\x00\x03person\x00\x05\x00\x00\x00\x00\x00\x00\x00".split("").sort
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
context "#attribute" do
|
62
|
+
|
63
|
+
asserts "that it adds an attribute or method to be included in output" do
|
64
|
+
template = rabl %{
|
65
|
+
object @user
|
66
|
+
attribute :name
|
67
|
+
}
|
68
|
+
scope = Object.new
|
69
|
+
scope.instance_variable_set :@user, User.new(:name => 'irvine')
|
70
|
+
template.render(scope).split("").sort
|
71
|
+
end.equals "!\x00\x00\x00\x03user\x00\x16\x00\x00\x00\x02name\x00\a\x00\x00\x00irvine\x00\x00\x00".split("").sort
|
72
|
+
|
73
|
+
asserts "that it can add attribute under a different key name through :as" do
|
74
|
+
template = rabl %{
|
75
|
+
object @user
|
76
|
+
attribute :name, :as => 'city'
|
77
|
+
}
|
78
|
+
scope = Object.new
|
79
|
+
scope.instance_variable_set :@user, User.new(:name => 'irvine')
|
80
|
+
template.render(scope).split("").sort
|
81
|
+
end.equals "!\x00\x00\x00\x03user\x00\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00\x00".split("").sort
|
82
|
+
|
83
|
+
asserts "that it can add attribute under a different key name through hash" do
|
84
|
+
template = rabl %{
|
85
|
+
object @user
|
86
|
+
attribute :name => :city
|
87
|
+
}
|
88
|
+
scope = Object.new
|
89
|
+
scope.instance_variable_set :@user, User.new(:name => 'irvine')
|
90
|
+
template.render(scope).split("").sort
|
91
|
+
end.equals "!\x00\x00\x00\x03user\x00\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00\x00".split("").sort
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
context "#code" do
|
96
|
+
|
97
|
+
asserts "that it can create an arbitraty code node" do
|
98
|
+
template = rabl %{
|
99
|
+
code(:foo) { 'bar' }
|
100
|
+
}
|
101
|
+
template.render(Object.new).split("").sort
|
102
|
+
end.equals "\x12\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00".split("").sort
|
103
|
+
|
104
|
+
asserts "that it can be passed conditionals" do
|
105
|
+
template = rabl %{
|
106
|
+
code(:foo, :if => lambda { |i| false }) { 'bar' }
|
107
|
+
}
|
108
|
+
template.render(Object.new).split("").sort
|
109
|
+
end.equals "\x05\x00\x00\x00\x00".split("").sort
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context "#child" do
|
114
|
+
|
115
|
+
asserts "that it can create a child node" do
|
116
|
+
template = rabl %{
|
117
|
+
object @user
|
118
|
+
attribute :name
|
119
|
+
child(@user) { attribute :city }
|
120
|
+
}
|
121
|
+
scope = Object.new
|
122
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
123
|
+
template.render(scope).split("").sort
|
124
|
+
end.equals "6\x00\x00\x00\x03user\x00+\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03user\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00\x00".split("").sort
|
125
|
+
|
126
|
+
asserts "that it can create a child node with different key" do
|
127
|
+
template = rabl %{
|
128
|
+
object @user
|
129
|
+
attribute :name
|
130
|
+
child(@user => :person) { attribute :city }
|
131
|
+
}
|
132
|
+
scope = Object.new
|
133
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
134
|
+
template.render(scope).split("").sort
|
135
|
+
end.equals "8\x00\x00\x00\x03user\x00-\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03person\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00\x00".split("").sort
|
136
|
+
end
|
137
|
+
|
138
|
+
context "#glue" do
|
139
|
+
|
140
|
+
asserts "that it glues data from a child node" do
|
141
|
+
template = rabl %{
|
142
|
+
object @user
|
143
|
+
attribute :name
|
144
|
+
glue(@user) { attribute :city }
|
145
|
+
glue(@user) { attribute :age }
|
146
|
+
}
|
147
|
+
scope = Object.new
|
148
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12)
|
149
|
+
template.render(scope).split("").sort
|
150
|
+
end.equals "4\x00\x00\x00\x03user\x00)\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x02city\x00\x03\x00\x00\x00LA\x00\x10age\x00\f\x00\x00\x00\x00\x00".split("").sort
|
151
|
+
end
|
152
|
+
|
153
|
+
teardown do
|
154
|
+
Rabl.reset_configuration!
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "with bson_engine" do
|
159
|
+
setup do
|
160
|
+
class CustomEncodeEngine
|
161
|
+
def self.serialize string
|
162
|
+
42
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
Rabl.configure do |config|
|
167
|
+
config.bson_engine = CustomEncodeEngine
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
asserts 'that it returns process by custom to_json' do
|
172
|
+
template = rabl %q{
|
173
|
+
object @user
|
174
|
+
}
|
175
|
+
scope = Object.new
|
176
|
+
scope.instance_variable_set :@user, User.new
|
177
|
+
template.render(scope)
|
178
|
+
end.equals "42"
|
179
|
+
|
180
|
+
teardown do
|
181
|
+
Rabl.reset_configuration!
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "without bson root" do
|
186
|
+
setup do
|
187
|
+
Rabl.configure do |config|
|
188
|
+
config.include_bson_root = false
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context "#object" do
|
193
|
+
|
194
|
+
asserts "that it sets data source" do
|
195
|
+
template = rabl %q{
|
196
|
+
object @user
|
197
|
+
}
|
198
|
+
scope = Object.new
|
199
|
+
scope.instance_variable_set :@user, User.new
|
200
|
+
template.render(scope)
|
201
|
+
end.matches "\x05\x00\x00\x00\x00"
|
202
|
+
|
203
|
+
asserts "that it can set root node" do
|
204
|
+
template = rabl %q{
|
205
|
+
object @user => :person
|
206
|
+
}
|
207
|
+
scope = Object.new
|
208
|
+
scope.instance_variable_set :@user, User.new
|
209
|
+
template.render(scope)
|
210
|
+
end.equals "\x05\x00\x00\x00\x00"
|
211
|
+
end
|
212
|
+
|
213
|
+
context "#collection" do
|
214
|
+
|
215
|
+
asserts "that it sets object to be casted as a simple array" do
|
216
|
+
template = rabl %{
|
217
|
+
collection @users
|
218
|
+
}
|
219
|
+
scope = Object.new
|
220
|
+
scope.instance_variable_set :@users, [User.new, User.new]
|
221
|
+
template.render(scope).split("").sort
|
222
|
+
end.equals "!\x00\x00\x00\x04users\x00\x15\x00\x00\x00\x030\x00\x05\x00\x00\x00\x00\x031\x00\x05\x00\x00\x00\x00\x00\x00".split("").sort
|
223
|
+
|
224
|
+
asserts "that it sets root node for objects" do
|
225
|
+
template = rabl %{
|
226
|
+
collection @users => :person
|
227
|
+
}
|
228
|
+
scope = Object.new
|
229
|
+
scope.instance_variable_set :@users, [User.new, User.new]
|
230
|
+
template.render(scope).split("").sort
|
231
|
+
end.equals "\"\x00\x00\x00\x04person\x00\x15\x00\x00\x00\x030\x00\x05\x00\x00\x00\x00\x031\x00\x05\x00\x00\x00\x00\x00\x00".split("").sort
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
context "#attribute" do
|
236
|
+
|
237
|
+
asserts "that it adds an attribute or method to be included in output" do
|
238
|
+
template = rabl %{
|
239
|
+
object @user
|
240
|
+
attribute :name
|
241
|
+
}
|
242
|
+
scope = Object.new
|
243
|
+
scope.instance_variable_set :@user, User.new(:name => 'irvine')
|
244
|
+
template.render(scope).split("").sort
|
245
|
+
end.equals "\x16\x00\x00\x00\x02name\x00\a\x00\x00\x00irvine\x00\x00".split("").sort
|
246
|
+
|
247
|
+
asserts "that it can add attribute under a different key name through :as" do
|
248
|
+
template = rabl %{
|
249
|
+
object @user
|
250
|
+
attribute :name, :as => 'city'
|
251
|
+
}
|
252
|
+
scope = Object.new
|
253
|
+
scope.instance_variable_set :@user, User.new(:name => 'irvine')
|
254
|
+
template.render(scope).split("").sort
|
255
|
+
end.equals "\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00".split("").sort
|
256
|
+
|
257
|
+
asserts "that it can add attribute under a different key name through hash" do
|
258
|
+
template = rabl %{
|
259
|
+
object @user
|
260
|
+
attribute :name => :city
|
261
|
+
}
|
262
|
+
scope = Object.new
|
263
|
+
scope.instance_variable_set :@user, User.new(:name => 'irvine')
|
264
|
+
template.render(scope).split("").sort
|
265
|
+
end.equals "\x16\x00\x00\x00\x02city\x00\a\x00\x00\x00irvine\x00\x00".split("").sort
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
context "#code" do
|
270
|
+
|
271
|
+
asserts "that it can create an arbitraty code node" do
|
272
|
+
template = rabl %{
|
273
|
+
code(:foo) { 'bar' }
|
274
|
+
}
|
275
|
+
template.render(Object.new).split("").sort
|
276
|
+
end.equals "\x12\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00".split("").sort
|
277
|
+
|
278
|
+
asserts "that it can be passed conditionals" do
|
279
|
+
template = rabl %{
|
280
|
+
code(:foo, :if => lambda { |i| false }) { 'bar' }
|
281
|
+
}
|
282
|
+
template.render(Object.new).split("").sort
|
283
|
+
end.equals "\x05\x00\x00\x00\x00".split("").sort
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
context "#child" do
|
288
|
+
|
289
|
+
asserts "that it can create a child node" do
|
290
|
+
template = rabl %{
|
291
|
+
object @user
|
292
|
+
attribute :name
|
293
|
+
child(@user) { attribute :city }
|
294
|
+
}
|
295
|
+
scope = Object.new
|
296
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
297
|
+
template.render(scope).split("").sort
|
298
|
+
end.equals "+\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03user\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00".split("").sort
|
299
|
+
|
300
|
+
asserts "that it can create a child node with different key" do
|
301
|
+
template = rabl %{
|
302
|
+
object @user
|
303
|
+
attribute :name
|
304
|
+
child(@user => :person) { attribute :city }
|
305
|
+
}
|
306
|
+
scope = Object.new
|
307
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
308
|
+
template.render(scope).split("").sort
|
309
|
+
end.equals "-\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x03person\x00\x12\x00\x00\x00\x02city\x00\x03\x00\x00\x00LA\x00\x00\x00".split("").sort
|
310
|
+
end
|
311
|
+
|
312
|
+
context "#glue" do
|
313
|
+
|
314
|
+
asserts "that it glues data from a child node" do
|
315
|
+
template = rabl %{
|
316
|
+
object @user
|
317
|
+
attribute :name
|
318
|
+
glue(@user) { attribute :city }
|
319
|
+
glue(@user) { attribute :age }
|
320
|
+
}
|
321
|
+
scope = Object.new
|
322
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :age => 12)
|
323
|
+
template.render(scope).split("").sort
|
324
|
+
end.equals ")\x00\x00\x00\x02name\x00\x04\x00\x00\x00leo\x00\x02city\x00\x03\x00\x00\x00LA\x00\x10age\x00\f\x00\x00\x00\x00".split("").sort
|
325
|
+
end
|
326
|
+
|
327
|
+
teardown do
|
328
|
+
Rabl.reset_configuration!
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rabl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 0.5.5.
|
5
|
+
version: 0.5.5.e
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nathan Esquenazi
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-02-
|
13
|
+
date: 2012-02-12 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: multi_json
|
@@ -100,7 +100,18 @@ dependencies:
|
|
100
100
|
version: 0.4.5
|
101
101
|
type: :development
|
102
102
|
version_requirements: *id008
|
103
|
-
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: bson
|
105
|
+
prerelease: false
|
106
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.5.2
|
112
|
+
type: :development
|
113
|
+
version_requirements: *id009
|
114
|
+
description: General ruby templating with json, bson, xml and msgpack support
|
104
115
|
email:
|
105
116
|
- nesquena@gmail.com
|
106
117
|
executables: []
|
@@ -251,6 +262,7 @@ files:
|
|
251
262
|
- lib/rabl/version.rb
|
252
263
|
- rabl.gemspec
|
253
264
|
- test.watchr
|
265
|
+
- test/bson_engine_test.rb
|
254
266
|
- test/builder_test.rb
|
255
267
|
- test/configuration_test.rb
|
256
268
|
- test/engine_test.rb
|
@@ -291,8 +303,9 @@ rubyforge_project: rabl
|
|
291
303
|
rubygems_version: 1.8.15
|
292
304
|
signing_key:
|
293
305
|
specification_version: 3
|
294
|
-
summary: General ruby templating
|
306
|
+
summary: General ruby templating with json, bson, xml and msgpack support
|
295
307
|
test_files:
|
308
|
+
- test/bson_engine_test.rb
|
296
309
|
- test/builder_test.rb
|
297
310
|
- test/configuration_test.rb
|
298
311
|
- test/engine_test.rb
|