rabl 0.6.5 → 0.6.6

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 (30) hide show
  1. data/CHANGELOG.md +6 -0
  2. data/README.md +4 -1
  3. data/Rakefile +1 -1
  4. data/fixtures/ashared/NOTES +18 -18
  5. data/fixtures/ashared/views/layouts/application.html.erb +9 -6
  6. data/fixtures/ashared/views/posts/_show_footer_script.js.erb +1 -0
  7. data/fixtures/ashared/views_rails_3/layouts/application.html.erb +13 -0
  8. data/fixtures/ashared/views_rails_3/posts/_show_footer_script.js.erb +1 -0
  9. data/fixtures/ashared/views_rails_3/posts/date.rabl +3 -0
  10. data/fixtures/ashared/views_rails_3/posts/index.html.erb +3 -0
  11. data/fixtures/ashared/views_rails_3/posts/index.rabl +12 -0
  12. data/fixtures/ashared/views_rails_3/posts/show.html.erb +3 -0
  13. data/fixtures/ashared/views_rails_3/posts/show.rabl +17 -0
  14. data/fixtures/ashared/views_rails_3/users/index.json.rabl +3 -0
  15. data/fixtures/ashared/views_rails_3/users/phone_number.json.rabl +6 -0
  16. data/fixtures/ashared/views_rails_3/users/show.json.rabl +16 -0
  17. data/fixtures/padrino_test/test/app/controllers/posts_controller_test.rb +2 -2
  18. data/fixtures/rails2/test/functionals/posts_controller_test.rb +2 -2
  19. data/fixtures/rails3/Gemfile +1 -1
  20. data/fixtures/rails3/app/controllers/posts_controller.rb +1 -1
  21. data/fixtures/rails3/test/functional/posts_controller_test.rb +3 -73
  22. data/fixtures/rails3_2/app/controllers/posts_controller.rb +1 -1
  23. data/fixtures/rails3_2/test/functional/posts_controller_test.rb +85 -5
  24. data/fixtures/sinatra_test/test/functional/posts_controller_test.rb +2 -2
  25. data/lib/rabl/partials.rb +8 -5
  26. data/lib/rabl/version.rb +1 -1
  27. data/test/integration/posts_controller_test.rb +2 -2
  28. data/test/integration/rails3_2/posts_controller_test.rb +188 -0
  29. data/test/integration/rails3_2/users_controller_test.rb +87 -0
  30. metadata +17 -2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.6.6
4
+
5
+ * Even more improvements to Rails template resolution (Thanks @databyte)
6
+ * Added fixture integration tests for rendering rabl inline from html (Thanks @databyte)
7
+ * Added useful note to README about Padrino (Thanks @simonc)
8
+
3
9
  ## 0.6.5
4
10
 
5
11
  * Fixed issue with multi_json version use ~> 1.0 (Thanks @sferik)
data/README.md CHANGED
@@ -36,6 +36,9 @@ and run `bundle install` to install the dependency.
36
36
 
37
37
  If you are using **Rails 2.X, Rails 3.X or Padrino**, RABL works without configuration.
38
38
 
39
+ **Important:** With Padrino, be sure that **the rabl gem is listed after the padrino gem in your Gemfile**, otherwise
40
+ Rabl will not register as a template engine.
41
+
39
42
  With Sinatra, or any other tilt-based framework, simply register:
40
43
 
41
44
  Rabl.register!
