rabl 0.1.0 → 0.1.1

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