roda 3.22.0 → 3.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +10 -0
- data/doc/release_notes/3.23.0.txt +28 -0
- data/lib/roda.rb +4 -1
- data/lib/roda/plugins/exception_page.rb +1 -1
- data/lib/roda/plugins/render.rb +78 -26
- data/lib/roda/plugins/type_routing.rb +1 -1
- data/lib/roda/session_middleware.rb +7 -0
- data/lib/roda/version.rb +1 -1
- data/spec/plugin/exception_page_spec.rb +11 -0
- data/spec/plugin/render_spec.rb +129 -126
- data/spec/plugin/type_routing_spec.rb +32 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2229b19a7b47a63c8f953c9a225f094d9b6c1120893629e30fea16fe189c8462
|
4
|
+
data.tar.gz: 341a5222c9bdf0cdc1aa56b654dd1accdce94257a5f9a756c8a8d37cf5bd5af8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c996fa5a43603f429fb061c84585a84dbe97719032893f3ae1fff22dcd8056fb1c71fb8fa103ea46fca1a50cbaf6156139e9b1ee03ac1151e7a33d576d08b724
|
7
|
+
data.tar.gz: 8eff9c58e5dc39d40e18445bb33a4dcba019034975c110382a9f143021ddaf6920b8e783cc031be07f431a295e2b973ed750cf9f71e064c0796822e51faa6145
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
= 3.23.0 (2019-08-13)
|
2
|
+
|
3
|
+
* Make roda/session_middleware work if type_routing plugin is loaded into Roda itself (jeremyevans) (#169)
|
4
|
+
|
5
|
+
* Handle requests with nothing before extension in the path in the type_routing plugin (jeremyevans) (#168)
|
6
|
+
|
7
|
+
* Always show line number in exception_page output in exception_page plugin (jeremyevans)
|
8
|
+
|
9
|
+
* Improve render/view performance up to 2x in development mode in the default case by calling compiled template methods directly (jeremyevans)
|
10
|
+
|
1
11
|
= 3.22.0 (2019-07-12)
|
2
12
|
|
3
13
|
* Improve render performance up to 4x in the default case by calling compiled template methods directly (jeremyevans)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
= Improvements
|
2
|
+
|
3
|
+
* The render/view methods in the render plugin, when called with
|
4
|
+
a single string/symbol argument (the most common case), are now
|
5
|
+
up to 2x faster in cache: false mode by directly calling compiled
|
6
|
+
template methods. This takes the performance increase in 3.22.0
|
7
|
+
and applies it to cache: false mode in addition to cache: true
|
8
|
+
mode. If the template file has changed, the compiled method is
|
9
|
+
removed, and a new compiled method replaces it.
|
10
|
+
|
11
|
+
* Template modification detection in the render plugin now uses a
|
12
|
+
faster check for modification, which also avoids a race condition.
|
13
|
+
|
14
|
+
* The type_routing plugin now handles requests with nothing but the
|
15
|
+
extension in the request path. This fixes cases when you have
|
16
|
+
one app partially route a request, and send the request to another
|
17
|
+
app, and that app uses the type_routing plugin and has an r.is
|
18
|
+
call at the root level.
|
19
|
+
|
20
|
+
* The roda/session_middleware middleware now works correctly if the
|
21
|
+
type_routing plugin is loaded into Roda itself (as opposed to a
|
22
|
+
Roda subclass).
|
23
|
+
|
24
|
+
* The exception_page plugin now always shows the line number for
|
25
|
+
each line. Previously, it only showed the line number if it was
|
26
|
+
showing the content of the line, which complicated debugging in
|
27
|
+
cases where the content of the line was no longer retrievable
|
28
|
+
due to file system permissions or restrictions (e.g. chroot).
|
data/lib/roda.rb
CHANGED
@@ -340,9 +340,12 @@ class Roda
|
|
340
340
|
end
|
341
341
|
|
342
342
|
# Load a new plugin into the current class. A plugin can be a module
|
343
|
-
# which is used directly, or a symbol
|
343
|
+
# which is used directly, or a symbol representing a registered plugin
|
344
344
|
# which will be required and then used. Returns nil.
|
345
345
|
#
|
346
|
+
# Note that you should not load plugins into a Roda class after the
|
347
|
+
# class has been subclassed, as doing so can break the subclasses.
|
348
|
+
#
|
346
349
|
# Roda.plugin PluginModule
|
347
350
|
# Roda.plugin :csrf
|
348
351
|
def plugin(plugin, *args, &block)
|
@@ -330,7 +330,7 @@ END
|
|
330
330
|
<ul class="traceback">
|
331
331
|
#{frames.map{|frame| id = frame[:id]; (<<END1)}.join
|
332
332
|
<li class="frame">
|
333
|
-
<code>#{h frame[:filename]}</code
|
333
|
+
<code>#{h frame[:filename]}:#{frame[:lineno]}</code> in <code>#{h frame[:function]}</code>
|
334
334
|
|
335
335
|
#{frame[:context_line] ? (<<END2) : '</li>'
|
336
336
|
<div class="context" id="c#{id}">
|
data/lib/roda/plugins/render.rb
CHANGED
@@ -161,20 +161,14 @@ class Roda
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
rescue NameError
|
171
|
-
compiled_templates_module = Module.new
|
172
|
-
app.send(:include, compiled_templates_module)
|
173
|
-
app.const_set(:RodaCompiledTemplates, compiled_templates_module)
|
174
|
-
end
|
175
|
-
opts[:template_method_cache] = orig_method_cache || (opts[:cache_class] || RodaCache).new
|
164
|
+
begin
|
165
|
+
app.const_get(:RodaCompiledTemplates, false)
|
166
|
+
rescue NameError
|
167
|
+
compiled_templates_module = Module.new
|
168
|
+
app.send(:include, compiled_templates_module)
|
169
|
+
app.const_set(:RodaCompiledTemplates, compiled_templates_module)
|
176
170
|
end
|
177
|
-
|
171
|
+
opts[:template_method_cache] = orig_method_cache || (opts[:cache_class] || RodaCache).new
|
178
172
|
opts[:cache] = orig_cache || (opts[:cache_class] || RodaCache).new
|
179
173
|
|
180
174
|
opts[:layout_opts] = (opts[:layout_opts] || {}).dup
|
@@ -244,15 +238,68 @@ class Roda
|
|
244
238
|
# If the template file exists and the modification time has
|
245
239
|
# changed, rebuild the template file, then call render on it.
|
246
240
|
def render(*args, &block)
|
247
|
-
|
248
|
-
|
241
|
+
modified?
|
242
|
+
@template.render(*args, &block)
|
243
|
+
end
|
244
|
+
|
245
|
+
# If the template file has been updated, return true and update
|
246
|
+
# the template object and the modification time. Other return false.
|
247
|
+
def modified?
|
248
|
+
begin
|
249
|
+
mtime = File.mtime(path = @path)
|
250
|
+
rescue
|
251
|
+
# ignore errors
|
252
|
+
else
|
249
253
|
if mtime != @mtime
|
250
254
|
@mtime = mtime
|
251
255
|
@template = @template_class.new(path, *@template_args)
|
256
|
+
return true
|
252
257
|
end
|
253
258
|
end
|
254
259
|
|
255
|
-
|
260
|
+
false
|
261
|
+
end
|
262
|
+
|
263
|
+
if COMPILED_METHOD_SUPPORT
|
264
|
+
# Compile a method in the given module with the given name that will
|
265
|
+
# call the compiled template method, updating the compiled template method
|
266
|
+
def define_compiled_method(roda_class, method_name)
|
267
|
+
mod = roda_class::RodaCompiledTemplates
|
268
|
+
internal_method_name = :"_#{method_name}"
|
269
|
+
begin
|
270
|
+
mod.send(:define_method, internal_method_name, send(:compiled_method, OPTS))
|
271
|
+
rescue ::NotImplementedError
|
272
|
+
return false
|
273
|
+
end
|
274
|
+
|
275
|
+
mod.send(:private, internal_method_name)
|
276
|
+
mod.send(:define_method, method_name, &compiled_method_lambda(self, roda_class, internal_method_name))
|
277
|
+
mod.send(:private, method_name)
|
278
|
+
|
279
|
+
method_name
|
280
|
+
end
|
281
|
+
|
282
|
+
private
|
283
|
+
|
284
|
+
# Return the compiled method for the current template object.
|
285
|
+
def compiled_method(_)
|
286
|
+
@template.send(:compiled_method, OPTS)
|
287
|
+
end
|
288
|
+
|
289
|
+
# Return the lambda used to define the compiled template method. This
|
290
|
+
# is separated into its own method so the lambda does not capture any
|
291
|
+
# unnecessary local variables
|
292
|
+
def compiled_method_lambda(template, roda_class, method_name)
|
293
|
+
mod = roda_class::RodaCompiledTemplates
|
294
|
+
lambda do |_, &block|
|
295
|
+
if template.modified?
|
296
|
+
mod.send(:define_method, method_name, template.send(:compiled_method, OPTS))
|
297
|
+
mod.send(:private, method_name)
|
298
|
+
end
|
299
|
+
|
300
|
+
send(method_name, OPTS, &block)
|
301
|
+
end
|
302
|
+
end
|
256
303
|
end
|
257
304
|
end
|
258
305
|
|
@@ -459,18 +506,23 @@ class Roda
|
|
459
506
|
template_opts = template_opts.merge(current_template_opts)
|
460
507
|
end
|
461
508
|
|
509
|
+
define_compiled_method = COMPILED_METHOD_SUPPORT &&
|
510
|
+
(method_cache_key = opts[:template_method_cache_key]) &&
|
511
|
+
(method_cache = render_opts[:template_method_cache]) &&
|
512
|
+
(method_cache[method_cache_key] != false) &&
|
513
|
+
!opts[:inline]
|
514
|
+
|
462
515
|
if render_opts[:check_template_mtime] && !opts[:template_block] && !cache
|
463
|
-
TemplateMtimeWrapper.new(opts[:template_class], opts[:path], 1, template_opts)
|
516
|
+
template = TemplateMtimeWrapper.new(opts[:template_class], opts[:path], 1, template_opts)
|
517
|
+
|
518
|
+
if define_compiled_method
|
519
|
+
method_name = :"_roda_template_#{self.class.object_id}_#{method_cache_key}"
|
520
|
+
method_cache[method_cache_key] = template.define_compiled_method(self.class, method_name)
|
521
|
+
end
|
464
522
|
else
|
465
523
|
template = opts[:template_class].new(opts[:path], 1, template_opts, &opts[:template_block])
|
466
524
|
|
467
|
-
if
|
468
|
-
(method_cache_key = opts[:template_method_cache_key]) &&
|
469
|
-
(method_cache = render_opts[:template_method_cache]) &&
|
470
|
-
(method_cache[method_cache_key] != false) &&
|
471
|
-
!opts[:inline] &&
|
472
|
-
cache != false
|
473
|
-
|
525
|
+
if define_compiled_method && cache != false
|
474
526
|
begin
|
475
527
|
unbound_method = template.send(:compiled_method, OPTS)
|
476
528
|
rescue ::NotImplementedError
|
@@ -482,9 +534,9 @@ class Roda
|
|
482
534
|
method_cache[method_cache_key] = method_name
|
483
535
|
end
|
484
536
|
end
|
485
|
-
|
486
|
-
template
|
487
537
|
end
|
538
|
+
|
539
|
+
template
|
488
540
|
end
|
489
541
|
end
|
490
542
|
|
@@ -131,7 +131,7 @@ class Roda
|
|
131
131
|
mimes.freeze
|
132
132
|
|
133
133
|
type_keys = config[:types].keys
|
134
|
-
config[:extension_regexp] = /(
|
134
|
+
config[:extension_regexp] = /(.*?)\.(#{Regexp.union(type_keys.map(&:to_s))})\z/
|
135
135
|
|
136
136
|
type_keys.each do |type|
|
137
137
|
app::RodaRequest.send(:define_method, type) do |&block|
|
@@ -150,11 +150,18 @@ class RodaSessionMiddleware
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
+
module RequestMethods
|
154
|
+
# Work around for if type_routing plugin is loaded into Roda class itself.
|
155
|
+
def _remaining_path(_)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
153
159
|
# Setup the middleware, passing +opts+ as the Roda sessions plugin options.
|
154
160
|
def initialize(app, opts)
|
155
161
|
mid = Class.new(Roda)
|
156
162
|
mid.plugin :sessions, opts
|
157
163
|
@req_class = mid::RodaRequest
|
164
|
+
@req_class.send(:include, RequestMethods)
|
158
165
|
@app = app
|
159
166
|
end
|
160
167
|
|
data/lib/roda/version.rb
CHANGED
@@ -139,6 +139,17 @@ describe "exception_page plugin" do
|
|
139
139
|
body.wont_include 'id="c0"'
|
140
140
|
end
|
141
141
|
|
142
|
+
it "should still show line numbers if the line content cannot be displayed" do
|
143
|
+
app(:exception_page) do |r|
|
144
|
+
instance_eval('raise "foo"', 'foo-bar.rb', 4200+42) rescue exception_page($!)
|
145
|
+
end
|
146
|
+
body = body('HTTP_ACCEPT'=>'text/html')
|
147
|
+
body.must_include "RuntimeError: foo"
|
148
|
+
body.must_include "foo-bar.rb:#{4200+42}"
|
149
|
+
body.must_include __FILE__
|
150
|
+
body.wont_include 'id="c0"'
|
151
|
+
end
|
152
|
+
|
142
153
|
it "should serve exception page assets" do
|
143
154
|
app(:exception_page) do |r|
|
144
155
|
r.exception_page_assets
|
data/spec/plugin/render_spec.rb
CHANGED
@@ -261,157 +261,160 @@ describe "render plugin" do
|
|
261
261
|
end
|
262
262
|
|
263
263
|
if Roda::RodaPlugins::Render::COMPILED_METHOD_SUPPORT
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
app(:bare) do
|
272
|
-
plugin :render, :views=>'spec/views', :engine=>'rdoc'
|
273
|
-
route do
|
274
|
-
render('a')
|
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
|
275
271
|
end
|
276
|
-
end
|
277
272
|
|
278
|
-
app.render_opts[:template_method_cache]['a'].must_be_nil
|
279
|
-
body.strip.must_equal "<p># a # * b</p>"
|
280
|
-
app.render_opts[:template_method_cache]['a'].must_equal false
|
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
|
-
app::RodaCompiledTemplates.private_instance_methods.length.must_equal 0
|
286
|
-
end
|
287
|
-
|
288
|
-
['comp_test', :comp_test].each do |template|
|
289
|
-
it "does not cache template renders when given a hash" do
|
290
273
|
app(:bare) do
|
291
|
-
plugin :render, :views=>'spec/views'
|
274
|
+
plugin :render, :views=>'spec/views', :engine=>'rdoc', :cache=>cache_plugin_option
|
292
275
|
route do
|
293
|
-
render(
|
276
|
+
render('a')
|
294
277
|
end
|
295
278
|
end
|
296
279
|
|
297
|
-
app.render_opts[:template_method_cache][
|
298
|
-
body.strip.must_equal "
|
299
|
-
app.render_opts[:template_method_cache][
|
300
|
-
body.strip.must_equal "
|
301
|
-
app.render_opts[:template_method_cache][
|
302
|
-
body.strip.must_equal "
|
303
|
-
app.render_opts[:template_method_cache][
|
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
|
304
287
|
app::RodaCompiledTemplates.private_instance_methods.length.must_equal 0
|
305
288
|
end
|
306
289
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
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
|
312
297
|
end
|
313
|
-
end
|
314
298
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
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
|
324
308
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
view(:template=>template)
|
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
|
332
315
|
end
|
333
|
-
end
|
334
316
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
app.render_opts[:template_method_cache][template].must_be_nil
|
345
|
-
app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
|
346
|
-
app::RodaCompiledTemplates.private_instance_methods.length.must_equal 0
|
347
|
-
end
|
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
|
348
326
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
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
|
356
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
|
357
349
|
end
|
358
350
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
body.strip.must_equal "act\nb"
|
368
|
-
app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
|
369
|
-
app.render_opts[:template_method_cache][:_roda_layout].must_be_kind_of(Symbol)
|
370
|
-
app::RodaCompiledTemplates.private_instance_methods.length.must_equal 2
|
371
|
-
end
|
372
|
-
|
373
|
-
it "caches template views without layout when additional layout options given when given a #{template.class}" do
|
374
|
-
app(:bare) do
|
375
|
-
plugin :render, :views=>'spec/views', :layout=>nil
|
376
|
-
route do
|
377
|
-
view(template)
|
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
|
378
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)
|
379
373
|
end
|
380
374
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
|
388
|
-
app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
|
389
|
-
body.strip.must_equal "ct"
|
390
|
-
app.render_opts[:template_method_cache][template].must_be_kind_of(Symbol)
|
391
|
-
app.render_opts[:template_method_cache][:_roda_layout].must_be_nil
|
392
|
-
app::RodaCompiledTemplates.private_instance_methods.length.must_equal 1
|
393
|
-
end
|
394
|
-
|
395
|
-
it "caches template views without layout when additional layout options given when given a #{template.class}" do
|
396
|
-
app(:bare) do
|
397
|
-
plugin :render, :views=>'spec/views', :layout_opts=>{:locals=>{:title=>"Home"}}
|
398
|
-
route do
|
399
|
-
view(template)
|
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
|
400
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
|
401
395
|
end
|
402
396
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
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
|
415
418
|
end
|
416
419
|
end
|
417
420
|
end
|
@@ -63,6 +63,38 @@ describe "type_routing plugin" do
|
|
63
63
|
body('/a.html', 'HTTP_ACCEPT' => 'application/xml').must_equal 'HTML: html'
|
64
64
|
end
|
65
65
|
|
66
|
+
it "works correctly in sub apps when sub app also handles extensions on empty paths" do
|
67
|
+
sup_app = app
|
68
|
+
@app = Class.new(sup_app)
|
69
|
+
sup_app.route do |r|
|
70
|
+
r.is do
|
71
|
+
r.get do
|
72
|
+
r.html { 'a' }
|
73
|
+
r.json { '{b:1}' }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
r.on 'test' do
|
78
|
+
r.get do
|
79
|
+
r.html { 'c' }
|
80
|
+
r.json { '{d:2}' }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
app.route do |r|
|
85
|
+
r.on "subpath" do
|
86
|
+
r.run(sup_app)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
body('/subpath').must_equal 'a'
|
91
|
+
body('/subpath.html').must_equal 'a'
|
92
|
+
body('/subpath.json').must_equal '{b:1}'
|
93
|
+
body('/subpath/test').must_equal 'c'
|
94
|
+
body('/subpath/test.html').must_equal 'c'
|
95
|
+
body('/subpath/test.json').must_equal '{d:2}'
|
96
|
+
end
|
97
|
+
|
66
98
|
it "uses the default if neither file extension nor Accept header are given" do
|
67
99
|
body('/a').must_equal 'HTML: html'
|
68
100
|
header('Content-Type', '/a').must_equal 'text/html'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -219,6 +219,7 @@ extra_rdoc_files:
|
|
219
219
|
- doc/release_notes/3.20.0.txt
|
220
220
|
- doc/release_notes/3.21.0.txt
|
221
221
|
- doc/release_notes/3.22.0.txt
|
222
|
+
- doc/release_notes/3.23.0.txt
|
222
223
|
files:
|
223
224
|
- CHANGELOG
|
224
225
|
- MIT-LICENSE
|
@@ -277,6 +278,7 @@ files:
|
|
277
278
|
- doc/release_notes/3.20.0.txt
|
278
279
|
- doc/release_notes/3.21.0.txt
|
279
280
|
- doc/release_notes/3.22.0.txt
|
281
|
+
- doc/release_notes/3.23.0.txt
|
280
282
|
- doc/release_notes/3.3.0.txt
|
281
283
|
- doc/release_notes/3.4.0.txt
|
282
284
|
- doc/release_notes/3.5.0.txt
|