@@ -583,6 +586,7 @@ Thanks to [Miso](http://gomiso.com) for allowing me to create this for our appli
583
586
  * [Nathan Esquenazi](https://github.com/nesquena) - Creator of the project
584
587
  * [Arthur Chiu](https://github.com/achiu) - Core Maintainer, Riot Testing Guru
585
588
  * [Tim Lee](https://github.com/timothy1ee) - RABL is an awesome name and was chosen by the Miso CTO.
589
+ * [David Sommers](https://github.com/databyte) - Enhanced template resolution and added caching support
586
590
  * [Rick Thomas](https://github.com/rickthomasjr) - Added options for extends and Sinatra testing
587
591
  * [Benjamin Yu](https://github.com/byu) - Added msgpack format support
588
592
  * [Chris Kimpton](https://github.com/kimptoc) - Helping with documentation and wiki
@@ -593,7 +597,6 @@ Thanks to [Miso](http://gomiso.com) for allowing me to create this for our appli
593
597
  * [Luke van der Hoeven](https://github.com/plukevdh) - Support non-ORM objects in templates
594
598
  * [Andrey Voronkov](https://github.com/Antiarchitect) - Added BSON format support
595
599
  * [Alli Witheford](https://github.com/alzeih) - Added Plist format support
596
- * [David Sommers](https://github.com/databyte) - Added template caching support for Rails
597
600
  * [Ryan Bigg](https://github.com/radar) - Improved template resolution code
598
601
 
599
602
  and many more contributors listed in the [CHANGELOG](https://github.com/nesquena/rabl/blob/master/CHANGELOG.md).
data/Rakefile CHANGED
@@ -32,7 +32,7 @@ task "test:setup" do
32
32
  Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture|
33
33
  puts "\n*** Setting up for #{File.basename(fixture)} tests ***\n"
34
34
  `export BUNDLE_GEMFILE=#{fixture}/Gemfile` if ENV['TRAVIS']
35
- puts `cd #{fixture}; bundle install;`
35
+ puts `cd #{fixture}; mkdir -p tmp/cache; bundle install;`
36
36
  end
37
37
  end
38
38
 
@@ -1,11 +1,20 @@
1
+ # Sinatra
2
+
3
+ cd fixtures/sinatra_test
4
+ ln -s "../ashared/models" models
5
+ ln -s "../ashared/views/" views
6
+ ln -s "../../ashared/migrate" db/migrate
7
+ ln -s ../../../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb
8
+ ln -s ../../../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb
9
+
1
10
  # Padrino
2
11
 
3
12
  cd fixtures/padrino_test
4
13
  ln -s "../ashared/models" models
5
14
  ln -s "../../ashared/views/" app/views
6
15
  ln -s "../../ashared/migrate" db/migrate
7
- ln ../../test/integration/posts_controller_test.rb test/app/controllers/posts_controller_test.rb
8
- ln ../../test/integration/users_controller_test.rb test/app/controllers/users_controller_test.rb
16
+ ln -s ../../../../../test/integration/posts_controller_test.rb test/app/controllers/posts_controller_test.rb
17
+ ln -s ../../../../../test/integration/users_controller_test.rb test/app/controllers/users_controller_test.rb
9
18
 
10
19
  # Rails 2
11
20
 
@@ -13,8 +22,8 @@ cd fixtures/rails2
13
22
  ln -s "../../ashared/models" app/models
14
23
  ln -s "../../ashared/views/" app/views
15
24
  ln -s "../../ashared/migrate" db/migrate
16
- ln ../../test/integration/posts_controller_test.rb test/functionals/posts_controller_test.rb
17
- ln ../../test/integration/users_controller_test.rb test/functionals/users_controller_test.rb
25
+ ln -s ../../../../test/integration/posts_controller_test.rb test/functionals/posts_controller_test.rb
26
+ ln -s ../../../../test/integration/users_controller_test.rb test/functionals/users_controller_test.rb
18
27
 
19
28
  # Rails 3
20
29
 
@@ -22,23 +31,14 @@ cd fixtures/rails3
22
31
  ln -s "../../ashared/models" app/models
23
32
  ln -s "../../ashared/views/" app/views
24
33
  ln -s "../../ashared/migrate" db/migrate
25
- ln ../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb
26
- ln ../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb
34
+ ln -s ../../../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb
35
+ ln -s ../../../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb
27
36
 
28
37
  # Rails 3.2
29
38
 
30
39
  cd fixtures/rails3_2
31
40
  ln -s "../../ashared/models" app/models
32
- ln -s "../../ashared/views/" app/views
33
- ln -s "../../ashared/migrate" db/migrate
34
- ln ../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb
35
- ln ../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb
36
-
37
- # Sinatra
38
-
39
- cd fixtures/sinatra_test
40
- ln -s "../ashared/models" models
41
- ln -s "../ashared/views/" views
41
+ ln -s "../../ashared/views_rails_3/" app/views
42
42
  ln -s "../../ashared/migrate" db/migrate
43
- ln ../../test/integration/posts_controller_test.rb test/functional/posts_controller_test.rb
44
- ln ../../test/integration/users_controller_test.rb test/functional/users_controller_test.rb
43
+ ln -s ../../../../test/integration/rails3_2/posts_controller_test.rb test/functional/posts_controller_test.rb
44
+ ln -s ../../../../test/integration/rails3_2/users_controller_test.rb test/functional/users_controller_test.rb
@@ -1,6 +1,9 @@
1
- <head>
2
- Not for RABL
3
- </head>
4
- <body>
5
- Not for RABL
6
- </body>
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>RABL ROCKS!</title>
5
+ </head>
6
+ <body>
7
+ <%= yield %>
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
1
+ var output = <%= render(file: 'posts/show', formats: :json).html_safe %>;
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>RABL ROCKS!</title>
5
+ </head>
6
+ <body>
7
+ <%= yield %>
8
+
9
+ <%= javascript_tag do %>
10
+ <%= yield(:footer_scripts) %>
11
+ <% end %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ var output = <%= render(file: 'posts/show', formats: :json).html_safe %>;
@@ -0,0 +1,3 @@
1
+ code(:day) { |d| d.day }
2
+ code(:hour) { |d| d.hour }
3
+ code(:full) { |d| d.iso8601 }
@@ -0,0 +1,3 @@
1
+ <%= content_for :footer_scripts do %>
2
+ var output = <%= render(file: 'posts/index', formats: :json).html_safe %>;
3
+ <% end %>
@@ -0,0 +1,12 @@
1
+ collection @posts => :articles
2
+ cache ['kittens!', @posts]
3
+
4
+ extends "posts/show"
5
+
6
+ node(:created_by_admin, :if => lambda { |p| p.user.is_admin }) do |p|
7
+ true
8
+ end
9
+
10
+ child({ :user => :admin }, { :if => lambda { |p| p.user.is_admin }}) do |p|
11
+ extends "users/show"
12
+ end
@@ -0,0 +1,3 @@
1
+ <%= content_for :footer_scripts do %>
2
+ <%= render partial: "show_footer_script", formats: :js %>
3
+ <% end %>
@@ -0,0 +1,17 @@
1
+ object @post
2
+ cache @post
3
+
4
+ attributes :title, :body
5
+ attributes :created_at => :posted_at
6
+
7
+ child :user do
8
+ extends "users/show"
9
+ end
10
+
11
+ glue :user do
12
+ attributes :username => :author_name
13
+ end
14
+
15
+ code(:created_date) do |p|
16
+ partial("posts/date", :object => p.created_at)
17
+ end
@@ -0,0 +1,3 @@
1
+ collection @users
2
+
3
+ extends "users/show"
@@ -0,0 +1,6 @@
1
+ attributes :prefix, :suffix, :area_code
2
+ attributes :is_primary => :primary
3
+
4
+ node :formatted do |n|
5
+ n.formatted
6
+ end
@@ -0,0 +1,16 @@
1
+ object @user => :person
2
+
3
+ attributes :username, :email, :location
4
+ attributes :created_at => :registered_at
5
+
6
+ node :role do |user|
7
+ user.is_admin ? 'admin' : 'normal'
8
+ end
9
+
10
+ child :phone_numbers => :pnumbers do
11
+ extends "users/phone_number"
12
+ end
13
+
14
+ node :node_numbers do |u|
15
+ partial("users/phone_number", :object => u.phone_numbers)
16
+ end
@@ -21,7 +21,7 @@ context "PostsController" do
21
21
 
22
22
  context "for index action" do
23
23
  setup do
24
- get "/posts"
24
+ get "/posts", format: :json
25
25
  end
26
26
 
27
27
  # Attributes (regular)
@@ -74,7 +74,7 @@ context "PostsController" do
74
74
 
75
75
  context "for show action" do
76
76
  setup do
77
- get "/posts/#{@post1.id}"
77
+ get "/posts/#{@post1.id}", format: :json
78
78
  json_output['post']
79
79
  end
80
80
 
@@ -21,7 +21,7 @@ context "PostsController" do
21
21
 
22
22
  context "for index action" do
23
23
  setup do
24
- get "/posts"
24
+ get "/posts", format: :json
25
25
  end
26
26
 
27
27
  # Attributes (regular)
@@ -74,7 +74,7 @@ context "PostsController" do
74
74
 
75
75
  context "for show action" do
76
76
  setup do
77
- get "/posts/#{@post1.id}"
77
+ get "/posts/#{@post1.id}", format: :json
78
78
  json_output['post']
79
79
  end
80
80
 
@@ -1,6 +1,6 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'rails', '3.0.8'
3
+ gem 'rails', '3.0.12'
4
4
 
5
5
  # Bundle edge Rails instead:
6
6
  # gem 'rails', :git => 'git://github.com/rails/rails.git'
@@ -1,5 +1,5 @@
1
1
  class PostsController < ApplicationController
2
- respond_to :json, :xml
2
+ respond_to :json, :xml, :html
3
3
 
4
4
  def index
5
5
  @posts = Post.all(:order => "id ASC")
@@ -7,14 +7,11 @@ rescue LoadError # Rails
7
7
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
8
8
  end
9
9
 
10
- require 'rexml/document'
11
-
12
10
  context "PostsController" do
13
11
  helper(:json_output) { JSON.parse(last_response.body) }
14
12
 
15
13
  setup do
16
14
  create_users!
17
- Rails.cache.clear
18
15
  Post.delete_all
19
16
  @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id)
20
17
  @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id)
@@ -24,7 +21,7 @@ context "PostsController" do
24
21
 
25
22
  context "for index action" do
26
23
  setup do
27
- get "/posts"
24
+ get "/posts", format: :json
28
25
  end
29
26
 
30
27
  # Attributes (regular)
@@ -77,11 +74,11 @@ context "PostsController" do
77
74
 
78
75
  context "for show action" do
79
76
  setup do
80
- get "/posts/#{@post1.id}"
77
+ get "/posts/#{@post1.id}", format: :json
81
78
  json_output['post']
82
79
  end
83
80
 
84
- # Attributes (regular)
81
+ # Attributes (regular)
85
82
  asserts("contains post title") { topic['title'] }.equals { @post1.title }
86
83
  asserts("contains post body") { topic['body'] }.equals { @post1.body }
87
84
 
@@ -108,71 +105,4 @@ context "PostsController" do
108
105
  asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 }
109
106
  end # date node
110
107
  end # show action
111
-
112
- context "for index action with caching in json" do
113
- helper(:cache_hit) do |key|
114
- Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl))
115
- end
116
-
117
- setup do
118
- mock(ActionController::Base).perform_caching.any_number_of_times { true }
119
- get "/posts.json"
120
- end
121
-
122
- asserts("contains post titles") do
123
- json_output['articles'].map { |o| o['article']['title'] }
124
- end.equals { @posts.map(&:title) }
125
-
126
- asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json'] }
127
- end # index action, caching, json
128
-
129
- context "for index action with caching in xml" do
130
- helper(:cache_hit) do |key|
131
- Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl))
132
- end
133
-
134
- setup do
135
- mock(ActionController::Base).perform_caching.any_number_of_times { true }
136
- get "/posts.xml"
137
- end
138
-
139
- asserts("contains post titles") do
140
- doc = REXML::Document.new topic.body
141
- doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text}
142
- end.equals { @posts.map(&:title) }
143
-
144
- asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml'] }
145
- end # index action, caching, xml
146
-
147
- context "for show action with caching" do
148
- helper(:cache_hit) do |key|
149
- Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl))
150
- end
151
-
152
- setup do
153
- mock(ActionController::Base).perform_caching.any_number_of_times { true }
154
- get "/posts/#{@post1.id}"
155
- end
156
-
157
- asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title }
158
-
159
- asserts(:body).equals { cache_hit [@post1, nil, 'json'] }
160
- end # show action, caching, json
161
-
162
- context "cache_all_output" do
163
- helper(:cache_hit) do |key|
164
- Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl))
165
- end
166
-
167
- setup do
168
- mock(ActionController::Base).perform_caching.any_number_of_times { true }
169
- Rabl.configuration.cache_all_output = true
170
- get "/posts"
171
- end
172
-
173
- asserts("contains cache hits per object (posts by title)") do
174
- json_output['articles'].map { |o| o['article']['title'] }
175
- end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } }
176
- end # index action, cache_all_output
177
-
178
108
  end
