rack 1.6.13 → 2.0.0.alpha

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 (138) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.md +139 -18
  3. data/README.rdoc +17 -25
  4. data/Rakefile +6 -14
  5. data/SPEC +8 -9
  6. data/contrib/rack_logo.svg +164 -111
  7. data/lib/rack.rb +70 -21
  8. data/lib/rack/auth/digest/request.rb +1 -1
  9. data/lib/rack/body_proxy.rb +14 -9
  10. data/lib/rack/builder.rb +3 -3
  11. data/lib/rack/chunked.rb +5 -5
  12. data/lib/rack/{commonlogger.rb → common_logger.rb} +2 -2
  13. data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
  14. data/lib/rack/content_length.rb +2 -2
  15. data/lib/rack/deflater.rb +4 -4
  16. data/lib/rack/directory.rb +49 -55
  17. data/lib/rack/etag.rb +2 -1
  18. data/lib/rack/events.rb +154 -0
  19. data/lib/rack/file.rb +55 -40
  20. data/lib/rack/handler.rb +2 -24
  21. data/lib/rack/handler/cgi.rb +15 -16
  22. data/lib/rack/handler/fastcgi.rb +13 -14
  23. data/lib/rack/handler/lsws.rb +11 -11
  24. data/lib/rack/handler/scgi.rb +15 -15
  25. data/lib/rack/handler/thin.rb +3 -0
  26. data/lib/rack/handler/webrick.rb +22 -24
  27. data/lib/rack/head.rb +15 -17
  28. data/lib/rack/lint.rb +38 -38
  29. data/lib/rack/lobster.rb +1 -1
  30. data/lib/rack/lock.rb +6 -10
  31. data/lib/rack/logger.rb +2 -2
  32. data/lib/rack/media_type.rb +38 -0
  33. data/lib/rack/{methodoverride.rb → method_override.rb} +4 -11
  34. data/lib/rack/mime.rb +18 -5
  35. data/lib/rack/mock.rb +35 -52
  36. data/lib/rack/multipart.rb +35 -6
  37. data/lib/rack/multipart/generator.rb +4 -4
  38. data/lib/rack/multipart/parser.rb +273 -158
  39. data/lib/rack/multipart/uploaded_file.rb +1 -2
  40. data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
  41. data/lib/rack/query_parser.rb +174 -0
  42. data/lib/rack/recursive.rb +8 -8
  43. data/lib/rack/reloader.rb +1 -2
  44. data/lib/rack/request.rb +370 -304
  45. data/lib/rack/response.rb +129 -56
  46. data/lib/rack/rewindable_input.rb +1 -12
  47. data/lib/rack/runtime.rb +10 -18
  48. data/lib/rack/sendfile.rb +5 -7
  49. data/lib/rack/server.rb +31 -25
  50. data/lib/rack/session/abstract/id.rb +93 -135
  51. data/lib/rack/session/cookie.rb +26 -28
  52. data/lib/rack/session/memcache.rb +8 -14
  53. data/lib/rack/session/pool.rb +14 -21
  54. data/lib/rack/show_exceptions.rb +386 -0
  55. data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
  56. data/lib/rack/static.rb +30 -5
  57. data/lib/rack/tempfile_reaper.rb +2 -2
  58. data/lib/rack/urlmap.rb +13 -14
  59. data/lib/rack/utils.rb +128 -221
  60. data/rack.gemspec +9 -5
  61. data/test/builder/an_underscore_app.rb +5 -0
  62. data/test/builder/options.ru +1 -1
  63. data/test/cgi/test.fcgi +1 -0
  64. data/test/cgi/test.gz +0 -0
  65. data/test/helper.rb +31 -0
  66. data/test/multipart/filename_with_encoded_words +7 -0
  67. data/test/multipart/{filename_with_null_byte → filename_with_single_quote} +1 -1
  68. data/test/multipart/quoted +15 -0
  69. data/test/multipart/rack-logo.png +0 -0
  70. data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
  71. data/test/spec_auth_basic.rb +20 -19
  72. data/test/spec_auth_digest.rb +47 -46
  73. data/test/spec_body_proxy.rb +27 -27
  74. data/test/spec_builder.rb +51 -41
  75. data/test/spec_cascade.rb +24 -22
  76. data/test/spec_cgi.rb +49 -67
  77. data/test/spec_chunked.rb +36 -34
  78. data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
  79. data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
  80. data/test/spec_config.rb +3 -2
  81. data/test/spec_content_length.rb +18 -17
  82. data/test/spec_content_type.rb +13 -12
  83. data/test/spec_deflater.rb +66 -40
  84. data/test/spec_directory.rb +72 -27
  85. data/test/spec_etag.rb +32 -31
  86. data/test/spec_events.rb +133 -0
  87. data/test/spec_fastcgi.rb +50 -72
  88. data/test/spec_file.rb +96 -77
  89. data/test/spec_handler.rb +19 -34
  90. data/test/spec_head.rb +15 -14
  91. data/test/spec_lint.rb +162 -197
  92. data/test/spec_lobster.rb +24 -23
  93. data/test/spec_lock.rb +69 -39
  94. data/test/spec_logger.rb +4 -3
  95. data/test/spec_media_type.rb +42 -0
  96. data/test/spec_method_override.rb +83 -0
  97. data/test/spec_mime.rb +19 -19
  98. data/test/spec_mock.rb +196 -151
  99. data/test/spec_multipart.rb +310 -202
  100. data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
  101. data/test/spec_recursive.rb +17 -14
  102. data/test/spec_request.rb +763 -607
  103. data/test/spec_response.rb +209 -156
  104. data/test/spec_rewindable_input.rb +50 -40
  105. data/test/spec_runtime.rb +11 -10
  106. data/test/spec_sendfile.rb +30 -35
  107. data/test/spec_server.rb +78 -52
  108. data/test/spec_session_abstract_id.rb +11 -33
  109. data/test/spec_session_cookie.rb +97 -65
  110. data/test/spec_session_memcache.rb +63 -101
  111. data/test/spec_session_pool.rb +48 -84
  112. data/test/spec_show_exceptions.rb +80 -0
  113. data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
  114. data/test/spec_static.rb +71 -32
  115. data/test/spec_tempfile_reaper.rb +11 -10
  116. data/test/spec_thin.rb +55 -50
  117. data/test/spec_urlmap.rb +79 -78
  118. data/test/spec_utils.rb +417 -345
  119. data/test/spec_version.rb +2 -8
  120. data/test/spec_webrick.rb +77 -67
  121. data/test/static/foo.html +1 -0
  122. data/test/testrequest.rb +1 -1
  123. data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
  124. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
  125. metadata +116 -71
  126. data/KNOWN-ISSUES +0 -44
  127. data/lib/rack/backports/uri/common_18.rb +0 -56
  128. data/lib/rack/backports/uri/common_192.rb +0 -52
  129. data/lib/rack/backports/uri/common_193.rb +0 -29
  130. data/lib/rack/handler/evented_mongrel.rb +0 -8
  131. data/lib/rack/handler/mongrel.rb +0 -106
  132. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  133. data/lib/rack/showexceptions.rb +0 -387
  134. data/lib/rack/utils/okjson.rb +0 -600
  135. data/test/spec_methodoverride.rb +0 -111
  136. data/test/spec_mongrel.rb +0 -182
  137. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  138. data/test/spec_showexceptions.rb +0 -98
