tdreyno-middleman 0.2.1 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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