@@ -1,5 +1,5 @@
1
1
  class PostsController < ApplicationController
2
- respond_to :json, :xml
2
+ respond_to :json, :xml, :html
3
3
 
4
4
  def index
5
5
  @posts = Post.all(:order => "id ASC")
@@ -7,11 +7,14 @@ rescue LoadError # Rails
7
7
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
8
8
  end
9
9
 
10
+ require 'rexml/document'
11
+
10
12
  context "PostsController" do
11
13
  helper(:json_output) { JSON.parse(last_response.body) }
12
14
 
13
15
  setup do
14
16
  create_users!
17
+ Rails.cache.clear
15
18
  Post.delete_all
16
19
  @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id)
17
20
  @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id)
@@ -21,7 +24,7 @@ context "PostsController" do
21
24
 
22
25
  context "for index action" do
23
26
  setup do
24
- get "/posts"
27
+ get "/posts", format: :json
25
28
  end
26
29
 
27
30
  # Attributes (regular)
@@ -70,15 +73,15 @@ context "PostsController" do
70
73
  denies("contains no created_by_admin node for non-admins") do
71
74
  json_output['articles'].first['article']
72
75
  end.includes(:created_by_admin)
73
- end # index action
76
+ end # index action, json
74
77
 
75
78
  context "for show action" do