@@ -1,22 +1,40 @@
1
+ require 'minitest/autorun'
2
+ require 'rack'
1
3
  require 'rack/response'
2
4
  require 'stringio'
3
5
 
4
6
  describe Rack::Response do
5
- should "have sensible default values" 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
6
24
  response = Rack::Response.new
7
25
  status, header, body = response.finish
8
- status.should.equal 200
9
- header.should.equal({})
26
+ status.must_equal 200
27
+ header.must_equal({})
10
28
  body.each { |part|
11
- part.should.equal ""
29
+ part.must_equal ""
12
30
  }
13
31
 
14
32
  response = Rack::Response.new
15
33
  status, header, body = *response
16
- status.should.equal 200
17
- header.should.equal({})
34
+ status.must_equal 200
35
+ header.must_equal({})
18
36
  body.each { |part|
19
- part.should.equal ""
37
+ part.must_equal ""
20
38
  }
21
39
  end
22
40
 
@@ -32,132 +50,82 @@ describe Rack::Response do
32
50
  parts = []
33
51
  body.each { |part| parts << part }
34
52
 
35
- parts.should.equal ["foo", "bar", "baz"]
53
+ parts.must_equal ["foo", "bar", "baz"]
36
54
  end
37
55
 
38
56
  it "can set and read headers" do
