tdreyno-middleman 0.2.1 → 0.2.4

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.
Files changed (58) hide show
  1. data/Rakefile +1 -0
  2. data/VERSION +1 -1
  3. data/bin/mm-build +2 -2
  4. data/lib/middleman.rb +16 -15
  5. data/middleman.gemspec +54 -2
  6. data/vendor/rack-test/History.txt +64 -0
  7. data/vendor/rack-test/MIT-LICENSE.txt +19 -0
  8. data/vendor/rack-test/README.rdoc +57 -0
  9. data/vendor/rack-test/Rakefile +62 -0
  10. data/vendor/rack-test/lib/rack/mock_session.rb +57 -0
  11. data/vendor/rack-test/lib/rack/test.rb +246 -0
  12. data/vendor/rack-test/lib/rack/test/cookie_jar.rb +169 -0
  13. data/vendor/rack-test/lib/rack/test/methods.rb +73 -0
  14. data/vendor/rack-test/lib/rack/test/mock_digest_request.rb +27 -0
  15. data/vendor/rack-test/lib/rack/test/uploaded_file.rb +36 -0
  16. data/vendor/rack-test/lib/rack/test/utils.rb +75 -0
  17. data/vendor/rack-test/spec/fixtures/config.ru +3 -0
  18. data/vendor/rack-test/spec/fixtures/fake_app.rb +109 -0
  19. data/vendor/rack-test/spec/fixtures/foo.txt +1 -0
  20. data/vendor/rack-test/spec/rack/test/cookie_spec.rb +176 -0
  21. data/vendor/rack-test/spec/rack/test/digest_auth_spec.rb +48 -0
  22. data/vendor/rack-test/spec/rack/test/multipart_spec.rb +85 -0
  23. data/vendor/rack-test/spec/rack/test/utils_spec.rb +44 -0
  24. data/vendor/rack-test/spec/rack/test_spec.rb +363 -0
  25. data/vendor/rack-test/spec/rcov.opts +1 -0
  26. data/vendor/rack-test/spec/spec.opts +1 -0
  27. data/vendor/rack-test/spec/spec_helper.rb +48 -0
  28. data/vendor/sinatra-markaby/CHANGES +7 -0
  29. data/vendor/sinatra-markaby/LICENSE +20 -0
  30. data/vendor/sinatra-markaby/README.rdoc +33 -0
  31. data/vendor/sinatra-markaby/Rakefile +45 -0
  32. data/vendor/sinatra-markaby/TODO +3 -0
  33. data/vendor/sinatra-markaby/VERSION.yml +4 -0
  34. data/vendor/sinatra-markaby/lib/sinatra/markaby.rb +31 -0
  35. data/vendor/sinatra-markaby/sinatra-markaby.gemspec +49 -0
  36. data/vendor/sinatra-markaby/test/sinatra_markaby_test.rb +72 -0
  37. data/vendor/sinatra-markaby/test/test_helper.rb +19 -0
  38. data/vendor/sinatra-markaby/test/views/hello.mab +1 -0
  39. data/vendor/sinatra-markaby/test/views/html.mab +4 -0
  40. data/vendor/sinatra-maruku/LICENSE +22 -0
  41. data/vendor/sinatra-maruku/README.markdown +85 -0
  42. data/vendor/sinatra-maruku/Rakefile +34 -0
  43. data/vendor/sinatra-maruku/VERSION.yml +4 -0
  44. data/vendor/sinatra-maruku/examples/app.rb +8 -0
  45. data/vendor/sinatra-maruku/examples/config.ru +4 -0
  46. data/vendor/sinatra-maruku/examples/mapp.rb +15 -0
  47. data/vendor/sinatra-maruku/examples/public/javascripts/application.js +0 -0
  48. data/vendor/sinatra-maruku/examples/public/stylesheets/application.css +23 -0
  49. data/vendor/sinatra-maruku/examples/public/stylesheets/print.css +0 -0
  50. data/vendor/sinatra-maruku/examples/views/index.maruku +32 -0
  51. data/vendor/sinatra-maruku/examples/views/layout.maruku +9 -0
  52. data/vendor/sinatra-maruku/lib/sinatra/maruku.rb +25 -0
  53. data/vendor/sinatra-maruku/sinatra-maruku.gemspec +70 -0
  54. data/vendor/sinatra-maruku/test/sinatra_maruku_test.rb +91 -0
  55. data/vendor/sinatra-maruku/test/test_helper.rb +21 -0
  56. data/vendor/sinatra-maruku/test/views/hello.maruku +1 -0
  57. data/vendor/sinatra-maruku/test/views/layout2.maruku +2 -0
  58. metadata +53 -1
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.rubyforge_project = "middleman"
13
13
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
14
  gem.executables = %w(mm-init mm-build mm-server)