76
79
  setup do
77
- get "/posts/#{@post1.id}"
80
+ get "/posts/#{@post1.id}", format: :json
78
81
  json_output['post']
79
82
  end
80
83
 
81
- # Attributes (regular)
84
+ # Attributes (regular)
82
85
  asserts("contains post title") { topic['title'] }.equals { @post1.title }
83
86
  asserts("contains post body") { topic['body'] }.equals { @post1.body }
84
87
 
@@ -104,5 +107,82 @@ context "PostsController" do
104
107
  asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour }
105
108
  asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 }
106
109
  end # date node
107
- end # show action
110
+ end # show action, json
111
+
112
+ context "for index action rendering JSON within HTML" do
113
+ setup do
114
+ get "/posts", format: :html
115
+ end
116
+
117
+ asserts(:body).includes { "<html>" }
118
+ end # index action, html
119
+
120
+ context "for show action rendering JSON within HTML" do
121
+ setup do
122
+ get "/posts/#{@post1.id}", format: :html
123
+ end
124
+
125
+ asserts(:body).includes { "<html>" }
126
+ end # show action, html
127
+
128
+ context "caching" do
129
+ helper(:cache_hit) do |key|
130
+ Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl))
131
+ end
132
+
133
+ setup do
134
+ mock(ActionController::Base).perform_caching.any_number_of_times { true }
135
+ end
136
+
137
+ context "for index action with caching in json" do
138
+ setup do
139
+ get "/posts", format: :json
140
+ end
141
+
142
+ asserts("contains post titles") do
143
+ json_output['articles'].map { |o| o['article']['title'] }
144
+ end.equals { @posts.map(&:title) }
145
+
146
+ asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json'] }
147
+ end # index action, caching, json
148
+
149
+ context "for index action with caching in xml" do
150
+ setup do
151
+ get "/posts", format: :xml
152
+ end
153
+
154
+ asserts("contains post titles") do
155
+ doc = REXML::Document.new topic.body
156
+ doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text}
157
+ end.equals { @posts.map(&:title) }
158
+
159
+ asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml'] }
160
+ end # index action, caching, xml
161
+
162
+ context "for show action with caching" do
163
+ setup do
164
+ get "/posts/#{@post1.id}", format: :json
165
+ end
166
+
167
+ asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title }
168
+
169
+ asserts(:body).equals { cache_hit [@post1, nil, 'json'] }
170
+ end # show action, caching, json
171
+
172
+ context "cache_all_output" do
173
+ helper(:cache_hit) do |key|
174
+ Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl))
175
+ end
176
+
177
+ setup do
178
+ Rabl.configuration.cache_all_output = true
179
+ get "/posts", format: :json
180
+ end
181
+
182
+ asserts("contains cache hits per object (posts by title)") do
183
+ json_output['articles'].map { |o| o['article']['title'] }
184
+ end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } }
185
+ end # index action, cache_all_output
186
+ end
187
+
108
188
  end
