rack 2.0.9.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/{HISTORY.md → CHANGELOG.md} +214 -164
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +79 -133
  5. data/Rakefile +25 -18
  6. data/SPEC +9 -9
  7. data/bin/rackup +1 -0
  8. data/example/lobster.ru +2 -0
  9. data/example/protectedlobster.rb +3 -1
  10. data/example/protectedlobster.ru +2 -0
  11. data/lib/rack/auth/abstract/handler.rb +3 -1
  12. data/lib/rack/auth/abstract/request.rb +2 -0
  13. data/lib/rack/auth/basic.rb +4 -1
  14. data/lib/rack/auth/digest/md5.rb +9 -7
  15. data/lib/rack/auth/digest/nonce.rb +6 -3
  16. data/lib/rack/auth/digest/params.rb +4 -2
  17. data/lib/rack/auth/digest/request.rb +2 -0
  18. data/lib/rack/body_proxy.rb +3 -6
  19. data/lib/rack/builder.rb +38 -15
  20. data/lib/rack/cascade.rb +6 -5
  21. data/lib/rack/chunked.rb +29 -6
  22. data/lib/rack/common_logger.rb +9 -11
  23. data/lib/rack/conditional_get.rb +3 -1
  24. data/lib/rack/config.rb +2 -0
  25. data/lib/rack/content_length.rb +3 -1
  26. data/lib/rack/content_type.rb +3 -1
  27. data/lib/rack/core_ext/regexp.rb +14 -0
  28. data/lib/rack/deflater.rb +28 -17
  29. data/lib/rack/directory.rb +17 -14
  30. data/lib/rack/etag.rb +3 -1
  31. data/lib/rack/events.rb +5 -3
  32. data/lib/rack/file.rb +5 -173
  33. data/lib/rack/files.rb +178 -0
  34. data/lib/rack/handler/cgi.rb +3 -1
  35. data/lib/rack/handler/fastcgi.rb +4 -2
  36. data/lib/rack/handler/lsws.rb +3 -1
  37. data/lib/rack/handler/scgi.rb +9 -6
  38. data/lib/rack/handler/thin.rb +3 -1
  39. data/lib/rack/handler/webrick.rb +4 -2
  40. data/lib/rack/handler.rb +7 -2
  41. data/lib/rack/head.rb +2 -0
  42. data/lib/rack/lint.rb +15 -12
  43. data/lib/rack/lobster.rb +7 -5
  44. data/lib/rack/lock.rb +2 -0
  45. data/lib/rack/logger.rb +2 -0
  46. data/lib/rack/media_type.rb +10 -5
  47. data/lib/rack/method_override.rb +4 -2
  48. data/lib/rack/mime.rb +9 -1
  49. data/lib/rack/mock.rb +74 -15
  50. data/lib/rack/multipart/generator.rb +6 -7
  51. data/lib/rack/multipart/parser.rb +55 -62
  52. data/lib/rack/multipart/uploaded_file.rb +2 -0
  53. data/lib/rack/multipart.rb +6 -3
  54. data/lib/rack/null_logger.rb +2 -0
  55. data/lib/rack/query_parser.rb +51 -25
  56. data/lib/rack/recursive.rb +7 -5
  57. data/lib/rack/reloader.rb +10 -4
  58. data/lib/rack/request.rb +79 -26
  59. data/lib/rack/response.rb +71 -31
  60. data/lib/rack/rewindable_input.rb +4 -2
  61. data/lib/rack/runtime.rb +4 -2
  62. data/lib/rack/sendfile.rb +15 -8
  63. data/lib/rack/server.rb +88 -16
  64. data/lib/rack/session/abstract/id.rb +40 -22
  65. data/lib/rack/session/cookie.rb +10 -9
  66. data/lib/rack/session/memcache.rb +4 -93
  67. data/lib/rack/session/pool.rb +4 -2
  68. data/lib/rack/show_exceptions.rb +15 -9
  69. data/lib/rack/show_status.rb +4 -2
  70. data/lib/rack/static.rb +15 -10
  71. data/lib/rack/tempfile_reaper.rb +2 -0
  72. data/lib/rack/urlmap.rb +11 -2
  73. data/lib/rack/utils.rb +64 -93
  74. data/lib/rack.rb +63 -60
  75. data/rack.gemspec +17 -7
  76. metadata +33 -175
  77. data/test/builder/an_underscore_app.rb +0 -5
  78. data/test/builder/anything.rb +0 -5
  79. data/test/builder/comment.ru +0 -4
  80. data/test/builder/end.ru +0 -5
  81. data/test/builder/line.ru +0 -1
  82. data/test/builder/options.ru +0 -2
  83. data/test/cgi/assets/folder/test.js +0 -1
  84. data/test/cgi/assets/fonts/font.eot +0 -1
  85. data/test/cgi/assets/images/image.png +0 -1
  86. data/test/cgi/assets/index.html +0 -1
  87. data/test/cgi/assets/javascripts/app.js +0 -1
  88. data/test/cgi/assets/stylesheets/app.css +0 -1
  89. data/test/cgi/lighttpd.conf +0 -26
  90. data/test/cgi/rackup_stub.rb +0 -6
  91. data/test/cgi/sample_rackup.ru +0 -5
  92. data/test/cgi/test +0 -9
  93. data/test/cgi/test+directory/test+file +0 -1
  94. data/test/cgi/test.fcgi +0 -9
  95. data/test/cgi/test.gz +0 -0
  96. data/test/cgi/test.ru +0 -5
  97. data/test/gemloader.rb +0 -10
  98. data/test/helper.rb +0 -34
  99. data/test/multipart/bad_robots +0 -259
  100. data/test/multipart/binary +0 -0
  101. data/test/multipart/content_type_and_no_filename +0 -6
  102. data/test/multipart/empty +0 -10
  103. data/test/multipart/fail_16384_nofile +0 -814
  104. data/test/multipart/file1.txt +0 -1
  105. data/test/multipart/filename_and_modification_param +0 -7
  106. data/test/multipart/filename_and_no_name +0 -6
  107. data/test/multipart/filename_with_encoded_words +0 -7
  108. data/test/multipart/filename_with_escaped_quotes +0 -6
  109. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  110. data/test/multipart/filename_with_null_byte +0 -7
  111. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  112. data/test/multipart/filename_with_single_quote +0 -7
  113. data/test/multipart/filename_with_unescaped_percentages +0 -6
  114. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  115. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  116. data/test/multipart/filename_with_unescaped_quotes +0 -6
  117. data/test/multipart/ie +0 -6
  118. data/test/multipart/invalid_character +0 -6
  119. data/test/multipart/mixed_files +0 -21
  120. data/test/multipart/nested +0 -10
  121. data/test/multipart/none +0 -9
  122. data/test/multipart/quoted +0 -15
  123. data/test/multipart/rack-logo.png +0 -0
  124. data/test/multipart/semicolon +0 -6
  125. data/test/multipart/text +0 -15
  126. data/test/multipart/three_files_three_fields +0 -31
  127. data/test/multipart/unity3d_wwwform +0 -11
  128. data/test/multipart/webkit +0 -32
  129. data/test/rackup/config.ru +0 -31
  130. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  131. data/test/spec_auth_basic.rb +0 -89
  132. data/test/spec_auth_digest.rb +0 -260
  133. data/test/spec_body_proxy.rb +0 -85
  134. data/test/spec_builder.rb +0 -233
  135. data/test/spec_cascade.rb +0 -63
  136. data/test/spec_cgi.rb +0 -84
  137. data/test/spec_chunked.rb +0 -103
  138. data/test/spec_common_logger.rb +0 -107
  139. data/test/spec_conditional_get.rb +0 -103
  140. data/test/spec_config.rb +0 -23
  141. data/test/spec_content_length.rb +0 -86
  142. data/test/spec_content_type.rb +0 -46
  143. data/test/spec_deflater.rb +0 -375
  144. data/test/spec_directory.rb +0 -148
  145. data/test/spec_etag.rb +0 -108
  146. data/test/spec_events.rb +0 -133
  147. data/test/spec_fastcgi.rb +0 -85
  148. data/test/spec_file.rb +0 -264
  149. data/test/spec_handler.rb +0 -57
  150. data/test/spec_head.rb +0 -46
  151. data/test/spec_lint.rb +0 -520
  152. data/test/spec_lobster.rb +0 -59
  153. data/test/spec_lock.rb +0 -204
  154. data/test/spec_logger.rb +0 -24
  155. data/test/spec_media_type.rb +0 -42
  156. data/test/spec_method_override.rb +0 -110
  157. data/test/spec_mime.rb +0 -51
  158. data/test/spec_mock.rb +0 -359
  159. data/test/spec_multipart.rb +0 -721
  160. data/test/spec_null_logger.rb +0 -21
  161. data/test/spec_recursive.rb +0 -75
  162. data/test/spec_request.rb +0 -1423
  163. data/test/spec_response.rb +0 -528
  164. data/test/spec_rewindable_input.rb +0 -128
  165. data/test/spec_runtime.rb +0 -50
  166. data/test/spec_sendfile.rb +0 -125
  167. data/test/spec_server.rb +0 -193
  168. data/test/spec_session_abstract_id.rb +0 -31
  169. data/test/spec_session_abstract_session_hash.rb +0 -45
  170. data/test/spec_session_cookie.rb +0 -442
  171. data/test/spec_session_memcache.rb +0 -357
  172. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  173. data/test/spec_session_pool.rb +0 -247
  174. data/test/spec_show_exceptions.rb +0 -93
  175. data/test/spec_show_status.rb +0 -104
  176. data/test/spec_static.rb +0 -184
  177. data/test/spec_tempfile_reaper.rb +0 -64
  178. data/test/spec_thin.rb +0 -96
  179. data/test/spec_urlmap.rb +0 -237
  180. data/test/spec_utils.rb +0 -742
  181. data/test/spec_version.rb +0 -11
  182. data/test/spec_webrick.rb +0 -206
  183. data/test/static/another/index.html +0 -1
  184. data/test/static/foo.html +0 -1
  185. data/test/static/index.html +0 -1
  186. data/test/testrequest.rb +0 -78
  187. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  188. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,528 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack'
