rabl 0.1.0 → 0.1.1

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/Gemfile CHANGED
@@ -2,3 +2,7 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in rabl.gemspec
4
4
  gemspec
5
+
6
+ platforms :mri_18 do
7
+ gem 'SystemTimer'
8
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Nathan Esquenazi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -43,11 +43,22 @@ To declare the data object for use in the template:
43
43
  # app/views/users/show.json.rabl
44
44
  object @user
45
45
 
46
- or a collection works:
46
+ or specify an alias for the object:
47
47
 
48
- object @users
48
+ object @user => :person
49
+ # => { "person" : { ... } }
49
50
 
50
- and this will be used as the default data object for the rendering.
51
+ or pass a collection of objects:
52
+
53
+ collection @users
54
+ # => [ { "user" : { ... } } ]
55
+
56
+ or even specify a root node label for the collection:
57
+
58
+ collection @users => :people
59
+ # => { "people" : [ { "person" : { ... } } ] }
60
+
61
+ and this will be used as the default data for the rendering.
51
62
 
52
63
  ### Attributes ###
53
64
 
@@ -59,13 +70,13 @@ Basic usage of the templater to define a few simple attributes for the response:
59
70
  or use with aliased attributes:
60
71
 
61
72
  # Take the value of model attribute `foo` and name the node `bar`
62
- # { bar : 5 }
63
73
  attribute :foo => :bar
74
+ # => { bar : 5 }
64
75
 
65
76
  or even multiple aliased attributes:
66
77
 
67
- # { baz : <bar value>, animal : <dog value> }
68
78
  attributes :bar => :baz, :dog => :animal
79
+ # => # { baz : <bar value>, animal : <dog value> }
69
80
 
70
81
  ### Child Nodes ###
71
82
 
@@ -154,7 +165,6 @@ Using partials and inheritance can significantly reduce code duplication in your
154
165
 
155
166
  Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full list:
156
167
 