@@ -21,7 +21,7 @@ context "PostsController" do
21
21
 
22
22
  context "for index action" do
23
23
  setup do
24
- get "/posts"
24
+ get "/posts", format: :json
25
25
  end
26
26
 
27
27
  # Attributes (regular)
@@ -74,7 +74,7 @@ context "PostsController" do
74
74
 
75
75
  context "for show action" do
76
76
  setup do
77
- get "/posts/#{@post1.id}"
77
+ get "/posts/#{@post1.id}", format: :json
78
78
  json_output['post']
79
79
  end
80
80
 
data/lib/rabl/partials.rb CHANGED
@@ -34,7 +34,8 @@ module Rabl
34
34
  file_path = if defined? Padrino
35
35
  fetch_padrino_source(file, options)
36
36
  elsif defined?(Rails) && context_scope
37
- fetch_rails_source(file, options)
37
+ view_path = Array(options[:view_path] || context_scope.view_paths.to_a)
38
+ fetch_rails_source(file, options) || fetch_manual_template(view_path, file)
38
39
  elsif defined? Sinatra
39
40
  fetch_sinatra_source(file, options)
40
41
  end
@@ -59,16 +60,18 @@ module Rabl
59
60
  def fetch_rails_source(file, options={})
60
61
  # use Rails template resolution mechanism if possible (find_template)
61
62
  source_format = request_format if defined?(request_format)
62
- view_path = Array(options[:view_path] || context_scope.view_paths.to_a)
63
63
  if source_format && context_scope.respond_to?(:lookup_context) # Rails 3
64
- lookup_proc = lambda { |partial| context_scope.lookup_context.find_template(file, [], partial) }
64
+ lookup_proc = lambda { |partial|
65
+ if context_scope.lookup_context.method(:find).parameters.count < 5
66
+ context_scope.lookup_context.find(file, [], partial)
67
+ else
68
+ context_scope.lookup_context.find(file, [], partial, [], {:formats => [:json]})
69
+ end }
65
70
  template = lookup_proc.call(false) rescue lookup_proc.call(true)
66
71
  template.identifier if template
67
72
  elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2
68
73
  template = context_scope.view_paths.find_template(file, source_format, false)
69
74
  template.filename if template
70
- else # manual file lookup
71
- fetch_manual_template(view_path, file)
72
75
  end
73
76
  end
74
77
 
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.6.5"
2
+ VERSION = "0.6.6"
3
3
  end
@@ -21,7 +21,7 @@ context "PostsController" do
21
21
 
22
22
  context "for index action" do
23
23
  setup do
24
- get "/posts"
24
+ get "/posts", format: :json
25
25
  end
26
26
 
27
27
  # Attributes (regular)
@@ -74,7 +74,7 @@ context "PostsController" do
74
74
 
75
75
  context "for show action" do