3
- require 'rack/response'
4
- require 'stringio'
5
-
6
- describe Rack::Response do
7
- it 'has cache-control methods' do
8
- response = Rack::Response.new
9
- cc = 'foo'
10
- response.cache_control = cc
11
- assert_equal cc, response.cache_control
12
- assert_equal cc, response.to_a[2]['Cache-Control']
13
- end
14
-
15
- it 'has an etag method' do
16
- response = Rack::Response.new
17
- etag = 'foo'
18
- response.etag = etag
19
- assert_equal etag, response.etag
20
- assert_equal etag, response.to_a[2]['ETag']
21
- end
22
-
23
- it "have sensible default values" do
24
- response = Rack::Response.new
25
- status, header, body = response.finish
26
- status.must_equal 200
27
- header.must_equal({})
28
- body.each { |part|
29
- part.must_equal ""
30
- }
31
-
32
- response = Rack::Response.new
33
- status, header, body = *response
34
- status.must_equal 200
35
- header.must_equal({})
36
- body.each { |part|
37
- part.must_equal ""
38
- }
39
- end
40
-
41
- it "can be written to" do
42
- response = Rack::Response.new
43
-
44
- _, _, body = response.finish do
45
- response.write "foo"
46
- response.write "bar"
47
- response.write "baz"
48
- end
49
-
50
- parts = []
51
- body.each { |part| parts << part }
52
-
53
- parts.must_equal ["foo", "bar", "baz"]
54
- end
55
-
56
- it "can set and read headers" do
57
- response = Rack::Response.new
58
- response["Content-Type"].must_be_nil
59
- response["Content-Type"] = "text/plain"
60
- response["Content-Type"].must_equal "text/plain"
61
- end
62
-
63
- it "can override the initial Content-Type with a different case" do
64
- response = Rack::Response.new("", 200, "content-type" => "text/plain")
65
- response["Content-Type"].must_equal "text/plain"
66
- end
67
-
68
- it "can set cookies" do
69
- response = Rack::Response.new
70
-
71
- response.set_cookie "foo", "bar"
72
- response["Set-Cookie"].must_equal "foo=bar"
73
- response.set_cookie "foo2", "bar2"
74
- response["Set-Cookie"].must_equal ["foo=bar", "foo2=bar2"].join("\n")
75
- response.set_cookie "foo3", "bar3"
76
- response["Set-Cookie"].must_equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
77
- end
78
-
79
- it "can set cookies with the same name for multiple domains" do
80
- response = Rack::Response.new
81
- response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
82
- response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
83
- response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
84
- end
85
-
86
- it "formats the Cookie expiration date accordingly to RFC 6265" do
87
- response = Rack::Response.new
88
-
89
- response.set_cookie "foo", {:value => "bar", :expires => Time.now+10}
90
- response["Set-Cookie"].must_match(
91
- /expires=..., \d\d ... \d\d\d\d \d\d:\d\d:\d\d .../)
92
- end
93
-
94
- it "can set secure cookies" do
95
- response = Rack::Response.new
96
- response.set_cookie "foo", {:value => "bar", :secure => true}
97
- response["Set-Cookie"].must_equal "foo=bar; secure"
98
- end
99
-
100
- it "can set http only cookies" do
101
- response = Rack::Response.new
102
- response.set_cookie "foo", {:value => "bar", :httponly => true}
103
- response["Set-Cookie"].must_equal "foo=bar; HttpOnly"
104
- end
105
-
106
- it "can set http only cookies with :http_only" do
107
- response = Rack::Response.new
108
- response.set_cookie "foo", {:value => "bar", :http_only => true}
109
- response["Set-Cookie"].must_equal "foo=bar; HttpOnly"
110
- end
111
-
112
- it "can set prefers :httponly for http only cookie setting when :httponly and :http_only provided" do
113
- response = Rack::Response.new
114
- response.set_cookie "foo", {:value => "bar", :httponly => false, :http_only => true}
115
- response["Set-Cookie"].must_equal "foo=bar"
116
- end
117
-
118
- it "can set SameSite cookies with symbol value :none" do
119
- response = Rack::Response.new
120
- response.set_cookie "foo", { value: "bar", same_site: :none }
121
- response["Set-Cookie"].must_equal "foo=bar; SameSite=None"
122
- end
123
-
124
- it "can set SameSite cookies with symbol value :None" do
125
- response = Rack::Response.new
126
- response.set_cookie "foo", { value: "bar", same_site: :None }
127
- response["Set-Cookie"].must_equal "foo=bar; SameSite=None"
128
- end
129
-
130
- it "can set SameSite cookies with string value 'None'" do
131
- response = Rack::Response.new
132
- response.set_cookie "foo", { value: "bar", same_site: "None" }
133
- response["Set-Cookie"].must_equal "foo=bar; SameSite=None"
134
- end
135
-
136
- it "can set SameSite cookies with symbol value :lax" do
137
- response = Rack::Response.new
138
- response.set_cookie "foo", {:value => "bar", :same_site => :lax}
139
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Lax"
140
- end
141
-
142
- it "can set SameSite cookies with symbol value :Lax" do
143
- response = Rack::Response.new
144
- response.set_cookie "foo", {:value => "bar", :same_site => :lax}
145
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Lax"
146
- end
147
-
148
- it "can set SameSite cookies with string value 'Lax'" do
149
- response = Rack::Response.new
150
- response.set_cookie "foo", {:value => "bar", :same_site => "Lax"}
151
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Lax"
152
- end
153
-
154
- it "can set SameSite cookies with boolean value true" do
155
- response = Rack::Response.new
156
- response.set_cookie "foo", {:value => "bar", :same_site => true}
157
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
158
- end
159
-
160
- it "can set SameSite cookies with symbol value :strict" do
161
- response = Rack::Response.new
162
- response.set_cookie "foo", {:value => "bar", :same_site => :strict}
163
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
164
- end
165
-
166
- it "can set SameSite cookies with symbol value :Strict" do
167
- response = Rack::Response.new
168
- response.set_cookie "foo", {:value => "bar", :same_site => :Strict}
169
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
170
- end
171
-
172
- it "can set SameSite cookies with string value 'Strict'" do
173
- response = Rack::Response.new
174
- response.set_cookie "foo", {:value => "bar", :same_site => "Strict"}
175
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
176
- end
177
-
178
- it "validates the SameSite option value" do
179
- response = Rack::Response.new
180
- lambda {
181
- response.set_cookie "foo", {:value => "bar", :same_site => "Foo"}
182
- }.must_raise(ArgumentError).
183
- message.must_match(/Invalid SameSite value: "Foo"/)
184
- end
185
-
186
- it "can set SameSite cookies with symbol value" do
187
- response = Rack::Response.new
188
- response.set_cookie "foo", {:value => "bar", :same_site => :Strict}
189
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
190
- end
191
-
192
- [ nil, false ].each do |non_truthy|
193
- it "omits SameSite attribute given a #{non_truthy.inspect} value" do
194
- response = Rack::Response.new
195
- response.set_cookie "foo", {:value => "bar", :same_site => non_truthy}
196
- response["Set-Cookie"].must_equal "foo=bar"
197
- end
198
- end
199
-
200
- it "can delete cookies" do
201
- response = Rack::Response.new
202
- response.set_cookie "foo", "bar"
203
- response.set_cookie "foo2", "bar2"
204
- response.delete_cookie "foo"
205
- response["Set-Cookie"].must_equal [
206
- "foo2=bar2",
207
- "foo=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
208
- ].join("\n")
209
- end
210
-
211
- it "can delete cookies with the same name from multiple domains" do
212
- response = Rack::Response.new
213
- response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
214
- response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
215
- response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
216
- response.delete_cookie "foo", :domain => ".example.com"
217
- response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=; domain=.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
218
- response.delete_cookie "foo", :domain => "sample.example.com"
219
- response["Set-Cookie"].must_equal ["foo=; domain=.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000",
220
- "foo=; domain=sample.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
221
- end
222
-
223
- it "can delete cookies with the same name with different paths" do
224
- response = Rack::Response.new
225
- response.set_cookie "foo", {:value => "bar", :path => "/"}
226
- response.set_cookie "foo", {:value => "bar", :path => "/path"}
227
- response["Set-Cookie"].must_equal ["foo=bar; path=/",
228
- "foo=bar; path=/path"].join("\n")
229
-
230
- response.delete_cookie "foo", :path => "/path"
231
- response["Set-Cookie"].must_equal ["foo=bar; path=/",
232
- "foo=; path=/path; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
233
- end
234
-
235
- it "can do redirects" do
236
- response = Rack::Response.new
237
- response.redirect "/foo"
238
- status, header, body = response.finish
239
- status.must_equal 302
240
- header["Location"].must_equal "/foo"
241
-
242
- response = Rack::Response.new
243
- response.redirect "/foo", 307
244
- status, header, body = response.finish
245
-
246
- status.must_equal 307
247
- end
248
-
249
- it "has a useful constructor" do
250
- r = Rack::Response.new("foo")
251
- status, header, body = r.finish
252
- str = ""; body.each { |part| str << part }
253
- str.must_equal "foo"
254
-
255
- r = Rack::Response.new(["foo", "bar"])
256
- status, header, body = r.finish
257
- str = ""; body.each { |part| str << part }
258
- str.must_equal "foobar"
259
-
260
- object_with_each = Object.new
261
- def object_with_each.each
262
- yield "foo"
263
- yield "bar"
264
- end
265
- r = Rack::Response.new(object_with_each)
266
- r.write "foo"
267
- status, header, body = r.finish
268
- str = ""; body.each { |part| str << part }
269
- str.must_equal "foobarfoo"
270
-
271
- r = Rack::Response.new([], 500)
272
- r.status.must_equal 500
273
-
274
- r = Rack::Response.new([], "200 OK")
275
- r.status.must_equal 200
276
- end
277
-
278
- it "has a constructor that can take a block" do
279
- r = Rack::Response.new { |res|
280
- res.status = 404
281
- res.write "foo"
282
- }
283
- status, _, body = r.finish
284
- str = ""; body.each { |part| str << part }
285
- str.must_equal "foo"
286
- status.must_equal 404
287
- end
288
-
289
- it "doesn't return invalid responses" do
290
- r = Rack::Response.new(["foo", "bar"], 204)
291
- _, header, body = r.finish
292
- str = ""; body.each { |part| str << part }
293
- str.must_be :empty?
294
- header["Content-Type"].must_be_nil
295
- header['Content-Length'].must_be_nil
296
-
297
- lambda {
298
- Rack::Response.new(Object.new)
299
- }.must_raise(TypeError).
300
- message.must_match(/stringable or iterable required/)
301
- end
302
-
303
- it "knows if it's empty" do
304
- r = Rack::Response.new
305
- r.must_be :empty?
306
- r.write "foo"
307
- r.wont_be :empty?
308
-
309
- r = Rack::Response.new
310
- r.must_be :empty?
311
- r.finish
312
- r.must_be :empty?
313
-
314
- r = Rack::Response.new
315
- r.must_be :empty?
316
- r.finish { }
317
- r.wont_be :empty?
318
- end
319
-
320
- it "provide access to the HTTP status" do
321
- res = Rack::Response.new
322
- res.status = 200
323
- res.must_be :successful?
324
- res.must_be :ok?
325
-
326
- res.status = 201
327
- res.must_be :successful?
328
- res.must_be :created?
329
-
330
- res.status = 202
331
- res.must_be :successful?
332
- res.must_be :accepted?
333
-
334
- res.status = 204
335
- res.must_be :successful?
336
- res.must_be :no_content?
337
-
338
- res.status = 301
339
- res.must_be :redirect?
340
- res.must_be :moved_permanently?
341
-
342
- res.status = 302
343
- res.must_be :redirect?
344
-
345
- res.status = 303
346
- res.must_be :redirect?
347
-
348
- res.status = 307
349
- res.must_be :redirect?
350
-
351
- res.status = 308
352
- res.must_be :redirect?
353
-
354
- res.status = 400
355
- res.wont_be :successful?
356
- res.must_be :client_error?
357
- res.must_be :bad_request?
358
-
359
- res.status = 401
360
- res.wont_be :successful?
361
- res.must_be :client_error?
362
- res.must_be :unauthorized?
363
-
364
- res.status = 404
365
- res.wont_be :successful?
366
- res.must_be :client_error?
367
- res.must_be :not_found?
368
-
369
- res.status = 405
370
- res.wont_be :successful?
371
- res.must_be :client_error?
372
- res.must_be :method_not_allowed?
373
-
374
- res.status = 412
375
- res.wont_be :successful?
376
- res.must_be :client_error?
377
- res.must_be :precondition_failed?
378
-
379
- res.status = 422
380
- res.wont_be :successful?
381
- res.must_be :client_error?
382
- res.must_be :unprocessable?
383
-
384
- res.status = 501
385
- res.wont_be :successful?
386
- res.must_be :server_error?
387
- end
388
-
389
- it "provide access to the HTTP headers" do
390
- res = Rack::Response.new
391
- res["Content-Type"] = "text/yaml"
392
-
393
- res.must_include "Content-Type"
394
- res.headers["Content-Type"].must_equal "text/yaml"
395
- res["Content-Type"].must_equal "text/yaml"
396
- res.content_type.must_equal "text/yaml"
397
- res.content_length.must_be_nil
398
- res.location.must_be_nil
399
- end
400
-
401
- it "does not add or change Content-Length when #finish()ing" do
402
- res = Rack::Response.new
403
- res.status = 200
404
- res.finish
405
- res.headers["Content-Length"].must_be_nil
406
-
407
- res = Rack::Response.new
408
- res.status = 200
409
- res.headers["Content-Length"] = "10"
410
- res.finish
411
- res.headers["Content-Length"].must_equal "10"
412
- end
413
-
414
- it "updates Content-Length when body appended to using #write" do
415
- res = Rack::Response.new
416
- res.status = 200
417
- res.headers["Content-Length"].must_be_nil
418
- res.write "Hi"
419
- res.headers["Content-Length"].must_equal "2"
420
- res.write " there"
421
- res.headers["Content-Length"].must_equal "8"
422
- end
423
-
424
- it "calls close on #body" do
425
- res = Rack::Response.new
426
- res.body = StringIO.new
427
- res.close
428
- res.body.must_be :closed?
429
- end
430
-
431
- it "calls close on #body when 204 or 304" do
432
- res = Rack::Response.new
433
- res.body = StringIO.new
434
- res.finish
435
- res.body.wont_be :closed?
436
-
437
- res.status = 204
438
- _, _, b = res.finish
439
- res.body.must_be :closed?
440
- b.wont_equal res.body
441
-
442
- res.body = StringIO.new
443
- res.status = 205
444
- _, _, b = res.finish
445
- res.body.wont_be :closed?
446
- b.wont_equal res.body
447
-
448
- res.body = StringIO.new
449
- res.status = 304
450
- _, _, b = res.finish
451
- res.body.must_be :closed?
452
- b.wont_equal res.body
453
- end
454
-
455
- it "wraps the body from #to_ary to prevent infinite loops" do
456
- res = Rack::Response.new
457
- res.finish.last.wont_respond_to(:to_ary)
458
- lambda { res.finish.last.to_ary }.must_raise NoMethodError
459
- end
460
- end
461
-
462
- describe Rack::Response, 'headers' do
463
- before do
464
- @response = Rack::Response.new([], 200, { 'Foo' => '1' })
465
- end
466
-
467
- it 'has_header?' do
468
- lambda { @response.has_header? nil }.must_raise NoMethodError
469
-
470
- @response.has_header?('Foo').must_equal true
471
- @response.has_header?('foo').must_equal true
472
- end
473
-
474
- it 'get_header' do
475
- lambda { @response.get_header nil }.must_raise NoMethodError
476
-
477
- @response.get_header('Foo').must_equal '1'
478
- @response.get_header('foo').must_equal '1'
479
- end
480
-
481
- it 'set_header' do
482
- lambda { @response.set_header nil, '1' }.must_raise NoMethodError
483
-
484
- @response.set_header('Foo', '2').must_equal '2'
485
- @response.has_header?('Foo').must_equal true
486
- @response.get_header('Foo').must_equal('2')
487
-
488
- @response.set_header('Foo', nil).must_be_nil
489
- @response.has_header?('Foo').must_equal true
490
- @response.get_header('Foo').must_be_nil
491
- end
492
-
493
- it 'add_header' do
494
- lambda { @response.add_header nil, '1' }.must_raise NoMethodError
495
-
496
- # Add a value to an existing header
497
- @response.add_header('Foo', '2').must_equal '1,2'
498
- @response.get_header('Foo').must_equal '1,2'
499
-
500
- # Add nil to an existing header
501
- @response.add_header('Foo', nil).must_equal '1,2'
502
- @response.get_header('Foo').must_equal '1,2'
503
-
504
- # Add nil to a nonexistent header
505
- @response.add_header('Bar', nil).must_be_nil
506
- @response.has_header?('Bar').must_equal false
507
- @response.get_header('Bar').must_be_nil
508
-
509
- # Add a value to a nonexistent header
510
- @response.add_header('Bar', '1').must_equal '1'
511
- @response.has_header?('Bar').must_equal true
512
- @response.get_header('Bar').must_equal '1'
513
- end
514
-
515
- it 'delete_header' do
516
- lambda { @response.delete_header nil }.must_raise NoMethodError
517
-
518
- @response.delete_header('Foo').must_equal '1'
519
- (!!@response.has_header?('Foo')).must_equal false
520
-
521
- @response.delete_header('Foo').must_be_nil
522
- @response.has_header?('Foo').must_equal false
523
-
524
- @response.set_header('Foo', 1)
525
- @response.delete_header('foo').must_equal 1
526
- @response.has_header?('Foo').must_equal false
527
- end
528
- end
@@ -1,128 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'stringio'
3
- require 'rack/rewindable_input'
4
-
5
- module RewindableTest
6
- extend Minitest::Spec::DSL
7
-
8
- def setup
9
- @rio = Rack::RewindableInput.new(@io)
10
- end
11
-
12
- class << self # HACK to get this running w/ as few changes as possible
13
- alias_method :should, :it
14
- end
15
-
16
- it "be able to handle to read()" do
17
- @rio.read.must_equal "hello world"
18
- end
19
-
20
- it "be able to handle to read(nil)" do
21
- @rio.read(nil).must_equal "hello world"
22
- end
23
-
24
- it "be able to handle to read(length)" do
25
- @rio.read(1).must_equal "h"
26
- end
27
-
28
- it "be able to handle to read(length, buffer)" do
29
- buffer = ""
30
- result = @rio.read(1, buffer)
31
- result.must_equal "h"
32
- result.object_id.must_equal buffer.object_id
33
- end
34
-
35
- it "be able to handle to read(nil, buffer)" do
36
- buffer = ""
37
- result = @rio.read(nil, buffer)
38
- result.must_equal "hello world"
39
- result.object_id.must_equal buffer.object_id
40
- end
41
-
42
- it "rewind to the beginning when #rewind is called" do
43
- @rio.read(1)
44
- @rio.rewind
45
- @rio.read.must_equal "hello world"
46
- end
47
-
48
- it "be able to handle gets" do
49
- @rio.gets.must_equal "hello world"
50
- end
51
-
52
- it "be able to handle each" do
53
- array = []
54
- @rio.each do |data|
55
- array << data
56
- end
57
- array.must_equal ["hello world"]
58
- end
59
-
60
- it "not buffer into a Tempfile if no data has been read yet" do
61
- @rio.instance_variable_get(:@rewindable_io).must_be_nil
62
- end
63
-
64
- it "buffer into a Tempfile when data has been consumed for the first time" do
65
- @rio.read(1)
66
- tempfile = @rio.instance_variable_get(:@rewindable_io)
67
- tempfile.wont_be :nil?
68
- @rio.read(1)
69
- tempfile2 = @rio.instance_variable_get(:@rewindable_io)
70
- tempfile2.path.must_equal tempfile.path
71
- end
72
-
73
- it "close the underlying tempfile upon calling #close" do
74
- @rio.read(1)
75
- tempfile = @rio.instance_variable_get(:@rewindable_io)
76
- @rio.close
77
- tempfile.must_be :closed?
78
- end
79
-
80
- it "be possible to call #close when no data has been buffered yet" do
81
- @rio.close.must_be_nil
82
- end
83
-
84
- it "be possible to call #close multiple times" do
85
- @rio.close.must_be_nil
86
- @rio.close.must_be_nil
87
- end
88
-
89
- after do
90
- @rio.close
91
- @rio = nil
92
- end
93
- end
94
-
95
- describe Rack::RewindableInput do
96
- describe "given an IO object that is already rewindable" do
97
- def setup
98
- @io = StringIO.new("hello world")
99
- super
100
- end
101
-
102
- include RewindableTest
103
- end
104
-
105
- describe "given an IO object that is not rewindable" do
106
- def setup
107
- @io = StringIO.new("hello world")
108
- @io.instance_eval do
109
- undef :rewind
110
- end
111
- super
112
- end
113
-
114
- include RewindableTest
115
- end
116
-
117
- describe "given an IO object whose rewind method raises Errno::ESPIPE" do
118
- def setup
119
- @io = StringIO.new("hello world")
120
- def @io.rewind
121
- raise Errno::ESPIPE, "You can't rewind this!"
122
- end
123
- super
124
- end
125
-
126
- include RewindableTest
127
- end
128
- end
data/test/spec_runtime.rb DELETED
@@ -1,50 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
- require 'rack/runtime'
5
-
6
- describe Rack::Runtime do
7
- def runtime_app(app, *args)
8
- Rack::Lint.new Rack::Runtime.new(app, *args)
9
- end
10
-
11
- def request
12
- Rack::MockRequest.env_for
13
- end
14
-
15
- it "sets X-Runtime is none is set" do
16
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
17
- response = runtime_app(app).call(request)
18
- response[1]['X-Runtime'].must_match(/[\d\.]+/)
19
- end
20
-
21
- it "doesn't set the X-Runtime if it is already set" do
22
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
23
- response = runtime_app(app).call(request)
24
- response[1]['X-Runtime'].must_equal "foobar"
25
- end
26
-
27
- it "allow a suffix to be set" do
28
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
29
- response = runtime_app(app, "Test").call(request)
30
- response[1]['X-Runtime-Test'].must_match(/[\d\.]+/)
31
- end
32
-
33
- it "allow multiple timers to be set" do
34
- app = lambda { |env| sleep 0.1; [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
35
- runtime = runtime_app(app, "App")
36
-
37
- # wrap many times to guarantee a measurable difference
38
- 100.times do |i|
39
- runtime = Rack::Runtime.new(runtime, i.to_s)
40
- end
41
- runtime = Rack::Runtime.new(runtime, "All")
42
-
43
- response = runtime.call(request)
44
-
45
- response[1]['X-Runtime-App'].must_match(/[\d\.]+/)
46
- response[1]['X-Runtime-All'].must_match(/[\d\.]+/)
47
-
48
- Float(response[1]['X-Runtime-All']).must_be :>, Float(response[1]['X-Runtime-App'])
49
- end
50
- end