rack-test 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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