15
+ gem.files.include ['vendor/**/*']
15
16
  gem.add_dependency("templater")
16
17
  gem.add_dependency("sinatra")
17
18
  gem.add_dependency("markaby")
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.2.4
data/bin/mm-build CHANGED
@@ -22,7 +22,7 @@ module Generators
22
22
 
23
23
  if (args[0] === args[1])
24
24
  newext = case File.extname(args.first)
25
- when '.haml', '.mab', '.maruku'
25
+ when '.haml', '.erb', '.mab', '.maruku'
26
26
  '.html'
27
27
  when '.sass'
28
28
  '.css'
@@ -48,7 +48,7 @@ module Generators
48
48
  file(action.downcase.gsub(/[^a-z0-9]+/, '_').to_sym, action, action.gsub('public/', ''))
49
49
  end
50
50
 
51
- glob! "views", %w(haml sass mab maruku)
51
+ glob! "views", %w(haml sass erb builder mab maruku)
52
52
  end
53
53
 
54
54
  add :build, Builder
data/lib/middleman.rb CHANGED
@@ -45,27 +45,28 @@ class Middleman < Sinatra::Base
45
45
  config.http_images_path = "/images/"
46
46
  end
47
47
  end
48
-
48
+
49
49
  get /(.*)/ do |path|
50
50
  path << "index.html" if path.match(%r{/$})
51
51
  path.gsub!(%r{^/}, '')
52
-
53
52
  template = path.gsub(File.extname(path), '').to_sym
54
- if path.match /.html$/
55
- if File.exists? File.join(options.views, "#{template}.haml")
56
- haml(template)
57
- elsif File.exists? File.join(options.views, "#{template}.maruku")
58
- maruku(template)
59
- elsif File.exists? File.join(options.views, "#{template}.mab")
60
- markaby(template)
53
+
54
+ result = nil
55
+
56
+ %w(haml erb builder maruku mab sass).each do |renderer|
57
+ next if !File.exists?(File.join(options.views, "#{template}.#{renderer}"))
58
+
59
+ renderer = "markaby" if renderer == "mab"
60
+ result = if renderer == "sass"
61
+ content_type 'text/css', :charset => 'utf-8'
62
+ sass(template, Compass.sass_engine_options)
61
63
  else
62
- pass
64
+ send(renderer.to_sym, template)
63
65
  end
64
- elsif path.match /.css$/
65
- content_type 'text/css', :charset => 'utf-8'
66
- sass(template, Compass.sass_engine_options)
67
- else
68
- pass
66
+
67
+ break
69
68
  end
69
+
70
+ result || pass
70
71
  end
71
72
  end
data/middleman.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{middleman}
5
- s.version = "0.2.1"
5
+ s.version = "0.2.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Thomas Reynolds"]
@@ -40,7 +40,59 @@ Gem::Specification.new do |s|
40
40
  "spec/fixtures/sample/views/services/index.haml",
41
41
  "spec/fixtures/sample/views/stylesheets/site.sass",
42
42
  "spec/generator_spec.rb",
