rack-test 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ History.txt
4
+ MIT-LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg
2
+ doc
3
+ coverage
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.4.1 / 2009-08-06
2
+
3
+ * Minor enhancements
4
+
5
+ * Support initializing a Rack::Test::Session with an app in addition to
6
+ a Rack::MockSession
7
+ * Allow CONTENT_TYPE to be specified in the env and not overwritten when
8
+ sending a POST or PUT
9
+
1
10
  == 0.4.0 / 2009-06-25
2
11
 
3
12
  * Minor enhancements
data/Rakefile CHANGED
@@ -1,9 +1,25 @@
1
1
  require "rubygems"
2
2
  require "rake/rdoctask"
3
- require "rake/gempackagetask"
4
- require "rake/clean"
5
3
  require "spec/rake/spectask"
6
- require File.expand_path("./lib/rack/test")
4
+
5
+ begin
6
+ require "jeweler"
7
+
8
+ Jeweler::Tasks.new do |s|
9
+ s.name = "rack-test"
10
+ s.author = "Bryan Helmkamp"
11
+ s.email = "bryan" + "@" + "brynary.com"
12
+ s.homepage = "http://github.com/brynary/rack-test"
13
+ s.summary = "Simple testing API built on Rack"
14
+ # s.description = "TODO"
15
+ s.rubyforge_project = "rack-test"
16
+ s.extra_rdoc_files = %w[README.rdoc MIT-LICENSE.txt]
17
+ end
18
+
19
+ Jeweler::RubyforgeTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler not available. Install it with: gem install jeweler"
22
+ end
7
23
 
8
24
  Spec::Rake::SpecTask.new do |t|
9
25
  t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
@@ -18,45 +34,18 @@ Spec::Rake::SpecTask.new(:rcov) do |t|
18
34
  end
19
35
  end
20
36
 
21
- desc "Run the specs"
22
- task :default => :spec
23
-
24
- spec = Gem::Specification.new do |s|
25
- s.name = "rack-test"
26
- s.version = Rack::Test::VERSION
27
- s.author = "Bryan Helmkamp"
28
- s.email = "bryan" + "@" + "brynary.com"
29
- s.homepage = "http://github.com/brynary/rack-test"
30
- s.summary = "Simple testing API built on Rack"
31
- s.description = s.summary
32
- s.files = %w[History.txt Rakefile README.rdoc] + Dir["lib/**/*"]
33
-
34
- # rdoc
35
- s.has_rdoc = true
36
- s.extra_rdoc_files = %w(README.rdoc MIT-LICENSE.txt)
37
- end
38
-
39
- Rake::GemPackageTask.new(spec) do |package|
40
- package.gem_spec = spec
41
- end
42
-
43
- desc "Delete generated RDoc"
44
- task :clobber_docs do
45
- FileUtils.rm_rf("doc")
46
- end
47
-
48
37
  desc "Generate RDoc"
49
- task :docs => :clobber_docs do
38
+ task :docs do
39
+ FileUtils.rm_rf("doc")
50
40
  system "hanna --title 'Rack::Test #{Rack::Test::VERSION} API Documentation'"
51
41
  end
52
42
 
53
- desc 'Install the package as a gem.'
54
- task :install => [:clean, :package] do
55
- gem = Dir['pkg/*.gem'].first
56
- sh "sudo gem install --no-rdoc --no-ri --local #{gem}"
57
- end
58
-
59
43
  desc 'Removes trailing whitespace'
60
44
  task :whitespace do
61
45
  sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;}
62
46
  end
47
+
48
+ task :spec => :check_dependencies
49
+
50
+ desc "Run the specs"
51
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.4.1
data/lib/rack/test.rb CHANGED
@@ -13,8 +13,7 @@ require "rack/test/uploaded_file"
13
13
 
14
14
  module Rack
15
15
  module Test
16
-
17
- VERSION = "0.4.0"
16
+ VERSION = ::File.read(::File.join(::File.dirname(__FILE__), "..", "..", "VERSION")).strip
18
17
 
19
18
  DEFAULT_HOST = "example.org"
20
19
  MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
@@ -31,8 +30,14 @@ module Rack
31
30
  # Initialize a new session for the given Rack app
32
31
  def initialize(mock_session)
33
32
  @headers = {}
34
- @rack_mock_session = mock_session
35
- @default_host = mock_session.default_host
33
+
34
+ if mock_session.is_a?(MockSession)
35
+ @rack_mock_session = mock_session
36
+ else
37
+ @rack_mock_session = MockSession.new(mock_session)
38
+ end
39
+
40
+ @default_host = @rack_mock_session.default_host
36
41
  end
37
42
 
38
43
  # Issue a GET request for the given URI with the given params and Rack
@@ -149,7 +154,7 @@ module Rack
149
154
 
