roda 3.22.0 → 3.23.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.
- 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
|