43
- "spec/spec_helper.rb"
43
+ "spec/spec_helper.rb",
44
+ "vendor/rack-test/History.txt",
45
+ "vendor/rack-test/MIT-LICENSE.txt",
46
+ "vendor/rack-test/README.rdoc",
47
+ "vendor/rack-test/Rakefile",
48
+ "vendor/rack-test/lib/rack/mock_session.rb",
49
+ "vendor/rack-test/lib/rack/test.rb",
50
+ "vendor/rack-test/lib/rack/test/cookie_jar.rb",
51
+ "vendor/rack-test/lib/rack/test/methods.rb",
52
+ "vendor/rack-test/lib/rack/test/mock_digest_request.rb",
53
+ "vendor/rack-test/lib/rack/test/uploaded_file.rb",
54
+ "vendor/rack-test/lib/rack/test/utils.rb",
55
+ "vendor/rack-test/spec/fixtures/config.ru",
56
+ "vendor/rack-test/spec/fixtures/fake_app.rb",
57
+ "vendor/rack-test/spec/fixtures/foo.txt",
58
+ "vendor/rack-test/spec/rack/test/cookie_spec.rb",
59
+ "vendor/rack-test/spec/rack/test/digest_auth_spec.rb",
60
+ "vendor/rack-test/spec/rack/test/multipart_spec.rb",
61
+ "vendor/rack-test/spec/rack/test/utils_spec.rb",
62
+ "vendor/rack-test/spec/rack/test_spec.rb",
63
+ "vendor/rack-test/spec/rcov.opts",
64
+ "vendor/rack-test/spec/spec.opts",
65
+ "vendor/rack-test/spec/spec_helper.rb",
66
+ "vendor/sinatra-markaby/CHANGES",
67
+ "vendor/sinatra-markaby/LICENSE",
68
+ "vendor/sinatra-markaby/README.rdoc",
69
+ "vendor/sinatra-markaby/Rakefile",
70
+ "vendor/sinatra-markaby/TODO",
71
+ "vendor/sinatra-markaby/VERSION.yml",
72
+ "vendor/sinatra-markaby/lib/sinatra/markaby.rb",
73
+ "vendor/sinatra-markaby/sinatra-markaby.gemspec",
74
+ "vendor/sinatra-markaby/test/sinatra_markaby_test.rb",
75
+ "vendor/sinatra-markaby/test/test_helper.rb",
76
+ "vendor/sinatra-markaby/test/views/hello.mab",
77
+ "vendor/sinatra-markaby/test/views/html.mab",
78
+ "vendor/sinatra-maruku/LICENSE",
79
+ "vendor/sinatra-maruku/README.markdown",
80
+ "vendor/sinatra-maruku/Rakefile",
81
+ "vendor/sinatra-maruku/VERSION.yml",
82
+ "vendor/sinatra-maruku/examples/app.rb",
83
+ "vendor/sinatra-maruku/examples/config.ru",
84
+ "vendor/sinatra-maruku/examples/mapp.rb",
85
+ "vendor/sinatra-maruku/examples/public/javascripts/application.js",
86
+ "vendor/sinatra-maruku/examples/public/stylesheets/application.css",
87
+ "vendor/sinatra-maruku/examples/public/stylesheets/print.css",
88
+ "vendor/sinatra-maruku/examples/views/index.maruku",
89
+ "vendor/sinatra-maruku/examples/views/layout.maruku",
90
+ "vendor/sinatra-maruku/lib/sinatra/maruku.rb",
91
+ "vendor/sinatra-maruku/sinatra-maruku.gemspec",
92
+ "vendor/sinatra-maruku/test/sinatra_maruku_test.rb",
93
+ "vendor/sinatra-maruku/test/test_helper.rb",
94
+ "vendor/sinatra-maruku/test/views/hello.maruku",
95
+ "vendor/sinatra-maruku/test/views/layout2.maruku"
44
96
  ]