39
57
  response = Rack::Response.new
40
- response["Content-Type"].should.equal nil
58
+ response["Content-Type"].must_equal nil
41
59
  response["Content-Type"] = "text/plain"
42
- response["Content-Type"].should.equal "text/plain"
60
+ response["Content-Type"].must_equal "text/plain"
43
61
  end
44
62
 
45
63
  it "can override the initial Content-Type with a different case" do
46
64
  response = Rack::Response.new("", 200, "content-type" => "text/plain")
47
- response["Content-Type"].should.equal "text/plain"
65
+ response["Content-Type"].must_equal "text/plain"
48
66
  end
49
67
 
50
68
  it "can set cookies" do
51
69
  response = Rack::Response.new
52
70
 
53
71
  response.set_cookie "foo", "bar"
54
- response["Set-Cookie"].should.equal "foo=bar"
72
+ response["Set-Cookie"].must_equal "foo=bar"
55
73
  response.set_cookie "foo2", "bar2"
56
- response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2"].join("\n")
74
+ response["Set-Cookie"].must_equal ["foo=bar", "foo2=bar2"].join("\n")
57
75
  response.set_cookie "foo3", "bar3"
58
- response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
76
+ response["Set-Cookie"].must_equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
59
77
  end
60
78
 
61
79
  it "can set cookies with the same name for multiple domains" do
62
80
  response = Rack::Response.new
63
81
  response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
64
82
  response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
65
- response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
83
+ response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
66
84
  end
67
85
 
68
86
  it "formats the Cookie expiration date accordingly to RFC 6265" do
69
87
  response = Rack::Response.new
70
88
 
71
89
  response.set_cookie "foo", {:value => "bar", :expires => Time.now+10}