76
76
  setup do
77
- get "/posts/#{@post1.id}"
77
+ get "/posts/#{@post1.id}", format: :json
78
78
  json_output['post']
79
79
  end
80
80
 
@@ -0,0 +1,188 @@
1
+ # Lives in <rabl>/test/integration/posts_controller_test.rb
2
+ # Symlinked to fixture applications
3
+
4
+ begin # Padrino
5
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb')
6
+ rescue LoadError # Rails
7
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
8
+ end
9
+
10
+ require 'rexml/document'
11
+
12
+ context "PostsController" do
13
+ helper(:json_output) { JSON.parse(last_response.body) }
14
+
15
+ setup do
16
+ create_users!
17
+ Rails.cache.clear
18
+ Post.delete_all
19
+ @post1 = Post.create(:title => "Foo", :body => "Bar", :user_id => @user1.id)
20
+ @post2 = Post.create(:title => "Baz", :body => "Bah", :user_id => @user2.id)
21
+ @post3 = Post.create(:title => "Kaz", :body => "Paz", :user_id => @user3.id)
22
+ @posts = [@post1, @post2, @post3]
23
+ end
24
+
25
+ context "for index action" do
26
+ setup do
27
+ get "/posts", format: :json
28
+ end
29
+
30
+ # Attributes (regular)
31
+ asserts("contains post titles") do
32
+ json_output['articles'].map { |o| o["article"]["title"] }
33
+ end.equals { @posts.map(&:title) }
34
+
35
+ asserts("contains post bodies") do
36
+ json_output['articles'].map { |o| o["article"]["body"] }
37
+ end.equals { @posts.map(&:body) }
38
+
39
+ # Attributes (custom name)
40
+ asserts("contains post posted_at") do
41
+ json_output['articles'].map { |o| o["article"]["posted_at"] }
42
+ end.equals { @posts.map(&:created_at).map(&:iso8601) }
43
+
44
+ # Child
45
+ asserts("contains post user child username") do
46
+ json_output['articles'].map { |o| o["article"]["user"]["username"] }
47
+ end.equals { @posts.map(&:user).map(&:username) }
48
+
49
+ asserts("contains post user child role") do
50
+ json_output['articles'].map { |o| o["article"]["user"]["role"] }
51
+ end.equals { ["normal", "normal", "admin"] }
52
+
53
+ # Child Numbers of the Child User
54
+ asserts("contains post user child numbers") do
55
+ json_output['articles'].map { |o| o["article"]["user"]["pnumbers"][0]["pnumber"]["formatted"] }
56
+ end.equals { @posts.map(&:user).map(&:phone_numbers).map(&:first).map(&:formatted) }
57
+
58
+ # Glue (username to article)
59
+ asserts("contains glued usernames") do
60
+ json_output['articles'].map { |o| o["article"]["author_name"] }
61
+ end.equals { @posts.map(&:user).map(&:username) }
62
+
63
+ # Conditional Child (admin)
64
+ asserts("contains admin child only for admins") do
65
+ json_output['articles'].map { |o| o["article"]["admin"]["username"] if o["article"].has_key?("admin") }.compact
66
+ end.equals { [@user3.username] }
67
+
68
+ # Conditional Node (created_by_admin)
69
+ asserts("contains created_by_admin node for admins") do
70
+ json_output['articles'].last['article']['created_by_admin']
71
+ end.equals { true }
72
+
73
+ denies("contains no created_by_admin node for non-admins") do
74
+ json_output['articles'].first['article']
75
+ end.includes(:created_by_admin)
76
+ end # index action, json
77
+
78
+ context "for show action" do
79
+ setup do
80
+ get "/posts/#{@post1.id}", format: :json
81
+ json_output['post']
82
+ end
83
+
84
+ # Attributes (regular)
85
+ asserts("contains post title") { topic['title'] }.equals { @post1.title }
86
+ asserts("contains post body") { topic['body'] }.equals { @post1.body }
87
+
88
+ # Attributes (custom name)
89
+ asserts("contains post posted_at") { topic['posted_at'] }.equals { @post1.created_at.iso8601 }
90
+
91
+ # Child
92
+ asserts("contains post user child username") { topic["user"]["username"] }.equals { @post1.user.username }
93
+ asserts("contains post user child role") { topic["user"]["role"] }.equals { "normal" }
94
+
95
+ # Child Numbers of the Child User
96
+ asserts("contains post user child numbers") do
97
+ topic["user"]["pnumbers"][0]["pnumber"]["formatted"]
98
+ end.equals { @post1.user.phone_numbers[0].formatted }
99
+
100
+ # Glue (username to article)
101
+ asserts("contains glued username") { topic["author_name"] }.equals { @post1.user.username }
102
+
103
+ # Non-ORM Date Node Partial
104
+ context "for date node" do
105
+ setup { json_output['post']['created_date'] }
106
+ asserts("contains date partial with day") { topic['day'] }.equals { @post1.created_at.day }
107
+ asserts("contains date partial with hour") { topic['hour'] }.equals { @post1.created_at.hour }
108
+ asserts("contains date partial with full") { topic['full'] }.equals { @post1.created_at.iso8601 }
109
+ end # date node
110
+ end # show action, json
111
+
112
+ context "for index action rendering JSON within HTML" do
113
+ setup do
114
+ get "/posts", format: :html
115
+ end
116
+
117
+ asserts(:body).includes { "<html>" }
118
+ end # index action, html
119
+
120
+ context "for show action rendering JSON within HTML" do
121
+ setup do
122
+ get "/posts/#{@post1.id}", format: :html
123
+ end
124
+
125
+ asserts(:body).includes { "<html>" }
126
+ end # show action, html
127
+
128
+ context "caching" do
129
+ helper(:cache_hit) do |key|
130
+ Rails.cache.read(ActiveSupport::Cache.expand_cache_key(key, :rabl))
131
+ end
132
+
133
+ setup do
134
+ mock(ActionController::Base).perform_caching.any_number_of_times { true }
135
+ end
136
+
137
+ context "for index action with caching in json" do
138
+ setup do
139
+ get "/posts", format: :json
140
+ end
141
+
142
+ asserts("contains post titles") do
143
+ json_output['articles'].map { |o| o['article']['title'] }
144
+ end.equals { @posts.map(&:title) }
145
+
146
+ asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'json'] }
147
+ end # index action, caching, json
148
+
149
+ context "for index action with caching in xml" do
150
+ setup do
151
+ get "/posts", format: :xml
152
+ end
153
+
154
+ asserts("contains post titles") do
155
+ doc = REXML::Document.new topic.body
156
+ doc.elements.inject('articles/article/title', []) {|arr, ele| arr << ele.text}
157
+ end.equals { @posts.map(&:title) }
158
+
159
+ asserts(:body).equals { cache_hit ['kittens!', @posts, nil, 'xml'] }
160
+ end # index action, caching, xml
161
+
162
+ context "for show action with caching" do
163
+ setup do
164
+ get "/posts/#{@post1.id}", format: :json
165
+ end
166
+
167
+ asserts("contains post title") { json_output['post']['title'] }.equals { @post1.title }
168
+
169
+ asserts(:body).equals { cache_hit [@post1, nil, 'json'] }
170
+ end # show action, caching, json
171
+
172
+ context "cache_all_output" do
173
+ helper(:cache_hit) do |key|
174
+ Rails.cache.read(ActiveSupport::Cache.expand_cache_key([key, 'article', 'json'], :rabl))
175
+ end
176
+
177
+ setup do
178
+ Rabl.configuration.cache_all_output = true
179
+ get "/posts", format: :json
180
+ end
181
+
182
+ asserts("contains cache hits per object (posts by title)") do
183
+ json_output['articles'].map { |o| o['article']['title'] }
184
+ end.equals { @posts.map{ |p| cache_hit(p)['article'][:title] } }
185
+ end # index action, cache_all_output
186
+ end
187
+
188
+ end
@@ -0,0 +1,87 @@
1
+ # Lives in <rabl>/test/integration/users_controller_test.rb
2
+ # Symlinked to fixture applications
3
+
4
+ begin # Sinatra
5
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_config.rb')
6
+ rescue LoadError # Rails
7
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
8
+ end
9
+
10
+ context "UsersController" do
11
+ helper(:json_output) { JSON.parse(last_response.body) }
12
+
13
+ setup do
14
+ create_users!
15
+ end
16
+
17
+ context "for index action" do
18
+ # Tests `collection @users` extending from 'show' template
19
+
20
+ setup do
21
+ get "/users"
22
+ end
23
+
24
+ # Attributes (regular)
25
+ asserts("contains user usernames") do
26
+ json_output.map { |u| u["user"]["username"] }
27
+ end.equals { @users.map(&:username) }
28
+ asserts("contains email") do
29
+ json_output.map { |u| u["user"]["email"] }
30
+ end.equals { @users.map(&:email) }
31
+ asserts("contains location") do
32
+ json_output.map { |u| u["user"]["location"] }
33
+ end.equals { @users.map(&:location) }
34
+
35
+ # Attributes (custom name)
36
+ asserts("contains registered_at") do
37
+ json_output.map { |u| u["user"]["registered_at"] }
38
+ end.equals { @users.map(&:created_at).map(&:iso8601) }
39
+
40
+ # Node (renders based on attribute)
41
+ asserts("contains role") do
42
+ json_output.map { |u| u["user"]["role"] }
43
+ end.equals ['normal', 'normal', 'admin']
44
+
45
+ # Child (custom collection name)
46
+ asserts("contains formatted phone numbers") do
47
+ json_output.map { |u| u["user"]["pnumbers"].map { |n| n["pnumber"]["formatted"] } }
48
+ end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
49
+
50
+ # Node (renders collection partial)
51
+ asserts("contains formatted node numbers") do
52
+ json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } }
53
+ end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
54
+ end # index
55
+
56
+ context "for show action" do
57
+ # Tests `object :user => :person` custom parent node name
58
+ setup do
59
+ get "/users/#{@user1.id}"
60
+ end
61
+
62
+ # Attributes (regular)
63
+ asserts("contains username") { json_output["person"]["username"] }.equals { @user1.username }
64
+ asserts("contains email") { json_output["person"]["email"] }.equals { @user1.email }
65
+ asserts("contains location") { json_output["person"]["location"] }.equals { @user1.location }
66
+ # Attributes (custom name)
67
+ asserts("contains registered_at") { json_output["person"]["registered_at"] }.equals { @user1.created_at.iso8601 }
68
+ # Node (renders based on attribute)
69
+ asserts("contains role node") { json_output["person"]["role"] }.equals "normal"
70
+
71
+ # Child (custom collection name)
72
+ asserts("contains first phone number") {
73
+ json_output["person"]["pnumbers"][0]["pnumber"]["formatted"]
74
+ }.equals { @user1.phone_numbers[0].formatted }
75
+ asserts("contains second phone number") {
76
+ json_output["person"]["pnumbers"][1]["pnumber"]["formatted"]
77
+ }.equals { @user1.phone_numbers[1].formatted }
78
+
79
+ # Node (renders collection partial)
80
+ asserts("contains first node number") {
81
+ json_output["person"]["node_numbers"][0]["formatted"]
82
+ }.equals { @user1.phone_numbers[0].formatted }
83
+ asserts("contains second node number") {
84
+ json_output["person"]["node_numbers"][1]["formatted"]
85
+ }.equals { @user1.phone_numbers[1].formatted }
86
+ end # show
87
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.6.5
5
+ version: 0.6.6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nathan Esquenazi
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-03-28 00:00:00 Z
13
+ date: 2012-03-31 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -152,12 +152,23 @@ files:
152
152
  - fixtures/ashared/models/post.rb
