rabl-rails 0.3.4 → 0.4.0

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.
Files changed (54) hide show
  1. data/.travis.yml +2 -2
  2. data/CHANGELOG.md +10 -0
  3. data/Gemfile +5 -9
  4. data/README.md +5 -3
  5. data/Rakefile +2 -2
  6. data/lib/rabl-rails.rb +21 -74
  7. data/lib/rabl-rails/compiler.rb +28 -38
  8. data/lib/rabl-rails/configuration.rb +48 -0
  9. data/lib/rabl-rails/handler.rb +3 -1
  10. data/lib/rabl-rails/helpers.rb +7 -0
  11. data/lib/rabl-rails/library.rb +43 -16
  12. data/lib/rabl-rails/nodes.rb +6 -0
  13. data/lib/rabl-rails/nodes/attribute.rb +17 -0
  14. data/lib/rabl-rails/nodes/child.rb +12 -0
  15. data/lib/rabl-rails/nodes/code.rb +19 -0
  16. data/lib/rabl-rails/nodes/condition.rb +14 -0
  17. data/lib/rabl-rails/nodes/glue.rb +25 -0
  18. data/lib/rabl-rails/nodes/node.rb +9 -0
  19. data/lib/rabl-rails/railtie.rb +0 -2
  20. data/lib/rabl-rails/renderer.rb +15 -13
  21. data/lib/rabl-rails/renderers/hash.rb +85 -0
  22. data/lib/rabl-rails/renderers/json.rb +9 -5
  23. data/lib/rabl-rails/renderers/plist.rb +6 -4
  24. data/lib/rabl-rails/renderers/xml.rb +6 -3
  25. data/lib/rabl-rails/responder.rb +1 -1
  26. data/lib/rabl-rails/template.rb +11 -5
  27. data/lib/rabl-rails/version.rb +1 -1
  28. data/lib/rabl-rails/visitors.rb +2 -0
  29. data/lib/rabl-rails/visitors/to_hash.rb +131 -0
  30. data/lib/rabl-rails/visitors/visitor.rb +17 -0
  31. data/rabl-rails.gemspec +3 -5
  32. data/test/helper.rb +75 -0
  33. data/test/renderers/test_hash_renderer.rb +90 -0
  34. data/test/renderers/test_json_renderer.rb +46 -0
  35. data/test/renderers/test_plist_renderer.rb +42 -0
  36. data/test/renderers/test_xml_renderer.rb +37 -0
  37. data/test/test_compiler.rb +283 -0
  38. data/test/test_configuration.rb +31 -0
  39. data/test/test_hash_visitor.rb +224 -0
  40. data/test/test_library.rb +85 -0
  41. data/test/{render_test.rb → test_render.rb} +18 -24
  42. metadata +99 -108
  43. data/lib/rabl-rails/condition.rb +0 -10
  44. data/lib/rabl-rails/renderers/base.rb +0 -171
  45. data/test/base_renderer_test.rb +0 -67
  46. data/test/cache_templates_test.rb +0 -35
  47. data/test/compiler_test.rb +0 -233
  48. data/test/deep_nesting_test.rb +0 -56
  49. data/test/keyword_test.rb +0 -47
  50. data/test/non_restful_response_test.rb +0 -35
  51. data/test/renderers/json_renderer_test.rb +0 -189
  52. data/test/renderers/plist_renderer_test.rb +0 -135
  53. data/test/renderers/xml_renderer_test.rb +0 -137
  54. data/test/test_helper.rb +0 -68
