rabl-rails 0.3.4 → 0.4.0

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