157
- * I am sloppy and failed to unit test this as I cobbled it together. Don't use it in production until I do, for now this is a fun experiment.
158
168
  * No configuration options yet for how to create the json (root nodes) :(
159
169
  * Better Tilt template support (precompiling templates)
160
170
  * Benchmarks and performance optimizations
@@ -177,4 +187,12 @@ There are a few excellent libraries that helped inspire RABL and they are listed
177
187
  * [JSON Builder](https://github.com/dewski/json_builder)
178
188
  * [Argonaut](https://github.com/jbr/argonaut)
179
189
 
180
- Thanks again for all of these great projects.
190
+ Thanks again for all of these great projects.
191
+
192
+ ## Examples
193
+
194
+ See the [examples](https://github.com/nesquena/rabl/tree/master/examples) directory.
195
+
196
+ ## Copyright
197
+
198
+ Copyright © 2011 Nathan Esquenazi. See [MIT-LICENSE](https://github.com/nesquena/rabl/blob/master/MIT-LICENSE) for details.
data/TODO CHANGED
@@ -1,7 +1,3 @@
1
1
  = TODO
2
2
 
3
- - Test the code, child and glue options
4
- - Add support for child collection with "root" for each
5
- - Child should support collections of children
6
- - Child should support symbol associations inside object
7
- - Add support for Rails 3
3
+ * Support xml and json rendering in Tilt template
data/lib/rabl.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rabl/version'
2
+ require 'rabl/helpers'
2
3
  require 'rabl/engine'
3
4
  require 'rabl/builder'
4
5
 
@@ -17,4 +18,4 @@ elsif defined?(Rails) && Rails.version =~ /^2/
17
18
  Rabl.register!
18
19
  elsif defined?(Rails) && Rails.version =~ /^3/
19
20
  Rabl.register!
20
- end
21
+ end
data/lib/rabl/builder.rb CHANGED
@@ -1,10 +1,14 @@
1
1
  module Rabl
2
2
  class Builder
3
+ include Rabl::Helpers
4
+
3
5
  # Constructs a new ejs hash based on given object and options
4
- def initialize(object, options, &block)
5
- @_object = object
6
- @_result = {}
7
- @options = options
6
+ def initialize(data, options={}, &block)
7
+ @options = options
8
+ @_scope = options[:scope]
9
+ @_data = data
10
+ @_object = data_object(data)
11
+ @_result = {}
8
12
  end
9
13
 
10
14
  # Returns a hash representation of the data object
@@ -30,9 +34,9 @@ module Rabl
30
34
  @options[:extends].each do |settings|
31
35
  extends(settings[:file], settings[:options], &settings[:block])
32
36
  end if @options.has_key?(:extends)
33
-
34
- @_root_name ||= data_name(@_object)
35
- (@options[:root] || options[:root]) ? { @_root_name => @_result } : @_result
37
+ # Return Hash
38
+ @_root_name ||= data_name(@_data)
39
+ (@options[:root] || options[:root]) && @_root_name ? { @_root_name => @_result } : @_result
36
40
  end
37
41
 
38
42
  # Indicates an attribute or method should be included in the json output
@@ -44,7 +48,7 @@ module Rabl
44
48
  else # array of attributes
45
49
  options = args.extract_options!
46
50
  args.each do |attribute|
47
- @_result[options[:as] || attribute] = @_object.try(attribute) if @_object.respond_to?(attribute)
51
+ @_result[options[:as] || attribute] = @_object.send(attribute) if @_object && @_object.respond_to?(attribute)
48
52
  end
49
53
  end
50
54
  end
@@ -65,7 +69,8 @@ module Rabl
65
69
  def child(data, options={}, &block)
66
70
  return false unless data.present?
67
71
  name, object = data_name(data), data_object(data)
68
- @_result[name] = self.object_to_hash(object, &block)
72
+ include_root = object.respond_to?(:each) # @users
73
+ @_result[name] = self.object_to_hash(object, :root => include_root, &block) if resolve_condition(options)
69
74
  end
70
75
 
71
76
  # Glues data from a child node to the json_output
@@ -73,7 +78,7 @@ module Rabl
73
78
  def glue(data, &block)
74
79
  return false unless data.present?
75
80
  object = data_object(data)
76
- glued_attributes = self.object_to_hash(object, &block)
81
+ glued_attributes = self.object_to_hash(object, :root => false, &block)
77
82
  @_result.merge!(glued_attributes) if glued_attributes
78
83
  end
79
84
 
@@ -81,42 +86,8 @@ module Rabl
81
86
  # extends("users/show") { attribute :full_name }
82
87
  def extends(file, options={}, &block)
83
88
  options = options.merge(:object => @_object)
84
- result = @options[:engine].partial(file, options, &block)
89
+ result = self.partial(file, options, &block)
85
90
  @_result.merge!(result) if result
86
91
  end
87
-
88
- protected
89
-
90
- # Returns a hash based representation of any data object given ejs template block
91
- # object_to_hash(@user) { attribute :full_name } => { ... }
92
- def object_to_hash(object, source=nil, &block)
93
- @options[:engine].object_to_hash(object, source, &block)
94
- end
95
-
96
- # data_object(data) => <AR Object>
97
- # data_object(@user => :person) => @user
98
- # data_object(:user => :person) => @_object.send(:user)
99
- def data_object(data)
100
- data = (data.is_a?(Hash) && data.keys.one?) ? data.keys.first : data
101
- data.is_a?(Symbol) ? @_object.send(data) : data
102
- end
103
-
104
- # data_name(data) => "user"
105
- # data_name(@user => :person) => :person
106
- # data_name(@users) => :user
107
- def data_name(data)
108
- return data.values.first if data.is_a?(Hash)
109
- @options[:engine].model_name(data)
110
- end
111
-
112
- # resolve_condition(:if => true) => true
113
- # resolve_condition(:if => lambda { |m| false }) => false
114
- # resolve_condition(:unless => lambda { |m| true }) => true
115
- def resolve_condition(options)
116
- return true if options[:if].nil? && options[:unless].nil?
117
- result = options[:if] == true || (options[:if].respond_to?(:call) && options[:if].call(@_object)) if options.has_key?(:if)
118
- result = options[:unless] == false || (options[:unless].respond_to?(:call) && !options[:unless].call(@_object)) if options.has_key?(:unless)
119
- result
120
- end
121
92
  end
122
93
  end
data/lib/rabl/engine.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module Rabl
2
2
  class Engine
3
+ include Rabl::Helpers
4
+
3
5
  # Constructs a new ejs engine based on given vars, handler and declarations
4
6
  # Rabl::Engine.new("...source...", { :format => "xml", :root => true, :view_path => "/path/to/views" })
5
7
  def initialize(source, options={})
@@ -10,20 +12,55 @@ module Rabl
10
12
  # Renders the representation based on source, object, scope and locals
11
13
  # Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
12
14
  def render(scope, locals, &block)
13
- @_locals = locals
14
- @_scope = scope
15
- @_options = @_options.merge(:scope => @_scope, :locals => @_locals, :engine => self)
15
+ @_locals, @_scope = locals, scope
16
16
  self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
17
- @_object = locals[:object] || self.default_object
17
+ @_options[:scope] = @_scope
18
+ @_data = locals[:object] || self.default_object
18
19
  instance_eval(@_source) if @_source.present?
19
20
  instance_eval(&block) if block_given?
20
21
  self.send("to_" + @_options[:format].to_s)
21
22
  end
22
23
 
24
+ # Returns a hash representation of the data object
25
+ # to_hash(:root => true)
26
+ def to_hash(options={})
27
+ data = data_object(@_data)
28
+ if is_record?(data) || !data # object @user
29
+ Rabl::Builder.new(@_data, @_options).to_hash(options)
30
+ elsif data.respond_to?(:each) # collection @users
31
+ data.map { |object| Rabl::Builder.new({ object => data_name(object) }, @_options).to_hash(options) }
32
+ end
33
+ end
34
+
35
+ # Returns a json representation of the data object
36
+ # to_json(:root => true)
37
+ def to_json(options={})
38
+ options = options.reverse_merge(:root => true)
39
+ result = @_collection_name ? { @_collection_name => to_hash(options) } : to_hash(options)
40
+ result.to_json
41
+ end
42
+
43
+ # Returns a json representation of the data object
44
+ # to_xml(:root => true)
45
+ def to_xml(options={})
46
+ options = options.reverse_merge(:root => false)
47
+ to_hash(options).to_xml(:root => data_name(@_data))
48
+ end
49
+
23
50
  # Sets the object to be used as the data source for this template
24
51
  # object(@user)
52
+ # object @user => :person
53
+ # object @users
25
54
  def object(data)
26
- @_object = data unless @_locals[:object]
55
+ @_data = data unless @_locals[:object]
56
+ end
57
+
58
+ # Sets the object as a collection casted to a simple array
59
+ # collection @users
60
+ # collection @users => :people
61
+ def collection(data)
62
+ @_collection_name = data.values.first if data.respond_to?(:each_pair)
63
+ self.object(data_object(data).to_a) if data
27
64
  end
28
65
 
29
66
  # Indicates an attribute or method should be included in the json output
@@ -47,6 +84,7 @@ module Rabl
47
84
  @_options[:code] ||= {}
48
85
  @_options[:code][name] = { :options => options, :block => block }
49
86
  end
87
+ alias_method :node, :code
50
88
 
51
89
  # Creates a child node that is included in json output
52
90
  # child(@user) { attribute :full_name }
@@ -69,84 +107,21 @@ module Rabl
69
107
  @_options[:extends].push({ :file => file, :options => options, :block => block })
70
108
  end
71
109
 
72
- # Renders a partial hash based on another rabl template
73
- # partial("users/show", :object => @user)
74
- def partial(file, options={}, &block)
75
- source = self.fetch_source(file)
76
- self.object_to_hash(options[:object], source, &block)
77
- end
78
-
79
- # Returns a hash representation of the data object
80
- # to_hash(:root => true)
81
- def to_hash(options={})
82
- if is_record?(@_object)
83
- Rabl::Builder.new(@_object, @_options).to_hash(options)
84
- elsif @_object.respond_to?(:each)
85
- @_object.map { |object| Rabl::Builder.new(object, @_options).to_hash(options) }
86
- end
87
- end
88
-
89
- # Returns a json representation of the data object
90
- # to_json(:root => true)
91
- def to_json(options={})
92
- options = options.reverse_merge(:root => true)
93
- to_hash(options).to_json
94
- end
95
-
96
- # Returns a json representation of the data object
97
- # to_xml(:root => true)
98
- def to_xml(options={})
99
- options = options.reverse_merge(:root => false)
100
- to_hash(options).to_xml(:root => model_name(@_object))
101
- end
102
-
103
- # Includes a helper module for RABL
110
+ # Includes a helper module with a RABL template
104
111
  # helper ExampleHelper
105
112
  def helper(*klazzes)
106
113
  klazzes.each { |klazz| self.class.send(:include, klazz) }
107
114
  end
108
115
  alias_method :helpers, :helper
109
116
 
110
- # Returns a hash based representation of any data object given ejs template block
111
- # object_to_hash(@user) { attribute :full_name } => { ... }
112
- def object_to_hash(object, source=nil, &block)
113
- return object unless is_record?(object) || object.respond_to?(:each)
114
- self.class.new(source, :format => "hash", :root => false).render(@_scope, :object => object, &block)
115
- end
116
-
117
- # model_name(@user) => "user"
118
- # model_name([@user]) => "user"
119
- # model_name([]) => "array"
120
- def model_name(data)
121
- if data.respond_to?(:first) && data.first.respond_to?(:valid?)
122
- model_name(data.first).pluralize
123
- else # actual data object
124
- data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase
125
- end
126
- end
127
-
128
117
  protected
129
118
 
130
119
  # Returns a guess at the default object for this template
120
+ # default_object => @user
131
121
  def default_object
132
122
  @_scope.respond_to?(:controller) ?
133
123
  instance_variable_get("@#{@_scope.controller.controller_name}") :
134
124
  nil
135
125
  end
136
-
137
- # Returns true if item is a ORM record; false otherwise
138
- def is_record?(obj)
139
- obj && obj.respond_to?(:valid?)
140
- end
141
-
142
- # Returns source for a given relative file
143
- # fetch_source("show") => "...contents..."
144
- def fetch_source(file)
145
- root_path = Rails.root if defined?(Rails)
146
- root_path = Padrino.root if defined?(Padrino)
147
- view_path = @_options[:view_path] || File.join(root_path, "app/views/")
148
- file_path = Dir[File.join(view_path, file + "*.rabl")].first
149
- File.read(file_path) if file_path
150
- end
151
126
  end
152
127
  end
@@ -0,0 +1,72 @@
1
+ module Rabl
2
+ module Helpers
3
+ # data_object(data) => <AR Object>
4
+ # data_object(@user => :person) => @user
5
+ # data_object(:user => :person) => @_object.send(:user)
6
+ def data_object(data)
7
+ data = (data.is_a?(Hash) && data.keys.one?) ? data.keys.first : data
8
+ data.is_a?(Symbol) && @_object ? @_object.send(data) : data
9
+ end
10
+
11
+ # data_name(data) => "user"
12
+ # data_name(@user => :person) => :person
13
+ # data_name(@users) => :user
14
+ # data_name([@user]) => "user"
15
+ # data_name([]) => "array"
16
+ def data_name(data)
17
+ return nil unless data # nil or false
18
+ return data.values.first if data.is_a?(Hash) # @user => :user
19
+ data = @_object.send(data) if data.is_a?(Symbol) && @_object # :address
20
+ if data.respond_to?(:first) && data.first.respond_to?(:valid?)
21
+ data_name(data.first).pluralize
22
+ else # actual data object
23
+ object_name = @_collection_name.to_s.singularize if @_collection_name
24
+ object_name ||= data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase
25
+ object_name
26
+ end
27
+ end
28
+
29
+ # Returns true if item is a ORM record; false otherwise
30
+ # is_record?(@user) => true
31
+ # is_record?([]) => false
32
+ def is_record?(obj)
33
+ obj && data_object(obj).respond_to?(:valid?)
34
+ end
35
+
36
+ # Returns a hash based representation of any data object given ejs template block
37
+ # object_to_hash(@user) { attribute :full_name } => { ... }
38
+ # object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
39
+ def object_to_hash(object, options={}, &block)
40
+ return object unless is_record?(object) || object.respond_to?(:each)
41
+ engine_options = { :format => "hash", :root => (options[:root] || false) }
42
+ Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
43
+ end
44
+
45
+ # resolve_condition(:if => true) => true
46
+ # resolve_condition(:if => lambda { |m| false }) => false
47
+ # resolve_condition(:unless => lambda { |m| true }) => true
48
+ def resolve_condition(options)
49
+ return true if options[:if].nil? && options[:unless].nil?
50
+ result = options[:if] == true || (options[:if].respond_to?(:call) && options[:if].call(@_object)) if options.has_key?(:if)
51
+ result = options[:unless] == false || (options[:unless].respond_to?(:call) && !options[:unless].call(@_object)) if options.has_key?(:unless)
52
+ result
53
+ end
54
+
55
+ # Renders a partial hash based on another rabl template
56
+ # partial("users/show", :object => @user)
57
+ def partial(file, options={}, &block)
58
+ source = self.fetch_source(file)
59
+ self.object_to_hash(options[:object], :source => source, &block)
60
+ end
61
+
62
+ # Returns source for a given relative file
63
+ # fetch_source("show", :view_path => "...") => "...contents..."
64
+ def fetch_source(file, options={})
65
+ root_path = Rails.root if defined?(Rails)
66
+ root_path = Padrino.root if defined?(Padrino)
67
+ view_path = options[:view_path] || File.join(root_path, "app/views/")
68
+ file_path = Dir[File.join(view_path, file + "*.rabl")].first
69
+ File.read(file_path) if file_path
70
+ end
71
+ end
72
+ end
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/rabl.gemspec CHANGED
@@ -21,4 +21,6 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_development_dependency 'riot', '~>0.12.3'
23
23
  s.add_development_dependency 'rr', '~>1.0.2'
24
+ s.add_development_dependency 'mongoid'
25
+ s.add_development_dependency 'bson_ext'
24
26
  end
data/test/builder_test.rb CHANGED
@@ -1 +1,190 @@
1
- require File.expand_path('../teststrap',__FILE__)
1
+ require File.expand_path('../teststrap', __FILE__)
2
+ require File.expand_path('../models/user', __FILE__)
3
+
4
+ context "Rabl::Builder" do
5
+
6
+ helper(:builder) { |obj,opt| Rabl::Builder.new(obj, opt) }
7
+ helper(:get_result) { |obj| obj.instance_variable_get("@_result") }
8
+ helper(:get_hash) { |obj, root| obj.to_hash(:root => root) }
9
+
10
+ setup do
11
+ @users = [User.new, User.new]
12
+ @user = User.new
13
+ builder User.new, {}
14
+ end
15
+
16
+ context "#initialize" do
17
+ asserts_topic.assigns :_object
18
+ asserts_topic.assigns :options
19
+ asserts_topic.assigns :_result
20
+ end
21
+
22
+ context "#to_hash" do
23
+
24
+ context "when given a simple object" do
25
+
26
+ setup { builder User.new, {} }
27
+ asserts "that the object is set properly" do
28
+ topic.attribute :name
29
+ get_hash(topic, true)
30
+ end.equivalent_to({ "user" => { :name => "rabl" } })
31
+
32
+ end
33
+
34
+ context "when given an object alias" do
35
+
36
+ setup { builder({ User.new => "person" }, {}) }
37
+ asserts "that the object is set properly" do
38
+ topic.attribute :name
39
+ get_hash(topic, true)
40
+ end.equivalent_to({ "person" => { :name => "rabl" } })
41
+
42
+ end
43
+
44
+ context "when specified with no root" do
45
+
46
+ setup { builder User.new, {} }
47
+ asserts "that the object is set properly" do
48
+ topic.attribute :name
49
+ get_hash(topic, false)
50
+ end.equivalent_to({ :name => "rabl" })
51
+
52
+ end
53
+
54
+ end
55
+
56
+ context "#attribute" do
57
+
58
+ context "when given an array" do
59
+
60
+ asserts "that the node" do
61
+ topic.attribute :name, :city
62
+ get_result(topic)
63
+ end.equivalent_to({:name => 'rabl', :city => 'irvine'})
64
+
65
+ denies "that with a non-existent attribute the node" do
66
+ topic.attribute :fake
67
+ get_result(topic)[:fake]
68
+ end.exists
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
+
86
+ end
87
+
88
+ context "#code" do
89
+
90
+ asserts "that it has node :foo" do
91
+ topic.code(:foo) { "bar" }
92
+ get_result(topic)
93
+ end.equivalent_to({:foo => 'bar'})
94
+
95
+ asserts "that using object it has node :boo" do
96
+ topic.code(:baz) { |u| u.city }
97
+ get_result(topic)
98
+ end.equivalent_to({:foo => 'bar', :baz => 'irvine'})
99
+ end
100
+
101
+ context "#child" do
102
+
103
+ denies "that it generates if no data present" do
104
+ topic.child nil
105
+ end
106
+
107
+ asserts "that it generates with a hash" do
108
+ b = builder @user, {}
109
+ mock(b).object_to_hash(@user,{ :root => false }).returns('xyz').subject
110
+
111
+ b.child(@user => :user) { attribute :name }
112
+ get_result(b)
113
+ end.equivalent_to({ :user => 'xyz'})
114
+
115
+ 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)
120
+ end.equivalent_to({ :person => { :name => "rabl" } })
121
+
122
+ asserts "that it generates with an object" do
123
+ b = builder @user, {}
124
+ 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)
129
+ end.equivalent_to({ :user => 'xyz'})
130
+
131
+ asserts "that it generates with an collection" do
132
+ b = builder @user, {}
133
+ mock(b).data_name(@users) { :users }
134
+ mock(b).object_to_hash(@users,{ :root => true }).returns('xyz').subject
135
+
136
+ b.child(@users) { attribute :name }
137
+ get_result(b)
138
+ end.equivalent_to({ :users => 'xyz'})
139
+ end
140
+
141
+ context "#glue" do
142
+
143
+ denies "that it generates if no data present" do
144
+ topic.glue nil
145
+ end
146
+
147
+ asserts "that it generates the glue attributes" do
148
+ b = builder @user, {}
149
+ mock(b).object_to_hash(@user,{ :root => false }).returns({:user => 'xyz'}).subject
150
+
151
+ b.glue(@user) { attribute :name }
152
+ get_result(b)
153
+ end.equivalent_to({ :user => 'xyz' })
154
+
155
+ asserts "that it appends the glue attributes to result" do
156
+ b = builder @user, {}
157
+
158
+ b.glue(@user) { attribute :name => :user_name }
159
+ get_result(b)
160
+ end.equivalent_to({ :user_name => 'rabl' })
161
+
162
+ asserts "that it does not generate new attributes if no glue attributes are present" do
163
+ b = builder @user, {}
164
+ mock(b).object_to_hash(@user,{ :root => false }).returns({}).subject
165
+
166
+ b.glue(@user) { attribute :name }
167
+ get_result(b)
168
+ end.equals({})
169
+ end
170
+
171
+ context "#extend" do
172
+
173
+ asserts "that it does not genereate if no data is present" do
174
+ b = builder @user, {}
175
+ mock(b).partial('users/show',{ :object => @user}).returns({}).subject
176
+
177
+ b.extends('users/show') { attribute :name }
178
+ get_result(b)
179
+ end.equals({})
180
+
181
+ asserts "that it generates if data is present" do
182
+ b = builder @user, {}
183
+ mock(b).partial('users/show',{ :object => @user}).returns({:user => 'xyz'}).subject
184
+
185
+ b.extends('users/show') { attribute :name }
186
+ get_result(b)
187
+ end.equivalent_to({:user => 'xyz'})
188
+ end
189
+
190
+ end
@@ -0,0 +1,9 @@
1
+ require 'mongoid'
2
+
3
+ class User
4
+ include Mongoid::Document
5
+
6
+ field :name, :type => String, :default => 'rabl'
7
+ field :city, :type => String, :default => 'irvine'
8
+ field :age, :type => Integer, :default => 24
9
+ end
data/test/teststrap.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'riot'
2
2
  require 'riot/rr'
3
+ require 'mongo'
4
+ require 'mongoid'
3
5
  require File.expand_path('../../lib/rabl',__FILE__)
4
6
 
5
7
  Riot.pretty_dots
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 0
10
- version: 0.1.0
5
+ version: 0.1.1
11
6
  platform: ruby
12
7
  authors:
13
8
  - Nathan Esquenazi
@@ -15,7 +10,8 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-04-13 00:00:00 Z
13
+ date: 2011-04-18 00:00:00 -07:00
14
+ default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
21
17
  name: riot
@@ -25,11 +21,6 @@ dependencies:
25
21
  requirements:
26
22
  - - ~>
27
23
  - !ruby/object:Gem::Version
28
- hash: 41
29
- segments:
30
- - 0
31
- - 12
32
- - 3
33
24
  version: 0.12.3
34
25
  type: :development
35
26
  version_requirements: *id001
@@ -41,14 +32,31 @@ dependencies:
41
32
  requirements:
42
33
  - - ~>
43
34
  - !ruby/object:Gem::Version
44
- hash: 19
45
- segments:
46
- - 1
47
- - 0
48
- - 2
49
35
  version: 1.0.2
50
36
  type: :development
51
37
  version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: mongoid
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: bson_ext
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
52
60
  description: General ruby templating for json or xml
53
61
  email:
54
62
  - nesquena@gmail.com
@@ -61,6 +69,7 @@ extra_rdoc_files: []
61
69
  files:
62
70
  - .gitignore
63
71
  - Gemfile
72
+ - MIT-LICENSE
64
73
  - README.md
65
74
  - Rakefile
66
75
  - TODO
@@ -70,14 +79,17 @@ files:
70
79
  - lib/rabl.rb
71
80
  - lib/rabl/builder.rb
72
81
  - lib/rabl/engine.rb
82
+ - lib/rabl/helpers.rb
73
83
  - lib/rabl/template.rb
74
84
  - lib/rabl/version.rb
75
85
  - rabl.gemspec
76
86
  - test.watchr
77
87
  - test/builder_test.rb
78
88
  - test/engine_test.rb
89
+ - test/models/user.rb
79
90
  - test/template_test.rb
80
91
  - test/teststrap.rb
92
+ has_rdoc: true
81
93
  homepage: https://github.com/nesquena/rabl
82
94
  licenses: []
83
95
 
@@ -91,28 +103,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
103
  requirements:
92
104
  - - ">="
93
105
  - !ruby/object:Gem::Version
94
- hash: 3
95
- segments:
96
- - 0
97
106
  version: "0"
98
107
  required_rubygems_version: !ruby/object:Gem::Requirement
99
108
  none: false
100
109
  requirements:
101
110
  - - ">="
102
111
  - !ruby/object:Gem::Version
103
- hash: 3
104
- segments:
105
- - 0
106
112
  version: "0"
107
113
  requirements: []
108
114
 
109
115
  rubyforge_project: rabl
110
- rubygems_version: 1.7.2
116
+ rubygems_version: 1.5.2
111
117
  signing_key:
112
118
  specification_version: 3
113
119
  summary: General ruby templating for json or xml
114
120
  test_files:
115
121
  - test/builder_test.rb
116
122
  - test/engine_test.rb
123
+ - test/models/user.rb
117
124
  - test/template_test.rb
118
125
  - test/teststrap.rb