roda 2.28.0 → 2.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.
- checksums.yaml +4 -4
- data/CHANGELOG +46 -0
- data/README.rdoc +25 -7
- data/doc/release_notes/2.29.0.txt +156 -0
- data/lib/roda.rb +25 -3
- data/lib/roda/plugins/_erubis_escaping.rb +2 -0
- data/lib/roda/plugins/_symbol_regexp_matchers.rb +22 -0
- data/lib/roda/plugins/assets.rb +3 -2
- data/lib/roda/plugins/branch_locals.rb +74 -0
- data/lib/roda/plugins/caching.rb +15 -7
- data/lib/roda/plugins/chunked.rb +10 -7
- data/lib/roda/plugins/content_for.rb +4 -1
- data/lib/roda/plugins/drop_body.rb +3 -2
- data/lib/roda/plugins/error_email.rb +3 -2
- data/lib/roda/plugins/error_mail.rb +3 -2
- data/lib/roda/plugins/head.rb +2 -1
- data/lib/roda/plugins/header_matchers.rb +3 -0
- data/lib/roda/plugins/heartbeat.rb +3 -2
- data/lib/roda/plugins/json.rb +5 -3
- data/lib/roda/plugins/json_parser.rb +3 -2
- data/lib/roda/plugins/mailer.rb +3 -3
- data/lib/roda/plugins/match_affix.rb +6 -0
- data/lib/roda/plugins/multi_route.rb +3 -1
- data/lib/roda/plugins/padrino_render.rb +3 -2
- data/lib/roda/plugins/params_capturing.rb +3 -3
- data/lib/roda/plugins/partials.rb +3 -3
- data/lib/roda/plugins/path.rb +4 -2
- data/lib/roda/plugins/path_rewriter.rb +2 -2
- data/lib/roda/plugins/per_thread_caching.rb +2 -0
- data/lib/roda/plugins/placeholder_string_matchers.rb +42 -0
- data/lib/roda/plugins/precompile_templates.rb +3 -2
- data/lib/roda/plugins/render.rb +86 -37
- data/lib/roda/plugins/render_each.rb +2 -1
- data/lib/roda/plugins/render_locals.rb +102 -0
- data/lib/roda/plugins/run_append_slash.rb +2 -1
- data/lib/roda/plugins/run_handler.rb +2 -1
- data/lib/roda/plugins/sinatra_helpers.rb +4 -4
- data/lib/roda/plugins/static_path_info.rb +2 -0
- data/lib/roda/plugins/static_routing.rb +1 -1
- data/lib/roda/plugins/streaming.rb +9 -4
- data/lib/roda/plugins/symbol_matchers.rb +23 -20
- data/lib/roda/plugins/view_options.rb +63 -28
- data/lib/roda/plugins/view_subdirs.rb +1 -0
- data/lib/roda/plugins/websockets.rb +2 -0
- data/lib/roda/version.rb +1 -1
- data/spec/composition_spec.rb +2 -2
- data/spec/matchers_spec.rb +6 -5
- data/spec/plugin/_erubis_escaping_spec.rb +5 -5
- data/spec/plugin/backtracking_array_spec.rb +0 -2
- data/spec/plugin/branch_locals_spec.rb +88 -0
- data/spec/plugin/content_for_spec.rb +8 -2
- data/spec/plugin/halt_spec.rb +8 -0
- data/spec/plugin/header_matchers_spec.rb +20 -5
- data/spec/plugin/multi_route_spec.rb +1 -1
- data/spec/plugin/named_templates_spec.rb +2 -2
- data/spec/plugin/params_capturing_spec.rb +1 -1
- data/spec/plugin/per_thread_caching_spec.rb +1 -1
- data/spec/plugin/placeholder_string_matchers_spec.rb +159 -0
- data/spec/plugin/render_locals_spec.rb +114 -0
- data/spec/plugin/render_spec.rb +83 -8
- data/spec/plugin/streaming_spec.rb +104 -4
- data/spec/plugin/symbol_matchers_spec.rb +1 -1
- data/spec/plugin/view_options_spec.rb +83 -7
- data/spec/plugin/websockets_spec.rb +7 -8
- data/spec/spec_helper.rb +22 -2
- metadata +11 -2
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'tilt/erb'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
warn "tilt not installed, skipping render_locals plugin test"
|
|
7
|
+
else
|
|
8
|
+
describe "render_locals plugin with :merge option" do
|
|
9
|
+
before do
|
|
10
|
+
app(:bare) do
|
|
11
|
+
plugin :render_locals, :render=>{:a=>1, :b=>2, :c=>3, :d=>4, :e=>5}, :layout=>{:a=>-1, :f=>6}, :merge=>true
|
|
12
|
+
plugin :render, :views=>"./spec/views", :check_paths=>true, :layout_opts=>{:inline=>'<%= a %>|<%= b %>|<%= c %>|<%= d %>|<%= e %>|<%= f %>|<%= yield %>'}
|
|
13
|
+
|
|
14
|
+
route do |r|
|
|
15
|
+
r.on "base" do
|
|
16
|
+
view(:inline=>'(<%= a %>|<%= b %>|<%= c %>|<%= d %>|<%= e %>)')
|
|
17
|
+
end
|
|
18
|
+
r.on "override" do
|
|
19
|
+
view(:inline=>'(<%= a %>|<%= b %>|<%= c %>|<%= d %>|<%= e %>)', :locals=>{:b=>-2, :d=>-4, :f=>-6}, :layout_opts=>{:locals=>{:d=>0, :c=>-3, :e=>-5}})
|
|
20
|
+
end
|
|
21
|
+
r.on "no_merge" do
|
|
22
|
+
view(:inline=>'(<%= a %>|<%= b %>|<%= c %>|<%= d %>|<%= e %>)', :locals=>{:b=>-2, :d=>-4, :f=>-6}, :layout_opts=>{:merge_locals=>false, :locals=>{:d=>0, :c=>-3, :e=>-5}})
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should choose method opts before plugin opts, and layout specific before locals" do
|
|
29
|
+
body("/base").must_equal '-1|2|3|4|5|6|(1|2|3|4|5)'
|
|
30
|
+
body("/override").must_equal '-1|-2|-3|0|-5|-6|(1|-2|3|-4|5)'
|
|
31
|
+
body("/no_merge").must_equal '-1|2|-3|0|-5|6|(1|-2|3|-4|5)'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "render_locals plugin" do
|
|
36
|
+
it "locals overrides" do
|
|
37
|
+
app(:bare) do
|
|
38
|
+
plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'multiple-layout'}
|
|
39
|
+
plugin :render_locals, :render=>{:title=>'Home', :b=>'B'}, :layout=>{:title=>'Roda', :a=>'A'}
|
|
40
|
+
|
|
41
|
+
route do |r|
|
|
42
|
+
view("multiple", :locals=>{:b=>"BB"}, :layout_opts=>{:locals=>{:a=>'AA'}})
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
body.strip.must_equal "Roda:AA::Home:BB"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it ":layout=>true/false/string/hash/not-present respects plugin layout switch and template" do
|
|
50
|
+
app(:bare) do
|
|
51
|
+
plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'layout-yield'}
|
|
52
|
+
plugin :render_locals, :layout=>{:title=>'a'}
|
|
53
|
+
|
|
54
|
+
route do |r|
|
|
55
|
+
opts = {:content=>'bar'}
|
|
56
|
+
opts[:layout] = true if r.path == '/'
|
|
57
|
+
opts[:layout] = false if r.path == '/f'
|
|
58
|
+
opts[:layout] = 'layout' if r.path == '/s'
|
|
59
|
+
opts[:layout] = {:template=>'layout'} if r.path == '/h'
|
|
60
|
+
view(opts)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
body.gsub("\n", '').must_equal "HeaderbarFooter"
|
|
65
|
+
body('/a').gsub("\n", '').must_equal "HeaderbarFooter"
|
|
66
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
67
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
68
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
69
|
+
|
|
70
|
+
app.plugin :render
|
|
71
|
+
body.gsub("\n", '').must_equal "HeaderbarFooter"
|
|
72
|
+
body('/a').gsub("\n", '').must_equal "HeaderbarFooter"
|
|
73
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
74
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
75
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
76
|
+
|
|
77
|
+
app.plugin :render, :layout=>true
|
|
78
|
+
body.gsub("\n", '').must_equal "HeaderbarFooter"
|
|
79
|
+
body('/a').gsub("\n", '').must_equal "HeaderbarFooter"
|
|
80
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
81
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
82
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
83
|
+
|
|
84
|
+
app.plugin :render, :layout=>'layout-alternative'
|
|
85
|
+
body.gsub("\n", '').must_equal "<title>Alternative Layout: a</title>bar"
|
|
86
|
+
body('/a').gsub("\n", '').must_equal "<title>Alternative Layout: a</title>bar"
|
|
87
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
88
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
89
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
90
|
+
|
|
91
|
+
app.plugin :render, :layout=>nil
|
|
92
|
+
body.gsub("\n", '').must_equal "HeaderbarFooter"
|
|
93
|
+
body('/a').gsub("\n", '').must_equal "bar"
|
|
94
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
95
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
96
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
97
|
+
|
|
98
|
+
app.plugin :render, :layout=>false
|
|
99
|
+
body.gsub("\n", '').must_equal "HeaderbarFooter"
|
|
100
|
+
body('/a').gsub("\n", '').must_equal "bar"
|
|
101
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
102
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
103
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
104
|
+
|
|
105
|
+
app.plugin :render, :layout_opts=>{:template=>'layout-alternative'}
|
|
106
|
+
app.plugin :render_locals, :layout=>{:title=>'a'}
|
|
107
|
+
body.gsub("\n", '').must_equal "<title>Alternative Layout: a</title>bar"
|
|
108
|
+
body('/a').gsub("\n", '').must_equal "bar"
|
|
109
|
+
body('/f').gsub("\n", '').must_equal "bar"
|
|
110
|
+
body('/s').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
111
|
+
body('/h').gsub("\n", '').must_equal "<title>Roda: a</title>bar"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/spec/plugin/render_spec.rb
CHANGED
|
@@ -50,7 +50,7 @@ describe "render plugin" do
|
|
|
50
50
|
body("/inline").strip.must_equal "Hello <%= name %>"
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
deprecated "with str as ext" do
|
|
54
54
|
app.plugin :render, :ext => "str"
|
|
55
55
|
body("/about").strip.must_equal "<h1>About Roda</h1>"
|
|
56
56
|
body("/home").strip.must_equal "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
|
@@ -69,7 +69,7 @@ describe "render plugin" do
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
describe "render plugin with :layout_opts=>{:merge_locals=>true}" do
|
|
72
|
-
before do
|
|
72
|
+
deprecated "should choose method opts before plugin opts, and layout specific before locals" do
|
|
73
73
|
app(:bare) do
|
|
74
74
|
plugin :render, :views=>"./spec/views", :check_paths=>true, :locals=>{:a=>1, :b=>2, :c=>3, :d=>4, :e=>5}, :layout_opts=>{:inline=>'<%= a %>|<%= b %>|<%= c %>|<%= d %>|<%= e %>|<%= f %>|<%= yield %>', :merge_locals=>true, :locals=>{:a=>-1, :f=>6}}
|
|
75
75
|
|
|
@@ -85,9 +85,7 @@ describe "render plugin with :layout_opts=>{:merge_locals=>true}" do
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
|
-
end
|
|
89
88
|
|
|
90
|
-
it "should choose method opts before plugin opts, and layout specific before locals" do
|
|
91
89
|
body("/base").must_equal '-1|2|3|4|5|6|(1|2|3|4|5)'
|
|
92
90
|
body("/override").must_equal '-1|-2|-3|0|-5|-6|(1|-2|3|-4|5)'
|
|
93
91
|
body("/no_merge").must_equal '-1|2|-3|0|-5|6|(1|-2|3|-4|5)'
|
|
@@ -109,6 +107,19 @@ describe "render plugin" do
|
|
|
109
107
|
body.gsub(/\n+/, "\n").must_equal "Header\nThis is the actual content.\nFooter\n"
|
|
110
108
|
end
|
|
111
109
|
|
|
110
|
+
it "should have :layout_opts=>:views plugin option respect :root app option" do
|
|
111
|
+
app(:bare) do
|
|
112
|
+
self.opts[:root] = 'spec'
|
|
113
|
+
plugin :render, :layout_opts=>{:views=>"views"}, :allowed_paths=>["spec/views"]
|
|
114
|
+
|
|
115
|
+
route do |r|
|
|
116
|
+
view(:content=>'a', :layout_opts=>{:locals=>{:title=>"Home"}})
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
body.strip.must_equal "<title>Roda: Home</title>\na"
|
|
121
|
+
end
|
|
122
|
+
|
|
112
123
|
it "views without default layouts" do
|
|
113
124
|
app(:bare) do
|
|
114
125
|
plugin :render, :views=>"./spec/views", :layout=>false
|
|
@@ -133,7 +144,7 @@ describe "render plugin" do
|
|
|
133
144
|
body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
|
134
145
|
end
|
|
135
146
|
|
|
136
|
-
|
|
147
|
+
deprecated "locals overrides" do
|
|
137
148
|
app(:bare) do
|
|
138
149
|
plugin :render, :views=>"./spec/views", :locals=>{:title=>'Home', :b=>'B'}, :layout_opts=>{:template=>'multiple-layout', :locals=>{:title=>'Roda', :a=>'A'}}
|
|
139
150
|
|
|
@@ -145,7 +156,7 @@ describe "render plugin" do
|
|
|
145
156
|
body.strip.must_equal "Roda:AA::Home:BB"
|
|
146
157
|
end
|
|
147
158
|
|
|
148
|
-
|
|
159
|
+
deprecated ":layout=>true/false/string/hash/not-present respects plugin layout switch and template" do
|
|
149
160
|
app(:bare) do
|
|
150
161
|
plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'layout-yield', :locals=>{:title=>'a'}}
|
|
151
162
|
|
|
@@ -362,6 +373,26 @@ describe "render plugin" do
|
|
|
362
373
|
app.render_opts[:explicit_cache].must_equal false
|
|
363
374
|
end
|
|
364
375
|
|
|
376
|
+
deprecated "Support :cache=>false plugin option to disable template caching, even when :cache=>true method option is given" do
|
|
377
|
+
app(:bare) do
|
|
378
|
+
plugin :render, :views=>"./spec/views", :cache=>false
|
|
379
|
+
|
|
380
|
+
route do |r|
|
|
381
|
+
@a = 'a'
|
|
382
|
+
r.is('a'){render('iv', :cache=>false)}
|
|
383
|
+
r.is('b'){render('iv', :cache=>true)}
|
|
384
|
+
render('iv')
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
body('/a').strip.must_equal "a"
|
|
389
|
+
app.render_opts[:cache].must_equal false
|
|
390
|
+
body('/b').strip.must_equal "a"
|
|
391
|
+
app.render_opts[:cache].must_equal false
|
|
392
|
+
body('/c').strip.must_equal "a"
|
|
393
|
+
app.render_opts[:cache].must_equal false
|
|
394
|
+
end
|
|
395
|
+
|
|
365
396
|
it "Support :cache=>false option to disable template caching" do
|
|
366
397
|
app(:bare) do
|
|
367
398
|
plugin :render, :views=>"./spec/views"
|
|
@@ -459,7 +490,7 @@ describe "render plugin" do
|
|
|
459
490
|
app.render_opts[:cache][['iv', c, nil, nil, proca]].wont_equal nil
|
|
460
491
|
end
|
|
461
492
|
|
|
462
|
-
it "Support :cache_key option to force the key used when caching" do
|
|
493
|
+
it "Support :cache_key option to force the key used when caching, unless :cache=>false option is used" do
|
|
463
494
|
app(:bare) do
|
|
464
495
|
plugin :render, :views=>"./spec/views"
|
|
465
496
|
|
|
@@ -544,7 +575,7 @@ describe "render plugin" do
|
|
|
544
575
|
Class.new(app).render_opts[:cache].must_equal false
|
|
545
576
|
end
|
|
546
577
|
|
|
547
|
-
it "with :check_paths=>true" do
|
|
578
|
+
it "with :check_paths=>true plugin option used" do
|
|
548
579
|
render_opts = {}
|
|
549
580
|
app(:bare) do
|
|
550
581
|
plugin :render, :views=>"./spec/views", :check_paths=>true
|
|
@@ -599,6 +630,50 @@ describe "render plugin" do
|
|
|
599
630
|
req("/c")
|
|
600
631
|
end
|
|
601
632
|
|
|
633
|
+
deprecated "with :check_paths plugin option not set" do
|
|
634
|
+
render_opts = {}
|
|
635
|
+
app(:bare) do
|
|
636
|
+
plugin :render, :views=>"./spec/views"
|
|
637
|
+
|
|
638
|
+
route do |r|
|
|
639
|
+
r.get 'a' do
|
|
640
|
+
render("a", render_opts)
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
r.get 'c' do
|
|
644
|
+
render("about/_test", :locals=>{:title=>'a'})
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
render("b", render_opts)
|
|
648
|
+
end
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
body.strip.must_equal "b"
|
|
652
|
+
body("/a").strip.must_equal 'a'
|
|
653
|
+
body("/c").strip.must_equal "<h1>Subdir: a</h1>"
|
|
654
|
+
|
|
655
|
+
app.plugin :render, :allowed_paths=>[]
|
|
656
|
+
body.strip.must_equal "b"
|
|
657
|
+
body("/a").strip.must_equal 'a'
|
|
658
|
+
body("/c").strip.must_equal "<h1>Subdir: a</h1>"
|
|
659
|
+
|
|
660
|
+
app.plugin :render, :allowed_paths=>['spec/views/about']
|
|
661
|
+
body.strip.must_equal "b"
|
|
662
|
+
body("/a").strip.must_equal 'a'
|
|
663
|
+
body("/c").strip.must_equal "<h1>Subdir: a</h1>"
|
|
664
|
+
|
|
665
|
+
app.plugin :render, :allowed_paths=>%w'spec/views/about spec/views/b'
|
|
666
|
+
body.strip.must_equal "b"
|
|
667
|
+
body("/a").strip.must_equal 'a'
|
|
668
|
+
body("/c").strip.must_equal "<h1>Subdir: a</h1>"
|
|
669
|
+
|
|
670
|
+
render_opts[:check_paths] = true
|
|
671
|
+
app.plugin :render, :check_paths=>false
|
|
672
|
+
body.strip.must_equal "b"
|
|
673
|
+
proc{req("/a")}.must_raise Roda::RodaError
|
|
674
|
+
body("/c").strip.must_equal "<h1>Subdir: a</h1>"
|
|
675
|
+
end
|
|
676
|
+
|
|
602
677
|
it "with a cache_class set" do
|
|
603
678
|
app(:bare) do
|
|
604
679
|
test_cache = Class.new(Roda::RodaCache) do
|
|
@@ -24,6 +24,106 @@ describe "streaming plugin" do
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
s, h, b = req
|
|
28
|
+
s.must_equal 200
|
|
29
|
+
h.must_equal('Content-Type'=>'text/html')
|
|
30
|
+
proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
|
|
31
|
+
a.must_equal %w'a b e'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should handle :loop option to loop" do
|
|
35
|
+
a = []
|
|
36
|
+
app(:streaming) do |r|
|
|
37
|
+
b = %w'a b c'
|
|
38
|
+
stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
|
|
39
|
+
out << b.shift
|
|
40
|
+
raise Roda::RodaError, 'foo' if b.length == 1
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
s, h, b = req
|
|
45
|
+
s.must_equal 200
|
|
46
|
+
h.must_equal('Content-Type'=>'text/html')
|
|
47
|
+
proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
|
|
48
|
+
a.must_equal %w'a b e'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "uses handle_stream_error for handling errors when streaming" do
|
|
52
|
+
a = []
|
|
53
|
+
app(:streaming) do |r|
|
|
54
|
+
b = %w'a b c'
|
|
55
|
+
stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
|
|
56
|
+
out << b.shift
|
|
57
|
+
raise Roda::RodaError, 'foo' if b.length == 1
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
app.send(:define_method, :handle_stream_error) do |error, out|
|
|
62
|
+
out << '1'
|
|
63
|
+
raise error
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
s, h, b = req
|
|
67
|
+
s.must_equal 200
|
|
68
|
+
h.must_equal('Content-Type'=>'text/html')
|
|
69
|
+
proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
|
|
70
|
+
a.must_equal %w'a b 1 e'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should allow closing the stream when handling an error" do
|
|
74
|
+
a = []
|
|
75
|
+
app(:streaming) do |r|
|
|
76
|
+
b = %w'a b c'
|
|
77
|
+
stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
|
|
78
|
+
out << b.shift
|
|
79
|
+
raise Roda::RodaError, 'foo' if b.length == 1
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
app.send(:define_method, :handle_stream_error) do |error, out|
|
|
84
|
+
out.close
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
s, h, b = req
|
|
88
|
+
s.must_equal 200
|
|
89
|
+
h.must_equal('Content-Type'=>'text/html')
|
|
90
|
+
b.each{|v| a << v}
|
|
91
|
+
a.must_equal %w'a b e'
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should allow ignoring errors when streaming" do
|
|
95
|
+
a = []
|
|
96
|
+
b2 = %w'a b c'
|
|
97
|
+
|
|
98
|
+
app(:streaming) do |r|
|
|
99
|
+
stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
|
|
100
|
+
out << b2.shift
|
|
101
|
+
raise Roda::RodaError
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
app.send(:define_method, :handle_stream_error) do |error, out|
|
|
106
|
+
out << '1'
|
|
107
|
+
out.close if b2.empty?
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
s, h, b = req
|
|
111
|
+
s.must_equal 200
|
|
112
|
+
h.must_equal('Content-Type'=>'text/html')
|
|
113
|
+
b.each{|v| a << v}
|
|
114
|
+
a.must_equal %w'a 1 b 1 c 1 e'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
deprecated "should handle errors when streaming, and run callbacks" do
|
|
118
|
+
a = []
|
|
119
|
+
app(:streaming) do |r|
|
|
120
|
+
stream(:callback=>proc{a << 'e'}) do |out|
|
|
121
|
+
%w'a b'.each{|v| out << v}
|
|
122
|
+
raise Roda::RodaError, 'foo'
|
|
123
|
+
out << 'c'
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
27
127
|
s, h, b = req
|
|
28
128
|
s.must_equal 200
|
|
29
129
|
h.must_equal('Content-Type'=>'text/html')
|
|
@@ -32,7 +132,7 @@ describe "streaming plugin" do
|
|
|
32
132
|
a.must_equal %w'a b e d'
|
|
33
133
|
end
|
|
34
134
|
|
|
35
|
-
|
|
135
|
+
deprecated "should handle :loop option to loop" do
|
|
36
136
|
a = []
|
|
37
137
|
app(:streaming) do |r|
|
|
38
138
|
b = %w'a b c'
|
|
@@ -50,7 +150,7 @@ describe "streaming plugin" do
|
|
|
50
150
|
a.must_equal %w'a b e d'
|
|
51
151
|
end
|
|
52
152
|
|
|
53
|
-
|
|
153
|
+
deprecated "uses handle_stream_error for handling errors when streaming" do
|
|
54
154
|
a = []
|
|
55
155
|
app(:streaming) do |r|
|
|
56
156
|
b = %w'a b c'
|
|
@@ -73,7 +173,7 @@ describe "streaming plugin" do
|
|
|
73
173
|
a.must_equal %w'a b 1 e d'
|
|
74
174
|
end
|
|
75
175
|
|
|
76
|
-
|
|
176
|
+
deprecated "should allow closing the stream when handling an error" do
|
|
77
177
|
a = []
|
|
78
178
|
app(:streaming) do |r|
|
|
79
179
|
b = %w'a b c'
|
|
@@ -95,7 +195,7 @@ describe "streaming plugin" do
|
|
|
95
195
|
a.must_equal %w'a b e d'
|
|
96
196
|
end
|
|
97
197
|
|
|
98
|
-
|
|
198
|
+
deprecated "should allow ignoring errors when streaming" do
|
|
99
199
|
a = []
|
|
100
200
|
b2 = %w'a b c'
|
|
101
201
|
|
|
@@ -49,7 +49,7 @@ describe "symbol_matchers plugin" do
|
|
|
49
49
|
body('/thing2/q').must_equal 'thing2q'
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
deprecated "works with placeholder string matchers" do
|
|
53
53
|
app(:bare) do
|
|
54
54
|
opts[:verbatim_string_matcher] = false
|
|
55
55
|
plugin :symbol_matchers
|
|
@@ -45,7 +45,43 @@ describe "view_options plugin view subdirs" do
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
describe "view_options plugin" do
|
|
48
|
-
it "should set view and layout options
|
|
48
|
+
it "should set view and layout options to use" do
|
|
49
|
+
app(:bare) do
|
|
50
|
+
plugin :render, :allowed_paths=>['spec/views']
|
|
51
|
+
plugin :view_options
|
|
52
|
+
plugin :render_locals, :render=>{:title=>'About Roda'}, :layout=>{:title=>'Home'}
|
|
53
|
+
|
|
54
|
+
route do
|
|
55
|
+
set_view_options :views=>'spec/views'
|
|
56
|
+
set_layout_options :views=>'spec/views', :template=>'layout-alternative'
|
|
57
|
+
view('about')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should merge multiple calls to set view and layout options" do
|
|
65
|
+
app(:bare) do
|
|
66
|
+
plugin :render, :allowed_paths=>['spec/views']
|
|
67
|
+
plugin :view_options
|
|
68
|
+
plugin :render_locals, :render=>{:title=>'Home', :b=>'B'}, :layout=>{:title=>'About Roda', :a=>'A'}
|
|
69
|
+
|
|
70
|
+
route do
|
|
71
|
+
set_layout_options :views=>'spec/views', :template=>'multiple-layout', :engine=>'str'
|
|
72
|
+
set_view_options :views=>'spec/views', :engine=>'str'
|
|
73
|
+
|
|
74
|
+
set_layout_options :engine=>'erb'
|
|
75
|
+
set_view_options :engine=>'erb'
|
|
76
|
+
|
|
77
|
+
view('multiple')
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
body.strip.must_equal "About Roda:A::Home:B"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
deprecated "should set view and layout options and locals to use" do
|
|
49
85
|
app(:view_options) do
|
|
50
86
|
set_view_options :views=>'spec/views'
|
|
51
87
|
set_view_locals :title=>'About Roda'
|
|
@@ -57,15 +93,15 @@ describe "view_options plugin" do
|
|
|
57
93
|
body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
|
|
58
94
|
end
|
|
59
95
|
|
|
60
|
-
|
|
96
|
+
deprecated "should merge multiple calls to set view and layout options and locals" do
|
|
61
97
|
app(:view_options) do
|
|
62
|
-
set_layout_options :views=>'spec/views', :template=>'multiple-layout', :
|
|
63
|
-
set_view_options :views=>'spec/views', :
|
|
98
|
+
set_layout_options :views=>'spec/views', :template=>'multiple-layout', :engine=>'str'
|
|
99
|
+
set_view_options :views=>'spec/views', :engine=>'str'
|
|
64
100
|
set_layout_locals :title=>'About Roda'
|
|
65
101
|
set_view_locals :title=>'Home'
|
|
66
102
|
|
|
67
|
-
set_layout_options :
|
|
68
|
-
set_view_options :
|
|
103
|
+
set_layout_options :engine=>'erb'
|
|
104
|
+
set_view_options :engine=>'erb'
|
|
69
105
|
set_layout_locals :a=>'A'
|
|
70
106
|
set_view_locals :b=>'B'
|
|
71
107
|
|
|
@@ -75,7 +111,7 @@ describe "view_options plugin" do
|
|
|
75
111
|
body.strip.must_equal "About Roda:A::Home:B"
|
|
76
112
|
end
|
|
77
113
|
|
|
78
|
-
|
|
114
|
+
deprecated "should have set_view_locals have more precedence than plugin options, but less than view/render method options" do
|
|
79
115
|
app(:bare) do
|
|
80
116
|
plugin :render, :views=>"./spec/views", :locals=>{:title=>'Home', :b=>'B'}, :layout_opts=>{:template=>'multiple-layout', :locals=>{:title=>'About Roda', :a=>'A'}}
|
|
81
117
|
plugin :view_options
|
|
@@ -113,5 +149,45 @@ describe "view_options plugin" do
|
|
|
113
149
|
body('/a').strip.must_equal "About Roda:AA::Home:BB"
|
|
114
150
|
body.strip.must_equal "About Roda:AAA::Home:BBB"
|
|
115
151
|
end
|
|
152
|
+
|
|
153
|
+
deprecated "should have set_view_locals have more precedence than plugin options, but less than view/render method options" do
|
|
154
|
+
app(:bare) do
|
|
155
|
+
plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'multiple-layout'}
|
|
156
|
+
plugin :render_locals, :render=>{:title=>'Home', :b=>'B'}, :layout=>{:title=>'About Roda', :a=>'A'}
|
|
157
|
+
plugin :view_options
|
|
158
|
+
|
|
159
|
+
route do |r|
|
|
160
|
+
r.is 'c' do
|
|
161
|
+
view(:multiple)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
set_view_locals :b=>'BB'
|
|
165
|
+
set_layout_locals :a=>'AA'
|
|
166
|
+
|
|
167
|
+
r.on 'b' do
|
|
168
|
+
set_view_locals :title=>'About'
|
|
169
|
+
set_layout_locals :title=>'Roda'
|
|
170
|
+
|
|
171
|
+
r.is 'a' do
|
|
172
|
+
view(:multiple)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
view("multiple", :locals=>{:b => "BBB"}, :layout_opts=>{:locals=>{:a=>'AAA'}})
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
r.is 'a' do
|
|
179
|
+
view(:multiple)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
view("multiple", :locals=>{:b => "BBB"}, :layout_opts=>{:locals=>{:a=>'AAA'}})
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
body('/c').strip.must_equal "About Roda:A::Home:B"
|
|
187
|
+
body('/b/a').strip.must_equal "Roda:AA::About:BB"
|
|
188
|
+
body('/b').strip.must_equal "Roda:AAA::About:BBB"
|
|
189
|
+
body('/a').strip.must_equal "About Roda:AA::Home:BB"
|
|
190
|
+
body.strip.must_equal "About Roda:AAA::Home:BBB"
|
|
191
|
+
end
|
|
116
192
|
end
|
|
117
193
|
end
|