45
97
  s.homepage = %q{http://github.com/tdreyno/middleman}
46
98
  s.rdoc_options = ["--charset=UTF-8"]
@@ -0,0 +1,64 @@
1
+ == Git
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
+
10
+ == 0.4.0 / 2009-06-25
11
+
12
+ * Minor enhancements
13
+
14
+ * Expose hook for building Rack::MockSessions for frameworks that need
15
+ to configure them before use
16
+ * Support passing in arrays of raw cookies in addition to a newline
17
+ separated string
18
+ * Support after_request callbacks in MockSession for things like running
19
+ background jobs
20
+ * Allow multiple named sessions using with_session
21
+ * Initialize Rack::Test::Sessions with Rack::MockSessions instead of apps.
22
+ This change should help integration with other Ruby web frameworks
23
+ (like Merb).
24
+ * Support sending bodies for PUT requests (Larry Diehl)
25
+
26
+ == 0.3.0 / 2009-05-17
27
+
28
+ * Major enhancements
29
+
30
+ * Ruby 1.9 compatible (Simon Rozet, Michael Fellinger)
31
+
32
+ * Minor enhancements
33
+
34
+ * Add CookieJar#[] and CookieJar#[]= methods
35
+ * Make the default host configurable
36
+ * Use Rack::Lint and fix errors (Simon Rozet)
37
+ * Extract Rack::MockSession from Rack::Test::Session to handle tracking
38
+ the last request and response and the cookie jar
39
+ * Add #set_cookie and #clear_cookies methods
40
+ * Rename #authorize to #basic_authorize (#authorize remains as an alias)
41
+ (Simon Rozet)
42
+
43
+ == 0.2.0 / 2009-04-26
44
+
45
+ Because #last_response is now a MockResponse instead of a Rack::Response,
46
+ #last_response.body now returns a string instead of an array.
47
+
48
+ * Major enhancements
49
+
50
+ * Support multipart requests via the UploadedFile class (thanks, Rails)
51
+
52
+ * Minor enhancements
53
+
54
+ * Updated for Rack 1.0
55
+ * Don't require rubygems (See http://gist.github.com/54177)
56
+ * Support HTTP Digest authentication with the #digest_authorize method
57
+ * #last_response returns a MockResponse instead of a Response
58
+ (Michael Fellinger)
59
+
60
+ == 0.1.0 / 2009-03-02
61
+
62
+ * 1 major enhancement
63
+
64
+ * Birthday!
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008-2009 Bryan Helmkamp, Engine Yard Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,57 @@
1
+ = Rack::Test
2
+
3
+ - http://gitrdoc.com/brynary/rack-test
4
+ - http://github.com/brynary/rack-test
5
+
6
+ == Description
7
+
8
+ Rack::Test is a small, simple testing API for Rack apps. It can be used on its
9
+ own or as a reusable starting point for Web frameworks and testing libraries
10
+ to build on. Most of its initial functionality is an extraction of Merb 1.0's
11
+ request helpers feature.
12
+
13
+ == Features
14
+
15
+ * Maintains a cookie jar across requests
16
+ * Easily follow redirects when desired
17
+ * Set request headers to be used by all subsequent requests
18
+ * Small footprint. Approximately 200 LOC
19
+
20
+ == Example
21
+
22
+ require "rack/test"
23
+
24
+ class HomepageTest < Test::Unit::TestCase
25
+ include Rack::Test::Methods
26
+
27
+ def app
28
+ MyApp.new
29
+ end
30
+
31
+ def test_redirect_logged_in_users_to_dashboard
32
+ authorize "bryan", "secret"
33
+ get "/"
34
+ follow_redirect!
35
+
36
+ assert_equal "http://example.org/redirected", last_request.url
37
+ assert last_response.ok?
38
+ end
39
+
40
+ end
41
+
42
+ == Install
43
+
44
+ To install the latest release as a gem:
45
+
46
+ sudo gem install rack-test
47
+
48
+ == Authors
49
+
50
+ - Maintained by {Bryan Helmkamp}[mailto:bryan@brynary.com]
51
+ - Contributions from Simon Rozet and Pat Nakajima
52
+ - Much of the original code was extracted from Merb 1.0's request helper
53
+
54
+ == License
55
+
56
+ Copyright (c) 2008-2009 Bryan Helmkamp, Engine Yard Inc.
57
+ See MIT-LICENSE.txt in this directory.
@@ -0,0 +1,62 @@
1
+ require "rubygems"
2
+ require "rake/rdoctask"
3
+ require "rake/gempackagetask"
4
+ require "rake/clean"
5
+ require "spec/rake/spectask"
6
+ require File.expand_path("./lib/rack/test")
7
+
8
+ Spec::Rake::SpecTask.new do |t|
9
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
10
+ end
11
+
12
+ desc "Run all specs in spec directory with RCov"
13
+ Spec::Rake::SpecTask.new(:rcov) do |t|
14
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
15
+ t.rcov = true
16
+ t.rcov_opts = lambda do
17
+ IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
18
+ end
19
+ end
20
+
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
+ desc "Generate RDoc"
49
+ task :docs => :clobber_docs do
50
+ system "hanna --title 'Rack::Test #{Rack::Test::VERSION} API Documentation'"
51
+ end
52
+
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
+ desc 'Removes trailing whitespace'
60
+ task :whitespace do
61
+ sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;}
62
+ end
@@ -0,0 +1,57 @@
1
+ module Rack
2
+
3
+ class MockSession
4
+ attr_writer :cookie_jar
5
+ attr_reader :last_response
6
+ attr_reader :default_host
7
+
8
+ def initialize(app, default_host = Rack::Test::DEFAULT_HOST)
9
+ @app = app
10
+ @after_request = []
11
+ @default_host = default_host
12
+ end
13
+
14
+ def after_request(&block)
15
+ @after_request << block
16
+ end
17
+
18
+ def clear_cookies
19
+ @cookie_jar = Rack::Test::CookieJar.new([], @default_host)
20
+ end
21
+
22
+ def set_cookie(cookie, uri = nil)
23
+ cookie_jar.merge(cookie, uri)
24
+ end
25
+
26
+ def request(uri, env)
27
+ env["HTTP_COOKIE"] ||= cookie_jar.for(uri)
28
+ @last_request = Rack::Request.new(env)
29
+ status, headers, body = @app.call(@last_request.env)
30
+ @last_response = MockResponse.new(status, headers, body, env["rack.errors"].flush)
31
+ cookie_jar.merge(last_response.headers["Set-Cookie"], uri)
32
+
33
+ @after_request.each { |hook| hook.call }
34
+ @last_response
35
+ end
36
+
37
+ # Return the last request issued in the session. Raises an error if no
38
+ # requests have been sent yet.
39
+ def last_request
40
+ raise Rack::Test::Error.new("No request yet. Request a page first.") unless @last_request
41
+ @last_request
42
+ end
43
+
44
+ # Return the last response received in the session. Raises an error if
45
+ # no requests have been sent yet.
46
+ def last_response
47
+ raise Rack::Test::Error.new("No response yet. Request a page first.") unless @last_response
48
+ @last_response
49
+ end
50
+
51
+ def cookie_jar
52
+ @cookie_jar ||= Rack::Test::CookieJar.new([], @default_host)
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,246 @@
1
+ unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__) + "/.."))
2
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/.."))
3
+ end
4
+
5
+ require "uri"
6
+ require "rack"
7
+ require "rack/mock_session"
8
+ require "rack/test/cookie_jar"
9
+ require "rack/test/mock_digest_request"
10
+ require "rack/test/utils"
11
+ require "rack/test/methods"
12
+ require "rack/test/uploaded_file"
13
+
14
+ module Rack
15
+ module Test
16
+
17
+ VERSION = "0.4.0"
18
+
19
+ DEFAULT_HOST = "example.org"
20
+ MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
21
+
22
+ # The common base class for exceptions raised by Rack::Test
23
+ class Error < StandardError; end
24
+
25
+ class Session
26
+ extend Forwardable
27
+ include Rack::Test::Utils
28
+
29
+ def_delegators :@rack_mock_session, :clear_cookies, :set_cookie, :last_response, :last_request
30
+
31
+ # Initialize a new session for the given Rack app
32
+ def initialize(mock_session)
33
+ @headers = {}
34
+
35
+ if mock_session.is_a?(MockSession)
36
+ @rack_mock_session = mock_session
37
+ else
38
+ @rack_mock_session = MockSession.new(mock_session)
39
+ end
40
+
41
+ @default_host = @rack_mock_session.default_host
42
+ end
43
+
44
+ # Issue a GET request for the given URI with the given params and Rack
45
+ # environment. Stores the issues request object in #last_request and
46
+ # the app's response in #last_response. Yield #last_response to a block
47
+ # if given.
48
+ #
49
+ # Example:
50
+ # get "/"
51
+ def get(uri, params = {}, env = {}, &block)
52
+ env = env_for(uri, env.merge(:method => "GET", :params => params))
53
+ process_request(uri, env, &block)
54
+ end
55
+
56
+ # Issue a POST request for the given URI. See #get
57
+ #
58
+ # Example:
59
+ # post "/signup", "name" => "Bryan"
60
+ def post(uri, params = {}, env = {}, &block)
61
+ env = env_for(uri, env.merge(:method => "POST", :params => params))
62
+ process_request(uri, env, &block)
63
+ end
64
+
65
+ # Issue a PUT request for the given URI. See #get
66
+ #
67
+ # Example:
68
+ # put "/"
69
+ def put(uri, params = {}, env = {}, &block)
70
+ env = env_for(uri, env.merge(:method => "PUT", :params => params))
71
+ process_request(uri, env, &block)
72
+ end
73
+
74
+ # Issue a DELETE request for the given URI. See #get
75
+ #
76
+ # Example:
77
+ # delete "/"
78
+ def delete(uri, params = {}, env = {}, &block)
79
+ env = env_for(uri, env.merge(:method => "DELETE", :params => params))
80
+ process_request(uri, env, &block)
81
+ end
82
+
83
+ # Issue a HEAD request for the given URI. See #get
84
+ #
85
+ # Example:
86
+ # head "/"
87
+ def head(uri, params = {}, env = {}, &block)
88
+ env = env_for(uri, env.merge(:method => "HEAD", :params => params))
89
+ process_request(uri, env, &block)
90
+ end
91
+
92
+ # Issue a request to the Rack app for the given URI and optional Rack
93
+ # environment. Stores the issues request object in #last_request and
94
+ # the app's response in #last_response. Yield #last_response to a block
95
+ # if given.
96
+ #
97
+ # Example:
98
+ # request "/"
99
+ def request(uri, env = {}, &block)
100
+ env = env_for(uri, env)
101
+ process_request(uri, env, &block)
102
+ end
103
+
104
+ # Set a header to be included on all subsequent requests through the
105
+ # session. Use a value of nil to remove a previously configured header.
106
+ #
107
+ # Example:
108
+ # header "User-Agent", "Firefox"
109
+ def header(name, value)
110
+ if value.nil?
111
+ @headers.delete(name)
112
+ else
113
+ @headers[name] = value
114
+ end
115
+ end
116
+
117
+ # Set the username and password for HTTP Basic authorization, to be
118
+ # included in subsequent requests in the HTTP_AUTHORIZATION header.
119
+ #
120
+ # Example:
121
+ # basic_authorize "bryan", "secret"
122
+ def basic_authorize(username, password)
123
+ encoded_login = ["#{username}:#{password}"].pack("m*")
124
+ header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
125
+ end
126
+
127
+ alias_method :authorize, :basic_authorize
128
+
129
+ def digest_authorize(username, password)
130
+ @digest_username = username
131
+ @digest_password = password
132
+ end
133
+
134
+ # Rack::Test will not follow any redirects automatically. This method
135
+ # will follow the redirect returned in the last response. If the last
136
+ # response was not a redirect, an error will be raised.
137
+ def follow_redirect!
138
+ unless last_response.redirect?
139
+ raise Error.new("Last response was not a redirect. Cannot follow_redirect!")
140
+ end
141
+
142
+ get(last_response["Location"])
143
+ end
144
+
145
+ private
146
+
147
+ def env_for(path, env)
148
+ uri = URI.parse(path)
149
+ uri.host ||= @default_host
150
+
151
+ env = default_env.merge(env)
152
+
153
+ env.update("HTTPS" => "on") if URI::HTTPS === uri
154
+ env["X-Requested-With"] = "XMLHttpRequest" if env[:xhr]
155
+
156
+ if (env[:method] == "POST" || env["REQUEST_METHOD"] == "POST" ||
157
+ env[:method] == "PUT" || env["REQUEST_METHOD"] == "PUT") && !env.has_key?(:input)
158
+ env["CONTENT_TYPE"] ||= "application/x-www-form-urlencoded"
159
+
160
+ multipart = (Hash === env[:params]) &&
161
+ env[:params].any? { |_, v| UploadedFile === v }
162
+
163
+ if multipart
164
+ env[:input] = multipart_body(env.delete(:params))
165
+ env["CONTENT_LENGTH"] ||= env[:input].length.to_s
166
+ env["CONTENT_TYPE"] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}"
167
+ else
168
+ env[:input] = params_to_string(env.delete(:params))
169
+ end
170
+ end
171
+
172
+ params = env[:params] || {}
173
+ params.update(parse_query(uri.query))
174
+
175
+ uri.query = requestify(params)
176
+
177
+ if env.has_key?(:cookie)
178
+ set_cookie(env.delete(:cookie), uri)
179
+ end
180
+
181
+ Rack::MockRequest.env_for(uri.to_s, env)
182
+ end
183
+
184
+ def process_request(uri, env)
185
+ uri = URI.parse(uri)
186
+ uri.host ||= @default_host
187
+
188
+ @rack_mock_session.request(uri, env)
189
+
190
+ if retry_with_digest_auth?(env)
191
+ auth_env = env.merge({
192
+ "HTTP_AUTHORIZATION" => digest_auth_header,
193
+ "rack-test.digest_auth_retry" => true
194
+ })
195
+ auth_env.delete('rack.request')
196
+ process_request(uri.path, auth_env)
197
+ else
198
+ yield last_response if block_given?
199
+
200
+ last_response
201
+ end
202
+ end
203
+
204
+ def digest_auth_header
205
+ challenge = last_response["WWW-Authenticate"].split(" ", 2).last
206
+ params = Rack::Auth::Digest::Params.parse(challenge)
207
+
208
+ params.merge!({
209
+ "username" => @digest_username,
210
+ "nc" => "00000001",
211
+ "cnonce" => "nonsensenonce",
212
+ "uri" => last_request.path_info,
213
+ "method" => last_request.env["REQUEST_METHOD"],
214
+ })
215
+
216
+ params["response"] = MockDigestRequest.new(params).response(@digest_password)
217
+
218
+ "Digest #{params}"
219
+ end
220
+
221
+ def retry_with_digest_auth?(env)
222
+ last_response.status == 401 &&
223
+ digest_auth_configured? &&
224
+ !env["rack-test.digest_auth_retry"]
225
+ end
226
+
227
+ def digest_auth_configured?
228
+ @digest_username
229
+ end
230
+
231
+ def default_env
232
+ { "rack.test" => true, "REMOTE_ADDR" => "127.0.0.1" }.merge(@headers)
233
+ end
234
+
235
+ def params_to_string(params)
236
+ case params
237
+ when Hash then requestify(params)
238
+ when nil then ""
239
+ else params
240
+ end
241
+ end
242
+
243
+ end
244
+
245
+ end
246
+ end