72
- response["Set-Cookie"].should.match(
90
+ response["Set-Cookie"].must_match(
73
91
  /expires=..., \d\d ... \d\d\d\d \d\d:\d\d:\d\d .../)
74
92
  end
75
93
 
76
94
  it "can set secure cookies" do
77
95
  response = Rack::Response.new
78
96
  response.set_cookie "foo", {:value => "bar", :secure => true}
79
- response["Set-Cookie"].should.equal "foo=bar; secure"
97
+ response["Set-Cookie"].must_equal "foo=bar; secure"
80
98
  end
81
99
 
82
100
  it "can set http only cookies" do
83
101
  response = Rack::Response.new
84
102
  response.set_cookie "foo", {:value => "bar", :httponly => true}
85
- response["Set-Cookie"].should.equal "foo=bar; HttpOnly"
103
+ response["Set-Cookie"].must_equal "foo=bar; HttpOnly"
86
104
  end
87
105
 
88
106
  it "can set http only cookies with :http_only" do
89
107
  response = Rack::Response.new
90
108
  response.set_cookie "foo", {:value => "bar", :http_only => true}
91
- response["Set-Cookie"].should.equal "foo=bar; HttpOnly"
109
+ response["Set-Cookie"].must_equal "foo=bar; HttpOnly"
92
110
  end
93
111
 
94
112
  it "can set prefers :httponly for http only cookie setting when :httponly and :http_only provided" do
95
113
  response = Rack::Response.new
96
114
  response.set_cookie "foo", {:value => "bar", :httponly => false, :http_only => true}
97
- response["Set-Cookie"].should.equal "foo=bar"
98
- end
99
-
100
- it "can set SameSite cookies with symbol value :lax" do
101
- response = Rack::Response.new
102
- response.set_cookie "foo", {:value => "bar", :same_site => :lax}
103
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Lax"
115
+ response["Set-Cookie"].must_equal "foo=bar"
104
116
  end
105
117
 
106
- it "can set SameSite cookies with symbol value :Lax" do
118
+ it "can set First-Party cookies" do
107
119
  response = Rack::Response.new
108
- response.set_cookie "foo", {:value => "bar", :same_site => :lax}
109
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Lax"
110
- end
111
-
112
- it "can set SameSite cookies with string value 'Lax'" do
113
- response = Rack::Response.new
114
- response.set_cookie "foo", {:value => "bar", :same_site => "Lax"}
115
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Lax"
116
- end
117
-
118
- it "can set SameSite cookies with boolean value true" do
119
- response = Rack::Response.new
120
- response.set_cookie "foo", {:value => "bar", :same_site => true}
121
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Strict"
122
- end
123
-
124
- it "can set SameSite cookies with symbol value :strict" do
125
- response = Rack::Response.new
126
- response.set_cookie "foo", {:value => "bar", :same_site => :strict}
127
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Strict"
128
- end
129
-
130
- it "can set SameSite cookies with symbol value :Strict" do
131
- response = Rack::Response.new
132
- response.set_cookie "foo", {:value => "bar", :same_site => :Strict}
133
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Strict"
134
- end
135
-
136
- it "can set SameSite cookies with string value 'Strict'" do
137
- response = Rack::Response.new
138
- response.set_cookie "foo", {:value => "bar", :same_site => "Strict"}
139
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Strict"
140
- end
141
-
142
- it "validates the SameSite option value" do
143
- response = Rack::Response.new
144
- lambda {
145
- response.set_cookie "foo", {:value => "bar", :same_site => "Foo"}
146
- }.should.raise(ArgumentError).
147
- message.should.match(/Invalid SameSite value: "Foo"/)
148
- end
149
-
150
- it "can set SameSite cookies with symbol value" do
151
- response = Rack::Response.new
152
- response.set_cookie "foo", {:value => "bar", :same_site => :Strict}
153
- response["Set-Cookie"].should.equal "foo=bar; SameSite=Strict"
120
+ response.set_cookie "foo", {:value => "bar", :first_party => true}
121
+ response["Set-Cookie"].must_equal "foo=bar; First-Party"
154
122
  end
155
123
 
156
124
  [ nil, false ].each do |non_truthy|
157
- it "omits SameSite attribute given a #{non_truthy.inspect} value" do
125
+ it "omits First-Party attribute given a #{non_truthy.inspect} value" do
158
126
  response = Rack::Response.new
159
- response.set_cookie "foo", {:value => "bar", :same_site => non_truthy}
160
- response["Set-Cookie"].should.equal "foo=bar"
127
+ response.set_cookie "foo", {:value => "bar", :first_party => non_truthy}
128
+ response["Set-Cookie"].must_equal "foo=bar"
161
129
  end
162
130
  end
163
131
 
@@ -166,7 +134,7 @@ describe Rack::Response do
166
134
  response.set_cookie "foo", "bar"
167
135
  response.set_cookie "foo2", "bar2"
168
136
  response.delete_cookie "foo"
169
- response["Set-Cookie"].should.equal [
137
+ response["Set-Cookie"].must_equal [
170
138
  "foo2=bar2",
171
139
  "foo=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
172
140
  ].join("\n")
@@ -176,11 +144,11 @@ describe Rack::Response do
176
144
  response = Rack::Response.new
177
145
  response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
178
146
  response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
179
- response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
147
+ response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
180
148
  response.delete_cookie "foo", :domain => ".example.com"
181
- response["Set-Cookie"].should.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")
149
+ 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")
182
150
  response.delete_cookie "foo", :domain => "sample.example.com"
183
- response["Set-Cookie"].should.equal ["foo=; domain=.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000",
151
+ response["Set-Cookie"].must_equal ["foo=; domain=.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000",
184
152
  "foo=; domain=sample.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
185
153
  end
186
154
 
@@ -188,11 +156,11 @@ describe Rack::Response do
188
156
  response = Rack::Response.new
189
157
  response.set_cookie "foo", {:value => "bar", :path => "/"}
190
158
  response.set_cookie "foo", {:value => "bar", :path => "/path"}
191
- response["Set-Cookie"].should.equal ["foo=bar; path=/",
159
+ response["Set-Cookie"].must_equal ["foo=bar; path=/",
192
160
  "foo=bar; path=/path"].join("\n")
193
161
 
194
162
  response.delete_cookie "foo", :path => "/path"
195
- response["Set-Cookie"].should.equal ["foo=bar; path=/",
163
+ response["Set-Cookie"].must_equal ["foo=bar; path=/",
196
164
  "foo=; path=/path; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
197
165
  end
198
166
 
@@ -200,26 +168,26 @@ describe Rack::Response do
200
168
  response = Rack::Response.new
201
169
  response.redirect "/foo"
202
170
  status, header, body = response.finish
203
- status.should.equal 302
204
- header["Location"].should.equal "/foo"
171
+ status.must_equal 302
172
+ header["Location"].must_equal "/foo"
205
173
 
206
174
  response = Rack::Response.new
207
175
  response.redirect "/foo", 307
208
176
  status, header, body = response.finish
209
177
 
210
- status.should.equal 307
178
+ status.must_equal 307
211
179
  end
212
180
 
213
181
  it "has a useful constructor" do
214
182
  r = Rack::Response.new("foo")
215
183
  status, header, body = r.finish
216
184
  str = ""; body.each { |part| str << part }
217
- str.should.equal "foo"
185
+ str.must_equal "foo"
218
186
 
219
187
  r = Rack::Response.new(["foo", "bar"])
220
188
  status, header, body = r.finish
221
189
  str = ""; body.each { |part| str << part }
222
- str.should.equal "foobar"
190
+ str.must_equal "foobar"
223
191
 
224
192
  object_with_each = Object.new
225
193
  def object_with_each.each
@@ -230,13 +198,13 @@ describe Rack::Response do
230
198
  r.write "foo"
231
199
  status, header, body = r.finish
232
200
  str = ""; body.each { |part| str << part }
233
- str.should.equal "foobarfoo"
201
+ str.must_equal "foobarfoo"
234
202
 
235
203
  r = Rack::Response.new([], 500)
236
- r.status.should.equal 500
204
+ r.status.must_equal 500
237
205
 
238
206
  r = Rack::Response.new([], "200 OK")
239
- r.status.should.equal 200
207
+ r.status.must_equal 200
240
208
  end
241
209
 
242
210
  it "has a constructor that can take a block" do
@@ -246,162 +214,247 @@ describe Rack::Response do
246
214
  }
247
215
  status, _, body = r.finish
248
216
  str = ""; body.each { |part| str << part }
249
- str.should.equal "foo"
250
- status.should.equal 404
217
+ str.must_equal "foo"
218
+ status.must_equal 404
251
219
  end
252
220
 
253
221
  it "doesn't return invalid responses" do
254
222
  r = Rack::Response.new(["foo", "bar"], 204)
255
223
  _, header, body = r.finish
256
224
  str = ""; body.each { |part| str << part }
257
- str.should.be.empty
258
- header["Content-Type"].should.equal nil
259
- header['Content-Length'].should.equal nil
225
+ str.must_be :empty?
226
+ header["Content-Type"].must_equal nil
227
+ header['Content-Length'].must_equal nil
260
228
 
261
229
  lambda {
262
230
  Rack::Response.new(Object.new)
263
- }.should.raise(TypeError).
264
- message.should =~ /stringable or iterable required/
231
+ }.must_raise(TypeError).
232
+ message.must_match(/stringable or iterable required/)
265
233
  end
266
234
 
267
235
  it "knows if it's empty" do
268
236
  r = Rack::Response.new
269
- r.should.be.empty
237
+ r.must_be :empty?
270
238
  r.write "foo"
271
- r.should.not.be.empty
239
+ r.wont_be :empty?
272
240
 
273
241
  r = Rack::Response.new
274
- r.should.be.empty
242
+ r.must_be :empty?
275
243
  r.finish
276
- r.should.be.empty
244
+ r.must_be :empty?
277
245
 
278
246
  r = Rack::Response.new
279
- r.should.be.empty
247
+ r.must_be :empty?
280
248
  r.finish { }
281
- r.should.not.be.empty
249
+ r.wont_be :empty?
282
250
  end
283
251
 
284
- should "provide access to the HTTP status" do
252
+ it "provide access to the HTTP status" do
285
253
  res = Rack::Response.new
286
254
  res.status = 200
287
- res.should.be.successful
288
- res.should.be.ok
255
+ res.must_be :successful?
256
+ res.must_be :ok?
289
257
 
290
258
  res.status = 201
291
- res.should.be.successful
292
- res.should.be.created
259
+ res.must_be :successful?
260
+ res.must_be :created?
293
261
 
294
262
  res.status = 202
295
- res.should.be.successful
296
- res.should.be.accepted
263
+ res.must_be :successful?
264
+ res.must_be :accepted?
265
+
266
+ res.status = 204
267
+ res.must_be :successful?
268
+ res.must_be :no_content?
269
+
270
+ res.status = 301
271
+ res.must_be :redirect?
272
+ res.must_be :moved_permanently?
273
+
274
+ res.status = 302
275
+ res.must_be :redirect?
276
+
277
+ res.status = 303
278
+ res.must_be :redirect?
279
+
280
+ res.status = 307
281
+ res.must_be :redirect?
282
+
283
+ res.status = 308
284
+ res.must_be :redirect?
297
285
 
298
286
  res.status = 400
299
- res.should.not.be.successful
300
- res.should.be.client_error
301
- res.should.be.bad_request
287
+ res.wont_be :successful?
288
+ res.must_be :client_error?
289
+ res.must_be :bad_request?
302
290
 
303
291
  res.status = 401
304
- res.should.not.be.successful
305
- res.should.be.client_error
306
- res.should.be.unauthorized
292
+ res.wont_be :successful?
293
+ res.must_be :client_error?
294
+ res.must_be :unauthorized?
307
295
 
308
296
  res.status = 404
309
- res.should.not.be.successful
310
- res.should.be.client_error
311
- res.should.be.not_found
297
+ res.wont_be :successful?
298
+ res.must_be :client_error?
299
+ res.must_be :not_found?
312
300
 
313
301
  res.status = 405
314
- res.should.not.be.successful
315
- res.should.be.client_error
316
- res.should.be.method_not_allowed
302
+ res.wont_be :successful?
303
+ res.must_be :client_error?
304
+ res.must_be :method_not_allowed?
317
305
 
318
- res.status = 418
319
- res.should.not.be.successful
320
- res.should.be.client_error
321
- res.should.be.i_m_a_teapot
306
+ res.status = 412
307
+ res.wont_be :successful?
308
+ res.must_be :client_error?
309
+ res.must_be :precondition_failed?
322
310
 
323
311
  res.status = 422
324
- res.should.not.be.successful
325
- res.should.be.client_error
326
- res.should.be.unprocessable
312
+ res.wont_be :successful?
313
+ res.must_be :client_error?
314
+ res.must_be :unprocessable?
327
315
 
328
316
  res.status = 501
329
- res.should.not.be.successful
330
- res.should.be.server_error
331
-
332
- res.status = 307
333
- res.should.be.redirect
317
+ res.wont_be :successful?
318
+ res.must_be :server_error?
334
319
  end
335
320
 
336
- should "provide access to the HTTP headers" do
321
+ it "provide access to the HTTP headers" do
337
322
  res = Rack::Response.new
338
323
  res["Content-Type"] = "text/yaml"
339
324
 
340
- res.should.include "Content-Type"
341
- res.headers["Content-Type"].should.equal "text/yaml"
342
- res["Content-Type"].should.equal "text/yaml"
343
- res.content_type.should.equal "text/yaml"
344
- res.content_length.should.be.nil
345
- res.location.should.be.nil
325
+ res.must_include "Content-Type"
326
+ res.headers["Content-Type"].must_equal "text/yaml"
327
+ res["Content-Type"].must_equal "text/yaml"
328
+ res.content_type.must_equal "text/yaml"
329
+ res.content_length.must_be_nil
330
+ res.location.must_be_nil
346
331
  end
347
332
 
348
333
  it "does not add or change Content-Length when #finish()ing" do
349
334
  res = Rack::Response.new
350
335
  res.status = 200
351
336
  res.finish
352
- res.headers["Content-Length"].should.be.nil
337
+ res.headers["Content-Length"].must_be_nil
353
338
 
354
339
  res = Rack::Response.new
355
340
  res.status = 200
356
341
  res.headers["Content-Length"] = "10"
357
342
  res.finish
358
- res.headers["Content-Length"].should.equal "10"
343
+ res.headers["Content-Length"].must_equal "10"
359
344
  end
360
345
 
361
346
  it "updates Content-Length when body appended to using #write" do
362
347
  res = Rack::Response.new
363
348
  res.status = 200
364
- res.headers["Content-Length"].should.be.nil
349
+ res.headers["Content-Length"].must_be_nil
365
350
  res.write "Hi"
366
- res.headers["Content-Length"].should.equal "2"
351
+ res.headers["Content-Length"].must_equal "2"
367
352
  res.write " there"
368
- res.headers["Content-Length"].should.equal "8"
353
+ res.headers["Content-Length"].must_equal "8"
369
354
  end
370
355
 
371
356
  it "calls close on #body" do
372
357
  res = Rack::Response.new
373
358
  res.body = StringIO.new
374
359
  res.close
375
- res.body.should.be.closed
360
+ res.body.must_be :closed?
376
361
  end
377
362
 
378
363
  it "calls close on #body when 204, 205, or 304" do
379
364
  res = Rack::Response.new
380
365
  res.body = StringIO.new
381
366
  res.finish
382
- res.body.should.not.be.closed
367
+ res.body.wont_be :closed?
383
368
 
384
369
  res.status = 204
385
370
  _, _, b = res.finish
386
- res.body.should.be.closed
387
- b.should.not.equal res.body
371
+ res.body.must_be :closed?
372
+ b.wont_equal res.body
388
373
 
389
374
  res.body = StringIO.new
390
375
  res.status = 205
391
376
  _, _, b = res.finish
392
- res.body.should.be.closed
393
- b.should.not.equal res.body
377
+ res.body.must_be :closed?
378
+ b.wont_equal res.body
394
379
 
395
380
  res.body = StringIO.new
396
381
  res.status = 304
397
382
  _, _, b = res.finish
398
- res.body.should.be.closed
399
- b.should.not.equal res.body
383
+ res.body.must_be :closed?
384
+ b.wont_equal res.body
400
385
  end
401
386
 
402
387
  it "wraps the body from #to_ary to prevent infinite loops" do
403
388
  res = Rack::Response.new
404
- res.finish.last.should.not.respond_to?(:to_ary)
405
- lambda { res.finish.last.to_ary }.should.raise(NoMethodError)
389
+ res.finish.last.wont_respond_to(:to_ary)
390
+ lambda { res.finish.last.to_ary }.must_raise NoMethodError
391
+ end
392
+ end
393
+
394
+ describe Rack::Response, 'headers' do
395
+ before do
396
+ @response = Rack::Response.new([], 200, { 'Foo' => '1' })
397
+ end
398
+
399
+ it 'has_header?' do
400
+ lambda { @response.has_header? nil }.must_raise NoMethodError
401
+
402
+ @response.has_header?('Foo').must_equal true
403
+ @response.has_header?('foo').must_equal true
404
+ end
405
+
406
+ it 'get_header' do
407
+ lambda { @response.get_header nil }.must_raise NoMethodError
408
+
409
+ @response.get_header('Foo').must_equal '1'
410
+ @response.get_header('foo').must_equal '1'
411
+ end
412
+
413
+ it 'set_header' do
414
+ lambda { @response.set_header nil, '1' }.must_raise NoMethodError
415
+
416
+ @response.set_header('Foo', '2').must_equal '2'
417
+ @response.has_header?('Foo').must_equal true
418
+ @response.get_header('Foo').must_equal('2')
419
+
420
+ @response.set_header('Foo', nil).must_be_nil
421
+ @response.has_header?('Foo').must_equal true
422
+ @response.get_header('Foo').must_be_nil
423
+ end
424
+
425
+ it 'add_header' do
426
+ lambda { @response.add_header nil, '1' }.must_raise NoMethodError
427
+
428
+ # Add a value to an existing header
429
+ @response.add_header('Foo', '2').must_equal '1,2'
430
+ @response.get_header('Foo').must_equal '1,2'
431
+
432
+ # Add nil to an existing header
433
+ @response.add_header('Foo', nil).must_equal '1,2'
434
+ @response.get_header('Foo').must_equal '1,2'
435
+
436
+ # Add nil to a nonexistent header
437
+ @response.add_header('Bar', nil).must_be_nil
438
+ @response.has_header?('Bar').must_equal false
439
+ @response.get_header('Bar').must_be_nil
440
+
441
+ # Add a value to a nonexistent header
442
+ @response.add_header('Bar', '1').must_equal '1'
443
+ @response.has_header?('Bar').must_equal true
444
+ @response.get_header('Bar').must_equal '1'
445
+ end
446
+
447
+ it 'delete_header' do
448
+ lambda { @response.delete_header nil }.must_raise NoMethodError
449
+
450
+ @response.delete_header('Foo').must_equal '1'
451
+ (!!@response.has_header?('Foo')).must_equal false
452
+
453
+ @response.delete_header('Foo').must_be_nil
454
+ @response.has_header?('Foo').must_equal false
455
+
456
+ @response.set_header('Foo', 1)
457
+ @response.delete_header('foo').must_equal 1
458
+ @response.has_header?('Foo').must_equal false
406
459
  end
407
460
  end