150
155
  if (env[:method] == "POST" || env["REQUEST_METHOD"] == "POST" ||
151
156
  env[:method] == "PUT" || env["REQUEST_METHOD"] == "PUT") && !env.has_key?(:input)
152
- env["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
157
+ env["CONTENT_TYPE"] ||= "application/x-www-form-urlencoded"
153
158
 
154
159
  multipart = (Hash === env[:params]) &&
155
160
  env[:params].any? { |_, v| UploadedFile === v }
data/rack-test.gemspec ADDED
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rack-test}
8
+ s.version = "0.4.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Bryan Helmkamp"]
12
+ s.date = %q{2009-08-06}
13
+ s.email = %q{bryan@brynary.com}
14
+ s.extra_rdoc_files = [
15
+ "MIT-LICENSE.txt",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".gitignore",
21
+ "History.txt",
22
+ "MIT-LICENSE.txt",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/rack/mock_session.rb",
27
+ "lib/rack/test.rb",
28
+ "lib/rack/test/cookie_jar.rb",
29
+ "lib/rack/test/methods.rb",
30
+ "lib/rack/test/mock_digest_request.rb",
31
+ "lib/rack/test/uploaded_file.rb",
32
+ "lib/rack/test/utils.rb",
33
+ "rack-test.gemspec",
34
+ "spec/fixtures/config.ru",
35
+ "spec/fixtures/fake_app.rb",
36
+ "spec/fixtures/foo.txt",
37
+ "spec/rack/test/cookie_spec.rb",
38
+ "spec/rack/test/digest_auth_spec.rb",
39
+ "spec/rack/test/multipart_spec.rb",
40
+ "spec/rack/test/utils_spec.rb",
41
+ "spec/rack/test_spec.rb",
42
+ "spec/rcov.opts",
43
+ "spec/spec.opts",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+ s.homepage = %q{http://github.com/brynary/rack-test}
47
+ s.rdoc_options = ["--charset=UTF-8"]
48
+ s.require_paths = ["lib"]
49
+ s.rubyforge_project = %q{rack-test}
50
+ s.rubygems_version = %q{1.3.4}
51
+ s.summary = %q{Simple testing API built on Rack}
52
+ s.test_files = [
53
+ "spec/fixtures/fake_app.rb",
54
+ "spec/rack/test/cookie_spec.rb",
55
+ "spec/rack/test/digest_auth_spec.rb",
56
+ "spec/rack/test/multipart_spec.rb",
57
+ "spec/rack/test/utils_spec.rb",
58
+ "spec/rack/test_spec.rb",
59
+ "spec/spec_helper.rb"
60
+ ]
61
+
62
+ if s.respond_to? :specification_version then
63
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
64
+ s.specification_version = 3
65
+
66
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
67
+ else
68
+ end
69
+ else
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ require "fake_app"
2
+
3
+ run Rack::Test::FakeApp
@@ -0,0 +1,109 @@
1
+ require "sinatra/base"
2
+
3
+ module Rack
4
+ module Test
5
+
6
+ class FakeApp < Sinatra::Default
7
+ head "/" do
8
+ "meh"
9
+ end
10
+
11
+ get "/" do
12
+ "Hello, GET: #{params.inspect}"
13
+ end
14
+
15
+ get "/redirect" do
16
+ redirect "/redirected"
17
+ end
18
+
19
+ get "/redirected" do
20
+ "You've been redirected"
21
+ end
22
+
23
+ get "/void" do
24
+ [200, {}, ""]
25
+ end
26
+
27
+ get "/cookies/show" do
28
+ request.cookies.inspect
29
+ end
30
+
31
+ get "/COOKIES/show" do
32
+ request.cookies.inspect
33
+ end
34
+
35
+ get "/not-cookies/show" do
36
+ request.cookies.inspect
37
+ end
38
+
39
+ get "/cookies/set-secure" do
40
+ raise if params["value"].nil?
41
+
42
+ response.set_cookie("secure-cookie", :value => params["value"], :secure => true)
43
+ "Set"
44
+ end
45
+
46
+ get "/cookies/set-simple" do
47
+ raise if params["value"].nil?
48
+
49
+ response.set_cookie "simple", params["value"]
50
+ "Set"
51
+ end
52
+
53
+ get "/cookies/delete" do
54
+ response.delete_cookie "value"
55
+ end
56
+
57
+ get "/cookies/count" do
58
+ old_value = request.cookies["count"].to_i || 0
59
+ new_value = (old_value + 1).to_s
60
+
61
+ response.set_cookie("count", :value => new_value)
62
+ new_value
63
+ end
64
+
65
+ get "/cookies/set" do
66
+ raise if params["value"].nil?
67
+
68
+ response.set_cookie("value", {
69
+ :value => params["value"],
70
+ :path => "/cookies",
71
+ :expires => Time.now + 10
72
+ })
73
+ "Set"
74
+ end
75
+
76
+ get "/cookies/domain" do
77
+ old_value = request.cookies["count"].to_i || 0
78
+ new_value = (old_value + 1).to_s
79
+
80
+ response.set_cookie("count", :value => new_value, :domain => "localhost.com")
81
+ new_value
82
+ end
83
+
84
+ get "/cookies/set-uppercase" do
85
+ raise if params["value"].nil?
86
+
87
+ response.set_cookie("VALUE", {
88
+ :value => params["value"],
89
+ :path => "/cookies",
90
+ :expires => Time.now + 10
91
+ })
92
+ "Set"
93
+ end
94
+
95
+ post "/" do
96
+ "Hello, POST: #{params.inspect}"
97
+ end
98
+
99
+ put "/" do
100
+ "Hello, PUT: #{params.inspect}"
101
+ end
102
+
103
+ delete "/" do
104
+ "Hello, DELETE: #{params.inspect}"
105
+ end
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1 @@
1
+ bar
@@ -0,0 +1,176 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+ def have_body(string)
5
+ simple_matcher "have body #{string.inspect}" do |response|
6
+ response.body.should == string
7
+ end
8
+ end
9
+
10
+ context "cookies" do
11
+ it "keeps a cookie jar" do
12
+ get "/cookies/show"
13
+ last_request.cookies.should == {}
14
+
15
+ get "/cookies/set", "value" => "1"
16
+ get "/cookies/show"
17
+ last_request.cookies.should == { "value" => "1" }
18
+ end
19
+
20
+ it "doesn't send expired cookies" do
21
+ get "/cookies/set", "value" => "1"
22
+ now = Time.now
23
+ Time.stub!(:now => now + 60)
24
+ get "/cookies/show"
25
+ last_request.cookies.should == {}
26
+ end
27
+
28
+ it "doesn't send cookies with the wrong domain" do
29
+ get "http://www.example.com/cookies/set", "value" => "1"
30
+ get "http://www.other.example/cookies/show"
31
+ last_request.cookies.should == {}
32
+ end
33
+
34
+ it "doesn't send cookies with the wrong path" do
35
+ get "/cookies/set", "value" => "1"
36
+ get "/not-cookies/show"
37
+ last_request.cookies.should == {}
38
+ end
39
+
40
+ it "persists cookies across requests that don't return any cookie headers" do
41
+ get "/cookies/set", "value" => "1"
42
+ get "/void"
43
+ get "/cookies/show"
44
+ last_request.cookies.should == { "value" => "1" }
45
+ end
46
+
47
+ it "deletes cookies" do
48
+ get "/cookies/set", "value" => "1"
49
+ get "/cookies/delete"
50
+ get "/cookies/show"
51
+ last_request.cookies.should == { }
52
+ end
53
+
54
+ xit "respects cookie domains when no domain is explicitly set" do
55
+ request("http://example.org/cookies/count").should have_body("1")
56
+ request("http://www.example.org/cookies/count").should have_body("1")
57
+ request("http://example.org/cookies/count").should have_body("2")
58
+ request("http://www.example.org/cookies/count").should have_body("2")
59
+ end
60
+
61
+ it "treats domains case insensitively" do
62
+ get "http://example.com/cookies/set", "value" => "1"
63
+ get "http://EXAMPLE.COM/cookies/show"
64
+ last_request.cookies.should == { "value" => "1" }
65
+ end
66
+
67
+ it "treats paths case sensitively" do
68
+ get "/cookies/set", "value" => "1"
69
+ get "/COOKIES/show"
70
+ last_request.cookies.should == {}
71
+ end
72
+
73
+ it "prefers more specific cookies" do
74
+ get "http://example.com/cookies/set", "value" => "domain"
75
+ get "http://sub.example.com/cookies/set", "value" => "sub"
76
+
77
+ get "http://sub.example.com/cookies/show"
78
+ last_request.cookies.should == { "value" => "sub" }
79
+
80
+ get "http://example.com/cookies/show"
81
+ last_request.cookies.should == { "value" => "domain" }
82
+ end
83
+
84
+ it "treats cookie names case insensitively" do
85
+ get "/cookies/set", "value" => "lowercase"
86
+ get "/cookies/set-uppercase", "value" => "UPPERCASE"
87
+ get "/cookies/show"
88
+ last_request.cookies.should == { "VALUE" => "UPPERCASE" }
89
+ end
90
+
91
+ it "defaults the domain to the request domain" do
92
+ get "http://example.com/cookies/set-simple", "value" => "cookie"
93
+ get "http://example.com/cookies/show"
94
+ last_request.cookies.should == { "simple" => "cookie" }
95
+
96
+ get "http://other.example/cookies/show"
97
+ last_request.cookies.should == {}
98
+ end
99
+
100
+ it "defaults the domain to the request path up to the last slash" do
101
+ get "/cookies/set-simple", "value" => "1"
102
+ get "/not-cookies/show"
103
+ last_request.cookies.should == {}
104
+ end
105
+
106
+ it "supports secure cookies" do
107
+ get "https://example.com/cookies/set-secure", "value" => "set"
108
+ get "http://example.com/cookies/show"
109
+ last_request.cookies.should == {}
110
+
111
+ get "https://example.com/cookies/show"
112
+ last_request.cookies.should == { "secure-cookie" => "set" }
113
+ end
114
+
115
+ it "keeps separate cookie jars for different domains" do
116
+ get "http://example.com/cookies/set", "value" => "example"
117
+ get "http://example.com/cookies/show"
118
+ last_request.cookies.should == { "value" => "example" }
119
+
120
+ get "http://other.example/cookies/set", "value" => "other"
121
+ get "http://other.example/cookies/show"
122
+ last_request.cookies.should == { "value" => "other" }
123
+
124
+ get "http://example.com/cookies/show"
125
+ last_request.cookies.should == { "value" => "example" }
126
+ end
127
+
128
+ it "allows cookies to be cleared" do
129
+ get "/cookies/set", "value" => "1"
130
+ clear_cookies
131
+ get "/cookies/show"
132
+ last_request.cookies.should == {}
133
+ end
134
+
135
+ it "allow cookies to be set" do
136
+ set_cookie "value=10"
137
+ get "/cookies/show"
138
+ last_request.cookies.should == { "value" => "10" }
139
+ end
140
+
141
+ it "allows an array of cookies to be set" do
142
+ set_cookie ["value=10", "foo=bar"]
143
+ get "/cookies/show"
144
+ last_request.cookies.should == { "value" => "10", "foo" => "bar" }
145
+ end
146
+
147
+ it "supports multiple sessions" do
148
+ with_session(:first) do
149
+ get "/cookies/set", "value" => "1"
150
+ get "/cookies/show"
151
+ last_request.cookies.should == { "value" => "1" }
152
+ end
153
+
154
+ with_session(:second) do
155
+ get "/cookies/show"
156
+ last_request.cookies.should == { }
157
+ end
158
+ end
159
+
160
+ it "uses :default as the default session name" do
161
+ get "/cookies/set", "value" => "1"
162
+ get "/cookies/show"
163
+ last_request.cookies.should == { "value" => "1" }
164
+
165
+ with_session(:default) do
166
+ get "/cookies/show"
167
+ last_request.cookies.should == { "value" => "1" }
168
+ end
169
+ end
170
+
171
+ it "accepts explicitly provided cookies" do
172
+ request "/cookies/show", :cookie => "value=1"
173
+ last_request.cookies.should == { "value" => "1" }
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+ context "HTTP Digest authentication" do
5
+
6
+ def app
7
+ app = Rack::Auth::Digest::MD5.new(Rack::Test::FakeApp.new) do |username|
8
+ { 'alice' => 'correct-password' }[username]
9
+ end
10
+ app.realm = 'WallysWorld'
11
+ app.opaque = 'this-should-be-secret'
12
+ app
13
+ end
14
+
15
+ def be_challenge
16
+ simple_matcher "a HTTP Digest challenge response" do |response|
17
+ response.status == 401 &&
18
+ response['WWW-Authenticate'] =~ /^Digest / &&
19
+ response.body.empty?
20
+ end
21
+ end
22
+
23
+ it 'incorrectly authenticates GETs' do
24
+ digest_authorize 'foo', 'bar'
25
+ get '/'
26
+ last_response.should be_challenge
27
+ end
28
+
29
+ it "correctly authenticates GETs" do
30
+ digest_authorize "alice", "correct-password"
31
+ response = get "/"
32
+ response.should be_ok
33
+ end
34
+
35
+ it "correctly authenticates POSTs" do
36
+ digest_authorize "alice", "correct-password"
37
+ response = post "/"
38
+ response.should be_ok
39
+ end
40
+
41
+ it "returns a re-challenge if authenticating incorrectly" do
42
+ digest_authorize "alice", "incorrect-password"
43
+ response = get "/"
44
+ response.should be_challenge
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+
5
+ def test_file_path
6
+ File.dirname(__FILE__) + "/../../fixtures/foo.txt"
7
+ end
8
+
9
+ def uploaded_file
10
+ Rack::Test::UploadedFile.new(test_file_path)
11
+ end
12
+
13
+ context "uploading a file" do
14
+ it "sends the multipart/form-data content type" do
15
+ post "/", "photo" => uploaded_file
16
+ last_request.env["CONTENT_TYPE"].should include("multipart/form-data;")
17
+ end
18
+
19
+ it "sends regular params" do
20
+ post "/", "photo" => uploaded_file, "foo" => "bar"
21
+ last_request.POST["foo"].should == "bar"
22
+ end
23
+
24
+ it "sends nested params" do
25
+ post "/", "photo" => uploaded_file, "foo" => {"bar" => "baz"}
26
+ last_request.POST["foo"]["bar"].should == "baz"
27
+ end
28
+
29
+ it "sends multiple nested params" do
30
+ post "/", "photo" => uploaded_file, "foo" => {"bar" => {"baz" => "bop"}}
31
+ last_request.POST["foo"]["bar"]["baz"].should == "bop"
32
+ end
33
+
34
+ xit "sends params with arrays" do
35
+ post "/", "photo" => uploaded_file, "foo" => ["1", "2"]
36
+ last_request.POST["foo[]"].should == ["1", "2"]
37
+ end
38
+
39
+ it "sends params with encoding sensitive values" do
40
+ post "/", "photo" => uploaded_file, "foo" => "bar? baz"
41
+ last_request.POST["foo"].should == "bar? baz"
42
+ end
43
+
44
+ it "sends params with parens in names" do
45
+ post "/", "photo" => uploaded_file, "foo(1i)" => "bar"
46
+ last_request.POST["foo(1i)"].should == "bar"
47
+ end
48
+
49
+ it "sends params with encoding sensitive names" do
50
+ post "/", "photo" => uploaded_file, "foo bar" => "baz"
51
+ last_request.POST["foo bar"].should == "baz"
52
+ end
53
+
54
+ it "sends files with the filename" do
55
+ post "/", "photo" => uploaded_file
56
+ last_request.POST["photo"][:filename].should == "foo.txt"
57
+ end
58
+
59
+ it "sends files with the text/plain MIME type by default" do
60
+ post "/", "photo" => uploaded_file
61
+ last_request.POST["photo"][:type].should == "text/plain"
62
+ end
63
+
64
+ it "sends files with the right name" do
65
+ post "/", "photo" => uploaded_file
66
+ last_request.POST["photo"][:name].should == "photo"
67
+ end
68
+
69
+ it "allows overriding the content type" do
70
+ post "/", "photo" => Rack::Test::UploadedFile.new(test_file_path, "image/jpeg")
71
+ last_request.POST["photo"][:type].should == "image/jpeg"
72
+ end
73
+
74
+ it "sends files with a Content-Length in the header" do
75
+ post "/", "photo" => uploaded_file
76
+ last_request.POST["photo"][:head].should include("Content-Length: 4")
77
+ end
78
+
79
+ it "sends files as Tempfiles" do
80
+ post "/", "photo" => uploaded_file
81
+ last_request.POST["photo"][:tempfile].should be_a(::Tempfile)
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe Rack::Test::Utils do
4
+ include Rack::Test::Utils
5
+
6
+ describe "requestify" do
7
+ it "converts empty strings to =" do
8
+ requestify("").should == "="
9
+ end
10
+
11
+ it "converts nil to =" do
12
+ requestify(nil).should == "="
13
+ end
14
+
15
+ it "converts hashes" do
16
+ requestify(:a => 1).should == "a=1"
17
+ end
18
+
19
+ it "converts hashes with multiple keys" do
20
+ hash = { :a => 1, :b => 2 }
21
+ ["a=1&b=2", "b=2&a=1"].should include(requestify(hash))
22
+ end
23
+
24
+ it "converts arrays with one element" do
25
+ requestify(:a => [1]).should == "a[]=1"
26
+ end
27
+
28
+ it "converts arrays with multiple elements" do
29
+ requestify(:a => [1, 2]).should == "a[]=1&a[]=2"
30
+ end
31
+
32
+ it "converts nested hashes" do
33
+ requestify(:a => { :b => 1 }).should == "a[b]=1"
34
+ end
35
+
36
+ it "converts arrays nested in a hash" do
37
+ requestify(:a => { :b => [1, 2] }).should == "a[b][]=1&a[b][]=2"
38
+ end
39
+
40
+ it "converts arrays of hashes" do
41
+ requestify(:a => [{ :b => 2}, { :c => 3}]).should == "a[][b]=2&a[][c]=3"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,363 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+ describe "initialization" do
5
+ it "supports being initialized with a Rack::MockSession app" do
6
+ session = Rack::Test::Session.new(Rack::MockSession.new(app))
7
+ session.request("/").should be_ok
8
+ end
9
+
10
+ it "supports being initialized with an app" do
11
+ session = Rack::Test::Session.new(app)
12
+ session.request("/").should be_ok
13
+ end
14
+ end
15
+
16
+ describe "#request" do
17
+ it "requests the URI using GET by default" do
18
+ request "/"
19
+ last_request.should be_get
20
+ last_response.should be_ok
21
+ end
22
+
23
+ it "returns a response" do
24
+ request("/").should be_ok
25
+ end
26
+
27
+ it "uses the provided env" do
28
+ request "/", "X-Foo" => "bar"
29
+ last_request.env["X-Foo"].should == "bar"
30
+ end
31
+
32
+ it "defaults to GET" do
33
+ request "/"
34
+ last_request.env["REQUEST_METHOD"].should == "GET"
35
+ end
36
+
37
+ it "defaults the REMOTE_ADDR to 127.0.0.1" do
38
+ request "/"
39
+ last_request.env["REMOTE_ADDR"].should == "127.0.0.1"
40
+ end
41
+
42
+ it "sets rack.test to true in the env" do
43
+ request "/"
44
+ last_request.env["rack.test"].should == true
45
+ end
46
+
47
+ it "defaults to port 80" do
48
+ request "/"
49
+ last_request.env["SERVER_PORT"].should == "80"
50
+ end
51
+
52
+ it "defaults to example.org" do
53
+ request "/"
54
+ last_request.env["SERVER_NAME"].should == "example.org"
55
+ end
56
+
57
+ it "yields the response to a given block" do
58
+ request "/" do |response|
59
+ response.should be_ok
60
+ end
61
+ end
62
+
63
+ it "supports sending :params" do
64
+ request "/", :params => { "foo" => "bar" }
65
+ last_request.GET["foo"].should == "bar"
66
+ end
67
+
68
+ it "doesn't follow redirects by default" do
69
+ request "/redirect"
70
+ last_response.should be_redirect
71
+ last_response.body.should be_empty
72
+ end
73
+
74
+ context "when input is given" do
75
+ it "should send the input" do
76
+ request "/", :method => "POST", :input => "foo"
77
+ last_request.env["rack.input"].read.should == "foo"
78
+ end
79
+
80
+ it "should not send a multipart request" do
81
+ request "/", :method => "POST", :input => "foo"
82
+ last_request.env["CONTENT_TYPE"].should_not == "application/x-www-form-urlencoded"
83
+ end
84
+ end
85
+
86
+ context "for a POST specified with :method" do
87
+ it "uses application/x-www-form-urlencoded as the CONTENT_TYPE" do
88
+ request "/", :method => "POST"
89
+ last_request.env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded"
90
+ end
91
+ end
92
+
93
+ context "for a POST specified with REQUEST_METHOD" do
94
+ it "uses application/x-www-form-urlencoded as the CONTENT_TYPE" do
95
+ request "/", "REQUEST_METHOD" => "POST"
96
+ last_request.env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded"
97
+ end
98
+ end
99
+
100
+ context "when CONTENT_TYPE is specified in the env" do
101
+ it "does not overwrite the CONTENT_TYPE" do
102
+ request "/", "CONTENT_TYPE" => "application/xml"
103
+ last_request.env["CONTENT_TYPE"].should == "application/xml"
104
+ end
105
+ end
106
+
107
+ context "when the URL is https://" do
108
+ it "sets SERVER_PORT to 443" do
109
+ get "https://example.org/"
110
+ last_request.env["SERVER_PORT"].should == "443"
111
+ end
112
+
113
+ it "sets HTTPS to on" do
114
+ get "https://example.org/"
115
+ last_request.env["HTTPS"].should == "on"
116
+ end
117
+ end
118
+
119
+ context "for a XHR" do
120
+ it "sends XMLHttpRequest for the X-Requested-With header" do
121
+ request "/", :xhr => true
122
+ last_request.env["X-Requested-With"].should == "XMLHttpRequest"
123
+ end
124
+ end
125
+ end
126
+
127
+ describe "#header" do
128
+ it "sets a header to be sent with requests" do
129
+ header "User-Agent", "Firefox"
130
+ request "/"
131
+
132
+ last_request.env["User-Agent"].should == "Firefox"
133
+ end
134
+
135
+ it "persists across multiple requests" do
136
+ header "User-Agent", "Firefox"
137
+ request "/"
138
+ request "/"
139
+
140
+ last_request.env["User-Agent"].should == "Firefox"
141
+ end
142
+
143
+ it "overwrites previously set headers" do
144
+ header "User-Agent", "Firefox"
145
+ header "User-Agent", "Safari"
146
+ request "/"
147
+
148
+ last_request.env["User-Agent"].should == "Safari"
149
+ end
150
+
151
+ it "can be used to clear a header" do
152
+ header "User-Agent", "Firefox"
153
+ header "User-Agent", nil
154
+ request "/"
155
+
156
+ last_request.env.should_not have_key("User-Agent")
157
+ end
158
+
159
+ it "is overridden by headers sent during the request" do
160
+ header "User-Agent", "Firefox"
161
+ request "/", "User-Agent" => "Safari"
162
+
163
+ last_request.env["User-Agent"].should == "Safari"
164
+ end
165
+ end
166
+
167
+ describe "#authorize" do
168
+ it "sets the HTTP_AUTHORIZATION header" do
169
+ authorize "bryan", "secret"
170
+ request "/"
171
+
172
+ last_request.env["HTTP_AUTHORIZATION"].should == "Basic YnJ5YW46c2VjcmV0\n"
173
+ end
174
+
175
+ it "includes the header for subsequent requests" do
176
+ basic_authorize "bryan", "secret"
177
+ request "/"
178
+ request "/"
179
+
180
+ last_request.env["HTTP_AUTHORIZATION"].should == "Basic YnJ5YW46c2VjcmV0\n"
181
+ end
182
+ end
183
+
184
+ describe "follow_redirect!" do
185
+ it "follows redirects" do
186
+ get "/redirect"
187
+ follow_redirect!
188
+
189
+ last_response.should_not be_redirect
190
+ last_response.body.should == "You've been redirected"
191
+ end
192
+
193
+ it "does not include params when following the redirect" do
194
+ get "/redirect", { "foo" => "bar" }
195
+ follow_redirect!
196
+
197
+ last_request.GET.should == {}
198
+ end
199
+
200
+ it "raises an error if the last_response is not set" do
201
+ lambda {
202
+ follow_redirect!
203
+ }.should raise_error(Rack::Test::Error)
204
+ end
205
+
206
+ it "raises an error if the last_response is not a redirect" do
207
+ get "/"
208
+
209
+ lambda {
210
+ follow_redirect!
211
+ }.should raise_error(Rack::Test::Error)
212
+ end
213
+ end
214
+
215
+ describe "#last_request" do
216
+ it "returns the most recent request" do
217
+ request "/"
218
+ last_request.env["PATH_INFO"].should == "/"
219
+ end
220
+
221
+ it "raises an error if no requests have been issued" do
222
+ lambda {
223
+ last_request
224
+ }.should raise_error(Rack::Test::Error)
225
+ end
226
+ end
227
+
228
+ describe "#last_response" do
229
+ it "returns the most recent response" do
230
+ request "/"
231
+ last_response["Content-Type"].should == "text/html"
232
+ end
233
+
234
+ it "raises an error if no requests have been issued" do
235
+ lambda {
236
+ last_response
237
+ }.should raise_error
238
+ end
239
+ end
240
+
241
+ describe "after_request" do
242
+ it "runs callbacks after each request" do
243
+ ran = false
244
+
245
+ rack_mock_session.after_request do
246
+ ran = true
247
+ end
248
+
249
+ get "/"
250
+ ran.should == true
251
+ end
252
+
253
+ it "runs multiple callbacks" do
254
+ count = 0
255
+
256
+ 2.times do
257
+ rack_mock_session.after_request do
258
+ count += 1
259
+ end
260
+ end
261
+
262
+ get "/"
263
+ count.should == 2
264
+ end
265
+ end
266
+
267
+ describe "#get" do
268
+ it_should_behave_like "any #verb methods"
269
+
270
+ def verb
271
+ "get"
272
+ end
273
+
274
+ it "uses the provided params hash" do
275
+ get "/", :foo => "bar"
276
+ last_request.GET.should == { "foo" => "bar" }
277
+ end
278
+
279
+ it "sends params with parens in names" do
280
+ get "/", "foo(1i)" => "bar"
281
+ last_request.GET["foo(1i)"].should == "bar"
282
+ end
283
+
284
+ it "supports params with encoding sensitive names" do
285
+ get "/", "foo bar" => "baz"
286
+ last_request.GET["foo bar"].should == "baz"
287
+ end
288
+
289
+ it "supports params with nested encoding sensitive names" do
290
+ get "/", "boo" => {"foo bar" => "baz"}
291
+ last_request.GET.should == {"boo" => {"foo bar" => "baz"}}
292
+ end
293
+
294
+ it "accepts params in the path" do
295
+ get "/?foo=bar"
296
+ last_request.GET.should == { "foo" => "bar" }
297
+ end
298
+ end
299
+
300
+ describe "#head" do
301
+ it_should_behave_like "any #verb methods"
302
+
303
+ def verb
304
+ "head"
305
+ end
306
+ end
307
+
308
+ describe "#post" do
309
+ it_should_behave_like "any #verb methods"
310
+
311
+ def verb
312
+ "post"
313
+ end
314
+
315
+ it "uses the provided params hash" do
316
+ post "/", :foo => "bar"
317
+ last_request.POST.should == { "foo" => "bar" }
318
+ end
319
+
320
+ it "supports params with encoding sensitive names" do
321
+ post "/", "foo bar" => "baz"
322
+ last_request.POST["foo bar"].should == "baz"
323
+ end
324
+
325
+ it "uses application/x-www-form-urlencoded as the CONTENT_TYPE" do
326
+ post "/"
327
+ last_request.env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded"
328
+ end
329
+
330
+ it "accepts a body" do
331
+ post "/", "Lobsterlicious!"
332
+ last_request.body.read.should == "Lobsterlicious!"
333
+ end
334
+
335
+ context "when CONTENT_TYPE is specified in the env" do
336
+ it "does not overwrite the CONTENT_TYPE" do
337
+ post "/", {}, { "CONTENT_TYPE" => "application/xml" }
338
+ last_request.env["CONTENT_TYPE"].should == "application/xml"
339
+ end
340
+ end
341
+ end
342
+
343
+ describe "#put" do
344
+ it_should_behave_like "any #verb methods"
345
+
346
+ def verb
347
+ "put"
348
+ end
349
+
350
+ it "accepts a body" do
351
+ put "/", "Lobsterlicious!"
352
+ last_request.body.read.should == "Lobsterlicious!"
353
+ end
354
+ end
355
+
356
+ describe "#delete" do
357
+ it_should_behave_like "any #verb methods"
358
+
359
+ def verb
360
+ "delete"
361
+ end
362
+ end
363
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1 @@
1
+ -x gems,spec
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,48 @@
1
+ require "rubygems"
2
+ require "spec"
3
+
4
+ gem "rack", "~> 1.0.0"
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/rack/test")
7
+ require File.dirname(__FILE__) + "/fixtures/fake_app"
8
+
9
+ Spec::Runner.configure do |config|
10
+ config.include Rack::Test::Methods
11
+
12
+ def app
13
+ Rack::Lint.new(Rack::Test::FakeApp.new)
14
+ end
15
+
16
+ end
17
+
18
+ describe "any #verb methods", :shared => true do
19
+ it "requests the URL using VERB" do
20
+ send(verb, "/")
21
+
22
+ last_request.env["REQUEST_METHOD"].should == verb.upcase
23
+ last_response.should be_ok
24
+ end
25
+
26
+ it "uses the provided env" do
27
+ send(verb, "/", {}, { "User-Agent" => "Rack::Test" })
28
+ last_request.env["User-Agent"].should == "Rack::Test"
29
+ end
30
+
31
+ it "yields the response to a given block" do
32
+ yielded = false
33
+
34
+ send(verb, "/") do |response|
35
+ response.should be_ok
36
+ yielded = true
37
+ end
38
+
39
+ yielded.should be_true
40
+ end
41
+
42
+ context "for a XHR" do
43
+ it "sends XMLHttpRequest for the X-Requested-With header" do
44
+ send(verb, "/", {}, { :xhr => true })
45
+ last_request.env["X-Requested-With"].should == "XMLHttpRequest"
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Helmkamp
@@ -9,38 +9,53 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-25 00:00:00 -04:00
12
+ date: 2009-08-06 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: Simple testing API built on Rack
16
+ description:
17
17
  email: bryan@brynary.com
18
18
  executables: []
19
19
 
20
20
  extensions: []
21
21
 
22
22
  extra_rdoc_files:
23
- - README.rdoc
24
23
  - MIT-LICENSE.txt
24
+ - README.rdoc
25
25
  files:
26
+ - .document
27
+ - .gitignore
26
28
  - History.txt
27
- - Rakefile
29
+ - MIT-LICENSE.txt
28
30
  - README.rdoc
31
+ - Rakefile
32
+ - VERSION
29
33
  - lib/rack/mock_session.rb
34
+ - lib/rack/test.rb
30
35
  - lib/rack/test/cookie_jar.rb
31
36
  - lib/rack/test/methods.rb
32
37
  - lib/rack/test/mock_digest_request.rb
33
38
  - lib/rack/test/uploaded_file.rb
34
39
  - lib/rack/test/utils.rb
35
- - lib/rack/test.rb
36
- - MIT-LICENSE.txt
40
+ - rack-test.gemspec
41
+ - spec/fixtures/config.ru
42
+ - spec/fixtures/fake_app.rb
43
+ - spec/fixtures/foo.txt
44
+ - spec/rack/test/cookie_spec.rb
45
+ - spec/rack/test/digest_auth_spec.rb
46
+ - spec/rack/test/multipart_spec.rb
47
+ - spec/rack/test/utils_spec.rb
48
+ - spec/rack/test_spec.rb
49
+ - spec/rcov.opts
50
+ - spec/spec.opts
51
+ - spec/spec_helper.rb
37
52
  has_rdoc: true
38
53
  homepage: http://github.com/brynary/rack-test
39
54
  licenses: []
40
55
 
41
56
  post_install_message:
42
- rdoc_options: []
43
-
57
+ rdoc_options:
58
+ - --charset=UTF-8
44
59
  require_paths:
45
60
  - lib
46
61
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -57,10 +72,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
72
  version:
58
73
  requirements: []
59
74
 
60
- rubyforge_project:
75
+ rubyforge_project: rack-test
61
76
  rubygems_version: 1.3.4
62
77
  signing_key:
63
78
  specification_version: 3
64
79
  summary: Simple testing API built on Rack
65
- test_files: []
66
-
80
+ test_files:
81
+ - spec/fixtures/fake_app.rb
82
+ - spec/rack/test/cookie_spec.rb
83
+ - spec/rack/test/digest_auth_spec.rb
84
+ - spec/rack/test/multipart_spec.rb
85
+ - spec/rack/test/utils_spec.rb
86
+ - spec/rack/test_spec.rb
87
+ - spec/spec_helper.rb