rack 1.6.12 → 2.0.7
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/COPYING +1 -1
- data/HISTORY.md +138 -8
- data/README.rdoc +18 -28
- data/Rakefile +6 -14
- data/SPEC +10 -11
- data/contrib/rack_logo.svg +164 -111
- data/example/protectedlobster.rb +1 -1
- data/example/protectedlobster.ru +1 -1
- data/lib/rack.rb +70 -21
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/auth/digest/params.rb +2 -3
- 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} +3 -3
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
- data/lib/rack/content_length.rb +2 -2
- data/lib/rack/deflater.rb +4 -39
- data/lib/rack/directory.rb +66 -54
- data/lib/rack/etag.rb +5 -4
- data/lib/rack/events.rb +154 -0
- data/lib/rack/file.rb +64 -40
- data/lib/rack/handler.rb +3 -25
- 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 +24 -26
- data/lib/rack/head.rb +15 -17
- data/lib/rack/lint.rb +40 -40
- data/lib/rack/lobster.rb +1 -1
- data/lib/rack/lock.rb +15 -10
- data/lib/rack/logger.rb +2 -2
- data/lib/rack/media_type.rb +38 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +6 -6
- data/lib/rack/mime.rb +18 -5
- data/lib/rack/mock.rb +36 -54
- data/lib/rack/multipart.rb +35 -6
- data/lib/rack/multipart/generator.rb +5 -5
- data/lib/rack/multipart/parser.rb +270 -157
- 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 +192 -0
- data/lib/rack/recursive.rb +8 -8
- data/lib/rack/request.rb +394 -305
- data/lib/rack/response.rb +130 -57
- 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 +30 -23
- data/lib/rack/session/abstract/id.rb +108 -138
- 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 +15 -14
- data/lib/rack/utils.rb +136 -211
- data/rack.gemspec +10 -9
- 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 +34 -0
- data/test/multipart/filename_with_encoded_words +7 -0
- data/test/multipart/filename_with_single_quote +7 -0
- data/test/multipart/quoted +15 -0
- data/test/multipart/rack-logo.png +0 -0
- data/test/multipart/unity3d_wwwform +11 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
- data/test/spec_auth_basic.rb +27 -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 +37 -35
- 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 +85 -49
- data/test/spec_directory.rb +87 -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 +120 -77
- data/test/spec_handler.rb +19 -34
- data/test/spec_head.rb +15 -14
- data/test/spec_lint.rb +164 -199
- data/test/spec_lobster.rb +24 -23
- data/test/spec_lock.rb +79 -39
- data/test/spec_logger.rb +4 -3
- data/test/spec_media_type.rb +42 -0
- data/test/{spec_methodoverride.rb → spec_method_override.rb} +34 -35
- data/test/spec_mime.rb +19 -19
- data/test/spec_mock.rb +206 -144
- data/test/spec_multipart.rb +322 -200
- data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
- data/test/spec_recursive.rb +17 -14
- data/test/spec_request.rb +780 -605
- data/test/spec_response.rb +215 -112
- 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_abstract_session_hash.rb +45 -0
- data/test/spec_session_cookie.rb +99 -67
- data/test/spec_session_memcache.rb +63 -101
- data/test/spec_session_pool.rb +48 -84
- data/test/{spec_showexceptions.rb → spec_show_exceptions.rb} +23 -28
- 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 +441 -346
- data/test/spec_version.rb +2 -8
- data/test/spec_webrick.rb +93 -71
- 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 +92 -70
- 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_mongrel.rb +0 -182
data/test/spec_mime.rb
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'rack/mime'
|
2
3
|
|
3
4
|
describe Rack::Mime do
|
4
5
|
|
5
6
|
it "should return the fallback mime-type for files with no extension" do
|
6
7
|
fallback = 'image/jpg'
|
7
|
-
Rack::Mime.mime_type(File.extname('no_ext'), fallback).
|
8
|
+
Rack::Mime.mime_type(File.extname('no_ext'), fallback).must_equal fallback
|
8
9
|
end
|
9
10
|
|
10
11
|
it "should always return 'application/octet-stream' for unknown file extensions" do
|
11
12
|
unknown_ext = File.extname('unknown_ext.abcdefg')
|
12
|
-
Rack::Mime.mime_type(unknown_ext).
|
13
|
+
Rack::Mime.mime_type(unknown_ext).must_equal 'application/octet-stream'
|
13
14
|
end
|
14
15
|
|
15
16
|
it "should return the mime-type for a given extension" do
|
16
17
|
# sanity check. it would be infeasible test every single mime-type.
|
17
|
-
Rack::Mime.mime_type(File.extname('image.jpg')).
|
18
|
+
Rack::Mime.mime_type(File.extname('image.jpg')).must_equal 'image/jpeg'
|
18
19
|
end
|
19
20
|
|
20
21
|
it "should support null fallbacks" do
|
21
|
-
Rack::Mime.mime_type('.nothing', nil).
|
22
|
+
Rack::Mime.mime_type('.nothing', nil).must_be_nil
|
22
23
|
end
|
23
24
|
|
24
25
|
it "should match exact mimes" do
|
25
|
-
Rack::Mime.match?('text/html', 'text/html').
|
26
|
-
Rack::Mime.match?('text/html', 'text/meme').
|
27
|
-
Rack::Mime.match?('text', 'text').
|
28
|
-
Rack::Mime.match?('text', 'binary').
|
26
|
+
Rack::Mime.match?('text/html', 'text/html').must_equal true
|
27
|
+
Rack::Mime.match?('text/html', 'text/meme').must_equal false
|
28
|
+
Rack::Mime.match?('text', 'text').must_equal true
|
29
|
+
Rack::Mime.match?('text', 'binary').must_equal false
|
29
30
|
end
|
30
31
|
|
31
32
|
it "should match class wildcard mimes" do
|
32
|
-
Rack::Mime.match?('text/html', 'text/*').
|
33
|
-
Rack::Mime.match?('text/plain', 'text/*').
|
34
|
-
Rack::Mime.match?('application/json', 'text/*').
|
35
|
-
Rack::Mime.match?('text/html', 'text').
|
33
|
+
Rack::Mime.match?('text/html', 'text/*').must_equal true
|
34
|
+
Rack::Mime.match?('text/plain', 'text/*').must_equal true
|
35
|
+
Rack::Mime.match?('application/json', 'text/*').must_equal false
|
36
|
+
Rack::Mime.match?('text/html', 'text').must_equal true
|
36
37
|
end
|
37
38
|
|
38
39
|
it "should match full wildcards" do
|
39
|
-
Rack::Mime.match?('text/html', '*').
|
40
|
-
Rack::Mime.match?('text/plain', '*').
|
41
|
-
Rack::Mime.match?('text/html', '*/*').
|
42
|
-
Rack::Mime.match?('text/plain', '*/*').
|
40
|
+
Rack::Mime.match?('text/html', '*').must_equal true
|
41
|
+
Rack::Mime.match?('text/plain', '*').must_equal true
|
42
|
+
Rack::Mime.match?('text/html', '*/*').must_equal true
|
43
|
+
Rack::Mime.match?('text/plain', '*/*').must_equal true
|
43
44
|
end
|
44
45
|
|
45
46
|
it "should match type wildcard mimes" do
|
46
|
-
Rack::Mime.match?('text/html', '*/html').
|
47
|
-
Rack::Mime.match?('text/plain', '*/plain').
|
47
|
+
Rack::Mime.match?('text/html', '*/html').must_equal true
|
48
|
+
Rack::Mime.match?('text/plain', '*/plain').must_equal true
|
48
49
|
end
|
49
50
|
|
50
51
|
end
|
51
|
-
|
data/test/spec_mock.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'yaml'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/mock'
|
@@ -19,279 +20,340 @@ app = Rack::Lint.new(lambda { |env|
|
|
19
20
|
})
|
20
21
|
|
21
22
|
describe Rack::MockRequest do
|
22
|
-
|
23
|
+
it "return a MockResponse" do
|
23
24
|
res = Rack::MockRequest.new(app).get("")
|
24
|
-
res.
|
25
|
+
res.must_be_kind_of Rack::MockResponse
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
+
it "be able to only return the environment" do
|
28
29
|
env = Rack::MockRequest.env_for("")
|
29
|
-
env.
|
30
|
-
env.
|
30
|
+
env.must_be_kind_of Hash
|
31
|
+
env.must_include "rack.version"
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
+
it "return an environment with a path" do
|
34
35
|
env = Rack::MockRequest.env_for("http://www.example.com/parse?location[]=1&location[]=2&age_group[]=2")
|
35
|
-
env["QUERY_STRING"].
|
36
|
-
env["PATH_INFO"].
|
37
|
-
env.
|
38
|
-
env.
|
36
|
+
env["QUERY_STRING"].must_equal "location[]=1&location[]=2&age_group[]=2"
|
37
|
+
env["PATH_INFO"].must_equal "/parse"
|
38
|
+
env.must_be_kind_of Hash
|
39
|
+
env.must_include "rack.version"
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
|
+
it "provide sensible defaults" do
|
42
43
|
res = Rack::MockRequest.new(app).request
|
43
44
|
|
44
45
|
env = YAML.load(res.body)
|
45
|
-
env["REQUEST_METHOD"].
|
46
|
-
env["SERVER_NAME"].
|
47
|
-
env["SERVER_PORT"].
|
48
|
-
env["QUERY_STRING"].
|
49
|
-
env["PATH_INFO"].
|
50
|
-
env["SCRIPT_NAME"].
|
51
|
-
env["rack.url_scheme"].
|
52
|
-
env["mock.postdata"].
|
46
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
47
|
+
env["SERVER_NAME"].must_equal "example.org"
|
48
|
+
env["SERVER_PORT"].must_equal "80"
|
49
|
+
env["QUERY_STRING"].must_equal ""
|
50
|
+
env["PATH_INFO"].must_equal "/"
|
51
|
+
env["SCRIPT_NAME"].must_equal ""
|
52
|
+
env["rack.url_scheme"].must_equal "http"
|
53
|
+
env["mock.postdata"].must_be :empty?
|
53
54
|
end
|
54
55
|
|
55
|
-
|
56
|
+
it "allow GET/POST/PUT/DELETE/HEAD" do
|
56
57
|
res = Rack::MockRequest.new(app).get("", :input => "foo")
|
57
58
|
env = YAML.load(res.body)
|
58
|
-
env["REQUEST_METHOD"].
|
59
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
59
60
|
|
60
61
|
res = Rack::MockRequest.new(app).post("", :input => "foo")
|
61
62
|
env = YAML.load(res.body)
|
62
|
-
env["REQUEST_METHOD"].
|
63
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
63
64
|
|
64
65
|
res = Rack::MockRequest.new(app).put("", :input => "foo")
|
65
66
|
env = YAML.load(res.body)
|
66
|
-
env["REQUEST_METHOD"].
|
67
|
+
env["REQUEST_METHOD"].must_equal "PUT"
|
67
68
|
|
68
69
|
res = Rack::MockRequest.new(app).patch("", :input => "foo")
|
69
70
|
env = YAML.load(res.body)
|
70
|
-
env["REQUEST_METHOD"].
|
71
|
+
env["REQUEST_METHOD"].must_equal "PATCH"
|
71
72
|
|
72
73
|
res = Rack::MockRequest.new(app).delete("", :input => "foo")
|
73
74
|
env = YAML.load(res.body)
|
74
|
-
env["REQUEST_METHOD"].
|
75
|
-
|
76
|
-
Rack::MockRequest.env_for("/", :method => "HEAD")["REQUEST_METHOD"].
|
77
|
-
should.equal "HEAD"
|
75
|
+
env["REQUEST_METHOD"].must_equal "DELETE"
|
78
76
|
|
79
|
-
Rack::MockRequest.env_for("/", :method => "
|
80
|
-
|
77
|
+
Rack::MockRequest.env_for("/", :method => "HEAD")["REQUEST_METHOD"]
|
78
|
+
.must_equal "HEAD"
|
79
|
+
|
80
|
+
Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"]
|
81
|
+
.must_equal "OPTIONS"
|
81
82
|
end
|
82
83
|
|
83
|
-
|
84
|
+
it "set content length" do
|
84
85
|
env = Rack::MockRequest.env_for("/", :input => "foo")
|
85
|
-
env["CONTENT_LENGTH"].
|
86
|
+
env["CONTENT_LENGTH"].must_equal "3"
|
86
87
|
end
|
87
88
|
|
88
|
-
|
89
|
+
it "allow posting" do
|
89
90
|
res = Rack::MockRequest.new(app).get("", :input => "foo")
|
90
91
|
env = YAML.load(res.body)
|
91
|
-
env["mock.postdata"].
|
92
|
+
env["mock.postdata"].must_equal "foo"
|
92
93
|
|
93
94
|
res = Rack::MockRequest.new(app).post("", :input => StringIO.new("foo"))
|
94
95
|
env = YAML.load(res.body)
|
95
|
-
env["mock.postdata"].
|
96
|
+
env["mock.postdata"].must_equal "foo"
|
96
97
|
end
|
97
98
|
|
98
|
-
|
99
|
+
it "use all parts of an URL" do
|
99
100
|
res = Rack::MockRequest.new(app).
|
100
101
|
get("https://bla.example.org:9292/meh/foo?bar")
|
101
|
-
res.
|
102
|
+
res.must_be_kind_of Rack::MockResponse
|
102
103
|
|
103
104
|
env = YAML.load(res.body)
|
104
|
-
env["REQUEST_METHOD"].
|
105
|
-
env["SERVER_NAME"].
|
106
|
-
env["SERVER_PORT"].
|
107
|
-
env["QUERY_STRING"].
|
108
|
-
env["PATH_INFO"].
|
109
|
-
env["rack.url_scheme"].
|
105
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
106
|
+
env["SERVER_NAME"].must_equal "bla.example.org"
|
107
|
+
env["SERVER_PORT"].must_equal "9292"
|
108
|
+
env["QUERY_STRING"].must_equal "bar"
|
109
|
+
env["PATH_INFO"].must_equal "/meh/foo"
|
110
|
+
env["rack.url_scheme"].must_equal "https"
|
110
111
|
end
|
111
112
|
|
112
|
-
|
113
|
+
it "set SSL port and HTTP flag on when using https" do
|
113
114
|
res = Rack::MockRequest.new(app).
|
114
115
|
get("https://example.org/foo")
|
115
|
-
res.
|
116
|
+
res.must_be_kind_of Rack::MockResponse
|
116
117
|
|
117
118
|
env = YAML.load(res.body)
|
118
|
-
env["REQUEST_METHOD"].
|
119
|
-
env["SERVER_NAME"].
|
120
|
-
env["SERVER_PORT"].
|
121
|
-
env["QUERY_STRING"].
|
122
|
-
env["PATH_INFO"].
|
123
|
-
env["rack.url_scheme"].
|
124
|
-
env["HTTPS"].
|
119
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
120
|
+
env["SERVER_NAME"].must_equal "example.org"
|
121
|
+
env["SERVER_PORT"].must_equal "443"
|
122
|
+
env["QUERY_STRING"].must_equal ""
|
123
|
+
env["PATH_INFO"].must_equal "/foo"
|
124
|
+
env["rack.url_scheme"].must_equal "https"
|
125
|
+
env["HTTPS"].must_equal "on"
|
125
126
|
end
|
126
127
|
|
127
|
-
|
128
|
+
it "prepend slash to uri path" do
|
128
129
|
res = Rack::MockRequest.new(app).
|
129
130
|
get("foo")
|
130
|
-
res.
|
131
|
+
res.must_be_kind_of Rack::MockResponse
|
131
132
|
|
132
133
|
env = YAML.load(res.body)
|
133
|
-
env["REQUEST_METHOD"].
|
134
|
-
env["SERVER_NAME"].
|
135
|
-
env["SERVER_PORT"].
|
136
|
-
env["QUERY_STRING"].
|
137
|
-
env["PATH_INFO"].
|
138
|
-
env["rack.url_scheme"].
|
134
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
135
|
+
env["SERVER_NAME"].must_equal "example.org"
|
136
|
+
env["SERVER_PORT"].must_equal "80"
|
137
|
+
env["QUERY_STRING"].must_equal ""
|
138
|
+
env["PATH_INFO"].must_equal "/foo"
|
139
|
+
env["rack.url_scheme"].must_equal "http"
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
+
it "properly convert method name to an uppercase string" do
|
142
143
|
res = Rack::MockRequest.new(app).request(:get)
|
143
144
|
env = YAML.load(res.body)
|
144
|
-
env["REQUEST_METHOD"].
|
145
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
145
146
|
end
|
146
147
|
|
147
|
-
|
148
|
+
it "accept params and build query string for GET requests" do
|
148
149
|
res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => {:foo => {:bar => "1"}})
|
149
150
|
env = YAML.load(res.body)
|
150
|
-
env["REQUEST_METHOD"].
|
151
|
-
env["QUERY_STRING"].
|
152
|
-
env["QUERY_STRING"].
|
153
|
-
env["PATH_INFO"].
|
154
|
-
env["mock.postdata"].
|
151
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
152
|
+
env["QUERY_STRING"].must_include "baz=2"
|
153
|
+
env["QUERY_STRING"].must_include "foo[bar]=1"
|
154
|
+
env["PATH_INFO"].must_equal "/foo"
|
155
|
+
env["mock.postdata"].must_equal ""
|
155
156
|
end
|
156
157
|
|
157
|
-
|
158
|
+
it "accept raw input in params for GET requests" do
|
158
159
|
res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => "foo[bar]=1")
|
159
160
|
env = YAML.load(res.body)
|
160
|
-
env["REQUEST_METHOD"].
|
161
|
-
env["QUERY_STRING"].
|
162
|
-
env["QUERY_STRING"].
|
163
|
-
env["PATH_INFO"].
|
164
|
-
env["mock.postdata"].
|
161
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
162
|
+
env["QUERY_STRING"].must_include "baz=2"
|
163
|
+
env["QUERY_STRING"].must_include "foo[bar]=1"
|
164
|
+
env["PATH_INFO"].must_equal "/foo"
|
165
|
+
env["mock.postdata"].must_equal ""
|
165
166
|
end
|
166
167
|
|
167
|
-
|
168
|
+
it "accept params and build url encoded params for POST requests" do
|
168
169
|
res = Rack::MockRequest.new(app).post("/foo", :params => {:foo => {:bar => "1"}})
|
169
170
|
env = YAML.load(res.body)
|
170
|
-
env["REQUEST_METHOD"].
|
171
|
-
env["QUERY_STRING"].
|
172
|
-
env["PATH_INFO"].
|
173
|
-
env["CONTENT_TYPE"].
|
174
|
-
env["mock.postdata"].
|
171
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
172
|
+
env["QUERY_STRING"].must_equal ""
|
173
|
+
env["PATH_INFO"].must_equal "/foo"
|
174
|
+
env["CONTENT_TYPE"].must_equal "application/x-www-form-urlencoded"
|
175
|
+
env["mock.postdata"].must_equal "foo[bar]=1"
|
175
176
|
end
|
176
177
|
|
177
|
-
|
178
|
+
it "accept raw input in params for POST requests" do
|
178
179
|
res = Rack::MockRequest.new(app).post("/foo", :params => "foo[bar]=1")
|
179
180
|
env = YAML.load(res.body)
|
180
|
-
env["REQUEST_METHOD"].
|
181
|
-
env["QUERY_STRING"].
|
182
|
-
env["PATH_INFO"].
|
183
|
-
env["CONTENT_TYPE"].
|
184
|
-
env["mock.postdata"].
|
181
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
182
|
+
env["QUERY_STRING"].must_equal ""
|
183
|
+
env["PATH_INFO"].must_equal "/foo"
|
184
|
+
env["CONTENT_TYPE"].must_equal "application/x-www-form-urlencoded"
|
185
|
+
env["mock.postdata"].must_equal "foo[bar]=1"
|
185
186
|
end
|
186
187
|
|
187
|
-
|
188
|
+
it "accept params and build multipart encoded params for POST requests" do
|
188
189
|
files = Rack::Multipart::UploadedFile.new(File.join(File.dirname(__FILE__), "multipart", "file1.txt"))
|
189
190
|
res = Rack::MockRequest.new(app).post("/foo", :params => { "submit-name" => "Larry", "files" => files })
|
190
191
|
env = YAML.load(res.body)
|
191
|
-
env["REQUEST_METHOD"].
|
192
|
-
env["QUERY_STRING"].
|
193
|
-
env["PATH_INFO"].
|
194
|
-
env["CONTENT_TYPE"].
|
192
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
193
|
+
env["QUERY_STRING"].must_equal ""
|
194
|
+
env["PATH_INFO"].must_equal "/foo"
|
195
|
+
env["CONTENT_TYPE"].must_equal "multipart/form-data; boundary=AaB03x"
|
195
196
|
# The gsub accounts for differences in YAMLs affect on the data.
|
196
|
-
env["mock.postdata"].gsub("\r", "").length.
|
197
|
+
env["mock.postdata"].gsub("\r", "").length.must_equal 206
|
197
198
|
end
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
}.should.not.raise(Rack::Lint::LintError)
|
200
|
+
it "behave valid according to the Rack spec" do
|
201
|
+
url = "https://bla.example.org:9292/meh/foo?bar"
|
202
|
+
Rack::MockRequest.new(app).get(url, :lint => true).
|
203
|
+
must_be_kind_of Rack::MockResponse
|
204
204
|
end
|
205
205
|
|
206
|
-
|
206
|
+
it "call close on the original body object" do
|
207
207
|
called = false
|
208
208
|
body = Rack::BodyProxy.new(['hi']) { called = true }
|
209
209
|
capp = proc { |e| [200, {'Content-Type' => 'text/plain'}, body] }
|
210
|
-
called.
|
210
|
+
called.must_equal false
|
211
211
|
Rack::MockRequest.new(capp).get('/', :lint => true)
|
212
|
-
called.
|
212
|
+
called.must_equal true
|
213
213
|
end
|
214
214
|
|
215
|
-
|
216
|
-
|
217
|
-
req = Rack::MockRequest.env_for("/foo")
|
215
|
+
it "defaults encoding to ASCII 8BIT" do
|
216
|
+
req = Rack::MockRequest.env_for("/foo")
|
218
217
|
|
219
|
-
|
218
|
+
keys = [
|
220
219
|
Rack::REQUEST_METHOD,
|
221
|
-
|
222
|
-
|
220
|
+
Rack::SERVER_NAME,
|
221
|
+
Rack::SERVER_PORT,
|
223
222
|
Rack::QUERY_STRING,
|
224
223
|
Rack::PATH_INFO,
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
req[k].encoding.should.equal Encoding::ASCII_8BIT
|
231
|
-
end
|
224
|
+
Rack::HTTPS,
|
225
|
+
Rack::RACK_URL_SCHEME
|
226
|
+
]
|
227
|
+
keys.each do |k|
|
228
|
+
assert_equal Encoding::ASCII_8BIT, req[k].encoding
|
232
229
|
end
|
233
230
|
end
|
234
231
|
end
|
235
232
|
|
236
233
|
describe Rack::MockResponse do
|
237
|
-
|
234
|
+
it "provide access to the HTTP status" do
|
238
235
|
res = Rack::MockRequest.new(app).get("")
|
239
|
-
res.
|
240
|
-
res.
|
236
|
+
res.must_be :successful?
|
237
|
+
res.must_be :ok?
|
241
238
|
|
242
239
|
res = Rack::MockRequest.new(app).get("/?status=404")
|
243
|
-
res.
|
244
|
-
res.
|
245
|
-
res.
|
240
|
+
res.wont_be :successful?
|
241
|
+
res.must_be :client_error?
|
242
|
+
res.must_be :not_found?
|
246
243
|
|
247
244
|
res = Rack::MockRequest.new(app).get("/?status=501")
|
248
|
-
res.
|
249
|
-
res.
|
245
|
+
res.wont_be :successful?
|
246
|
+
res.must_be :server_error?
|
250
247
|
|
251
248
|
res = Rack::MockRequest.new(app).get("/?status=307")
|
252
|
-
res.
|
249
|
+
res.must_be :redirect?
|
253
250
|
|
254
251
|
res = Rack::MockRequest.new(app).get("/?status=201", :lint => true)
|
255
|
-
res.
|
252
|
+
res.must_be :empty?
|
256
253
|
end
|
257
254
|
|
258
|
-
|
255
|
+
it "provide access to the HTTP headers" do
|
259
256
|
res = Rack::MockRequest.new(app).get("")
|
260
|
-
res.
|
261
|
-
res.headers["Content-Type"].
|
262
|
-
res.original_headers["Content-Type"].
|
263
|
-
res["Content-Type"].
|
264
|
-
res.content_type.
|
265
|
-
res.content_length.
|
266
|
-
res.location.
|
257
|
+
res.must_include "Content-Type"
|
258
|
+
res.headers["Content-Type"].must_equal "text/yaml"
|
259
|
+
res.original_headers["Content-Type"].must_equal "text/yaml"
|
260
|
+
res["Content-Type"].must_equal "text/yaml"
|
261
|
+
res.content_type.must_equal "text/yaml"
|
262
|
+
res.content_length.wont_equal 0
|
263
|
+
res.location.must_be_nil
|
267
264
|
end
|
268
265
|
|
269
|
-
|
266
|
+
it "provide access to the HTTP body" do
|
270
267
|
res = Rack::MockRequest.new(app).get("")
|
271
|
-
res.body.
|
272
|
-
res
|
273
|
-
res.should.match(/rack/)
|
274
|
-
res.should.satisfy { |r| r.match(/rack/) }
|
268
|
+
res.body.must_match(/rack/)
|
269
|
+
assert_match(res, /rack/)
|
275
270
|
end
|
276
271
|
|
277
|
-
|
272
|
+
it "provide access to the Rack errors" do
|
278
273
|
res = Rack::MockRequest.new(app).get("/?error=foo", :lint => true)
|
279
|
-
res.
|
280
|
-
res.errors.
|
281
|
-
res.errors.
|
274
|
+
res.must_be :ok?
|
275
|
+
res.errors.wont_be :empty?
|
276
|
+
res.errors.must_include "foo"
|
282
277
|
end
|
283
278
|
|
284
|
-
|
279
|
+
it "allow calling body.close afterwards" do
|
285
280
|
# this is exactly what rack-test does
|
286
281
|
body = StringIO.new("hi")
|
287
282
|
res = Rack::MockResponse.new(200, {}, body)
|
288
283
|
body.close if body.respond_to?(:close)
|
289
|
-
res.body.
|
284
|
+
res.body.must_equal 'hi'
|
290
285
|
end
|
291
286
|
|
292
|
-
|
287
|
+
it "optionally make Rack errors fatal" do
|
293
288
|
lambda {
|
294
289
|
Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
|
295
|
-
}.
|
290
|
+
}.must_raise Rack::MockRequest::FatalWarning
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe Rack::MockResponse, 'headers' do
|
295
|
+
before do
|
296
|
+
@res = Rack::MockRequest.new(app).get('')
|
297
|
+
@res.set_header 'FOO', '1'
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'has_header?' do
|
301
|
+
lambda { @res.has_header? nil }.must_raise NoMethodError
|
302
|
+
|
303
|
+
@res.has_header?('FOO').must_equal true
|
304
|
+
@res.has_header?('Foo').must_equal true
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'get_header' do
|
308
|
+
lambda { @res.get_header nil }.must_raise NoMethodError
|
309
|
+
|
310
|
+
@res.get_header('FOO').must_equal '1'
|
311
|
+
@res.get_header('Foo').must_equal '1'
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'set_header' do
|
315
|
+
lambda { @res.set_header nil, '1' }.must_raise NoMethodError
|
316
|
+
|
317
|
+
@res.set_header('FOO', '2').must_equal '2'
|
318
|
+
@res.get_header('FOO').must_equal '2'
|
319
|
+
|
320
|
+
@res.set_header('Foo', '3').must_equal '3'
|
321
|
+
@res.get_header('Foo').must_equal '3'
|
322
|
+
@res.get_header('FOO').must_equal '3'
|
323
|
+
|
324
|
+
@res.set_header('FOO', nil).must_be_nil
|
325
|
+
@res.get_header('FOO').must_be_nil
|
326
|
+
@res.has_header?('FOO').must_equal true
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'add_header' do
|
330
|
+
lambda { @res.add_header nil, '1' }.must_raise NoMethodError
|
331
|
+
|
332
|
+
# Sets header on first addition
|
333
|
+
@res.add_header('FOO', '1').must_equal '1,1'
|
334
|
+
@res.get_header('FOO').must_equal '1,1'
|
335
|
+
|
336
|
+
# Ignores nil additions
|
337
|
+
@res.add_header('FOO', nil).must_equal '1,1'
|
338
|
+
@res.get_header('FOO').must_equal '1,1'
|
339
|
+
|
340
|
+
# Converts additions to strings
|
341
|
+
@res.add_header('FOO', 2).must_equal '1,1,2'
|
342
|
+
@res.get_header('FOO').must_equal '1,1,2'
|
343
|
+
|
344
|
+
# Respects underlying case-sensitivity
|
345
|
+
@res.add_header('Foo', 'yep').must_equal '1,1,2,yep'
|
346
|
+
@res.get_header('Foo').must_equal '1,1,2,yep'
|
347
|
+
@res.get_header('FOO').must_equal '1,1,2,yep'
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'delete_header' do
|
351
|
+
lambda { @res.delete_header nil }.must_raise NoMethodError
|
352
|
+
|
353
|
+
@res.delete_header('FOO').must_equal '1'
|
354
|
+
@res.has_header?('FOO').must_equal false
|
355
|
+
|
356
|
+
@res.has_header?('Foo').must_equal false
|
357
|
+
@res.delete_header('Foo').must_be_nil
|
296
358
|
end
|
297
359
|
end
|