roda 3.28.0 → 3.29.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +10 -0
  3. data/README.rdoc +10 -0
  4. data/doc/release_notes/3.29.0.txt +15 -0
  5. data/lib/roda.rb +1 -0
  6. data/lib/roda/plugins/caching.rb +2 -0
  7. data/lib/roda/plugins/common_logger.rb +1 -1
  8. data/lib/roda/plugins/exception_page.rb +7 -1
  9. data/lib/roda/plugins/indifferent_params.rb +2 -0
  10. data/lib/roda/version.rb +1 -1
  11. metadata +4 -214
  12. data/Rakefile +0 -108
  13. data/doc/release_notes/1.0.0.txt +0 -329
  14. data/doc/release_notes/1.1.0.txt +0 -226
  15. data/doc/release_notes/1.2.0.txt +0 -406
  16. data/doc/release_notes/1.3.0.txt +0 -109
  17. data/doc/release_notes/2.0.0.txt +0 -75
  18. data/doc/release_notes/2.1.0.txt +0 -124
  19. data/doc/release_notes/2.10.0.txt +0 -27
  20. data/doc/release_notes/2.11.0.txt +0 -70
  21. data/doc/release_notes/2.12.0.txt +0 -40
  22. data/doc/release_notes/2.13.0.txt +0 -10
  23. data/doc/release_notes/2.14.0.txt +0 -44
  24. data/doc/release_notes/2.15.0.txt +0 -53
  25. data/doc/release_notes/2.16.0.txt +0 -48
  26. data/doc/release_notes/2.17.0.txt +0 -62
  27. data/doc/release_notes/2.18.0.txt +0 -69
  28. data/doc/release_notes/2.19.0.txt +0 -30
  29. data/doc/release_notes/2.2.0.txt +0 -97
  30. data/doc/release_notes/2.20.0.txt +0 -5
  31. data/doc/release_notes/2.21.0.txt +0 -17
  32. data/doc/release_notes/2.22.0.txt +0 -41
  33. data/doc/release_notes/2.23.0.txt +0 -29
  34. data/doc/release_notes/2.24.0.txt +0 -65
  35. data/doc/release_notes/2.25.0.txt +0 -14
  36. data/doc/release_notes/2.26.0.txt +0 -13
  37. data/doc/release_notes/2.27.0.txt +0 -56
  38. data/doc/release_notes/2.28.0.txt +0 -17
  39. data/doc/release_notes/2.29.0.txt +0 -156
  40. data/doc/release_notes/2.3.0.txt +0 -109
  41. data/doc/release_notes/2.4.0.txt +0 -55
  42. data/doc/release_notes/2.5.0.txt +0 -23
  43. data/doc/release_notes/2.5.1.txt +0 -4
  44. data/doc/release_notes/2.6.0.txt +0 -21
  45. data/doc/release_notes/2.7.0.txt +0 -75
  46. data/doc/release_notes/2.8.0.txt +0 -44
  47. data/doc/release_notes/2.9.0.txt +0 -6
  48. data/spec/all.rb +0 -1
  49. data/spec/assets/css/app.scss +0 -1
  50. data/spec/assets/css/no_access.css +0 -1
  51. data/spec/assets/css/raw.css +0 -1
  52. data/spec/assets/js/head/app.js +0 -1
  53. data/spec/composition_spec.rb +0 -31
  54. data/spec/define_roda_method_spec.rb +0 -274
  55. data/spec/env_spec.rb +0 -11
  56. data/spec/freeze_spec.rb +0 -37
  57. data/spec/integration_spec.rb +0 -209
  58. data/spec/matchers_spec.rb +0 -832
  59. data/spec/opts_spec.rb +0 -42
  60. data/spec/plugin/_after_hook_spec.rb +0 -19
  61. data/spec/plugin/all_verbs_spec.rb +0 -29
  62. data/spec/plugin/assets_preloading_spec.rb +0 -98
  63. data/spec/plugin/assets_spec.rb +0 -745
  64. data/spec/plugin/backtracking_array_spec.rb +0 -42
  65. data/spec/plugin/branch_locals_spec.rb +0 -106
  66. data/spec/plugin/caching_spec.rb +0 -337
  67. data/spec/plugin/chunked_spec.rb +0 -201
  68. data/spec/plugin/class_level_routing_spec.rb +0 -164
  69. data/spec/plugin/class_matchers_spec.rb +0 -40
  70. data/spec/plugin/common_logger_spec.rb +0 -85
  71. data/spec/plugin/content_for_spec.rb +0 -162
  72. data/spec/plugin/content_security_policy_spec.rb +0 -175
  73. data/spec/plugin/cookies_spec.rb +0 -51
  74. data/spec/plugin/csrf_spec.rb +0 -111
  75. data/spec/plugin/default_headers_spec.rb +0 -82
  76. data/spec/plugin/default_status_spec.rb +0 -95
  77. data/spec/plugin/delay_build_spec.rb +0 -23
  78. data/spec/plugin/delegate_spec.rb +0 -23
  79. data/spec/plugin/delete_empty_headers_spec.rb +0 -27
  80. data/spec/plugin/direct_call_spec.rb +0 -28
  81. data/spec/plugin/disallow_file_uploads_spec.rb +0 -25
  82. data/spec/plugin/drop_body_spec.rb +0 -24
  83. data/spec/plugin/early_hints_spec.rb +0 -19
  84. data/spec/plugin/empty_root_spec.rb +0 -14
  85. data/spec/plugin/environments_spec.rb +0 -42
  86. data/spec/plugin/error_email_spec.rb +0 -97
  87. data/spec/plugin/error_handler_spec.rb +0 -216
  88. data/spec/plugin/error_mail_spec.rb +0 -93
  89. data/spec/plugin/exception_page_spec.rb +0 -168
  90. data/spec/plugin/flash_spec.rb +0 -121
  91. data/spec/plugin/h_spec.rb +0 -11
  92. data/spec/plugin/halt_spec.rb +0 -119
  93. data/spec/plugin/hash_matcher_spec.rb +0 -27
  94. data/spec/plugin/hash_routes_spec.rb +0 -535
  95. data/spec/plugin/head_spec.rb +0 -52
  96. data/spec/plugin/header_matchers_spec.rb +0 -98
  97. data/spec/plugin/heartbeat_spec.rb +0 -74
  98. data/spec/plugin/hooks_spec.rb +0 -152
  99. data/spec/plugin/indifferent_params_spec.rb +0 -14
  100. data/spec/plugin/json_parser_spec.rb +0 -141
  101. data/spec/plugin/json_spec.rb +0 -83
  102. data/spec/plugin/mail_processor_spec.rb +0 -451
  103. data/spec/plugin/mailer_spec.rb +0 -282
  104. data/spec/plugin/match_affix_spec.rb +0 -43
  105. data/spec/plugin/match_hook_spec.rb +0 -79
  106. data/spec/plugin/middleware_spec.rb +0 -237
  107. data/spec/plugin/middleware_stack_spec.rb +0 -81
  108. data/spec/plugin/module_include_spec.rb +0 -48
  109. data/spec/plugin/multi_route_spec.rb +0 -268
  110. data/spec/plugin/multi_run_spec.rb +0 -87
  111. data/spec/plugin/multi_view_spec.rb +0 -50
  112. data/spec/plugin/multibyte_string_matcher_spec.rb +0 -44
  113. data/spec/plugin/named_templates_spec.rb +0 -96
  114. data/spec/plugin/not_allowed_spec.rb +0 -69
  115. data/spec/plugin/not_found_spec.rb +0 -128
  116. data/spec/plugin/optimized_string_matchers_spec.rb +0 -43
  117. data/spec/plugin/padrino_render_spec.rb +0 -34
  118. data/spec/plugin/param_matchers_spec.rb +0 -69
  119. data/spec/plugin/params_capturing_spec.rb +0 -33
  120. data/spec/plugin/partials_spec.rb +0 -43
  121. data/spec/plugin/pass_spec.rb +0 -29
  122. data/spec/plugin/path_matchers_spec.rb +0 -42
  123. data/spec/plugin/path_rewriter_spec.rb +0 -45
  124. data/spec/plugin/path_spec.rb +0 -222
  125. data/spec/plugin/placeholder_string_matchers_spec.rb +0 -126
  126. data/spec/plugin/precompile_templates_spec.rb +0 -61
  127. data/spec/plugin/public_spec.rb +0 -85
  128. data/spec/plugin/render_each_spec.rb +0 -82
  129. data/spec/plugin/render_locals_spec.rb +0 -114
  130. data/spec/plugin/render_spec.rb +0 -912
  131. data/spec/plugin/request_aref_spec.rb +0 -51
  132. data/spec/plugin/request_headers_spec.rb +0 -39
  133. data/spec/plugin/response_request_spec.rb +0 -43
  134. data/spec/plugin/route_block_args_spec.rb +0 -86
  135. data/spec/plugin/route_csrf_spec.rb +0 -305
  136. data/spec/plugin/run_append_slash_spec.rb +0 -77
  137. data/spec/plugin/run_handler_spec.rb +0 -53
  138. data/spec/plugin/sessions_spec.rb +0 -452
  139. data/spec/plugin/shared_vars_spec.rb +0 -45
  140. data/spec/plugin/sinatra_helpers_spec.rb +0 -537
  141. data/spec/plugin/slash_path_empty_spec.rb +0 -22
  142. data/spec/plugin/static_routing_spec.rb +0 -192
  143. data/spec/plugin/static_spec.rb +0 -30
  144. data/spec/plugin/status_303_spec.rb +0 -28
  145. data/spec/plugin/status_handler_spec.rb +0 -158
  146. data/spec/plugin/streaming_spec.rb +0 -246
  147. data/spec/plugin/strip_path_prefix_spec.rb +0 -24
  148. data/spec/plugin/symbol_matchers_spec.rb +0 -51
  149. data/spec/plugin/symbol_status_spec.rb +0 -25
  150. data/spec/plugin/symbol_views_spec.rb +0 -32
  151. data/spec/plugin/timestamp_public_spec.rb +0 -85
  152. data/spec/plugin/type_routing_spec.rb +0 -348
  153. data/spec/plugin/typecast_params_spec.rb +0 -1370
  154. data/spec/plugin/unescape_path_spec.rb +0 -22
  155. data/spec/plugin/view_options_spec.rb +0 -170
  156. data/spec/plugin_spec.rb +0 -71
  157. data/spec/redirect_spec.rb +0 -41
  158. data/spec/request_spec.rb +0 -97
  159. data/spec/response_spec.rb +0 -199
  160. data/spec/route_spec.rb +0 -39
  161. data/spec/session_middleware_spec.rb +0 -129
  162. data/spec/session_spec.rb +0 -37
  163. data/spec/spec_helper.rb +0 -137
  164. data/spec/version_spec.rb +0 -14
  165. data/spec/views/_test.erb +0 -1
  166. data/spec/views/a.erb +0 -1
  167. data/spec/views/a.rdoc +0 -2
  168. data/spec/views/about.erb +0 -1
  169. data/spec/views/about.str +0 -1
  170. data/spec/views/about/_test.css.gz +0 -0
  171. data/spec/views/about/_test.erb +0 -1
  172. data/spec/views/about/_test.erb.gz +0 -0
  173. data/spec/views/about/comp_test.erb +0 -1
  174. data/spec/views/b.erb +0 -1
  175. data/spec/views/c.erb +0 -1
  176. data/spec/views/comp_layout.erb +0 -1
  177. data/spec/views/comp_test.erb +0 -1
  178. data/spec/views/content-yield.erb +0 -1
  179. data/spec/views/each.str +0 -1
  180. data/spec/views/home.erb +0 -2
  181. data/spec/views/home.str +0 -2
  182. data/spec/views/iv.erb +0 -1
  183. data/spec/views/layout-alternative.erb +0 -2
  184. data/spec/views/layout-yield.erb +0 -3
  185. data/spec/views/layout.erb +0 -2
  186. data/spec/views/layout.str +0 -2
  187. data/spec/views/multiple-layout.erb +0 -1
  188. data/spec/views/multiple.erb +0 -1
