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.
- checksums.yaml +5 -5
- data/HISTORY.md +139 -18
- data/README.rdoc +17 -25
- data/Rakefile +6 -14
- data/SPEC +8 -9
- data/contrib/rack_logo.svg +164 -111
- data/lib/rack.rb +70 -21
- data/lib/rack/auth/digest/request.rb +1 -1
- data/lib/rack/body_proxy.rb +14 -9
- data/lib/rack/builder.rb +3 -3
- data/lib/rack/chunked.rb +5 -5
- data/lib/rack/{commonlogger.rb → common_logger.rb} +2 -2
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
- data/lib/rack/content_length.rb +2 -2
- data/lib/rack/deflater.rb +4 -4
- data/lib/rack/directory.rb +49 -55
- data/lib/rack/etag.rb +2 -1
- data/lib/rack/events.rb +154 -0
- data/lib/rack/file.rb +55 -40
- data/lib/rack/handler.rb +2 -24
- data/lib/rack/handler/cgi.rb +15 -16
- data/lib/rack/handler/fastcgi.rb +13 -14
- data/lib/rack/handler/lsws.rb +11 -11
- data/lib/rack/handler/scgi.rb +15 -15
- data/lib/rack/handler/thin.rb +3 -0
- data/lib/rack/handler/webrick.rb +22 -24
- data/lib/rack/head.rb +15 -17
- data/lib/rack/lint.rb +38 -38
- data/lib/rack/lobster.rb +1 -1
- data/lib/rack/lock.rb +6 -10
- data/lib/rack/logger.rb +2 -2
- data/lib/rack/media_type.rb +38 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +4 -11
- data/lib/rack/mime.rb +18 -5
- data/lib/rack/mock.rb +35 -52
- data/lib/rack/multipart.rb +35 -6
- data/lib/rack/multipart/generator.rb +4 -4
- data/lib/rack/multipart/parser.rb +273 -158
- data/lib/rack/multipart/uploaded_file.rb +1 -2
- data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
- data/lib/rack/query_parser.rb +174 -0
- data/lib/rack/recursive.rb +8 -8
- data/lib/rack/reloader.rb +1 -2
- data/lib/rack/request.rb +370 -304
- data/lib/rack/response.rb +129 -56
- data/lib/rack/rewindable_input.rb +1 -12
- data/lib/rack/runtime.rb +10 -18
- data/lib/rack/sendfile.rb +5 -7
- data/lib/rack/server.rb +31 -25
- data/lib/rack/session/abstract/id.rb +93 -135
- data/lib/rack/session/cookie.rb +26 -28
- data/lib/rack/session/memcache.rb +8 -14
- data/lib/rack/session/pool.rb +14 -21
- data/lib/rack/show_exceptions.rb +386 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
- data/lib/rack/static.rb +30 -5
- data/lib/rack/tempfile_reaper.rb +2 -2
- data/lib/rack/urlmap.rb +13 -14
- data/lib/rack/utils.rb +128 -221
- data/rack.gemspec +9 -5
- data/test/builder/an_underscore_app.rb +5 -0
- data/test/builder/options.ru +1 -1
- data/test/cgi/test.fcgi +1 -0
- data/test/cgi/test.gz +0 -0
- data/test/helper.rb +31 -0
- data/test/multipart/filename_with_encoded_words +7 -0
- data/test/multipart/{filename_with_null_byte → filename_with_single_quote} +1 -1
- data/test/multipart/quoted +15 -0
- data/test/multipart/rack-logo.png +0 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
- data/test/spec_auth_basic.rb +20 -19
- data/test/spec_auth_digest.rb +47 -46
- data/test/spec_body_proxy.rb +27 -27
- data/test/spec_builder.rb +51 -41
- data/test/spec_cascade.rb +24 -22
- data/test/spec_cgi.rb +49 -67
- data/test/spec_chunked.rb +36 -34
- data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
- data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
- data/test/spec_config.rb +3 -2
- data/test/spec_content_length.rb +18 -17
- data/test/spec_content_type.rb +13 -12
- data/test/spec_deflater.rb +66 -40
- data/test/spec_directory.rb +72 -27
- data/test/spec_etag.rb +32 -31
- data/test/spec_events.rb +133 -0
- data/test/spec_fastcgi.rb +50 -72
- data/test/spec_file.rb +96 -77
- data/test/spec_handler.rb +19 -34
- data/test/spec_head.rb +15 -14
- data/test/spec_lint.rb +162 -197
- data/test/spec_lobster.rb +24 -23
- data/test/spec_lock.rb +69 -39
- data/test/spec_logger.rb +4 -3
- data/test/spec_media_type.rb +42 -0
- data/test/spec_method_override.rb +83 -0
- data/test/spec_mime.rb +19 -19
- data/test/spec_mock.rb +196 -151
- data/test/spec_multipart.rb +310 -202
- data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
- data/test/spec_recursive.rb +17 -14
- data/test/spec_request.rb +763 -607
- data/test/spec_response.rb +209 -156
- data/test/spec_rewindable_input.rb +50 -40
- data/test/spec_runtime.rb +11 -10
- data/test/spec_sendfile.rb +30 -35
- data/test/spec_server.rb +78 -52
- data/test/spec_session_abstract_id.rb +11 -33
- data/test/spec_session_cookie.rb +97 -65
- data/test/spec_session_memcache.rb +63 -101
- data/test/spec_session_pool.rb +48 -84
- data/test/spec_show_exceptions.rb +80 -0
- data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
- data/test/spec_static.rb +71 -32
- data/test/spec_tempfile_reaper.rb +11 -10
- data/test/spec_thin.rb +55 -50
- data/test/spec_urlmap.rb +79 -78
- data/test/spec_utils.rb +417 -345
- data/test/spec_version.rb +2 -8
- data/test/spec_webrick.rb +77 -67
- data/test/static/foo.html +1 -0
- data/test/testrequest.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
- metadata +116 -71
- data/KNOWN-ISSUES +0 -44
- data/lib/rack/backports/uri/common_18.rb +0 -56
- data/lib/rack/backports/uri/common_192.rb +0 -52
- data/lib/rack/backports/uri/common_193.rb +0 -29
- data/lib/rack/handler/evented_mongrel.rb +0 -8
- data/lib/rack/handler/mongrel.rb +0 -106
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/showexceptions.rb +0 -387
- data/lib/rack/utils/okjson.rb +0 -600
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_showexceptions.rb +0 -98
data/test/spec_methodoverride.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
require 'rack/methodoverride'
|
3
|
-
require 'rack/mock'
|
4
|
-
|
5
|
-
describe Rack::MethodOverride do
|
6
|
-
def app
|
7
|
-
Rack::Lint.new(Rack::MethodOverride.new(lambda {|e|
|
8
|
-
[200, {"Content-Type" => "text/plain"}, []]
|
9
|
-
}))
|
10
|
-
end
|
11
|
-
|
12
|
-
should "not affect GET requests" do
|
13
|
-
env = Rack::MockRequest.env_for("/?_method=delete", :method => "GET")
|
14
|
-
app.call env
|
15
|
-
|
16
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
17
|
-
end
|
18
|
-
|
19
|
-
should "modify REQUEST_METHOD for POST requests when _method parameter is set" do
|
20
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=put")
|
21
|
-
app.call env
|
22
|
-
|
23
|
-
env["REQUEST_METHOD"].should.equal "PUT"
|
24
|
-
end
|
25
|
-
|
26
|
-
if RUBY_VERSION >= "1.9"
|
27
|
-
should "set rack.errors for invalid UTF8 _method values" do
|
28
|
-
errors = StringIO.new
|
29
|
-
env = Rack::MockRequest.env_for("/",
|
30
|
-
:method => "POST",
|
31
|
-
:input => "_method=\xBF".force_encoding("ASCII-8BIT"),
|
32
|
-
"rack.errors" => errors)
|
33
|
-
|
34
|
-
app.call env
|
35
|
-
|
36
|
-
errors.rewind
|
37
|
-
errors.read.should.equal "Invalid string for method\n"
|
38
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
should "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
|
43
|
-
env = Rack::MockRequest.env_for("/",
|
44
|
-
:method => "POST",
|
45
|
-
"HTTP_X_HTTP_METHOD_OVERRIDE" => "PATCH"
|
46
|
-
)
|
47
|
-
app.call env
|
48
|
-
|
49
|
-
env["REQUEST_METHOD"].should.equal "PATCH"
|
50
|
-
end
|
51
|
-
|
52
|
-
should "not modify REQUEST_METHOD if the method is unknown" do
|
53
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo")
|
54
|
-
app.call env
|
55
|
-
|
56
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
57
|
-
end
|
58
|
-
|
59
|
-
should "not modify REQUEST_METHOD when _method is nil" do
|
60
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar")
|
61
|
-
app.call env
|
62
|
-
|
63
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
64
|
-
end
|
65
|
-
|
66
|
-
should "store the original REQUEST_METHOD prior to overriding" do
|
67
|
-
env = Rack::MockRequest.env_for("/",
|
68
|
-
:method => "POST",
|
69
|
-
:input => "_method=options")
|
70
|
-
app.call env
|
71
|
-
|
72
|
-
env["rack.methodoverride.original_method"].should.equal "POST"
|
73
|
-
end
|
74
|
-
|
75
|
-
should "not modify REQUEST_METHOD when given invalid multipart form data" do
|
76
|
-
input = <<EOF
|
77
|
-
--AaB03x\r
|
78
|
-
content-disposition: form-data; name="huge"; filename="huge"\r
|
79
|
-
EOF
|
80
|
-
env = Rack::MockRequest.env_for("/",
|
81
|
-
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
82
|
-
"CONTENT_LENGTH" => input.size.to_s,
|
83
|
-
:method => "POST", :input => input)
|
84
|
-
app.call env
|
85
|
-
|
86
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
87
|
-
end
|
88
|
-
|
89
|
-
should "write error to RACK_ERRORS when given invalid multipart form data" do
|
90
|
-
input = <<EOF
|
91
|
-
--AaB03x\r
|
92
|
-
content-disposition: form-data; name="huge"; filename="huge"\r
|
93
|
-
EOF
|
94
|
-
env = Rack::MockRequest.env_for("/",
|
95
|
-
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
96
|
-
"CONTENT_LENGTH" => input.size.to_s,
|
97
|
-
"rack.errors" => StringIO.new,
|
98
|
-
:method => "POST", :input => input)
|
99
|
-
Rack::MethodOverride.new(proc { [200, {"Content-Type" => "text/plain"}, []] }).call env
|
100
|
-
|
101
|
-
env["rack.errors"].rewind
|
102
|
-
env["rack.errors"].read.should =~ /Bad request content body/
|
103
|
-
end
|
104
|
-
|
105
|
-
should "not modify REQUEST_METHOD for POST requests when the params are unparseable" do
|
106
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "(%bad-params%)")
|
107
|
-
app.call env
|
108
|
-
|
109
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
110
|
-
end
|
111
|
-
end
|
data/test/spec_mongrel.rb
DELETED
@@ -1,182 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'rack'
|
3
|
-
require 'rack/handler/mongrel'
|
4
|
-
require File.expand_path('../testrequest', __FILE__)
|
5
|
-
require 'timeout'
|
6
|
-
|
7
|
-
Thread.abort_on_exception = true
|
8
|
-
$tcp_defer_accept_opts = nil
|
9
|
-
$tcp_cork_opts = nil
|
10
|
-
|
11
|
-
describe Rack::Handler::Mongrel do
|
12
|
-
extend TestRequest::Helpers
|
13
|
-
|
14
|
-
@server = Mongrel::HttpServer.new(@host='127.0.0.1', @port=9201)
|
15
|
-
@server.register('/test',
|
16
|
-
Rack::Handler::Mongrel.new(Rack::Lint.new(TestRequest.new)))
|
17
|
-
@server.register('/stream',
|
18
|
-
Rack::Handler::Mongrel.new(Rack::Lint.new(StreamingRequest)))
|
19
|
-
@acc = @server.run
|
20
|
-
|
21
|
-
should "respond" do
|
22
|
-
lambda {
|
23
|
-
GET("/test")
|
24
|
-
}.should.not.raise
|
25
|
-
end
|
26
|
-
|
27
|
-
should "be a Mongrel" do
|
28
|
-
GET("/test")
|
29
|
-
status.should.equal 200
|
30
|
-
response["SERVER_SOFTWARE"].should =~ /Mongrel/
|
31
|
-
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
32
|
-
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
33
|
-
response["SERVER_PORT"].should.equal "9201"
|
34
|
-
response["SERVER_NAME"].should.equal "127.0.0.1"
|
35
|
-
end
|
36
|
-
|
37
|
-
should "have rack headers" do
|
38
|
-
GET("/test")
|
39
|
-
response["rack.version"].should.equal [1,3]
|
40
|
-
response["rack.multithread"].should.be.true
|
41
|
-
response["rack.multiprocess"].should.be.false
|
42
|
-
response["rack.run_once"].should.be.false
|
43
|
-
end
|
44
|
-
|
45
|
-
should "have CGI headers on GET" do
|
46
|
-
GET("/test")
|
47
|
-
response["REQUEST_METHOD"].should.equal "GET"
|
48
|
-
response["SCRIPT_NAME"].should.equal "/test"
|
49
|
-
response["REQUEST_PATH"].should.equal "/test"
|
50
|
-
response["PATH_INFO"].should.be.equal ""
|
51
|
-
response["QUERY_STRING"].should.equal ""
|
52
|
-
response["test.postdata"].should.equal ""
|
53
|
-
|
54
|
-
GET("/test/foo?quux=1")
|
55
|
-
response["REQUEST_METHOD"].should.equal "GET"
|
56
|
-
response["SCRIPT_NAME"].should.equal "/test"
|
57
|
-
response["REQUEST_PATH"].should.equal "/test/foo"
|
58
|
-
response["PATH_INFO"].should.equal "/foo"
|
59
|
-
response["QUERY_STRING"].should.equal "quux=1"
|
60
|
-
end
|
61
|
-
|
62
|
-
should "have CGI headers on POST" do
|
63
|
-
POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
64
|
-
status.should.equal 200
|
65
|
-
response["REQUEST_METHOD"].should.equal "POST"
|
66
|
-
response["SCRIPT_NAME"].should.equal "/test"
|
67
|
-
response["REQUEST_PATH"].should.equal "/test"
|
68
|
-
response["QUERY_STRING"].should.equal ""
|
69
|
-
response["HTTP_X_TEST_HEADER"].should.equal "42"
|
70
|
-
response["test.postdata"].should.equal "rack-form-data=23"
|
71
|
-
end
|
72
|
-
|
73
|
-
should "support HTTP auth" do
|
74
|
-
GET("/test", {:user => "ruth", :passwd => "secret"})
|
75
|
-
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
76
|
-
end
|
77
|
-
|
78
|
-
should "set status" do
|
79
|
-
GET("/test?secret")
|
80
|
-
status.should.equal 403
|
81
|
-
response["rack.url_scheme"].should.equal "http"
|
82
|
-
end
|
83
|
-
|
84
|
-
should "provide a .run" do
|
85
|
-
block_ran = false
|
86
|
-
Thread.new {
|
87
|
-
Rack::Handler::Mongrel.run(lambda {}, {:Host => '127.0.0.1', :Port => 9211}) { |server|
|
88
|
-
server.should.be.kind_of Mongrel::HttpServer
|
89
|
-
block_ran = true
|
90
|
-
}
|
91
|
-
}
|
92
|
-
sleep 1
|
93
|
-
block_ran.should.be.true
|
94
|
-
end
|
95
|
-
|
96
|
-
should "provide a .run that maps a hash" do
|
97
|
-
block_ran = false
|
98
|
-
Thread.new {
|
99
|
-
map = {'/'=>lambda{},'/foo'=>lambda{}}
|
100
|
-
Rack::Handler::Mongrel.run(map, :map => true, :Host => '127.0.0.1', :Port => 9221) { |server|
|
101
|
-
server.should.be.kind_of Mongrel::HttpServer
|
102
|
-
server.classifier.uris.size.should.equal 2
|
103
|
-
server.classifier.uris.should.not.include '/arf'
|
104
|
-
server.classifier.uris.should.include '/'
|
105
|
-
server.classifier.uris.should.include '/foo'
|
106
|
-
block_ran = true
|
107
|
-
}
|
108
|
-
}
|
109
|
-
sleep 1
|
110
|
-
block_ran.should.be.true
|
111
|
-
end
|
112
|
-
|
113
|
-
should "provide a .run that maps a urlmap" do
|
114
|
-
block_ran = false
|
115
|
-
Thread.new {
|
116
|
-
map = Rack::URLMap.new({'/'=>lambda{},'/bar'=>lambda{}})
|
117
|
-
Rack::Handler::Mongrel.run(map, {:map => true, :Host => '127.0.0.1', :Port => 9231}) { |server|
|
118
|
-
server.should.be.kind_of Mongrel::HttpServer
|
119
|
-
server.classifier.uris.size.should.equal 2
|
120
|
-
server.classifier.uris.should.not.include '/arf'
|
121
|
-
server.classifier.uris.should.include '/'
|
122
|
-
server.classifier.uris.should.include '/bar'
|
123
|
-
block_ran = true
|
124
|
-
}
|
125
|
-
}
|
126
|
-
sleep 1
|
127
|
-
block_ran.should.be.true
|
128
|
-
end
|
129
|
-
|
130
|
-
should "provide a .run that maps a urlmap restricting by host" do
|
131
|
-
block_ran = false
|
132
|
-
Thread.new {
|
133
|
-
map = Rack::URLMap.new({
|
134
|
-
'/' => lambda{},
|
135
|
-
'/foo' => lambda{},
|
136
|
-
'/bar' => lambda{},
|
137
|
-
'http://127.0.0.1/' => lambda{},
|
138
|
-
'http://127.0.0.1/bar' => lambda{},
|
139
|
-
'http://falsehost/arf' => lambda{},
|
140
|
-
'http://falsehost/qux' => lambda{}
|
141
|
-
})
|
142
|
-
opt = {:map => true, :Port => 9241, :Host => '127.0.0.1'}
|
143
|
-
Rack::Handler::Mongrel.run(map, opt) { |server|
|
144
|
-
server.should.be.kind_of Mongrel::HttpServer
|
145
|
-
server.classifier.uris.should.include '/'
|
146
|
-
server.classifier.handler_map['/'].size.should.equal 2
|
147
|
-
server.classifier.uris.should.include '/foo'
|
148
|
-
server.classifier.handler_map['/foo'].size.should.equal 1
|
149
|
-
server.classifier.uris.should.include '/bar'
|
150
|
-
server.classifier.handler_map['/bar'].size.should.equal 2
|
151
|
-
server.classifier.uris.should.not.include '/qux'
|
152
|
-
server.classifier.uris.should.not.include '/arf'
|
153
|
-
server.classifier.uris.size.should.equal 3
|
154
|
-
block_ran = true
|
155
|
-
}
|
156
|
-
}
|
157
|
-
sleep 1
|
158
|
-
block_ran.should.be.true
|
159
|
-
end
|
160
|
-
|
161
|
-
should "stream #each part of the response" do
|
162
|
-
body = ''
|
163
|
-
begin
|
164
|
-
Timeout.timeout(1) do
|
165
|
-
Net::HTTP.start(@host, @port) do |http|
|
166
|
-
get = Net::HTTP::Get.new('/stream')
|
167
|
-
http.request(get) do |response|
|
168
|
-
response.read_body { |part| body << part }
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
rescue Timeout::Error
|
173
|
-
end
|
174
|
-
body.should.not.be.empty
|
175
|
-
end
|
176
|
-
|
177
|
-
@acc.raise Mongrel::StopServer
|
178
|
-
end
|
179
|
-
|
180
|
-
rescue LoadError
|
181
|
-
warn "Skipping Rack::Handler::Mongrel tests (Mongrel is required). `gem install mongrel` and try again."
|
182
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'minitest/global_expectations/autorun'
|
4
|
-
require 'rack/session/abstract/id'
|
5
|
-
|
6
|
-
describe Rack::Session::Abstract::PersistedSecure::SecureSessionHash do
|
7
|
-
attr_reader :hash
|
8
|
-
|
9
|
-
def setup
|
10
|
-
super
|
11
|
-
@store = Class.new do
|
12
|
-
def load_session(req)
|
13
|
-
[Rack::Session::SessionId.new("id"), { foo: :bar, baz: :qux }]
|
14
|
-
end
|
15
|
-
def session_exists?(req)
|
16
|
-
true
|
17
|
-
end
|
18
|
-
end
|
19
|
-
@hash = Rack::Session::Abstract::PersistedSecure::SecureSessionHash.new(@store.new, nil)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "returns keys" do
|
23
|
-
assert_equal ["foo", "baz"], hash.keys
|
24
|
-
end
|
25
|
-
|
26
|
-
it "returns values" do
|
27
|
-
assert_equal [:bar, :qux], hash.values
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "#[]" do
|
31
|
-
it "returns value for a matching key" do
|
32
|
-
assert_equal :bar, hash[:foo]
|
33
|
-
end
|
34
|
-
|
35
|
-
it "returns value for a 'session_id' key" do
|
36
|
-
assert_equal "id", hash['session_id']
|
37
|
-
end
|
38
|
-
|
39
|
-
it "returns nil value for missing 'session_id' key" do
|
40
|
-
store = @store.new
|
41
|
-
def store.load_session(req)
|
42
|
-
[nil, {}]
|
43
|
-
end
|
44
|
-
@hash = Rack::Session::Abstract::PersistedSecure::SecureSessionHash.new(store, nil)
|
45
|
-
assert_nil hash['session_id']
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "#fetch" do
|
50
|
-
it "returns value for a matching key" do
|
51
|
-
assert_equal :bar, hash.fetch(:foo)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "works with a default value" do
|
55
|
-
assert_equal :default, hash.fetch(:unknown, :default)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "works with a block" do
|
59
|
-
assert_equal :default, hash.fetch(:unkown) { :default }
|
60
|
-
end
|
61
|
-
|
62
|
-
it "it raises when fetching unknown keys without defaults" do
|
63
|
-
lambda { hash.fetch(:unknown) }.must_raise KeyError
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
describe "#stringify_keys" do
|
68
|
-
it "returns hash or session hash with keys stringified" do
|
69
|
-
assert_equal({ "foo" => :bar, "baz" => :qux }, hash.send(:stringify_keys, hash).to_h)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
data/test/spec_showexceptions.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
require 'rack/showexceptions'
|
2
|
-
require 'rack/lint'
|
3
|
-
require 'rack/mock'
|
4
|
-
|
5
|
-
describe Rack::ShowExceptions do
|
6
|
-
def show_exceptions(app)
|
7
|
-
Rack::Lint.new Rack::ShowExceptions.new(app)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "catches exceptions" do
|
11
|
-
res = nil
|
12
|
-
|
13
|
-
req = Rack::MockRequest.new(
|
14
|
-
show_exceptions(
|
15
|
-
lambda{|env| raise RuntimeError }
|
16
|
-
))
|
17
|
-
|
18
|
-
lambda{
|
19
|
-
res = req.get("/", "HTTP_ACCEPT" => "text/html")
|
20
|
-
}.should.not.raise
|
21
|
-
|
22
|
-
res.should.be.a.server_error
|
23
|
-
res.status.should.equal 500
|
24
|
-
|
25
|
-
res.should =~ /RuntimeError/
|
26
|
-
res.should =~ /ShowExceptions/
|
27
|
-
end
|
28
|
-
|
29
|
-
it "responds with HTML only to requests accepting HTML" do
|
30
|
-
res = nil
|
31
|
-
|
32
|
-
req = Rack::MockRequest.new(
|
33
|
-
show_exceptions(
|
34
|
-
lambda{|env| raise RuntimeError, "It was never supposed to work" }
|
35
|
-
))
|
36
|
-
|
37
|
-
[
|
38
|
-
# Serve text/html when the client accepts text/html
|
39
|
-
["text/html", ["/", {"HTTP_ACCEPT" => "text/html"}]],
|
40
|
-
["text/html", ["/", {"HTTP_ACCEPT" => "*/*"}]],
|
41
|
-
# Serve text/plain when the client does not accept text/html
|
42
|
-
["text/plain", ["/"]],
|
43
|
-
["text/plain", ["/", {"HTTP_ACCEPT" => "application/json"}]]
|
44
|
-
].each do |exmime, rargs|
|
45
|
-
lambda{
|
46
|
-
res = req.get(*rargs)
|
47
|
-
}.should.not.raise
|
48
|
-
|
49
|
-
res.should.be.a.server_error
|
50
|
-
res.status.should.equal 500
|
51
|
-
|
52
|
-
res.content_type.should.equal exmime
|
53
|
-
|
54
|
-
res.body.should.include "RuntimeError"
|
55
|
-
res.body.should.include "It was never supposed to work"
|
56
|
-
|
57
|
-
if exmime == "text/html"
|
58
|
-
res.body.should.include '</html>'
|
59
|
-
else
|
60
|
-
res.body.should.not.include '</html>'
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
it "handles exceptions without a backtrace" do
|
66
|
-
res = nil
|
67
|
-
|
68
|
-
req = Rack::MockRequest.new(
|
69
|
-
show_exceptions(
|
70
|
-
lambda{|env| raise RuntimeError, "", [] }
|
71
|
-
)
|
72
|
-
)
|
73
|
-
|
74
|
-
lambda{
|
75
|
-
res = req.get("/", "HTTP_ACCEPT" => "text/html")
|
76
|
-
}.should.not.raise
|
77
|
-
|
78
|
-
res.should.be.a.server_error
|
79
|
-
res.status.should.equal 500
|
80
|
-
|
81
|
-
res.should =~ /RuntimeError/
|
82
|
-
res.should =~ /ShowExceptions/
|
83
|
-
res.should =~ /unknown location/
|
84
|
-
end
|
85
|
-
|
86
|
-
it "knows to prefer plaintext for non-html" do
|
87
|
-
# We don't need an app for this
|
88
|
-
exc = Rack::ShowExceptions.new(nil)
|
89
|
-
|
90
|
-
[
|
91
|
-
[{ "HTTP_ACCEPT" => "text/plain" }, true],
|
92
|
-
[{ "HTTP_ACCEPT" => "text/foo" }, true],
|
93
|
-
[{ "HTTP_ACCEPT" => "text/html" }, false]
|
94
|
-
].each do |env, expected|
|
95
|
-
expected.should.equal exc.prefers_plaintext?(env)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|