rack 1.6.13 → 2.1.4.3
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 +4 -4
- data/CHANGELOG.md +92 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +105 -141
- data/Rakefile +27 -28
- data/SPEC +6 -7
- data/bin/rackup +1 -0
- data/contrib/rack_logo.svg +164 -111
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +4 -2
- data/example/protectedlobster.ru +3 -1
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +7 -1
- data/lib/rack/auth/basic.rb +4 -1
- data/lib/rack/auth/digest/md5.rb +9 -7
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +5 -4
- data/lib/rack/auth/digest/request.rb +3 -1
- data/lib/rack/body_proxy.rb +11 -9
- data/lib/rack/builder.rb +42 -18
- data/lib/rack/cascade.rb +6 -5
- data/lib/rack/chunked.rb +33 -10
- data/lib/rack/{commonlogger.rb → common_logger.rb} +14 -10
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +3 -1
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +5 -3
- data/lib/rack/content_type.rb +3 -1
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +33 -53
- data/lib/rack/directory.rb +75 -60
- data/lib/rack/etag.rb +8 -5
- data/lib/rack/events.rb +156 -0
- data/lib/rack/file.rb +4 -149
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler/cgi.rb +18 -17
- data/lib/rack/handler/fastcgi.rb +17 -16
- data/lib/rack/handler/lsws.rb +14 -12
- data/lib/rack/handler/scgi.rb +22 -19
- data/lib/rack/handler/thin.rb +6 -1
- data/lib/rack/handler/webrick.rb +28 -28
- data/lib/rack/handler.rb +9 -26
- data/lib/rack/head.rb +17 -17
- data/lib/rack/lint.rb +55 -52
- data/lib/rack/lobster.rb +8 -6
- data/lib/rack/lock.rb +17 -10
- data/lib/rack/logger.rb +4 -2
- data/lib/rack/media_type.rb +43 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
- data/lib/rack/mime.rb +27 -6
- data/lib/rack/mock.rb +101 -60
- data/lib/rack/multipart/generator.rb +11 -12
- data/lib/rack/multipart/parser.rb +292 -161
- data/lib/rack/multipart/uploaded_file.rb +3 -2
- data/lib/rack/multipart.rb +38 -8
- data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
- data/lib/rack/query_parser.rb +218 -0
- data/lib/rack/recursive.rb +11 -9
- data/lib/rack/reloader.rb +10 -4
- data/lib/rack/request.rb +447 -305
- data/lib/rack/response.rb +196 -83
- data/lib/rack/rewindable_input.rb +5 -14
- data/lib/rack/runtime.rb +12 -18
- data/lib/rack/sendfile.rb +19 -14
- data/lib/rack/server.rb +118 -41
- data/lib/rack/session/abstract/id.rb +139 -94
- data/lib/rack/session/cookie.rb +34 -26
- data/lib/rack/session/memcache.rb +4 -93
- data/lib/rack/session/pool.rb +12 -10
- data/lib/rack/show_exceptions.rb +392 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +7 -5
- data/lib/rack/static.rb +41 -11
- data/lib/rack/tempfile_reaper.rb +4 -2
- data/lib/rack/urlmap.rb +25 -15
- data/lib/rack/utils.rb +203 -277
- data/lib/rack.rb +76 -24
- data/rack.gemspec +25 -14
- metadata +62 -183
- data/HISTORY.md +0 -375
- 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/builder/anything.rb +0 -5
- data/test/builder/comment.ru +0 -4
- data/test/builder/end.ru +0 -5
- data/test/builder/line.ru +0 -1
- data/test/builder/options.ru +0 -2
- data/test/cgi/assets/folder/test.js +0 -1
- data/test/cgi/assets/fonts/font.eot +0 -1
- data/test/cgi/assets/images/image.png +0 -1
- data/test/cgi/assets/index.html +0 -1
- data/test/cgi/assets/javascripts/app.js +0 -1
- data/test/cgi/assets/stylesheets/app.css +0 -1
- data/test/cgi/lighttpd.conf +0 -26
- data/test/cgi/rackup_stub.rb +0 -6
- data/test/cgi/sample_rackup.ru +0 -5
- data/test/cgi/test +0 -9
- data/test/cgi/test+directory/test+file +0 -1
- data/test/cgi/test.fcgi +0 -8
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- data/test/multipart/bad_robots +0 -259
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +0 -6
- data/test/multipart/empty +0 -10
- data/test/multipart/fail_16384_nofile +0 -814
- data/test/multipart/file1.txt +0 -1
- data/test/multipart/filename_and_modification_param +0 -7
- data/test/multipart/filename_and_no_name +0 -6
- data/test/multipart/filename_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
- data/test/multipart/filename_with_null_byte +0 -7
- data/test/multipart/filename_with_percent_escaped_quotes +0 -6
- data/test/multipart/filename_with_unescaped_percentages +0 -6
- data/test/multipart/filename_with_unescaped_percentages2 +0 -6
- data/test/multipart/filename_with_unescaped_percentages3 +0 -6
- data/test/multipart/filename_with_unescaped_quotes +0 -6
- data/test/multipart/ie +0 -6
- data/test/multipart/invalid_character +0 -6
- data/test/multipart/mixed_files +0 -21
- data/test/multipart/nested +0 -10
- data/test/multipart/none +0 -9
- data/test/multipart/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- data/test/multipart/webkit +0 -32
- data/test/rackup/config.ru +0 -31
- data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
- data/test/spec_auth_basic.rb +0 -81
- data/test/spec_auth_digest.rb +0 -259
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -223
- data/test/spec_cascade.rb +0 -61
- data/test/spec_cgi.rb +0 -102
- data/test/spec_chunked.rb +0 -101
- data/test/spec_commonlogger.rb +0 -93
- data/test/spec_conditionalget.rb +0 -102
- data/test/spec_config.rb +0 -22
- data/test/spec_content_length.rb +0 -85
- data/test/spec_content_type.rb +0 -45
- data/test/spec_deflater.rb +0 -339
- data/test/spec_directory.rb +0 -88
- data/test/spec_etag.rb +0 -107
- data/test/spec_fastcgi.rb +0 -107
- data/test/spec_file.rb +0 -221
- data/test/spec_handler.rb +0 -72
- data/test/spec_head.rb +0 -45
- data/test/spec_lint.rb +0 -550
- data/test/spec_lobster.rb +0 -58
- data/test/spec_lock.rb +0 -164
- data/test/spec_logger.rb +0 -23
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -297
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_multipart.rb +0 -600
- data/test/spec_nulllogger.rb +0 -20
- data/test/spec_recursive.rb +0 -72
- data/test/spec_request.rb +0 -1232
- data/test/spec_response.rb +0 -407
- data/test/spec_rewindable_input.rb +0 -118
- data/test/spec_runtime.rb +0 -49
- data/test/spec_sendfile.rb +0 -130
- data/test/spec_server.rb +0 -167
- data/test/spec_session_abstract_id.rb +0 -53
- data/test/spec_session_cookie.rb +0 -410
- data/test/spec_session_memcache.rb +0 -358
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_session_pool.rb +0 -246
- data/test/spec_showexceptions.rb +0 -98
- data/test/spec_showstatus.rb +0 -103
- data/test/spec_static.rb +0 -145
- data/test/spec_tempfile_reaper.rb +0 -63
- data/test/spec_thin.rb +0 -91
- data/test/spec_urlmap.rb +0 -236
- data/test/spec_utils.rb +0 -647
- data/test/spec_version.rb +0 -17
- data/test/spec_webrick.rb +0 -184
- data/test/static/another/index.html +0 -1
- data/test/static/index.html +0 -1
- data/test/testrequest.rb +0 -78
- data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/test/spec_utils.rb
DELETED
@@ -1,647 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require 'rack/utils'
|
3
|
-
require 'rack/mock'
|
4
|
-
require 'timeout'
|
5
|
-
|
6
|
-
describe Rack::Utils do
|
7
|
-
|
8
|
-
# A helper method which checks
|
9
|
-
# if certain query parameters
|
10
|
-
# are equal.
|
11
|
-
def equal_query_to(query)
|
12
|
-
parts = query.split('&')
|
13
|
-
lambda{|other| (parts & other.split('&')) == parts }
|
14
|
-
end
|
15
|
-
|
16
|
-
def kcodeu
|
17
|
-
one8 = RUBY_VERSION.to_f < 1.9
|
18
|
-
default_kcode, $KCODE = $KCODE, 'U' if one8
|
19
|
-
yield
|
20
|
-
ensure
|
21
|
-
$KCODE = default_kcode if one8
|
22
|
-
end
|
23
|
-
|
24
|
-
should "round trip binary data" do
|
25
|
-
r = [218, 0].pack 'CC'
|
26
|
-
if defined?(::Encoding)
|
27
|
-
z = Rack::Utils.unescape(Rack::Utils.escape(r), Encoding::BINARY)
|
28
|
-
else
|
29
|
-
z = Rack::Utils.unescape(Rack::Utils.escape(r))
|
30
|
-
end
|
31
|
-
r.should.equal z
|
32
|
-
end
|
33
|
-
|
34
|
-
should "escape correctly" do
|
35
|
-
Rack::Utils.escape("fo<o>bar").should.equal "fo%3Co%3Ebar"
|
36
|
-
Rack::Utils.escape("a space").should.equal "a+space"
|
37
|
-
Rack::Utils.escape("q1!2\"'w$5&7/z8)?\\").
|
38
|
-
should.equal "q1%212%22%27w%245%267%2Fz8%29%3F%5C"
|
39
|
-
end
|
40
|
-
|
41
|
-
should "escape correctly for multibyte characters" do
|
42
|
-
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
43
|
-
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
44
|
-
Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
45
|
-
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
46
|
-
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
47
|
-
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
48
|
-
end
|
49
|
-
|
50
|
-
if RUBY_VERSION[/^\d+\.\d+/] == '1.8'
|
51
|
-
should "escape correctly for multibyte characters if $KCODE is set to 'U'" do
|
52
|
-
kcodeu do
|
53
|
-
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
54
|
-
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
55
|
-
Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
56
|
-
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
57
|
-
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
58
|
-
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
should "unescape multibyte characters correctly if $KCODE is set to 'U'" do
|
63
|
-
kcodeu do
|
64
|
-
Rack::Utils.unescape('%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8').should.equal(
|
65
|
-
"\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0])
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
should "escape objects that responds to to_s" do
|
71
|
-
kcodeu do
|
72
|
-
Rack::Utils.escape(:id).should.equal "id"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
if "".respond_to?(:encode)
|
77
|
-
should "escape non-UTF8 strings" do
|
78
|
-
Rack::Utils.escape("ø".encode("ISO-8859-1")).should.equal "%F8"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
should "not hang on escaping long strings that end in % (http://redmine.ruby-lang.org/issues/5149)" do
|
83
|
-
lambda {
|
84
|
-
timeout(1) do
|
85
|
-
lambda {
|
86
|
-
URI.decode_www_form_component "A string that causes catastrophic backtracking as it gets longer %"
|
87
|
-
}.should.raise(ArgumentError)
|
88
|
-
end
|
89
|
-
}.should.not.raise(Timeout::Error)
|
90
|
-
end
|
91
|
-
|
92
|
-
should "escape path spaces with %20" do
|
93
|
-
Rack::Utils.escape_path("foo bar").should.equal "foo%20bar"
|
94
|
-
end
|
95
|
-
|
96
|
-
should "unescape correctly" do
|
97
|
-
Rack::Utils.unescape("fo%3Co%3Ebar").should.equal "fo<o>bar"
|
98
|
-
Rack::Utils.unescape("a+space").should.equal "a space"
|
99
|
-
Rack::Utils.unescape("a%20space").should.equal "a space"
|
100
|
-
Rack::Utils.unescape("q1%212%22%27w%245%267%2Fz8%29%3F%5C").
|
101
|
-
should.equal "q1!2\"'w$5&7/z8)?\\"
|
102
|
-
end
|
103
|
-
|
104
|
-
should "parse query strings correctly" do
|
105
|
-
Rack::Utils.parse_query("foo=bar").
|
106
|
-
should.equal "foo" => "bar"
|
107
|
-
Rack::Utils.parse_query("foo=\"bar\"").
|
108
|
-
should.equal "foo" => "\"bar\""
|
109
|
-
Rack::Utils.parse_query("foo=bar&foo=quux").
|
110
|
-
should.equal "foo" => ["bar", "quux"]
|
111
|
-
Rack::Utils.parse_query("foo=1&bar=2").
|
112
|
-
should.equal "foo" => "1", "bar" => "2"
|
113
|
-
Rack::Utils.parse_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
|
114
|
-
should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
|
115
|
-
Rack::Utils.parse_query("foo%3Dbaz=bar").should.equal "foo=baz" => "bar"
|
116
|
-
Rack::Utils.parse_query("=").should.equal "" => ""
|
117
|
-
Rack::Utils.parse_query("=value").should.equal "" => "value"
|
118
|
-
Rack::Utils.parse_query("key=").should.equal "key" => ""
|
119
|
-
Rack::Utils.parse_query("&key&").should.equal "key" => nil
|
120
|
-
Rack::Utils.parse_query(";key;", ";,").should.equal "key" => nil
|
121
|
-
Rack::Utils.parse_query(",key,", ";,").should.equal "key" => nil
|
122
|
-
Rack::Utils.parse_query(";foo=bar,;", ";,").should.equal "foo" => "bar"
|
123
|
-
Rack::Utils.parse_query(",foo=bar;,", ";,").should.equal "foo" => "bar"
|
124
|
-
end
|
125
|
-
|
126
|
-
should "not create infinite loops with cycle structures" do
|
127
|
-
ex = { "foo" => nil }
|
128
|
-
ex["foo"] = ex
|
129
|
-
|
130
|
-
params = Rack::Utils::KeySpaceConstrainedParams.new
|
131
|
-
params['foo'] = params
|
132
|
-
lambda {
|
133
|
-
params.to_params_hash.to_s.should.equal ex.to_s
|
134
|
-
}.should.not.raise
|
135
|
-
end
|
136
|
-
|
137
|
-
should "raise an exception if the params are too deep" do
|
138
|
-
len = Rack::Utils.param_depth_limit
|
139
|
-
|
140
|
-
lambda {
|
141
|
-
Rack::Utils.parse_nested_query("foo#{"[a]" * len}=bar")
|
142
|
-
}.should.raise(RangeError)
|
143
|
-
|
144
|
-
lambda {
|
145
|
-
Rack::Utils.parse_nested_query("foo#{"[a]" * (len - 1)}=bar")
|
146
|
-
}.should.not.raise
|
147
|
-
end
|
148
|
-
|
149
|
-
should "parse nested query strings correctly" do
|
150
|
-
Rack::Utils.parse_nested_query("foo").
|
151
|
-
should.equal "foo" => nil
|
152
|
-
Rack::Utils.parse_nested_query("foo=").
|
153
|
-
should.equal "foo" => ""
|
154
|
-
Rack::Utils.parse_nested_query("foo=bar").
|
155
|
-
should.equal "foo" => "bar"
|
156
|
-
Rack::Utils.parse_nested_query("foo=\"bar\"").
|
157
|
-
should.equal "foo" => "\"bar\""
|
158
|
-
|
159
|
-
Rack::Utils.parse_nested_query("foo=bar&foo=quux").
|
160
|
-
should.equal "foo" => "quux"
|
161
|
-
Rack::Utils.parse_nested_query("foo&foo=").
|
162
|
-
should.equal "foo" => ""
|
163
|
-
Rack::Utils.parse_nested_query("foo=1&bar=2").
|
164
|
-
should.equal "foo" => "1", "bar" => "2"
|
165
|
-
Rack::Utils.parse_nested_query("&foo=1&&bar=2").
|
166
|
-
should.equal "foo" => "1", "bar" => "2"
|
167
|
-
Rack::Utils.parse_nested_query("foo&bar=").
|
168
|
-
should.equal "foo" => nil, "bar" => ""
|
169
|
-
Rack::Utils.parse_nested_query("foo=bar&baz=").
|
170
|
-
should.equal "foo" => "bar", "baz" => ""
|
171
|
-
Rack::Utils.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
|
172
|
-
should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
|
173
|
-
|
174
|
-
Rack::Utils.parse_nested_query("a=b&pid%3D1234=1023").
|
175
|
-
should.equal "pid=1234" => "1023", "a" => "b"
|
176
|
-
|
177
|
-
Rack::Utils.parse_nested_query("foo[]").
|
178
|
-
should.equal "foo" => [nil]
|
179
|
-
Rack::Utils.parse_nested_query("foo[]=").
|
180
|
-
should.equal "foo" => [""]
|
181
|
-
Rack::Utils.parse_nested_query("foo[]=bar").
|
182
|
-
should.equal "foo" => ["bar"]
|
183
|
-
Rack::Utils.parse_nested_query("foo[]=bar&foo").
|
184
|
-
should.equal "foo" => nil
|
185
|
-
Rack::Utils.parse_nested_query("foo[]=bar&foo[").
|
186
|
-
should.equal "foo" => ["bar"], "foo[" => nil
|
187
|
-
Rack::Utils.parse_nested_query("foo[]=bar&foo[=baz").
|
188
|
-
should.equal "foo" => ["bar"], "foo[" => "baz"
|
189
|
-
Rack::Utils.parse_nested_query("foo[]=bar&foo[]").
|
190
|
-
should.equal "foo" => ["bar", nil]
|
191
|
-
Rack::Utils.parse_nested_query("foo[]=bar&foo[]=").
|
192
|
-
should.equal "foo" => ["bar", ""]
|
193
|
-
|
194
|
-
Rack::Utils.parse_nested_query("foo[]=1&foo[]=2").
|
195
|
-
should.equal "foo" => ["1", "2"]
|
196
|
-
Rack::Utils.parse_nested_query("foo=bar&baz[]=1&baz[]=2&baz[]=3").
|
197
|
-
should.equal "foo" => "bar", "baz" => ["1", "2", "3"]
|
198
|
-
Rack::Utils.parse_nested_query("foo[]=bar&baz[]=1&baz[]=2&baz[]=3").
|
199
|
-
should.equal "foo" => ["bar"], "baz" => ["1", "2", "3"]
|
200
|
-
|
201
|
-
Rack::Utils.parse_nested_query("x[y][z]=1").
|
202
|
-
should.equal "x" => {"y" => {"z" => "1"}}
|
203
|
-
Rack::Utils.parse_nested_query("x[y][z][]=1").
|
204
|
-
should.equal "x" => {"y" => {"z" => ["1"]}}
|
205
|
-
Rack::Utils.parse_nested_query("x[y][z]=1&x[y][z]=2").
|
206
|
-
should.equal "x" => {"y" => {"z" => "2"}}
|
207
|
-
Rack::Utils.parse_nested_query("x[y][z][]=1&x[y][z][]=2").
|
208
|
-
should.equal "x" => {"y" => {"z" => ["1", "2"]}}
|
209
|
-
|
210
|
-
Rack::Utils.parse_nested_query("x[y][][z]=1").
|
211
|
-
should.equal "x" => {"y" => [{"z" => "1"}]}
|
212
|
-
Rack::Utils.parse_nested_query("x[y][][z][]=1").
|
213
|
-
should.equal "x" => {"y" => [{"z" => ["1"]}]}
|
214
|
-
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=2").
|
215
|
-
should.equal "x" => {"y" => [{"z" => "1", "w" => "2"}]}
|
216
|
-
|
217
|
-
Rack::Utils.parse_nested_query("x[y][][v][w]=1").
|
218
|
-
should.equal "x" => {"y" => [{"v" => {"w" => "1"}}]}
|
219
|
-
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][v][w]=2").
|
220
|
-
should.equal "x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}
|
221
|
-
|
222
|
-
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][z]=2").
|
223
|
-
should.equal "x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}
|
224
|
-
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
|
225
|
-
should.equal "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
|
226
|
-
|
227
|
-
lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y]z=2") }.
|
228
|
-
should.raise(Rack::Utils::ParameterTypeError).
|
229
|
-
message.should.equal "expected Hash (got String) for param `y'"
|
230
|
-
|
231
|
-
lambda { Rack::Utils.parse_nested_query("x[y]=1&x[]=1") }.
|
232
|
-
should.raise(Rack::Utils::ParameterTypeError).
|
233
|
-
message.should.match(/expected Array \(got [^)]*\) for param `x'/)
|
234
|
-
|
235
|
-
lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y][][w]=2") }.
|
236
|
-
should.raise(Rack::Utils::ParameterTypeError).
|
237
|
-
message.should.equal "expected Array (got String) for param `y'"
|
238
|
-
|
239
|
-
if RUBY_VERSION.to_f > 1.9
|
240
|
-
lambda { Rack::Utils.parse_nested_query("foo%81E=1") }.
|
241
|
-
should.raise(Rack::Utils::InvalidParameterError).
|
242
|
-
message.should.equal "invalid byte sequence in UTF-8"
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
should "build query strings correctly" do
|
247
|
-
Rack::Utils.build_query("foo" => "bar").should.be equal_query_to("foo=bar")
|
248
|
-
Rack::Utils.build_query("foo" => ["bar", "quux"]).
|
249
|
-
should.be equal_query_to("foo=bar&foo=quux")
|
250
|
-
Rack::Utils.build_query("foo" => "1", "bar" => "2").
|
251
|
-
should.be equal_query_to("foo=1&bar=2")
|
252
|
-
Rack::Utils.build_query("my weird field" => "q1!2\"'w$5&7/z8)?").
|
253
|
-
should.be equal_query_to("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F")
|
254
|
-
end
|
255
|
-
|
256
|
-
should "build nested query strings correctly" do
|
257
|
-
Rack::Utils.build_nested_query("foo" => nil).should.equal "foo"
|
258
|
-
Rack::Utils.build_nested_query("foo" => "").should.equal "foo="
|
259
|
-
Rack::Utils.build_nested_query("foo" => "bar").should.equal "foo=bar"
|
260
|
-
|
261
|
-
Rack::Utils.build_nested_query("foo" => "1", "bar" => "2").
|
262
|
-
should.be equal_query_to("foo=1&bar=2")
|
263
|
-
Rack::Utils.build_nested_query("foo" => 1, "bar" => 2).
|
264
|
-
should.be equal_query_to("foo=1&bar=2")
|
265
|
-
Rack::Utils.build_nested_query("my weird field" => "q1!2\"'w$5&7/z8)?").
|
266
|
-
should.be equal_query_to("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F")
|
267
|
-
|
268
|
-
Rack::Utils.build_nested_query("foo" => [nil]).
|
269
|
-
should.equal "foo[]"
|
270
|
-
Rack::Utils.build_nested_query("foo" => [""]).
|
271
|
-
should.equal "foo[]="
|
272
|
-
Rack::Utils.build_nested_query("foo" => ["bar"]).
|
273
|
-
should.equal "foo[]=bar"
|
274
|
-
Rack::Utils.build_nested_query('foo' => []).
|
275
|
-
should.equal ''
|
276
|
-
Rack::Utils.build_nested_query('foo' => {}).
|
277
|
-
should.equal ''
|
278
|
-
Rack::Utils.build_nested_query('foo' => 'bar', 'baz' => []).
|
279
|
-
should.equal 'foo=bar'
|
280
|
-
Rack::Utils.build_nested_query('foo' => 'bar', 'baz' => {}).
|
281
|
-
should.equal 'foo=bar'
|
282
|
-
|
283
|
-
# The ordering of the output query string is unpredictable with 1.8's
|
284
|
-
# unordered hash. Test that build_nested_query performs the inverse
|
285
|
-
# function of parse_nested_query.
|
286
|
-
[{"foo" => nil, "bar" => ""},
|
287
|
-
{"foo" => "bar", "baz" => ""},
|
288
|
-
{"foo" => ["1", "2"]},
|
289
|
-
{"foo" => "bar", "baz" => ["1", "2", "3"]},
|
290
|
-
{"foo" => ["bar"], "baz" => ["1", "2", "3"]},
|
291
|
-
{"foo" => ["1", "2"]},
|
292
|
-
{"foo" => "bar", "baz" => ["1", "2", "3"]},
|
293
|
-
{"x" => {"y" => {"z" => "1"}}},
|
294
|
-
{"x" => {"y" => {"z" => ["1"]}}},
|
295
|
-
{"x" => {"y" => {"z" => ["1", "2"]}}},
|
296
|
-
{"x" => {"y" => [{"z" => "1"}]}},
|
297
|
-
{"x" => {"y" => [{"z" => ["1"]}]}},
|
298
|
-
{"x" => {"y" => [{"z" => "1", "w" => "2"}]}},
|
299
|
-
{"x" => {"y" => [{"v" => {"w" => "1"}}]}},
|
300
|
-
{"x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}},
|
301
|
-
{"x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}},
|
302
|
-
{"x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}}
|
303
|
-
].each { |params|
|
304
|
-
qs = Rack::Utils.build_nested_query(params)
|
305
|
-
Rack::Utils.parse_nested_query(qs).should.equal params
|
306
|
-
}
|
307
|
-
|
308
|
-
lambda { Rack::Utils.build_nested_query("foo=bar") }.
|
309
|
-
should.raise(ArgumentError).
|
310
|
-
message.should.equal "value must be a Hash"
|
311
|
-
end
|
312
|
-
|
313
|
-
should "parse query strings that have a non-existent value" do
|
314
|
-
key = "post/2011/08/27/Deux-%22rat%C3%A9s%22-de-l-Universit"
|
315
|
-
Rack::Utils.parse_query(key).should.equal Rack::Utils.unescape(key) => nil
|
316
|
-
end
|
317
|
-
|
318
|
-
should "build query strings without = with non-existent values" do
|
319
|
-
key = "post/2011/08/27/Deux-%22rat%C3%A9s%22-de-l-Universit"
|
320
|
-
key = Rack::Utils.unescape(key)
|
321
|
-
Rack::Utils.build_query(key => nil).should.equal Rack::Utils.escape(key)
|
322
|
-
end
|
323
|
-
|
324
|
-
should "parse q-values" do
|
325
|
-
# XXX handle accept-extension
|
326
|
-
Rack::Utils.q_values("foo;q=0.5,bar,baz;q=0.9").should.equal [
|
327
|
-
[ 'foo', 0.5 ],
|
328
|
-
[ 'bar', 1.0 ],
|
329
|
-
[ 'baz', 0.9 ]
|
330
|
-
]
|
331
|
-
end
|
332
|
-
|
333
|
-
should "select best quality match" do
|
334
|
-
Rack::Utils.best_q_match("text/html", %w[text/html]).should.equal "text/html"
|
335
|
-
|
336
|
-
# More specific matches are preferred
|
337
|
-
Rack::Utils.best_q_match("text/*;q=0.5,text/html;q=1.0", %w[text/html]).should.equal "text/html"
|
338
|
-
|
339
|
-
# Higher quality matches are preferred
|
340
|
-
Rack::Utils.best_q_match("text/*;q=0.5,text/plain;q=1.0", %w[text/plain text/html]).should.equal "text/plain"
|
341
|
-
|
342
|
-
# Respect requested content type
|
343
|
-
Rack::Utils.best_q_match("application/json", %w[application/vnd.lotus-1-2-3 application/json]).should.equal "application/json"
|
344
|
-
|
345
|
-
# All else equal, the available mimes are preferred in order
|
346
|
-
Rack::Utils.best_q_match("text/*", %w[text/html text/plain]).should.equal "text/html"
|
347
|
-
Rack::Utils.best_q_match("text/plain,text/html", %w[text/html text/plain]).should.equal "text/html"
|
348
|
-
|
349
|
-
# When there are no matches, return nil:
|
350
|
-
Rack::Utils.best_q_match("application/json", %w[text/html text/plain]).should.equal nil
|
351
|
-
end
|
352
|
-
|
353
|
-
should "escape html entities [&><'\"/]" do
|
354
|
-
Rack::Utils.escape_html("foo").should.equal "foo"
|
355
|
-
Rack::Utils.escape_html("f&o").should.equal "f&o"
|
356
|
-
Rack::Utils.escape_html("f<o").should.equal "f<o"
|
357
|
-
Rack::Utils.escape_html("f>o").should.equal "f>o"
|
358
|
-
Rack::Utils.escape_html("f'o").should.equal "f'o"
|
359
|
-
Rack::Utils.escape_html('f"o').should.equal "f"o"
|
360
|
-
Rack::Utils.escape_html("f/o").should.equal "f/o"
|
361
|
-
Rack::Utils.escape_html("<foo></foo>").should.equal "<foo></foo>"
|
362
|
-
end
|
363
|
-
|
364
|
-
should "escape html entities even on MRI when it's bugged" do
|
365
|
-
test_escape = lambda do
|
366
|
-
kcodeu do
|
367
|
-
Rack::Utils.escape_html("\300<").should.equal "\300<"
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
if RUBY_VERSION.to_f < 1.9
|
372
|
-
test_escape.call
|
373
|
-
else
|
374
|
-
test_escape.should.raise(ArgumentError)
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
if "".respond_to?(:encode)
|
379
|
-
should "escape html entities in unicode strings" do
|
380
|
-
# the following will cause warnings if the regex is poorly encoded:
|
381
|
-
Rack::Utils.escape_html("☃").should.equal "☃"
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
should "figure out which encodings are acceptable" do
|
386
|
-
helper = lambda do |a, b|
|
387
|
-
Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => a))
|
388
|
-
Rack::Utils.select_best_encoding(a, b)
|
389
|
-
end
|
390
|
-
|
391
|
-
helper.call(%w(), [["x", 1]]).should.equal(nil)
|
392
|
-
helper.call(%w(identity), [["identity", 0.0]]).should.equal(nil)
|
393
|
-
helper.call(%w(identity), [["*", 0.0]]).should.equal(nil)
|
394
|
-
|
395
|
-
helper.call(%w(identity), [["compress", 1.0], ["gzip", 1.0]]).should.equal("identity")
|
396
|
-
|
397
|
-
helper.call(%w(compress gzip identity), [["compress", 1.0], ["gzip", 1.0]]).should.equal("compress")
|
398
|
-
helper.call(%w(compress gzip identity), [["compress", 0.5], ["gzip", 1.0]]).should.equal("gzip")
|
399
|
-
|
400
|
-
helper.call(%w(foo bar identity), []).should.equal("identity")
|
401
|
-
helper.call(%w(foo bar identity), [["*", 1.0]]).should.equal("foo")
|
402
|
-
helper.call(%w(foo bar identity), [["*", 1.0], ["foo", 0.9]]).should.equal("bar")
|
403
|
-
|
404
|
-
helper.call(%w(foo bar identity), [["foo", 0], ["bar", 0]]).should.equal("identity")
|
405
|
-
helper.call(%w(foo bar baz identity), [["*", 0], ["identity", 0.1]]).should.equal("identity")
|
406
|
-
end
|
407
|
-
|
408
|
-
should "return the bytesize of String" do
|
409
|
-
Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
|
410
|
-
end
|
411
|
-
|
412
|
-
should "should perform constant time string comparison" do
|
413
|
-
Rack::Utils.secure_compare('a', 'a').should.equal true
|
414
|
-
Rack::Utils.secure_compare('a', 'b').should.equal false
|
415
|
-
end
|
416
|
-
|
417
|
-
should "return status code for integer" do
|
418
|
-
Rack::Utils.status_code(200).should.equal 200
|
419
|
-
end
|
420
|
-
|
421
|
-
should "return status code for string" do
|
422
|
-
Rack::Utils.status_code("200").should.equal 200
|
423
|
-
end
|
424
|
-
|
425
|
-
should "return status code for symbol" do
|
426
|
-
Rack::Utils.status_code(:ok).should.equal 200
|
427
|
-
end
|
428
|
-
|
429
|
-
should "return rfc2822 format from rfc2822 helper" do
|
430
|
-
Rack::Utils.rfc2822(Time.at(0).gmtime).should == "Thu, 01 Jan 1970 00:00:00 -0000"
|
431
|
-
end
|
432
|
-
|
433
|
-
should "return rfc2109 format from rfc2109 helper" do
|
434
|
-
Rack::Utils.rfc2109(Time.at(0).gmtime).should == "Thu, 01-Jan-1970 00:00:00 GMT"
|
435
|
-
end
|
436
|
-
|
437
|
-
should "clean directory traversal" do
|
438
|
-
Rack::Utils.clean_path_info("/cgi/../cgi/test").should.equal "/cgi/test"
|
439
|
-
Rack::Utils.clean_path_info(".").should.empty
|
440
|
-
Rack::Utils.clean_path_info("test/..").should.empty
|
441
|
-
end
|
442
|
-
|
443
|
-
should "clean unsafe directory traversal to safe path" do
|
444
|
-
Rack::Utils.clean_path_info("/../README.rdoc").should.equal "/README.rdoc"
|
445
|
-
Rack::Utils.clean_path_info("../test/spec_utils.rb").should.equal "test/spec_utils.rb"
|
446
|
-
end
|
447
|
-
|
448
|
-
should "not clean directory traversal with encoded periods" do
|
449
|
-
Rack::Utils.clean_path_info("/%2E%2E/README").should.equal "/%2E%2E/README"
|
450
|
-
end
|
451
|
-
|
452
|
-
should "clean slash only paths" do
|
453
|
-
Rack::Utils.clean_path_info("/").should.equal "/"
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
describe Rack::Utils, "byte_range" do
|
458
|
-
should "ignore missing or syntactically invalid byte ranges" do
|
459
|
-
Rack::Utils.byte_ranges({},500).should.equal nil
|
460
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "foobar"},500).should.equal nil
|
461
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "furlongs=123-456"},500).should.equal nil
|
462
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes="},500).should.equal nil
|
463
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=-"},500).should.equal nil
|
464
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=123,456"},500).should.equal nil
|
465
|
-
# A range of non-positive length is syntactically invalid and ignored:
|
466
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=456-123"},500).should.equal nil
|
467
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=456-455"},500).should.equal nil
|
468
|
-
end
|
469
|
-
|
470
|
-
should "parse simple byte ranges" do
|
471
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=123-456"},500).should.equal [(123..456)]
|
472
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=123-"},500).should.equal [(123..499)]
|
473
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=-100"},500).should.equal [(400..499)]
|
474
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=0-0"},500).should.equal [(0..0)]
|
475
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=499-499"},500).should.equal [(499..499)]
|
476
|
-
end
|
477
|
-
|
478
|
-
should "parse several byte ranges" do
|
479
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=500-600,601-999"},1000).should.equal [(500..600),(601..999)]
|
480
|
-
end
|
481
|
-
|
482
|
-
should "truncate byte ranges" do
|
483
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=123-999"},500).should.equal [(123..499)]
|
484
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=600-999"},500).should.equal []
|
485
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=-999"},500).should.equal [(0..499)]
|
486
|
-
end
|
487
|
-
|
488
|
-
should "ignore unsatisfiable byte ranges" do
|
489
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=500-501"},500).should.equal []
|
490
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=500-"},500).should.equal []
|
491
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=999-"},500).should.equal []
|
492
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=-0"},500).should.equal []
|
493
|
-
end
|
494
|
-
|
495
|
-
should "handle byte ranges of empty files" do
|
496
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=123-456"},0).should.equal []
|
497
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=0-"},0).should.equal []
|
498
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=-100"},0).should.equal []
|
499
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=0-0"},0).should.equal []
|
500
|
-
Rack::Utils.byte_ranges({"HTTP_RANGE" => "bytes=-0"},0).should.equal []
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
describe Rack::Utils::HeaderHash do
|
505
|
-
should "retain header case" do
|
506
|
-
h = Rack::Utils::HeaderHash.new("Content-MD5" => "d5ff4e2a0 ...")
|
507
|
-
h['ETag'] = 'Boo!'
|
508
|
-
h.to_hash.should.equal "Content-MD5" => "d5ff4e2a0 ...", "ETag" => 'Boo!'
|
509
|
-
end
|
510
|
-
|
511
|
-
should "check existence of keys case insensitively" do
|
512
|
-
h = Rack::Utils::HeaderHash.new("Content-MD5" => "d5ff4e2a0 ...")
|
513
|
-
h.should.include 'content-md5'
|
514
|
-
h.should.not.include 'ETag'
|
515
|
-
end
|
516
|
-
|
517
|
-
should "merge case-insensitively" do
|
518
|
-
h = Rack::Utils::HeaderHash.new("ETag" => 'HELLO', "content-length" => '123')
|
519
|
-
merged = h.merge("Etag" => 'WORLD', 'Content-Length' => '321', "Foo" => 'BAR')
|
520
|
-
merged.should.equal "Etag"=>'WORLD', "Content-Length"=>'321', "Foo"=>'BAR'
|
521
|
-
end
|
522
|
-
|
523
|
-
should "overwrite case insensitively and assume the new key's case" do
|
524
|
-
h = Rack::Utils::HeaderHash.new("Foo-Bar" => "baz")
|
525
|
-
h["foo-bar"] = "bizzle"
|
526
|
-
h["FOO-BAR"].should.equal "bizzle"
|
527
|
-
h.length.should.equal 1
|
528
|
-
h.to_hash.should.equal "foo-bar" => "bizzle"
|
529
|
-
end
|
530
|
-
|
531
|
-
should "be converted to real Hash" do
|
532
|
-
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
533
|
-
h.to_hash.should.be.instance_of Hash
|
534
|
-
end
|
535
|
-
|
536
|
-
should "convert Array values to Strings when converting to Hash" do
|
537
|
-
h = Rack::Utils::HeaderHash.new("foo" => ["bar", "baz"])
|
538
|
-
h.to_hash.should.equal({ "foo" => "bar\nbaz" })
|
539
|
-
end
|
540
|
-
|
541
|
-
should "replace hashes correctly" do
|
542
|
-
h = Rack::Utils::HeaderHash.new("Foo-Bar" => "baz")
|
543
|
-
j = {"foo" => "bar"}
|
544
|
-
h.replace(j)
|
545
|
-
h["foo"].should.equal "bar"
|
546
|
-
end
|
547
|
-
|
548
|
-
should "be able to delete the given key case-sensitively" do
|
549
|
-
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
550
|
-
h.delete("foo")
|
551
|
-
h["foo"].should.be.nil
|
552
|
-
h["FOO"].should.be.nil
|
553
|
-
end
|
554
|
-
|
555
|
-
should "be able to delete the given key case-insensitively" do
|
556
|
-
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
557
|
-
h.delete("FOO")
|
558
|
-
h["foo"].should.be.nil
|
559
|
-
h["FOO"].should.be.nil
|
560
|
-
end
|
561
|
-
|
562
|
-
should "return the deleted value when #delete is called on an existing key" do
|
563
|
-
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
564
|
-
h.delete("Foo").should.equal("bar")
|
565
|
-
end
|
566
|
-
|
567
|
-
should "return nil when #delete is called on a non-existant key" do
|
568
|
-
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
569
|
-
h.delete("Hello").should.be.nil
|
570
|
-
end
|
571
|
-
|
572
|
-
should "avoid unnecessary object creation if possible" do
|
573
|
-
a = Rack::Utils::HeaderHash.new("foo" => "bar")
|
574
|
-
b = Rack::Utils::HeaderHash.new(a)
|
575
|
-
b.object_id.should.equal(a.object_id)
|
576
|
-
b.should.equal(a)
|
577
|
-
end
|
578
|
-
|
579
|
-
should "convert Array values to Strings when responding to #each" do
|
580
|
-
h = Rack::Utils::HeaderHash.new("foo" => ["bar", "baz"])
|
581
|
-
h.each do |k,v|
|
582
|
-
k.should.equal("foo")
|
583
|
-
v.should.equal("bar\nbaz")
|
584
|
-
end
|
585
|
-
end
|
586
|
-
|
587
|
-
should "not create headers out of thin air" do
|
588
|
-
h = Rack::Utils::HeaderHash.new
|
589
|
-
h['foo']
|
590
|
-
h['foo'].should.be.nil
|
591
|
-
h.should.not.include 'foo'
|
592
|
-
end
|
593
|
-
end
|
594
|
-
|
595
|
-
describe Rack::Utils::Context do
|
596
|
-
class ContextTest
|
597
|
-
attr_reader :app
|
598
|
-
def initialize app; @app=app; end
|
599
|
-
def call env; context env; end
|
600
|
-
def context env, app=@app; app.call(env); end
|
601
|
-
end
|
602
|
-
test_target1 = proc{|e| e.to_s+' world' }
|
603
|
-
test_target2 = proc{|e| e.to_i+2 }
|
604
|
-
test_target3 = proc{|e| nil }
|
605
|
-
test_target4 = proc{|e| [200,{'Content-Type'=>'text/plain', 'Content-Length'=>'0'},['']] }
|
606
|
-
test_app = ContextTest.new test_target4
|
607
|
-
|
608
|
-
should "set context correctly" do
|
609
|
-
test_app.app.should.equal test_target4
|
610
|
-
c1 = Rack::Utils::Context.new(test_app, test_target1)
|
611
|
-
c1.for.should.equal test_app
|
612
|
-
c1.app.should.equal test_target1
|
613
|
-
c2 = Rack::Utils::Context.new(test_app, test_target2)
|
614
|
-
c2.for.should.equal test_app
|
615
|
-
c2.app.should.equal test_target2
|
616
|
-
end
|
617
|
-
|
618
|
-
should "alter app on recontexting" do
|
619
|
-
c1 = Rack::Utils::Context.new(test_app, test_target1)
|
620
|
-
c2 = c1.recontext(test_target2)
|
621
|
-
c2.for.should.equal test_app
|
622
|
-
c2.app.should.equal test_target2
|
623
|
-
c3 = c2.recontext(test_target3)
|
624
|
-
c3.for.should.equal test_app
|
625
|
-
c3.app.should.equal test_target3
|
626
|
-
end
|
627
|
-
|
628
|
-
should "run different apps" do
|
629
|
-
c1 = Rack::Utils::Context.new test_app, test_target1
|
630
|
-
c2 = c1.recontext test_target2
|
631
|
-
c3 = c2.recontext test_target3
|
632
|
-
c4 = c3.recontext test_target4
|
633
|
-
a4 = Rack::Lint.new c4
|
634
|
-
a5 = Rack::Lint.new test_app
|
635
|
-
r1 = c1.call('hello')
|
636
|
-
r1.should.equal 'hello world'
|
637
|
-
r2 = c2.call(2)
|
638
|
-
r2.should.equal 4
|
639
|
-
r3 = c3.call(:misc_symbol)
|
640
|
-
r3.should.be.nil
|
641
|
-
r4 = Rack::MockRequest.new(a4).get('/')
|
642
|
-
r4.status.should.equal 200
|
643
|
-
r5 = Rack::MockRequest.new(a5).get('/')
|
644
|
-
r5.status.should.equal 200
|
645
|
-
r4.body.should.equal r5.body
|
646
|
-
end
|
647
|
-
end
|
data/test/spec_version.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require 'rack'
|
3
|
-
|
4
|
-
describe Rack do
|
5
|
-
describe 'version' do
|
6
|
-
it 'defaults to a hard-coded api version' do
|
7
|
-
Rack.version.should.equal("1.3")
|
8
|
-
end
|
9
|
-
end
|
10
|
-
describe 'release' do
|
11
|
-
it 'matches version in .gemspec' do
|
12
|
-
gemspec_path = File.join(File.dirname(File.expand_path(__FILE__)), '../rack.gemspec')
|
13
|
-
gemspec = Gem::Specification.load(gemspec_path)
|
14
|
-
Rack.release.split('.').take(2).should.equal gemspec.version.to_s.split('.').take(2)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|