rack-test 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/History.txt +9 -0
- data/lib/rack/test.rb +3 -2
- data/lib/rack/test/cookie_jar.rb +5 -1
- data/lib/rack/test/utils.rb +53 -24
- data/rack-test.gemspec +5 -4
- data/spec/fixtures/bar.txt +1 -0
- data/spec/fixtures/fake_app.rb +1 -1
- data/spec/rack/test/cookie_spec.rb +6 -0
- data/spec/rack/test/multipart_spec.rb +47 -0
- data/spec/rack/test/utils_spec.rb +24 -0
- data/spec/rack/test_spec.rb +7 -0
- metadata +27 -9
data/.gitignore
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== Git
|
2
|
+
|
3
|
+
* Bug fixes
|
4
|
+
|
5
|
+
* Don't stomp on Content-Type's supplied via #header (Bryan Helmkamp)
|
6
|
+
* Fixed build_multipart to allow for arrays of files (Louis Rose)
|
7
|
+
* Don't raise an error if raw cookies contain a blank line (John Reilly)
|
8
|
+
* Handle parameter names with brackets properly (Tanner Donovan)
|
9
|
+
|
1
10
|
== 0.5.3 / 2009-11-27
|
2
11
|
|
3
12
|
* Bug fixes
|
data/lib/rack/test.rb
CHANGED
@@ -9,7 +9,7 @@ require "rack/test/uploaded_file"
|
|
9
9
|
|
10
10
|
module Rack
|
11
11
|
module Test
|
12
|
-
VERSION = "0.5.
|
12
|
+
VERSION = "0.5.4"
|
13
13
|
|
14
14
|
DEFAULT_HOST = "example.org"
|
15
15
|
MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
|
@@ -255,7 +255,8 @@ module Rack
|
|
255
255
|
converted_headers = {}
|
256
256
|
|
257
257
|
@headers.each do |name, value|
|
258
|
-
env_key =
|
258
|
+
env_key = name.upcase.gsub("-", "_")
|
259
|
+
env_key = "HTTP_" + env_key unless "CONTENT_TYPE" == env_key
|
259
260
|
converted_headers[env_key] = value
|
260
261
|
end
|
261
262
|
|
data/lib/rack/test/cookie_jar.rb
CHANGED
@@ -118,7 +118,11 @@ module Rack
|
|
118
118
|
def merge(raw_cookies, uri = nil)
|
119
119
|
return unless raw_cookies
|
120
120
|
|
121
|
-
|
121
|
+
if raw_cookies.is_a? String
|
122
|
+
raw_cookies = raw_cookies.split("\n")
|
123
|
+
raw_cookies.reject!{|c| c.empty? }
|
124
|
+
end
|
125
|
+
|
122
126
|
raw_cookies.each do |raw_cookie|
|
123
127
|
cookie = Cookie.new(raw_cookie, uri, @default_host)
|
124
128
|
self << cookie if cookie.valid?(uri)
|
data/lib/rack/test/utils.rb
CHANGED
@@ -8,7 +8,10 @@ module Rack
|
|
8
8
|
case value
|
9
9
|
when Array
|
10
10
|
value.map do |v|
|
11
|
-
|
11
|
+
unless unescape(prefix) =~ /\[\]$/
|
12
|
+
prefix = "#{prefix}[]"
|
13
|
+
end
|
14
|
+
build_nested_query(v, "#{prefix}")
|
12
15
|
end.join("&")
|
13
16
|
when Hash
|
14
17
|
value.map do |k, v|
|
@@ -51,11 +54,17 @@ module Rack
|
|
51
54
|
|
52
55
|
case value
|
53
56
|
when Array
|
54
|
-
value.map
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
value.map do |v|
|
58
|
+
|
59
|
+
if (v.is_a?(Hash))
|
60
|
+
build_multipart(v, false).each { |subkey, subvalue|
|
61
|
+
flattened_params["#{k}[]#{subkey}"] = subvalue
|
62
|
+
}
|
63
|
+
else
|
64
|
+
flattened_params["#{k}[]"] = value
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
59
68
|
when Hash
|
60
69
|
build_multipart(value, false).each { |subkey, subvalue|
|
61
70
|
flattened_params[k + subkey] = subvalue
|
@@ -66,35 +75,55 @@ module Rack
|
|
66
75
|
end
|
67
76
|
|
68
77
|
if first
|
69
|
-
flattened_params
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
build_parts(flattened_params)
|
79
|
+
else
|
80
|
+
flattened_params
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
module_function :build_multipart
|
85
|
+
|
86
|
+
private
|
87
|
+
def build_parts(parameters)
|
88
|
+
parameters.map { |name, value|
|
89
|
+
if value.respond_to?(:original_filename)
|
90
|
+
build_file_part(name, value)
|
91
|
+
|
92
|
+
elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) }
|
93
|
+
value.map do |v|
|
94
|
+
build_file_part(name, v)
|
95
|
+
end.join
|
96
|
+
|
97
|
+
else
|
98
|
+
build_primitive_part(name, value)
|
99
|
+
end
|
100
|
+
|
101
|
+
}.join + "--#{MULTIPART_BOUNDARY}--\r"
|
102
|
+
end
|
103
|
+
|
104
|
+
def build_primitive_part(parameter_name, value)
|
73
105
|
<<-EOF
|
74
106
|
--#{MULTIPART_BOUNDARY}\r
|
75
|
-
Content-Disposition: form-data; name="#{
|
76
|
-
Content-Type: #{file.content_type}\r
|
77
|
-
Content-Length: #{::File.stat(file.path).size}\r
|
107
|
+
Content-Disposition: form-data; name="#{parameter_name}"\r
|
78
108
|
\r
|
79
|
-
#{
|
109
|
+
#{value}\r
|
80
110
|
EOF
|
81
|
-
|
82
|
-
|
111
|
+
end
|
112
|
+
|
113
|
+
def build_file_part(parameter_name, uploaded_file)
|
114
|
+
::File.open(uploaded_file.path, "rb") do |physical_file|
|
115
|
+
physical_file.set_encoding(Encoding::BINARY) if physical_file.respond_to?(:set_encoding)
|
83
116
|
<<-EOF
|
84
117
|
--#{MULTIPART_BOUNDARY}\r
|
85
|
-
Content-Disposition: form-data; name="#{
|
118
|
+
Content-Disposition: form-data; name="#{parameter_name}"; filename="#{escape(uploaded_file.original_filename)}"\r
|
119
|
+
Content-Type: #{uploaded_file.content_type}\r
|
120
|
+
Content-Length: #{::File.stat(uploaded_file.path).size}\r
|
86
121
|
\r
|
87
|
-
#{
|
122
|
+
#{physical_file.read}\r
|
88
123
|
EOF
|
89
|
-
end
|
90
|
-
}.join + "--#{MULTIPART_BOUNDARY}--\r"
|
91
|
-
else
|
92
|
-
flattened_params
|
93
124
|
end
|
94
125
|
end
|
95
126
|
|
96
|
-
module_function :build_multipart
|
97
|
-
|
98
127
|
end
|
99
128
|
|
100
129
|
end
|
data/rack-test.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{rack-test}
|
5
|
-
s.version = "0.5.
|
5
|
+
s.version = "0.5.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Bryan Helmkamp"]
|
9
|
-
s.date = %q{
|
9
|
+
s.date = %q{2010-05-26}
|
10
10
|
s.description = %q{Rack::Test is a small, simple testing API for Rack apps. It can be used on its
|
11
11
|
own or as a reusable starting point for Web frameworks and testing libraries
|
12
12
|
to build on. Most of its initial functionality is an extraction of Merb 1.0's
|
@@ -32,6 +32,7 @@ request helpers feature.}
|
|
32
32
|
"lib/rack/test/uploaded_file.rb",
|
33
33
|
"lib/rack/test/utils.rb",
|
34
34
|
"rack-test.gemspec",
|
35
|
+
"spec/fixtures/bar.txt",
|
35
36
|
"spec/fixtures/config.ru",
|
36
37
|
"spec/fixtures/fake_app.rb",
|
37
38
|
"spec/fixtures/foo.txt",
|
@@ -46,7 +47,7 @@ request helpers feature.}
|
|
46
47
|
s.homepage = %q{http://github.com/brynary/rack-test}
|
47
48
|
s.require_paths = ["lib"]
|
48
49
|
s.rubyforge_project = %q{rack-test}
|
49
|
-
s.rubygems_version = %q{1.3.
|
50
|
+
s.rubygems_version = %q{1.3.7}
|
50
51
|
s.summary = %q{Simple testing API built on Rack}
|
51
52
|
s.test_files = [
|
52
53
|
"spec/fixtures/fake_app.rb",
|
@@ -62,7 +63,7 @@ request helpers feature.}
|
|
62
63
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
63
64
|
s.specification_version = 3
|
64
65
|
|
65
|
-
if Gem::Version.new(Gem::
|
66
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
66
67
|
s.add_runtime_dependency(%q<rack>, [">= 1.0"])
|
67
68
|
else
|
68
69
|
s.add_dependency(%q<rack>, [">= 1.0"])
|
@@ -0,0 +1 @@
|
|
1
|
+
baz
|
data/spec/fixtures/fake_app.rb
CHANGED
@@ -161,6 +161,12 @@ describe Rack::Test::Session do
|
|
161
161
|
last_request.cookies.should == { "value" => "10", "foo" => "bar" }
|
162
162
|
end
|
163
163
|
|
164
|
+
it "skips emtpy string cookies" do
|
165
|
+
set_cookie "value=10\n\nfoo=bar"
|
166
|
+
get "/cookies/show"
|
167
|
+
last_request.cookies.should == { "value" => "10", "foo" => "bar" }
|
168
|
+
end
|
169
|
+
|
164
170
|
it "parses multiple cookies properly" do
|
165
171
|
get "/cookies/set-multiple"
|
166
172
|
get "/cookies/show"
|
@@ -6,10 +6,18 @@ describe Rack::Test::Session do
|
|
6
6
|
File.dirname(__FILE__) + "/../../fixtures/foo.txt"
|
7
7
|
end
|
8
8
|
|
9
|
+
def second_test_file_path
|
10
|
+
File.dirname(__FILE__) + "/../../fixtures/bar.txt"
|
11
|
+
end
|
12
|
+
|
9
13
|
def uploaded_file
|
10
14
|
Rack::Test::UploadedFile.new(test_file_path)
|
11
15
|
end
|
12
16
|
|
17
|
+
def second_uploaded_file
|
18
|
+
Rack::Test::UploadedFile.new(second_test_file_path)
|
19
|
+
end
|
20
|
+
|
13
21
|
context "uploading a file" do
|
14
22
|
it "sends the multipart/form-data content type" do
|
15
23
|
post "/", "photo" => uploaded_file
|
@@ -84,4 +92,43 @@ describe Rack::Test::Session do
|
|
84
92
|
end
|
85
93
|
end
|
86
94
|
|
95
|
+
|
96
|
+
context "uploading two files" do
|
97
|
+
it "sends the multipart/form-data content type" do
|
98
|
+
post "/", "photos" => [uploaded_file, second_uploaded_file]
|
99
|
+
last_request.env["CONTENT_TYPE"].should include("multipart/form-data;")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "sends files with the filename" do
|
103
|
+
post "/", "photos" => [uploaded_file, second_uploaded_file]
|
104
|
+
last_request.POST["photos"].collect{|photo| photo[:filename]}.should == ["foo.txt", "bar.txt"]
|
105
|
+
end
|
106
|
+
|
107
|
+
it "sends files with the text/plain MIME type by default" do
|
108
|
+
post "/", "photos" => [uploaded_file, second_uploaded_file]
|
109
|
+
last_request.POST["photos"].collect{|photo| photo[:type]}.should == ["text/plain", "text/plain"]
|
110
|
+
end
|
111
|
+
|
112
|
+
it "sends files with the right names" do
|
113
|
+
post "/", "photos" => [uploaded_file, second_uploaded_file]
|
114
|
+
last_request.POST["photos"].all?{|photo| photo[:name].should == "photos[]" }
|
115
|
+
end
|
116
|
+
|
117
|
+
it "allows mixed content types" do
|
118
|
+
image_file = Rack::Test::UploadedFile.new(test_file_path, "image/jpeg")
|
119
|
+
|
120
|
+
post "/", "photos" => [uploaded_file, image_file]
|
121
|
+
last_request.POST["photos"].collect{|photo| photo[:type]}.should == ["text/plain", "image/jpeg"]
|
122
|
+
end
|
123
|
+
|
124
|
+
it "sends files with a Content-Length in the header" do
|
125
|
+
post "/", "photos" => [uploaded_file, second_uploaded_file]
|
126
|
+
last_request.POST["photos"].all?{|photo| photo[:head].should include("Content-Length: 4") }
|
127
|
+
end
|
128
|
+
|
129
|
+
it "sends both files as Tempfiles" do
|
130
|
+
post "/", "photos" => [uploaded_file, second_uploaded_file]
|
131
|
+
last_request.POST["photos"].all?{|photo| photo[:tempfile].should be_a(::Tempfile) }
|
132
|
+
end
|
133
|
+
end
|
87
134
|
end
|
@@ -33,6 +33,10 @@ describe Rack::Test::Utils do
|
|
33
33
|
build_nested_query(:a => [1, 2]).should == "a[]=1&a[]=2"
|
34
34
|
end
|
35
35
|
|
36
|
+
it "converts arrays with brackets '[]' in the name" do
|
37
|
+
build_nested_query("a[]" => [1, 2]).should == "a%5B%5D=1&a%5B%5D=2"
|
38
|
+
end
|
39
|
+
|
36
40
|
it "converts nested hashes" do
|
37
41
|
build_nested_query(:a => { :b => 1 }).should == "a[b]=1"
|
38
42
|
end
|
@@ -63,6 +67,26 @@ describe Rack::Test::Utils do
|
|
63
67
|
params["files"][:tempfile].read.should == "bar\n"
|
64
68
|
end
|
65
69
|
|
70
|
+
it "builds multipart bodies from array of files" do
|
71
|
+
files = [Rack::Test::UploadedFile.new(multipart_file("foo.txt")), Rack::Test::UploadedFile.new(multipart_file("bar.txt"))]
|
72
|
+
data = build_multipart("submit-name" => "Larry", "files" => files)
|
73
|
+
|
74
|
+
options = {
|
75
|
+
"CONTENT_TYPE" => "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}",
|
76
|
+
"CONTENT_LENGTH" => data.length.to_s,
|
77
|
+
:input => StringIO.new(data)
|
78
|
+
}
|
79
|
+
env = Rack::MockRequest.env_for("/", options)
|
80
|
+
params = Rack::Utils::Multipart.parse_multipart(env)
|
81
|
+
check params["submit-name"].should == "Larry"
|
82
|
+
|
83
|
+
check params["files"][0][:filename].should == "foo.txt"
|
84
|
+
params["files"][0][:tempfile].read.should == "bar\n"
|
85
|
+
|
86
|
+
check params["files"][1][:filename].should == "bar.txt"
|
87
|
+
params["files"][1][:tempfile].read.should == "baz\n"
|
88
|
+
end
|
89
|
+
|
66
90
|
it "builds nested multipart bodies" do
|
67
91
|
files = Rack::Test::UploadedFile.new(multipart_file("foo.txt"))
|
68
92
|
data = build_multipart("people" => [{"submit-name" => "Larry", "files" => files}])
|
data/spec/rack/test_spec.rb
CHANGED
@@ -212,6 +212,13 @@ describe Rack::Test::Session do
|
|
212
212
|
last_request.env["HTTP_USER_AGENT"].should == "Firefox"
|
213
213
|
end
|
214
214
|
|
215
|
+
it "sets a Content-Type to be sent with requests" do
|
216
|
+
header "Content-Type", "application/json"
|
217
|
+
request "/"
|
218
|
+
|
219
|
+
last_request.env["CONTENT_TYPE"].should == "application/json"
|
220
|
+
end
|
221
|
+
|
215
222
|
it "persists across multiple requests" do
|
216
223
|
header "User-Agent", "Firefox"
|
217
224
|
request "/"
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-test
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 3
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 4
|
10
|
+
version: 0.5.4
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Bryan Helmkamp
|
@@ -9,19 +15,24 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-05-26 00:00:00 -04:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: rack
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
23
33
|
version: "1.0"
|
24
|
-
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
25
36
|
description: |-
|
26
37
|
Rack::Test is a small, simple testing API for Rack apps. It can be used on its
|
27
38
|
own or as a reusable starting point for Web frameworks and testing libraries
|
@@ -51,6 +62,7 @@ files:
|
|
51
62
|
- lib/rack/test/uploaded_file.rb
|
52
63
|
- lib/rack/test/utils.rb
|
53
64
|
- rack-test.gemspec
|
65
|
+
- spec/fixtures/bar.txt
|
54
66
|
- spec/fixtures/config.ru
|
55
67
|
- spec/fixtures/fake_app.rb
|
56
68
|
- spec/fixtures/foo.txt
|
@@ -71,21 +83,27 @@ rdoc_options: []
|
|
71
83
|
require_paths:
|
72
84
|
- lib
|
73
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
74
87
|
requirements:
|
75
88
|
- - ">="
|
76
89
|
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
77
93
|
version: "0"
|
78
|
-
version:
|
79
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
80
96
|
requirements:
|
81
97
|
- - ">="
|
82
98
|
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
83
102
|
version: "0"
|
84
|
-
version:
|
85
103
|
requirements: []
|
86
104
|
|
87
105
|
rubyforge_project: rack-test
|
88
|
-
rubygems_version: 1.3.
|
106
|
+
rubygems_version: 1.3.7
|
89
107
|
signing_key:
|
90
108
|
specification_version: 3
|
91
109
|
summary: Simple testing API built on Rack
|