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,22 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "slash_path_empty" do
4
- it "considers a / path as empty" do
5
- app(:slash_path_empty) do |r|
6
- r.is{"1"}
7
- r.is("a"){"2"}
8
- r.get("b"){"3"}
9
- end
10
-
11
- body("").must_equal '1'
12
- body.must_equal '1'
13
- body("a").must_equal ''
14
- body("/a").must_equal '2'
15
- body("/a/").must_equal '2'
16
- body("/a/b").must_equal ''
17
- body("b").must_equal ''
18
- body("/b").must_equal '3'
19
- body("/b/").must_equal '3'
20
- body("/b/c").must_equal ''
21
- end
22
- end
@@ -1,192 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "static_routing plugin" do
4
- it "adds support for static routes that are taken before normal routes" do
5
- app(:bare) do
6
- plugin :static_routing
7
- static_route "/foo" do |r|
8
- "#{r.path}:#{r.remaining_path}"
9
- end
10
- static_route "/bar" do |r|
11
- r.get{"GET:#{r.path}:#{r.remaining_path}"}
12
- r.post{"POST:#{r.path}:#{r.remaining_path}"}
13
- end
14
- static_get "/bar" do |r|
15
- r.get{"GET2:#{r.path}:#{r.remaining_path}"}
16
- end
17
- static_route "/quux" do |r|
18
- r.halt [500, {}, []]
19
- end
20
-
21
- route do |r|
22
- r.on 'foo' do
23
- r.get true do
24
- 'foo1'
25
- end
26
- r.root do
27
- 'foo2'
28
- end
29
- end
30
-
31
- r.get 'baz' do
32
- 'baz'
33
- end
34
- end
35
- end
36
-
37
- 2.times do
38
- body('/foo').must_equal '/foo:'
39
- body('/foo/').must_equal 'foo2'
40
- body('/bar').must_equal 'GET2:/bar:'
41
- body('/bar', 'REQUEST_METHOD'=>'POST').must_equal 'POST:/bar:'
42
- status('/bar', 'REQUEST_METHOD'=>'PATCH').must_equal 404
43
- body('/baz').must_equal 'baz'
44
- status('/quux').must_equal 500
45
- @app = Class.new(@app)
46
- end
47
- end
48
-
49
- it "works with hooks plugin if loaded after" do
50
- a = []
51
- app(:bare) do
52
- plugin :hooks
53
- plugin :static_routing
54
-
55
- before{a << 1}
56
- after{a << 2}
57
-
58
- static_route "/foo" do |r|
59
- a << 3
60
- "bar"
61
- end
62
-
63
- route{}
64
- end
65
- body('/foo').must_equal 'bar'
66
- a.must_equal [1,3,2]
67
- end
68
-
69
- it "works with hooks plugin if loaded before" do
70
- a = []
71
- app(:bare) do
72
- plugin :static_routing
73
- plugin :hooks
74
-
75
- before{a << 1}
76
- after{a << 2}
77
-
78
- static_route "/foo" do |r|
79
- a << 3
80
- "bar"
81
- end
82
-
83
- route{}
84
- end
85
- body('/foo').must_equal 'bar'
86
- a.must_equal [1,3,2]
87
- end
88
-
89
- it "supports overridding static routes" do
90
- app(:static_routing) do |r|
91
- end
92
- app.static_route('/foo'){'bar'}
93
- body('/foo').must_equal 'bar'
94
- app.static_route('/foo'){'baz'}
95
- body('/foo').must_equal 'baz'
96
- end
97
-
98
- it "keeps existing routes when loading the plugin" do
99
- app(:bare) do
100
- plugin :static_routing
101
- static_route "/foo" do |r|
102
- "#{r.path}:#{r.remaining_path}"
103
- end
104
- plugin :static_routing
105
-
106
- route{}
107
- end
108
- body('/foo').must_equal '/foo:'
109
- end
110
-
111
- it "does not allow placeholders in static routes" do
112
- app(:bare) do
113
- plugin :static_routing
114
- static_route "/:foo" do |r|
115
- "#{r.path}:#{r.remaining_path}"
116
- end
117
-
118
- route{}
119
- end
120
- body('/:foo').must_equal '/:foo:'
121
- status('/a').must_equal 404
122
- end
123
-
124
- it "duplicates data structures in subclasses" do
125
- app(:bare) do
126
- plugin :static_routing
127
- static_route "/foo" do |r|
128
- 'foo'
129
- end
130
-
131
- route{}
132
- end
133
-
134
- old_app = @app
135
- @app = Class.new(old_app)
136
- old_app.static_route '/bar' do |r|
137
- 'bar1'
138
- end
139
- old_app.static_get '/foo' do |r|
140
- 'foop'
141
- end
142
- @app.static_route '/bar' do |r|
143
- 'bar2'
144
- end
145
-
146
- body('/foo').must_equal 'foo'
147
- body('/bar').must_equal 'bar2'
148
- body('/foo', 'REQUEST_METHOD'=>'POST').must_equal 'foo'
149
- @app = old_app
150
- body('/foo').must_equal 'foop'
151
- body('/bar').must_equal 'bar1'
152
- body('/foo', 'REQUEST_METHOD'=>'POST').must_equal 'foo'
153
- end
154
-
155
- it "freezes static routes when app is frozen" do
156
- app(:bare) do
157
- plugin :static_routing
158
- static_route("/foo"){}
159
- freeze
160
-
161
- proc do
162
- static_get("/foo"){}
163
- end.must_raise
164
-
165
- proc do
166
- static_route("/bar"){}
167
- end.must_raise
168
- end
169
- end
170
-
171
- it 'works with route_block_args plugin' do
172
- app(:bare) do
173
- plugin :static_routing
174
- plugin :route_block_args do
175
- [request.request_method, request.path]
176
- end
177
-
178
- static_route "/foo" do |meth, path|
179
- "#{path}-#{meth}"
180
- end
181
-
182
- static_get "/bar" do |meth, path|
183
- "#{path}-#{meth}-bar"
184
- end
185
-
186
- route{'a'}
187
- end
188
-
189
- body('/foo').must_equal '/foo-GET'
190
- body('/bar').must_equal '/bar-GET-bar'
191
- end
192
- end
@@ -1,30 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "static plugin" do
4
- it "adds support for serving static files" do
5
- app(:bare) do
6
- plugin :static, ['/about'], :root=>'spec/views'
7
-
8
- route do
9
- 'a'
10
- end
11
- end
12
-
13
- body.must_equal 'a'
14
- body('/about/_test.erb').must_equal File.read('spec/views/about/_test.erb')
15
- end
16
-
17
- it "respects the application's :root option" do
18
- app(:bare) do
19
- opts[:root] = File.expand_path('../../', __FILE__)
20
- plugin :static, ['/about'], :root=>'views'
21
-
22
- route do
23
- 'a'
24
- end
25
- end
26
-
27
- body.must_equal 'a'
28
- body('/about/_test.erb').must_equal File.read('spec/views/about/_test.erb')
29
- end
30
- end
@@ -1,28 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "status_303 plugin" do
4
- it 'uses a 302 for get requests' do
5
- app(:status_303) do
6
- request.redirect '/foo'
7
- fail 'redirect should halt'
8
- end
9
- status.must_equal 302
10
- body.must_equal ''
11
- header('Location').must_equal '/foo'
12
- end
13
-
14
- it 'uses the code given when specified' do
15
- app(:status_303) do
16
- request.redirect '/foo', 301
17
- end
18
- status.must_equal 301
19
- end
20
-
21
- it 'uses 303 for post requests if request is HTTP 1.1, 302 for 1.0' do
22
- app(:status_303) do
23
- request.redirect '/foo'
24
- end
25
- status('HTTP_VERSION' => 'HTTP/1.1', 'REQUEST_METHOD'=>'POST').must_equal 303
26
- status('HTTP_VERSION' => 'HTTP/1.0', 'REQUEST_METHOD'=>'POST').must_equal 302
27
- end
28
- end
@@ -1,158 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "status_handler plugin" do
4
- it "executes on no arguments" do
5
- app(:bare) do
6
- plugin :status_handler
7
-
8
- status_handler(404) do
9
- "not found"
10
- end
11
-
12
- route do |r|
13
- r.on "a" do
14
- "found"
15
- end
16
- end
17
- end
18
-
19
- body.must_equal 'not found'
20
- status.must_equal 404
21
- body("/a").must_equal 'found'
22
- status("/a").must_equal 200
23
- end
24
-
25
- it "passes request if block accepts argument" do
26
- app(:bare) do
27
- plugin :status_handler
28
-
29
- status_handler(404) do |r|
30
- r.path + 'foo'
31
- end
32
-
33
- route do |r|
34
- end
35
- end
36
-
37
- body('/').must_equal '/foo'
38
- body("/a").must_equal '/afoo'
39
- status("/").must_equal 404
40
- end
41
-
42
- it "allows overriding status inside status_handler" do
43
- app(:bare) do
44
- plugin :status_handler
45
-
46
- status_handler(404) do
47
- response.status = 403
48
- "not found"
49
- end
50
-
51
- route do |r|
52
- end
53
- end
54
-
55
- status.must_equal 403
56
- end
57
-
58
- it "calculates correct Content-Length" do
59
- app(:bare) do
60
- plugin :status_handler
61
-
62
- status_handler(404) do
63
- "a"
64
- end
65
-
66
- route{}
67
- end
68
-
69
- header('Content-Length').must_equal "1"
70
- end
71
-
72
- it "clears existing headers" do
73
- app(:bare) do
74
- plugin :status_handler
75
-
76
- status_handler(404) do
77
- "a"
78
- end
79
-
80
- route do |r|
81
- response['Content-Type'] = 'text/pdf'
82
- response['Foo'] = 'bar'
83
- nil
84
- end
85
- end
86
-
87
- header('Content-Type').must_equal 'text/html'
88
- header('Foo').must_be_nil
89
- end
90
-
91
- it "does not modify behavior if status_handler is not called" do
92
- app(:status_handler) do |r|
93
- r.on "a" do
94
- "found"
95
- end
96
- end
97
-
98
- body.must_equal ''
99
- body("/a").must_equal 'found'
100
- end
101
-
102
- it "does not modify behavior if body is not an array" do
103
- app(:bare) do
104
- plugin :status_handler
105
-
106
- status_handler(404) do
107
- "not found"
108
- end
109
-
110
- o = Object.new
111
- def o.each; end
112
- route do |r|
113
- r.halt [404, {}, o]
114
- end
115
- end
116
-
117
- body.must_equal ''
118
- end
119
-
120
- it "does not modify behavior if body is not an empty array" do
121
- app(:bare) do
122
- plugin :status_handler
123
-
124
- status_handler(404) do
125
- "not found"
126
- end
127
-
128
- route do |r|
129
- response.status = 404
130
- response.write 'a'
131
- end
132
- end
133
-
134
- body.must_equal 'a'
135
- end
136
-
137
- it "does not allow further status handlers to be added after freezing" do
138
- app(:bare) do
139
- plugin :status_handler
140
-
141
- status_handler(404) do
142
- "not found"
143
- end
144
-
145
- route{}
146
- end
147
-
148
- app.freeze
149
-
150
- body.must_equal 'not found'
151
- status.must_equal 404
152
-
153
- proc{app.status_handler(404) { "blah" }}.must_raise
154
-
155
- body.must_equal 'not found'
156
- end
157
-
158
- end
@@ -1,246 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "streaming plugin" do
4
- it "adds stream method for streaming responses" do
5
- app(:streaming) do |r|
6
- stream do |out|
7
- %w'a b c'.each do |v|
8
- (out << v).must_equal out
9
- out.write(v).must_equal 1
10
- end
11
- end
12
- end
13
-
14
- s, h, b = req
15
- s.must_equal 200
16
- h.must_equal('Content-Type'=>'text/html')
17
- b.to_a.must_equal %w'a a b b c c'
18
- end
19
-
20
- it "works with IO.copy_stream" do
21
- app(:streaming) do |r|
22
- stream do |out|
23
- %w'a b c'.each{|v| IO.copy_stream(StringIO.new(v), out) }
24
- end
25
- end
26
-
27
- s, h, b = req
28
- s.must_equal 200
29
- h.must_equal('Content-Type'=>'text/html')
30
- # dup as copy_stream reuses the buffer
31
- b.map(&:dup).must_equal %w'a b c'
32
- end
33
-
34
- it "should handle errors when streaming, and run callbacks" do
35
- a = []
36
- app(:streaming) do |r|
37
- stream(:callback=>proc{a << 'e'}) do |out|
38
- %w'a b'.each{|v| out << v}
39
- raise Roda::RodaError, 'foo'
40
- out << 'c'
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 "should handle :loop option to loop" 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
- s, h, b = req
62
- s.must_equal 200
63
- h.must_equal('Content-Type'=>'text/html')
64
- proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
65
- a.must_equal %w'a b e'
66
- end
67
-
68
- it "uses handle_stream_error for handling errors when streaming" do
69
- a = []
70
- app(:streaming) do |r|
71
- b = %w'a b c'
72
- stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
73
- out << b.shift
74
- raise Roda::RodaError, 'foo' if b.length == 1
75
- end
76
- end
77
-
78
- app.send(:define_method, :handle_stream_error) do |error, out|
79
- out << '1'
80
- raise error
81
- end
82
-
83
- s, h, b = req
84
- s.must_equal 200
85
- h.must_equal('Content-Type'=>'text/html')
86
- proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
87
- a.must_equal %w'a b 1 e'
88
- end
89
-
90
- it "should allow closing the stream when handling an error" do
91
- a = []
92
- app(:streaming) do |r|
93
- b = %w'a b c'
94
- stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
95
- out << b.shift
96
- raise Roda::RodaError, 'foo' if b.length == 1
97
- end
98
- end
99
-
100
- app.send(:define_method, :handle_stream_error) do |error, out|
101
- out.close
102
- end
103
-
104
- s, h, b = req
105
- s.must_equal 200
106
- h.must_equal('Content-Type'=>'text/html')
107
- b.each{|v| a << v}
108
- a.must_equal %w'a b e'
109
- end
110
-
111
- it "should allow ignoring errors when streaming" do
112
- a = []
113
- b2 = %w'a b c'
114
-
115
- app(:streaming) do |r|
116
- stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
117
- out << b2.shift
118
- raise Roda::RodaError
119
- end
120
- end
121
-
122
- app.send(:define_method, :handle_stream_error) do |error, out|
123
- out << '1'
124
- out.close if b2.empty?
125
- end
126
-
127
- s, h, b = req
128
- s.must_equal 200
129
- h.must_equal('Content-Type'=>'text/html')
130
- b.each{|v| a << v}
131
- a.must_equal %w'a 1 b 1 c 1 e'
132
- end
133
-
134
- describe "with :async" do
135
- it "should stream in a thread" do
136
- main_thread = Thread.current
137
- minitest = self
138
- app(:streaming) do |r|
139
- stream(:async=>true) do |out|
140
- minitest.refute_equal Thread.current, main_thread
141
- %w'a b c'.each do |v|
142
- out << v
143
- end
144
- end
145
- end
146
-
147
- s, h, b = req
148
- s.must_equal 200
149
- h.must_equal('Content-Type'=>'text/html')
150
- b.to_a.must_equal %w'a b c'
151
- end
152
-
153
- it "should propagate exceptions" do
154
- app(:streaming) do |r|
155
- stream(:async=>true) do |out|
156
- Thread.current.report_on_exception = false if Thread.current.respond_to?(:report_on_exception=)
157
- %w'a b'.each{|v| out << v}
158
- raise Roda::RodaError, 'foo'
159
- out << 'c'
160
- end
161
- end
162
-
163
- s, h, b = req
164
- s.must_equal 200
165
- h.must_equal('Content-Type'=>'text/html')
166
- a = []
167
- proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
168
- a.must_equal %w'a b'
169
- end
170
-
171
- it "should terminate the thread on close" do
172
- q = Queue.new
173
- app(:streaming) do |r|
174
- stream(:async=>true) do |out|
175
- %w'a b c d e f g h i j'.each{|v| out << v}
176
- q.deq
177
- out << 'k'
178
- end
179
- end
180
-
181
- *, b = req
182
- e = b.enum_for(:each)
183
- 10.times{e.next}
184
- b.close
185
- q.enq 'x'
186
- proc{e.next}.must_raise(StopIteration)
187
- end
188
-
189
- it "should still run callbacks on close" do
190
- callback = false
191
- app(:streaming) do |r|
192
- stream(:async=>true, :callback=>proc{callback = true}) do |out|
193
- %w'a b c'.each{|v| out << v}
194
- end
195
- end
196
-
197
- *, b = req
198
- b.close
199
- callback.must_equal true
200
- end
201
-
202
- it "should apply backpressure by default" do
203
- q = Queue.new
204
- a = []
205
- app(:streaming) do |r|
206
- stream(:async=>true) do |out|
207
- %w'a b c d e f g h i j'.each do |v|
208
- out << v
209
- a << v
210
- end
211
-
212
- q.enq 'x'
213
-
214
- out << 'k'
215
- a << 'k'
216
- end
217
- end
218
-
219
- req
220
- q.deq
221
- a.must_equal %w'a b c d e f g h i j'
222
- end
223
-
224
- it "should handle :queue option to override queue" do
225
- q = Queue.new
226
- a = []
227
- app(:streaming) do |r|
228
- stream(:async=>true, queue: SizedQueue.new(5)) do |out|
229
- %w'a b c d e'.each do |v|
230
- out << v
231
- a << v
232
- end
233
-
234
- q.enq 'x'
235
-
236
- out << 'f'
237
- a << 'f'
238
- end
239
- end
240
-
241
- req
242
- q.deq
243
- a.must_equal %w'a b c d e'
244
- end
245
- end if RUBY_VERSION >= '2.3'
246
- end