153
153
  - fixtures/ashared/models/user.rb
154
154
  - fixtures/ashared/views/layouts/application.html.erb
155
+ - fixtures/ashared/views/posts/_show_footer_script.js.erb
155
156
  - fixtures/ashared/views/posts/date.rabl
156
157
  - fixtures/ashared/views/posts/index.rabl
157
158
  - fixtures/ashared/views/posts/show.rabl
158
159
  - fixtures/ashared/views/users/index.json.rabl
159
160
  - fixtures/ashared/views/users/phone_number.json.rabl
160
161
  - fixtures/ashared/views/users/show.json.rabl
162
+ - fixtures/ashared/views_rails_3/layouts/application.html.erb
163
+ - fixtures/ashared/views_rails_3/posts/_show_footer_script.js.erb
164
+ - fixtures/ashared/views_rails_3/posts/date.rabl
165
+ - fixtures/ashared/views_rails_3/posts/index.html.erb
166
+ - fixtures/ashared/views_rails_3/posts/index.rabl
167
+ - fixtures/ashared/views_rails_3/posts/show.html.erb
168
+ - fixtures/ashared/views_rails_3/posts/show.rabl
169
+ - fixtures/ashared/views_rails_3/users/index.json.rabl
170
+ - fixtures/ashared/views_rails_3/users/phone_number.json.rabl
171
+ - fixtures/ashared/views_rails_3/users/show.json.rabl
161
172
  - fixtures/padrino_test/.components
162
173
  - fixtures/padrino_test/.gitignore
163
174
  - fixtures/padrino_test/Gemfile
@@ -345,6 +356,8 @@ files:
345
356
  - test/engine_test.rb
346
357
  - test/helpers_test.rb
347
358
  - test/integration/posts_controller_test.rb
359
+ - test/integration/rails3_2/posts_controller_test.rb
360
+ - test/integration/rails3_2/users_controller_test.rb
348
361
  - test/integration/test_init.rb
349
362
  - test/integration/users_controller_test.rb
350
363
  - test/models/ormless.rb
@@ -389,6 +402,8 @@ test_files:
389
402
  - test/engine_test.rb
390
403
  - test/helpers_test.rb
391
404
  - test/integration/posts_controller_test.rb
405
+ - test/integration/rails3_2/posts_controller_test.rb
406
+ - test/integration/rails3_2/users_controller_test.rb
392
407
  - test/integration/test_init.rb
393
408
  - test/integration/users_controller_test.rb
394
409
  - test/models/ormless.rb