@@ -1,912 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- begin
4
- require 'tilt'
5
- require 'tilt/erb'
6
- require 'tilt/string'
7
- require_relative '../../lib/roda/plugins/render'
8
- rescue LoadError
9
- warn "tilt not installed, skipping render plugin test"
10
- else
11
- describe "render plugin" do
12
- before do
13
- app(:bare) do
14
- plugin :render, :views=>"./spec/views", :check_paths=>true
15
-
16
- route do |r|
17
- r.on "home" do
18
- view("home", :locals=>{:name => "Agent Smith", :title => "Home"}, :layout_opts=>{:locals=>{:title=>"Home"}})
19
- end
20
-
21
- r.on "about" do
22
- render("about", :locals=>{:title => "About Roda"})
23
- end
24
-
25
- r.on "inline" do
26
- view(:inline=>"Hello <%= name %>", :locals=>{:name => "Agent Smith"}, :layout=>nil)
27
- end
28
-
29
- r.on "path" do
30
- render(:path=>"./spec/views/about.erb", :locals=>{:title => "Path"}, :layout_opts=>{:locals=>{:title=>"Home"}})
31
- end
32
-
33
- r.on "content" do
34
- view(:content=>'bar', :layout_opts=>{:locals=>{:title=>"Home"}})
35
- end
36
- end
37
- end
38
- end
39
-
40
- it "default actions" do
41
- body("/about").strip.must_equal "<h1>About Roda</h1>"
42
- body("/home").strip.must_equal "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
43
- body("/inline").strip.must_equal "Hello Agent Smith"
44
- body("/path").strip.must_equal "<h1>Path</h1>"
45
- body("/content").strip.must_equal "<title>Roda: Home</title>\nbar"
46
- end
47
-
48
- it "with str as engine" do
49
- app.plugin :render, :engine => "str"
50
- body("/about").strip.must_equal "<h1>About Roda</h1>"
51
- body("/home").strip.must_equal "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
52
- body("/inline").strip.must_equal "Hello <%= name %>"
53
- end
54
-
55
- it "custom default layout support" do
56
- app.plugin :render, :layout => "layout-alternative"
57
- body("/home").strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
58
- end
59
-
60
- it "using hash for :layout" do
61
- app.plugin :render, :layout => {:inline=> 'a<%= yield %>b'}
62
- body("/home").strip.must_equal "a<h1>Home</h1>\n<p>Hello Agent Smith</p>\nb"
63
- end
64
- end
65
-
66
- describe "render plugin" do
67
- file = 'spec/iv.erb'
68
- before do
69
- File.binwrite(file, File.binread('spec/views/iv.erb'))
70
- end
71
- after do
72
- File.delete(file) if File.file?(file)
73
- end
74
-
75
- [{:cache=>false}, {:explicit_cache=>true}, {:check_template_mtime=>true}].each do |cache_plugin_opts|
76
- it "checks mtime if #{cache_plugin_opts} plugin option is used" do
77
- app(:bare) do
78
- plugin :render, {:views=>"./spec"}.merge!(cache_plugin_opts)
79
-
80
- route do |r|
81
- @a = 'a'
82
- render('iv')
83
- end
84
- end
85
-
86
- t = Time.now
87
- body.strip.must_equal "a"
88
-
89
- File.binwrite(file, File.binread(file) + "b")
90
- File.utime(t, t+1, file)
91
- body.gsub("\n", '').must_equal "ab"
92
-
93
- File.binwrite(file, File.binread(file) + "c")
94
- File.utime(t, t+2, file)
95
- body.gsub("\n", '').must_equal "abc"
96
-
97
- mtime = File.mtime(file)
98
- File.binwrite(file, File.binread(file) + "d")
99
- File.utime(t, mtime, file)
100
- body.gsub("\n", '').must_equal "abc"
101
-
102
- File.delete(file)
103
- body.gsub("\n", '').must_equal "abc"
104
- end
105
- end
106
-
107
- it "does not check mtime if :cache render option is used" do
108
- app(:bare) do
109
- plugin :render, :views=>"./spec", :cache=>false
110
-
111
- route do |r|
112
- @a = 'a'
113
- render('iv', :cache=>true)
114
- end
115
- end
116
-
117
- t = Time.now+1
118
- body.strip.must_equal "a"
119
-
120
- File.binwrite(file, File.binread(file) + "b")
121
- File.utime(t, t+1, file)
122
- body.gsub("\n", '').must_equal "a"
123
- end
124
- end
125
-
126
- describe "render plugin" do
127
- it "simple layout support" do
128
- app(:bare) do
129
- plugin :render
130
-
131
- route do |r|
132
- render(:path=>"spec/views/layout-yield.erb") do
133
- render(:path=>"spec/views/content-yield.erb")
134
- end
135
- end
136
- end
137
-
138
- body.gsub(/\n+/, "\n").must_equal "Header\nThis is the actual content.\nFooter\n"
139
- end
140
-
141
- it "should have :layout_opts=>:views plugin option respect :root app option" do
142
- app(:bare) do
143
- self.opts[:root] = 'spec'
144
- plugin :render, :layout_opts=>{:views=>"views"}, :allowed_paths=>["spec/views"]
145
-
146
- route do |r|
147
- view(:content=>'a', :layout_opts=>{:locals=>{:title=>"Home"}})
148
- end
149
- end
150
-
151
- body.strip.must_equal "<title>Roda: Home</title>\na"
152
- end
153
-
154
- it "views without default layouts" do
155
- app(:bare) do
156
- plugin :render, :views=>"./spec/views", :layout=>false
157
-
158
- route do |r|
159
- view("home", :locals=>{:name=>"Agent Smith", :title=>"Home"})
160
- end
161
- end
162
-
163
- body.strip.must_equal "<h1>Home</h1>\n<p>Hello Agent Smith</p>"
164
- end
165
-
166
- it "layout overrides" do
167
- app(:bare) do
168
- plugin :render, :views=>"./spec/views"
169
-
170
- route do |r|
171
- view("home", :locals=>{:name=>"Agent Smith", :title=>"Home" }, :layout=>"layout-alternative", :layout_opts=>{:locals=>{:title=>"Home"}})
172
- end
173
- end
174
-
175
- body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
176
- end
177
-
178
- it ":layout=>true/false/string/hash/not-present respects plugin layout switch and template" do
179
- app(:bare) do
180
- plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'layout-yield'}
181
-
182
- route do |r|
183
- opts = {:content=>'bar'}
184
- opts[:layout] = true if r.path == '/'
185
- opts[:layout] = false if r.path == '/f'
186
- opts[:layout] = 'layout' if r.path == '/s'
187
- opts[:layout] = {:template=>'layout'} if r.path == '/h'
188
- opts[:layout_opts] = {:locals=>{:title=>'a'}}
189
- view(opts)
190
- end
191
- end
192
-
193
- body.gsub("\n", '').must_equal "HeaderbarFooter"
194
- body('/a').gsub("\n", '').must_equal "HeaderbarFooter"
195
- body('/f').gsub("\n", '').must_equal "bar"
196
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
197
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
198
-
199
- app.plugin :render
200
- body.gsub("\n", '').must_equal "HeaderbarFooter"
201
- body('/a').gsub("\n", '').must_equal "HeaderbarFooter"
202
- body('/f').gsub("\n", '').must_equal "bar"
203
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
204
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
205
-
206
- app.plugin :render, :layout=>true
207
- body.gsub("\n", '').must_equal "HeaderbarFooter"
208
- body('/a').gsub("\n", '').must_equal "HeaderbarFooter"
209
- body('/f').gsub("\n", '').must_equal "bar"
210
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
211
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
212
-
213
- app.plugin :render, :layout=>'layout-alternative'
214
- body.gsub("\n", '').must_equal "<title>Alternative Layout: a</title>bar"
215
- body('/a').gsub("\n", '').must_equal "<title>Alternative Layout: a</title>bar"
216
- body('/f').gsub("\n", '').must_equal "bar"
217
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
218
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
219
-
220
- app.plugin :render, :layout=>nil
221
- body.gsub("\n", '').must_equal "HeaderbarFooter"
222
- body('/a').gsub("\n", '').must_equal "bar"
223
- body('/f').gsub("\n", '').must_equal "bar"
224
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
225
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
226
-
227
- app.plugin :render, :layout=>false
228
- body.gsub("\n", '').must_equal "HeaderbarFooter"
229
- body('/a').gsub("\n", '').must_equal "bar"
230
- body('/f').gsub("\n", '').must_equal "bar"
231
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
232
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
233
-
234
- app.plugin :render, :layout_opts=>{:template=>'layout-alternative', :locals=>{:title=>'a'}}
235
- body.gsub("\n", '').must_equal "<title>Alternative Layout: a</title>bar"
236
- body('/a').gsub("\n", '').must_equal "bar"
237
- body('/f').gsub("\n", '').must_equal "bar"
238
- body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
239
- body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
240
- end
241
-
242
- it "app :root option affects :views default" do
243
- app
244
- app.plugin :render
245
- app.render_opts[:views].must_equal File.join(Dir.pwd, 'views')
246
-
247
- app.opts[:root] = '/foo'
248
- app.plugin :render
249
- # Work around for Windows
250
- app.render_opts[:views].sub(/\A\w:/, '').must_equal '/foo/views'
251
-
252
- app.opts[:root] = '/foo/bar'
253
- app.plugin :render
254
- app.render_opts[:views].sub(/\A\w:/, '').must_equal '/foo/bar/views'
255
-
256
- app.opts[:root] = nil
257
- app.plugin :render
258
- app.render_opts[:views].must_equal File.join(Dir.pwd, 'views')
259
- app.plugin :render, :views=>'bar'
260
- app.render_opts[:views].must_equal File.join(Dir.pwd, 'bar')
261
- end
262
-
263
- if Roda::RodaPlugins::Render::COMPILED_METHOD_SUPPORT
264
- [true, false].each do |cache_plugin_option|
265
- multiplier = cache_plugin_option ? 1 : 2
266
- it "does not cache template renders when using a template library that doesn't support it with plugin option :cache=>#{cache_plugin_option}" do
267
- begin
268
- require 'tilt/rdoc'
269
- rescue
270
- next
271
- end
272
-
273
- app(:bare) do
274
- plugin :render, :views=>'spec/views', :engine=>'rdoc', :cache=>cache_plugin_option
275
- route do
276
- render('a')
277
- end
278
- end
279
-
280
- app.render_opts[:template_method_cache]['a'].must_be_nil
281
- body.strip.must_equal "<p># a # * b</p>"
282
- app.render_opts[:template_method_cache]['a'].must_equal false
283
- body.strip.must_equal "<p># a # * b</p>"
284
- app.render_opts[:template_method_cache]['a'].must_equal false
285
- body.strip.must_equal "<p># a # * b</p>"
286
- app.render_opts[:template_method_cache]['a'].must_equal false
287
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal 0
288
- end
289
-
290
- ['comp_test', :comp_test].each do |template|
291
- it "does not cache template renders when given a hash with #{template.class} value with plugin option :cache=>#{cache_plugin_option}" do
292
- app(:bare) do
293
- plugin :render, :views=>'spec/views', :cache=>cache_plugin_option
294
- route do
295
- render(:template=>template)
296
- end
297
- end
298
-
299
- app.render_opts[:template_method_cache][template].must_be_nil
300
- body.strip.must_equal "ct"
301
- app.render_opts[:template_method_cache][template].must_be_nil
302
- body.strip.must_equal "ct"
303
- app.render_opts[:template_method_cache][template].must_be_nil
304
- body.strip.must_equal "ct"
305
- app.render_opts[:template_method_cache][template].must_be_nil
306
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal 0
307
- end
308
-
309
- it "caches template renders when given a #{template.class} with plugin option :cache=>#{cache_plugin_option}" do
310
- app(:bare) do
311
- plugin :render, :views=>'spec/views', :cache=>cache_plugin_option
312
- route do
313
- render(template)
314
- end
315
- end
316
-
317
- app.render_opts[:template_method_cache][template].must_be_nil
318
- body.strip.must_equal "ct"
319
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
320
- body.strip.must_equal "ct"
321
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
322
- body.strip.must_equal "ct"
323
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
324
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal multiplier
325
- end
326
-
327
- it "does not cache template views or layout when given a hash with #{template.class} value with plugin option :cache=>#{cache_plugin_option}" do
328
- app(:bare) do
329
- layout = template.to_s.sub('test', 'layout')
330
- layout = layout.to_sym if template.is_a?(Symbol)
331
- plugin :render, :views=>'spec/views', :layout=>layout, :cache=>cache_plugin_option
332
- route do
333
- view(:template=>template)
334
- end
335
- end
336
-
337
- app.render_opts[:template_method_cache][template].must_be_nil
338
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
339
- body.strip.must_equal "act\nb"
340
- app.render_opts[:template_method_cache][template].must_be_nil
341
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
342
- body.strip.must_equal "act\nb"
343
- app.render_opts[:template_method_cache][template].must_be_nil
344
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
345
- body.strip.must_equal "act\nb"
346
- app.render_opts[:template_method_cache][template].must_be_nil
347
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
348
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal 0
349
- end
350
-
351
- it "caches template views with layout when given a #{template.class} with plugin option :cache=>#{cache_plugin_option}" do
352
- app(:bare) do
353
- layout = template.to_s.sub('test', 'layout')
354
- layout = layout.to_sym if template.is_a?(Symbol)
355
- plugin :render, :views=>'spec/views', :layout=>layout, :cache=>cache_plugin_option
356
- route do
357
- view(template)
358
- end
359
- end
360
-
361
- app.render_opts[:template_method_cache][template].must_be_nil
362
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
363
- body.strip.must_equal "act\nb"
364
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
365
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
366
- body.strip.must_equal "act\nb"
367
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
368
- app.render_opts[:template_method_cache][:_roda_layout].must_be_kind_of(Symbol)
369
- body.strip.must_equal "act\nb"
370
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
371
- app.render_opts[:template_method_cache][:_roda_layout].must_be_kind_of(Symbol)
372
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal(2*multiplier)
373
- end
374
-
375
- it "caches template views without layout when additional layout options given when given a #{template.class} with plugin option :cache=>#{cache_plugin_option}" do
376
- app(:bare) do
377
- plugin :render, :views=>'spec/views', :layout=>nil, :cache=>cache_plugin_option
378
- route do
379
- view(template)
380
- end
381
- end
382
-
383
- app.render_opts[:template_method_cache][template].must_be_nil
384
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
385
- body.strip.must_equal "ct"
386
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
387
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
388
- body.strip.must_equal "ct"
389
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
390
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
391
- body.strip.must_equal "ct"
392
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
393
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
394
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal multiplier
395
- end
396
-
397
- it "caches template views without layout when additional layout options given when given a #{template.class} with plugin option :cache=>#{cache_plugin_option}" do
398
- app(:bare) do
399
- plugin :render, :views=>'spec/views', :layout_opts=>{:locals=>{:title=>"Home"}}, :cache=>cache_plugin_option
400
- route do
401
- view(template)
402
- end
403
- end
404
-
405
- app.render_opts[:template_method_cache][template].must_be_nil
406
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
407
- body.strip.must_equal "<title>Roda: Home</title>\nct"
408
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
409
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
410
- body.strip.must_equal "<title>Roda: Home</title>\nct"
411
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
412
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
413
- body.strip.must_equal "<title>Roda: Home</title>\nct"
414
- app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
415
- app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
416
- app::RodaCompiledTemplates.private_instance_methods.length.must_equal multiplier
417
- end
418
- end
419
- end
420
- end
421
-
422
- it "inline layouts and inline views" do
423
- app(:render) do
424
- view({:inline=>'bar'}, :layout=>{:inline=>'Foo: <%= yield %>'})
425
- end
426
-
427
- body.strip.must_equal "Foo: bar"
428
- end
429
-
430
- it "inline renders with opts" do
431
- app(:render) do
432
- render({:inline=>'<%= bar %>'}, {:engine=>'str'})
433
- end
434
-
435
- body.strip.must_equal '<%= bar %>'
436
- end
437
-
438
- it "template renders with :template opts" do
439
- app(:bare) do
440
- plugin :render, :views => "./spec/views"
441
- route do
442
- render(:template=>"about", :locals=>{:title => "About Roda"})
443
- end
444
- end
445
- body.strip.must_equal "<h1>About Roda</h1>"
446
- end
447
-
448
- it "template renders with :template_class opts" do
449
- app(:render) do
450
- @a = 1
451
- render(:inline=>'i#{@a}', :template_class=>::Tilt[:str])
452
- end
453
- body.must_equal "i1"
454
- end
455
-
456
- it "can specify engine-specific options via :engine_opts" do
457
- app(:bare) do
458
- plugin :render, :engine_opts=>{'a.erb'=>{:outvar=>'@a'}}
459
- route do |r|
460
- @a = nil
461
- r.is('a') do
462
- render(:inline=>'<%= @a.class.name %>', :engine=>'a.erb')
463
- end
464
- render(:inline=>'<%= @a.class.name %>')
465
- end
466
- end
467
-
468
- body('/a').must_equal "String"
469
- body.must_equal "NilClass"
470
- end
471
-
472
- it "template cache respects :template_opts" do
473
- c = Class.new do
474
- def initialize(path, _, opts)
475
- @path = path
476
- @opts = opts
477
- end
478
- def render(*)
479
- "#{@path}-#{@opts[:foo]}"
480
- end
481
- end
482
-
483
- app(:render) do |r|
484
- r.is "a" do
485
- render(:inline=>"i", :template_class=>c, :template_opts=>{:foo=>'a'})
486
- end
487
- r.is "b" do
488
- render(:inline=>"i", :template_class=>c, :template_opts=>{:foo=>'b'})
489
- end
490
- end
491
-
492
- body('/a').must_equal "i-a"
493
- body('/b').must_equal "i-b"
494
- end
495
-
496
- it "template cache respects :template_block" do
497
- c = Class.new do
498
- def initialize(path, *, &block)
499
- @path = path
500
- @block = block
501
- end
502
- def render(*)
503
- "#{@path}-#{@block.call}"
504
- end
505
- end
506
-
507
- proca = proc{'a'}
508
- procb = proc{'b'}
509
-
510
- app(:render) do |r|
511
- r.is "a" do
512
- render(:path=>"i", :template_class=>c, :template_block=>proca)
513
- end
514
- r.is "b" do
515
- render(:path=>"i", :template_class=>c, :template_block=>procb)
516
- end
517
- end
518
-
519
- body('/a').must_equal "i-a"
520
- body('/b').must_equal "i-b"
521
- end
522
-
523
- it "template cache respects :locals" do
524
- template = '<%= @a ? b : c %>'
525
-
526
- app(:render) do |r|
527
- r.is "a" do
528
- @a = true
529
- render(:inline=>template.dup, :locals=>{:b=>1})
530
- end
531
- r.is "b" do
532
- @a = true
533
- render(:inline=>template.dup, :locals=>{:b=>2, :c=>4})
534
- end
535
- r.is "c" do
536
- @a = nil
537
- render(:inline=>template.dup, :locals=>{:c=>3})
538
- end
539
- end
540
-
541
- body('/a').must_equal "1"
542
- body('/b').must_equal "2"
543
- body('/c').must_equal "3"
544
- end
545
-
546
- it "Default to :check_template_mtime=>true in development mode" do
547
- with_rack_env('development') do
548
- app(:render){}
549
- end
550
- app.render_opts[:check_template_mtime].must_equal true
551
- app(:render){}
552
- app.render_opts[:check_template_mtime].must_equal false
553
- end
554
-
555
- it "Support :cache=>false plugin option to disable template caching by default, except :cache=>true method option is given" do
556
- app(:bare) do
557
- plugin :render, :views=>"./spec/views", :cache=>false
558
-
559
- route do |r|
560
- @a = 'a'
561
- r.is('a'){render('iv', :cache=>false, :cache_key=>:a)}
562
- r.is('b'){render('iv', :cache=>true, :cache_key=>:a)}
563
- render('iv', :cache_key=>:a)
564
- end
565
- end
566
-
567
- body('/a').strip.must_equal "a"
568
- app.render_opts[:cache][:a].must_be_nil
569
- body('/b').strip.must_equal "a"
570
- app.render_opts[:cache][:a].wont_be_nil
571
- body('/c').strip.must_equal "a"
572
- app.render_opts[:cache][:a].wont_be_nil
573
- end
574
-
575
- it "Support :cache=>false option to disable template caching" do
576
- app(:bare) do
577
- plugin :render, :views=>"./spec/views"
578
-
579
- route do |r|
580
- @a = 'a'
581
- r.is('a'){render('iv', :cache=>false)}
582
- render('iv')
583
- end
584
- end
585
-
586
- body('/a').strip.must_equal "a"
587
- app.render_opts[:cache][File.expand_path('spec/views/iv.erb')].must_be_nil
588
- body('/b').strip.must_equal "a"
589
- app.render_opts[:cache][File.expand_path('spec/views/iv.erb')].wont_be_nil
590
- end
591
-
592
- it "Support :cache=>false option to disable template caching even when :cache_key is given" do
593
- app(:bare) do
594
- plugin :render, :views=>"./spec/views"
595
-
596
- route do |r|
597
- @a = 'a'
598
- r.is('a'){render('iv', :cache=>false, :cache_key=>:foo)}
599
- render('iv', :cache_key=>:foo)
600
- end
601
- end
602
-
603
- body('/a').strip.must_equal "a"
604
- app.render_opts[:cache][:foo].must_be_nil
605
- body('/b').strip.must_equal "a"
606
- app.render_opts[:cache][:foo].wont_be_nil
607
- end
608
-
609
- [{}, {:cache=>true}].each do |cache_val_opts|
610
- [{}, {:cache_key=>:foo}].each do |cache_key_opts|
611
- cache_opts = cache_key_opts.merge(cache_val_opts)
612
- it "Support :explicit_cache plugin option with #{cache_opts} render option" do
613
- app(:bare) do
614
- plugin :render, :views=>"./spec/views", :explicit_cache=>true
615
-
616
- route do |r|
617
- @a = 'a'
618
- render('iv', cache_opts)
619
- end
620
- end
621
-
622
- body('/a').strip.must_equal "a"
623
- template = app.render_opts[:cache][cache_opts[:cache_key] || File.expand_path("spec/views/iv.erb")]
624
- template.must_be_kind_of(cache_val_opts.empty? ? Roda::RodaPlugins::Render::TemplateMtimeWrapper : Tilt::Template)
625
- body('/a').strip.must_equal "a"
626
- end
627
- end
628
- end
629
-
630
- it "Support :cache=>true option to enable template caching when :template_block is used" do
631
- c = Class.new do
632
- def initialize(path, *, &block)
633
- @path = path
634
- @block = block
635
- end
636
- def render(*)
637
- "#{@path}-#{@block.call}"
638
- end
639
- end
640
-
641
- proca = proc{'a'}
642
-
643
- app(:bare) do
644
- plugin :render, :views=>"./spec/views"
645
-
646
- route do |r|
647
- @a = 'a'
648
- r.is('a'){render(:path=>'iv', :template_class=>c, :template_block=>proca)}
649
- render(:path=>'iv', :template_class=>c, :template_block=>proca, :cache=>true)
650
- end
651
- end
652
-
653
- body('/a').strip.must_equal "iv-a"
654
- app.render_opts[:cache][['iv', c, nil, nil, proca]].must_be_nil
655
- body('/b').strip.must_equal "iv-a"
656
- app.render_opts[:cache][['iv', c, nil, nil, proca]].wont_be_nil
657
- end
658
-
659
- it "Support :cache_key option to force the key used when caching, unless :cache=>false option is used" do
660
- app(:bare) do
661
- plugin :render, :views=>"./spec/views"
662
-
663
- route do |r|
664
- @a = 'a'
665
- r.is('a'){render('iv', :cache_key=>:a)}
666
- r.is('about'){render('about', :cache_key=>:a, :cache=>false, :locals=>{:title=>'a'})}
667
- render('about', :cache_key=>:a)
668
- end
669
- end
670
-
671
- body('/a').strip.must_equal "a"
672
- body('/b').strip.must_equal "a"
673
- body('/about').strip.must_equal "<h1>a</h1>"
674
- end
675
-
676
- it "Support :scope option to override object in which to evaluate the template" do
677
- app(:bare) do
678
- plugin :render, :views=>"./spec/views"
679
-
680
- route do |r|
681
- render(:inline=>'<%= first %>-<%= last %>', :scope=>[1,2])
682
- end
683
- end
684
-
685
- body.must_equal "1-2"
686
- end
687
-
688
- it "should dup render_opts when subclassing" do
689
- c = Class.new(Roda)
690
- c.plugin :render, :foo=>:bar
691
- sc = Class.new(c)
692
- c.render_opts.wont_be_same_as(sc.render_opts)
693
- c.render_opts[:foo].must_equal :bar
694
- end
695
-
696
- it "should use a copy of superclass's cache when subclassing" do
697
- c = Class.new(Roda)
698
- c.plugin :render
699
- c.render_opts[:cache][:foo] = 1
700
- sc = Class.new(c)
701
-
702
- c.render_opts.wont_be_same_as(sc.render_opts)
703
- c.render_opts[:cache].wont_be_same_as(sc.render_opts[:cache])
704
- sc.render_opts[:cache][:foo].must_equal 1
705
- end
706
-
707
- it "should not modifying existing cache if loading the plugin a separate time" do
708
- c = Class.new(Roda)
709
- c.plugin :render
710
- cache = c.render_opts[:cache]
711
- c.render_opts[:check_template_mtime].must_equal false
712
- c.plugin :render
713
- c.render_opts[:cache].must_be_same_as cache
714
- c.render_opts[:check_template_mtime].must_equal false
715
-
716
- c.plugin :render, :cache=>false
717
- c.render_opts[:cache].must_be_same_as cache
718
- c.render_opts[:check_template_mtime].must_equal true
719
- c.plugin :render
720
- c.render_opts[:cache].must_be_same_as cache
721
- c.render_opts[:check_template_mtime].must_equal true
722
- end
723
-
724
- it "render plugin call should not override existing options" do
725
- c = Class.new(Roda)
726
- c.plugin :render, :layout_opts=>{:template=>'foo'}
727
- c.plugin :render
728
- c.render_opts[:layout_opts][:template].must_equal 'foo'
729
- end
730
-
731
- it "should not use cache by default in subclass if not caching by default in superclass" do
732
- app(:bare) do
733
- plugin :render, :views=>"./spec/views", :cache=>false
734
-
735
- route do |r|
736
- view(:inline=>"Hello <%= name %>", :cache_key=>:a, :locals=>{:name => "Agent Smith"}, :layout=>nil)
737
- end
738
- end
739
-
740
- body("/inline").strip.must_equal "Hello Agent Smith"
741
- Class.new(app).render_opts[:check_template_mtime].must_equal true
742
- end
743
-
744
- it "with :check_paths=>true plugin option used" do
745
- render_opts = {}
746
- app(:bare) do
747
- plugin :render, :views=>"./spec/views", :check_paths=>true
748
-
749
- route do |r|
750
- r.get 'a' do
751
- render("a", render_opts)
752
- end
753
-
754
- r.get 'c' do
755
- render("about/_test", :locals=>{:title=>'a'})
756
- end
757
-
758
- render("b", render_opts)
759
- end
760
- end
761
-
762
- body.strip.must_equal "b"
763
- req("/a")
764
- req("/c")
765
-
766
- @app = Class.new(app)
767
- app.plugin :render, :allowed_paths=>[]
768
- proc{req}.must_raise Roda::RodaError
769
- proc{req("/a")}.must_raise Roda::RodaError
770
- proc{req("/c")}.must_raise Roda::RodaError
771
-
772
- @app = Class.new(app)
773
- app.plugin :render, :allowed_paths=>['spec/views/about']
774
- proc{req}.must_raise Roda::RodaError
775
- proc{req("/a")}.must_raise Roda::RodaError
776
- req("/c")
777
-
778
- @app = Class.new(app)
779
- app.plugin :render, :allowed_paths=>%w'spec/views/about spec/views/b'
780
- body.strip.must_equal "b"
781
- proc{req("/a")}.must_raise Roda::RodaError
782
- req("/c")
783
-
784
- render_opts[:check_paths] = true
785
- @app = Class.new(app)
786
- app.plugin :render, :check_paths=>false
787
- body.strip.must_equal "b"
788
- proc{req("/a")}.must_raise Roda::RodaError
789
- req("/c")
790
-
791
- render_opts.delete(:check_paths)
792
- app.plugin :render
793
- body.strip.must_equal "b"
794
- req("/a")
795
- req("/c")
796
-
797
- render_opts[:check_paths] = true
798
- body.strip.must_equal "b"
799
- proc{req("/a")}.must_raise Roda::RodaError
800
- req("/c")
801
- end
802
-
803
- it "with a cache_class set" do
804
- app(:bare) do
805
- test_cache = Class.new(Roda::RodaCache) do
806
- def [](key)
807
- super
808
- end
809
- def []=(key, value)
810
- super
811
- end
812
- def test_method
813
- end
814
- end
815
-
816
- plugin :render, :views=>"./spec/views", :cache=>true, :cache_class=>test_cache
817
-
818
- route do |r|
819
- view(:inline=>"foo", :layout=>nil)
820
- end
821
- end
822
-
823
- body("/inline").strip.must_equal "foo"
824
-
825
- Class.new(app).render_opts[:cache].must_respond_to :test_method
826
- end
827
-
828
- end
829
- end
830
-
831
- begin
832
- require 'tilt'
833
- require 'tilt/erubi'
834
- rescue LoadError
835
- warn "tilt 2 or erubi not installed, skipping render :escape=>true test"
836
- else
837
- describe ":render plugin :escape option" do
838
- before do
839
- if defined?(Tilt::ErubiTemplate) && ::Tilt['erb'] != Tilt::ErubiTemplate
840
- # Set erubi as default erb template handler
841
- Tilt.register(Tilt::ErubiTemplate, 'erb')
842
- end
843
- end
844
-
845
- it "should escape inside <%= %> and not inside <%== %>, and handle postfix conditionals" do
846
- app(:bare) do
847
- plugin :render, :escape=>true
848
-
849
- route do |r|
850
- render(:inline=>'<%= "<>" %> <%== "<>" %><%= "<>" if false %>')
851
- end
852
- end
853
-
854
- body.must_equal '&lt;&gt; <>'
855
- end
856
-
857
- it "should allow for per-branch escaping via set_view options" do
858
- app(:bare) do
859
- plugin :render, :escape=>true
860
- plugin :view_options
861
-
862
- route do |r|
863
- set_view_options :template_opts=>{:escape=>false}
864
- r.is 'a' do
865
- set_view_options :template_opts=>{:engine_class=>render_opts[:template_opts][:engine_class]}
866
- render(:inline=>'<%= "<>" %>')
867
- end
868
- render(:inline=>'<%= "<>" %>')
869
- end
870
- end
871
-
872
- body('/a').must_equal '&lt;&gt;'
873
- body.must_equal '<>'
874
- end
875
-
876
- it "should accept :escape=>String to only escape for that template engine" do
877
- app(:bare) do
878
- plugin :render, :escape=>'erb'
879
-
880
- route do |r|
881
- r.is 'a' do
882
- render(:inline=>'<%= "<>" %> <%== "<>" %><%= "<>" if false %>', :engine=>'unescaped.erb')
883
- end
884
- render(:inline=>'<%= "<>" %> <%== "<>" %><%= "<>" if false %>')
885
- end
886
- end
887
-
888
- body.must_equal '&lt;&gt; <>'
889
- body('/a').must_equal '<> &lt;&gt;'
890
- end
891
-
892
- it "should accept :escape=>Array to only escape for those template engines" do
893
- app(:bare) do
894
- plugin :render, :escape=>%w'erb erubi', :engine_opts=>{'erubi'=>{:bufvar=>'_buf'}}
895
-
896
- route do |r|
897
- r.is 'a' do
898
- render(:inline=>'<%= "<>" %> <%== "<>" %><%= "<>" if false %>', :engine=>'unescaped.erb')
899
- end
900
- r.is 'b' do
901
- render(:inline=>'<%= _buf.length %><%= "<>" %> <%== "<>" %><%= "<>" if false %>', :engine=>'erubi')
902
- end
903
- render(:inline=>'<%= "<>" %> <%== "<>" %><%= "<>" if false %>')
904
- end
905
- end
906
-
907
- body.must_equal '&lt;&gt; <>'
908
- body('/a').must_equal '<> &lt;&gt;'
909
- body('/b').must_equal '0&lt;&gt; <>'
910
- end
911
- end
912
- end