@@ -1,56 +0,0 @@
1
- require 'test_helper'
2
-
3
- class DeepNestingTest < ActiveSupport::TestCase
4
-
5
- class Post
6
- attr_accessor :id, :title
7
-
8
- def initialize(id, title)
9
- @id, @title = id, title
10
- end
11
-
12
- def comments
13
- [Struct.new(:id, :content).new(1, 'first'), Struct.new(:id, :content).new(2, 'second')]
14
- end
15
- end
16
-
17
- setup do
18
- RablRails::Library.reset_instance
19
- @post = Post.new(42, 'I rock !')
20
- @user = User.new(1, 'foobar', 'male')
21
- @user.stub(:posts).and_return([@post])
22
-
23
- @context = Context.new
24
- @context.assigns['user'] = @user
25
- @context.virtual_path = 'users/show'
26
- @context.stub(:lookup_context).and_return(double(:find_template => double(:source => %{ object :@comment\n attribute :content })))
27
- end
28
-
29
- test "compile and render deep nesting template" do
30
- source = %{
31
- object :@user
32
- attributes :id, :name
33
- child :posts do
34
- attribute :title
35
- child :comments do
36
- extends 'comments/show'
37
- end
38
- end
39
- }
40
-
41
- assert_equal(MultiJson.encode(:user => {
42
- :id => 1,
43
- :name => 'foobar',
44
- :posts => [{
45
- :title => 'I rock !',
46
- :comments => [
47
- { :content => 'first' },
48
- { :content => 'second' }
49
- ]
50
- }]
51
- }), RablRails::Library.instance.get_rendered_template(source, @context))
52
- end
53
- end
54
-
55
-
56
-
@@ -1,47 +0,0 @@
1
- require 'test_helper'
2
-
3
- class KeywordTest < ActiveSupport::TestCase
4
- class Collection
5
- attr_accessor :id, :name
6
-
7
- def initialize(id, name)
8
- @id = id
9
- @name = name
10
- end
11
-
12
- def cover(size)
13
- "foo_#{size}"
14
- end
15
- end
16
-
17
- setup do
18
- RablRails::Library.reset_instance
19
- @context = Context.new
20
- @user = User.new(1, 'Marty')
21
- @collections = [Collection.new(1, 'first'), Collection.new(2, 'last')]
22
- @context.assigns['user'] = @user
23
- @context.assigns['collections'] = @collections
24
- @context.virtual_path = 'user/show'
25
- @context.stub(lookup_context: nil)
26
- end
27
-
28
- test "collections model should not collide with rabl-rails reserved keyword" do
29
- source = %{
30
- object :@user
31
- child(:@collections => :collections) do
32
- attributes :id, :name
33
- node(:cover_url) { |c|
34
- c.cover(:medium)
35
- }
36
- end
37
- }
38
-
39
- assert_equal(MultiJson.encode(
40
- user: { collections: [{
41
- id: 1, name: 'first', cover_url: "foo_medium"
42
- }, {
43
- id: 2, name: 'last', cover_url: "foo_medium"
44
- }] }
45
- ), RablRails::Library.instance.get_rendered_template(source, @context))
46
- end
47
- end
@@ -1,35 +0,0 @@
1
- require 'test_helper'
2
-
3
- class NonRestfulResponseTest < ActiveSupport::TestCase
4
- setup do
5
- RablRails::Library.reset_instance
6
-
7
- @user = User.new(1, 'foo', 'male')
8
- @user.stub_chain(:posts, :count).and_return(10)
9
- @user.stub(:respond_to?).with(:each).and_return(false)
10
-
11
- @context = Context.new
12
- @context.stub(:instance_variable_get).with(:@user).and_return(@user)
13
- @context.stub(:instance_variable_get).with(:@virtual_path).and_return('user/show')
14
- @context.stub(:instance_variable_get).with(:@_assigns).and_return({'user' => @user})
15
- @context.stub(:lookup_context)
16
- end
17
-
18
- test "compile and render non restful resource" do
19
- source = %{
20
- object false
21
- node(:post_count) { @user.posts.count }
22
- child(:@user => :user) do
23
- attributes :id, :name
24
- end
25
- }
26
-
27
- assert_equal(MultiJson.encode({
28
- :post_count => 10,
29
- :user => {
30
- :id => 1,
31
- :name => 'foo'
32
- }
33
- }), RablRails::Library.instance.get_rendered_template(source, @context))
34
- end
35
- end
@@ -1,189 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestJsonRenderer < ActiveSupport::TestCase
4
-
5
- setup do
6
- @data = User.new(1, 'foobar', 'male')
7
-
8
- @context = Context.new
9
- @context.assigns['data'] = @data
10
-
11
- @template = RablRails::CompiledTemplate.new
12
- @template.data = :@data
13
- end
14
-
15
- def render_json_output
16
- RablRails::Renderers::JSON.new(@context).render(@template)
17
- end
18
-
19
- test "render object wth empty template" do
20
- @template.source = {}
21
- assert_equal %q({}), render_json_output
22
- end
23
-
24
- test "render collection with empty template" do
25
- @context.assigns['data'] = [@data]
26
- @template.source = {}
27
- assert_equal %q([{}]), render_json_output
28
- end
29
-
30
- test "render object with local methods (used by decent_exposure)" do
31
- @context.stub(:user).and_return(@data)
32
- @template.data = :user
33
- @template.source = { :id => :id }
34
- assert_equal %q({"id":1}), render_json_output
35
- end
36
-
37
- test "render single object attributes" do
38
- @template.source = { :id => :id, :name => :name }
39
- assert_equal %q({"id":1,"name":"foobar"}), render_json_output
40
- end
41
-
42
- test "render child with object association" do
43
- @data.stub(:address).and_return(double(:city => 'Paris'))
44
- @template.source = { :address => { :_data => :address, :city => :city } }
45
- assert_equal %q({"address":{"city":"Paris"}}), render_json_output
46
- end
47
-
48
- test "render child with arbitrary data source" do
49
- @template.source = { :author => { :_data => :@data, :name => :name } }
50
- assert_equal %q({"author":{"name":"foobar"}}), render_json_output
51
- end
52
-
53
- test "render child with local methods (used by decent_exposure)" do
54
- @context.stub(:user).and_return(@data)
55
- @template.source = { :author => { :_data => :user, :name => :name } }
56
- assert_equal %q({"author":{"name":"foobar"}}), render_json_output
57
- end
58
-
59
- test "render glued attributes from single object" do
60
- @template.source = { :_glue0 => { :_data => :@data, :name => :name } }
61
- assert_equal %q({"name":"foobar"}), render_json_output
62
- end
63
-
64
- test "render glued node" do
65
- @template.source = { :_glue0 => { :_data => :@data, :foo => lambda { |u| u.name } } }
66
- assert_equal(%q({"foo":"foobar"}), render_json_output)
67
- end
68
-
69
- test "render collection with attributes" do
70
- @data = [User.new(1, 'foo', 'male'), User.new(2, 'bar', 'female')]
71
- @context.assigns['data'] = @data
72
- @template.source = { :uid => :id, :name => :name, :gender => :sex }
73
- assert_equal %q([{"uid":1,"name":"foo","gender":"male"},{"uid":2,"name":"bar","gender":"female"}]), render_json_output
74
- end
75
-
76
- test "render node property" do
77
- proc = lambda { |object| object.name }
78
- @template.source = { :name => proc }
79
- assert_equal %q({"name":"foobar"}), render_json_output
80
- end
81
-
82
- test "render node property with true condition" do
83
- condition = lambda { |u| true }
84
- proc = lambda { |object| object.name }
85
- @template.source = { :name => [condition, proc] }
86
- assert_equal %q({"name":"foobar"}), render_json_output
87
- end
88
-
89
- test "render node property with false condition" do
90
- condition = lambda { |u| false }
91
- proc = lambda { |object| object.name }
92
- @template.source = { :name => [condition, proc] }
93
- assert_equal %q({}), render_json_output
94
- end
95
-
96
- test "node with context method call" do
97
- @context.stub(:respond_to?).with(:@data).and_return(false)
98
- @context.stub(:respond_to?).with(:context_method).and_return(true)
99
- @context.stub(:context_method).and_return('marty')
100
- proc = lambda { |object| context_method }
101
- @template.source = { :name => proc }
102
- assert_equal %q({"name":"marty"}), render_json_output
103
- end
104
-
105
- test "partial should be evaluated at rendering time" do
106
- # Set assigns
107
- @context.assigns['user'] = @data
108
-
109
- # Stub Library#get
110
- t = RablRails::CompiledTemplate.new
111
- t.source = { :name => :name }
112
- RablRails::Library.reset_instance
113
- RablRails::Library.instance.should_receive(:compile_template_from_path).with('users/base').and_return(t)
114
-
115
- @template.data = false
116
- @template.source = { :user => ->(s) { partial('users/base', :object => @user) } }
117
-
118
- assert_equal %q({"user":{"name":"foobar"}}), render_json_output
119
- end
120
-
121
- test "partial with no values should raise an error" do
122
- @template.data = false
123
- @template.source = { :user => ->(s) { partial('users/base') } }
124
-
125
- assert_raises(RablRails::Renderers::PartialError) { render_json_output }
126
- end
127
-
128
- test "partial with empty values should not raise an error" do
129
- @template.data = false
130
- @template.source = { :users => ->(s) { partial('users/base', :object => []) } }
131
-
132
- assert_equal %q({"users":[]}), render_json_output
133
- end
134
-
135
- test "condition blocks are transparent if the condition passed" do
136
- c = RablRails::Condition.new(->(u) { true }, { :name => :name })
137
- @template.source = { :_if0 => c }
138
- assert_equal %q({"name":"foobar"}), render_json_output
139
- end
140
-
141
- test "condition blocks are ignored if the condition is not met" do
142
- c = RablRails::Condition.new(->(u) { false }, { :name => :name })
143
- @template.source = { :_if0 => c }
144
- assert_equal %q({}), render_json_output
145
- end
146
-
147
- test "render object with root node" do
148
- RablRails.include_json_root = true
149
- @template.root_name = :author
150
- @template.source = { :id => :id, :name => :name }
151
- assert_equal %q({"author":{"id":1,"name":"foobar"}}), render_json_output
152
- end
153
-
154
- test "render object with root options set to false" do
155
- RablRails.include_json_root = false
156
- @template.root_name = :author
157
- @template.source = { :id => :id, :name => :name }
158
- assert_equal %q({"id":1,"name":"foobar"}), render_json_output
159
- end
160
-
161
- test "merge should raise is return from given block is not a hash" do
162
- @template.source = { :_merge0 => ->(c) { 'foo' } }
163
- assert_raises(RablRails::Renderers::PartialError) { render_json_output }
164
- end
165
-
166
- test "result from merge is merge inside current response" do
167
- @template.source = { :_merge0 => ->(c) { { :custom => c.name } } }
168
- assert_equal %q({"custom":"foobar"}), render_json_output
169
- end
170
-
171
- test "render with jsonp callback" do
172
- RablRails.enable_jsonp_callbacks = true
173
- @context.stub(:params).and_return({ callback: 'some_callback' })
174
- @template.source = { :name => :name }
175
- assert_equal %q[some_callback({"name":"foobar"})], render_json_output
176
- end
177
-
178
- test "cache key should be different from Base to avoid name collisions" do
179
- ActionController::Base.stub(:perform_caching).and_return(true)
180
- @data.stub(:cache_key).and_return('data_cache_key')
181
- @template.cache_key = nil
182
-
183
- @cache = double
184
- @cache.should_receive(:fetch).with('data_cache_key.json').and_return(%("some":"json"))
185
- Rails.stub(:cache).and_return(@cache)
186
-
187
- assert_equal %("some":"json"), render_json_output
188
- end
189
- end
@@ -1,135 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestPlistRenderer < ActiveSupport::TestCase
4
- INDENT_REGEXP = /\n(\s)*/
5
- HEADER_REGEXP = /<\?[^>]+><![^>]+>/
6
-
7
- setup do
8
- @data = User.new(1, 'foobar', 'male')
9
-
10
- @context = Context.new
11
- @context.assigns['data'] = @data
12
-
13
- @template = RablRails::CompiledTemplate.new
14
- @template.data = :@data
15
- @template.root_name = :user
16
- end
17
-
18
- def render_plist_output
19
- output = RablRails::Renderers::PLIST.new(@context).render(@template).to_s.gsub!(INDENT_REGEXP, '')
20
- output.sub!(HEADER_REGEXP, '').gsub!(%r(</?plist[^>]*>), '').sub!(%r(<dict/?>), '').sub(%r(</dict>), '')
21
- end
22
-
23
- test "plist engine should responsd to #dump" do
24
- assert_raises(RuntimeError) { RablRails.plist_engine = Object.new }
25
- end
26
-
27
- test "render object wth empty template" do
28
- @template.source = {}
29
- assert_equal %q(), render_plist_output
30
- end
31
-
32
- test "render collection with empty template" do
33
- @context.assigns['data'] = [@data]
34
- @template.source = {}
35
- assert_equal %q(<array></array>), render_plist_output
36
- end
37
-
38
- test "render object with local methods (used by decent_exposure)" do
39
- @context.stub(:user).and_return(@data)
40
- @template.data = :user
41
- @template.source = { :id => :id }
42
- assert_equal %q(<key>id</key><integer>1</integer>), render_plist_output
43
- end
44
-
45
- test "render single object attributes" do
46
- @template.source = { :id => :id, :name => :name }
47
- assert_equal %q(<key>id</key><integer>1</integer><key>name</key><string>foobar</string>), render_plist_output
48
- end
49
-
50
- test "render child with object association" do
51
- @data.stub(:address).and_return(double(:city => 'Paris'))
52
- @template.source = { :address => { :_data => :address, :city => :city } }
53
- assert_equal %q(<key>address</key><dict><key>city</key><string>Paris</string></dict>), render_plist_output
54
- end
55
-
56
- test "render child with arbitrary data source" do
57
- @template.source = { :author => { :_data => :@data, :name => :name } }
58
- assert_equal %q(<key>author</key><dict><key>name</key><string>foobar</string></dict>), render_plist_output
59
- end
60
-
61
- test "render child with local methods (used by decent_exposure)" do
62
- @context.stub(:user).and_return(@data)
63
- @template.source = { :author => { :_data => :user, :name => :name } }
64
- assert_equal %q(<key>author</key><dict><key>name</key><string>foobar</string></dict>), render_plist_output
65
- end
66
-
67
- test "render node property" do
68
- proc = lambda { |object| object.name }
69
- @template.source = { :name => proc }
70
- assert_equal %q(<key>name</key><string>foobar</string>), render_plist_output
71
- end
72
-
73
- test "render node property with true condition" do
74
- condition = lambda { |u| true }
75
- proc = lambda { |object| object.name }
76
- @template.source = { :name => [condition, proc] }
77
- assert_equal %q(<key>name</key><string>foobar</string>), render_plist_output
78
- end
79
-
80
- test "render node property with false condition" do
81
- condition = lambda { |u| false }
82
- proc = lambda { |object| object.name }
83
- @template.source = { :name => [condition, proc] }
84
- assert_equal %q(), render_plist_output
85
- end
86
-
87
- test "node with context method call" do
88
- @context.stub(:respond_to?).with(:@data).and_return(false)
89
- @context.stub(:respond_to?).with(:context_method).and_return(true)
90
- @context.stub(:context_method).and_return('marty')
91
- proc = lambda { |object| context_method }
92
- @template.source = { :name => proc }
93
- assert_equal %q(<key>name</key><string>marty</string>), render_plist_output
94
- end
95
-
96
- test "partial with no values should raise an error" do
97
- @template.data = false
98
- @template.source = { :user => ->(s) { partial('users/base') } }
99
-
100
- assert_raises(RablRails::Renderers::PartialError) { render_plist_output }
101
- end
102
-
103
- test "partial with empty values should not raise an error" do
104
- @template.data = false
105
- @template.source = { :users => ->(s) { partial('users/base', :object => []) } }
106
-
107
- assert_equal %q(<key>users</key><array/>), render_plist_output
108
- end
109
-
110
- test "condition blocks are transparent if the condition passed" do
111
- c = RablRails::Condition.new(->(u) { true }, { :name => :name })
112
- @template.source = { :_if0 => c }
113
- assert_equal %q(<key>name</key><string>foobar</string>), render_plist_output
114
- end
115
-
116
- test "condition blocks are ignored if the condition is not met" do
117
- c = RablRails::Condition.new(->(u) { false }, { :name => :name })
118
- @template.source = { :_if0 => c }
119
- assert_equal %q(), render_plist_output
120
- end
121
-
122
- test "render object with root node" do
123
- RablRails.include_plist_root = true
124
- @template.root_name = :author
125
- @template.source = { :id => :id, :name => :name }
126
- assert_equal %q(<key>author</key><dict><key>id</key><integer>1</integer><key>name</key><string>foobar</string></dict>), render_plist_output
127
- end
128
-
129
- test "render object with root options set to false" do
130
- RablRails.include_plist_root = false
131
- @template.root_name = :author
132
- @template.source = { :id => :id, :name => :name }
133
- assert_equal %q(<key>id</key><integer>1</integer><key>name</key><string>foobar</string>), render_plist_output
134
- end
135
- end