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.
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/mm-build +2 -2
- data/lib/middleman.rb +16 -15
- data/middleman.gemspec +54 -2
- data/vendor/rack-test/History.txt +64 -0
- data/vendor/rack-test/MIT-LICENSE.txt +19 -0
- data/vendor/rack-test/README.rdoc +57 -0
- data/vendor/rack-test/Rakefile +62 -0
- data/vendor/rack-test/lib/rack/mock_session.rb +57 -0
- data/vendor/rack-test/lib/rack/test.rb +246 -0
- data/vendor/rack-test/lib/rack/test/cookie_jar.rb +169 -0
- data/vendor/rack-test/lib/rack/test/methods.rb +73 -0
- data/vendor/rack-test/lib/rack/test/mock_digest_request.rb +27 -0
- data/vendor/rack-test/lib/rack/test/uploaded_file.rb +36 -0
- data/vendor/rack-test/lib/rack/test/utils.rb +75 -0
- data/vendor/rack-test/spec/fixtures/config.ru +3 -0
- data/vendor/rack-test/spec/fixtures/fake_app.rb +109 -0
- data/vendor/rack-test/spec/fixtures/foo.txt +1 -0
- data/vendor/rack-test/spec/rack/test/cookie_spec.rb +176 -0
- data/vendor/rack-test/spec/rack/test/digest_auth_spec.rb +48 -0
- data/vendor/rack-test/spec/rack/test/multipart_spec.rb +85 -0
- data/vendor/rack-test/spec/rack/test/utils_spec.rb +44 -0
- data/vendor/rack-test/spec/rack/test_spec.rb +363 -0
- data/vendor/rack-test/spec/rcov.opts +1 -0
- data/vendor/rack-test/spec/spec.opts +1 -0
- data/vendor/rack-test/spec/spec_helper.rb +48 -0
- data/vendor/sinatra-markaby/CHANGES +7 -0
- data/vendor/sinatra-markaby/LICENSE +20 -0
- data/vendor/sinatra-markaby/README.rdoc +33 -0
- data/vendor/sinatra-markaby/Rakefile +45 -0
- data/vendor/sinatra-markaby/TODO +3 -0
- data/vendor/sinatra-markaby/VERSION.yml +4 -0
- data/vendor/sinatra-markaby/lib/sinatra/markaby.rb +31 -0
- data/vendor/sinatra-markaby/sinatra-markaby.gemspec +49 -0
- data/vendor/sinatra-markaby/test/sinatra_markaby_test.rb +72 -0
- data/vendor/sinatra-markaby/test/test_helper.rb +19 -0
- data/vendor/sinatra-markaby/test/views/hello.mab +1 -0
- data/vendor/sinatra-markaby/test/views/html.mab +4 -0
- data/vendor/sinatra-maruku/LICENSE +22 -0
- data/vendor/sinatra-maruku/README.markdown +85 -0
- data/vendor/sinatra-maruku/Rakefile +34 -0
- data/vendor/sinatra-maruku/VERSION.yml +4 -0
- data/vendor/sinatra-maruku/examples/app.rb +8 -0
- data/vendor/sinatra-maruku/examples/config.ru +4 -0
- data/vendor/sinatra-maruku/examples/mapp.rb +15 -0
- data/vendor/sinatra-maruku/examples/public/javascripts/application.js +0 -0
- data/vendor/sinatra-maruku/examples/public/stylesheets/application.css +23 -0
- data/vendor/sinatra-maruku/examples/public/stylesheets/print.css +0 -0
- data/vendor/sinatra-maruku/examples/views/index.maruku +32 -0
- data/vendor/sinatra-maruku/examples/views/layout.maruku +9 -0
- data/vendor/sinatra-maruku/lib/sinatra/maruku.rb +25 -0
- data/vendor/sinatra-maruku/sinatra-maruku.gemspec +70 -0
- data/vendor/sinatra-maruku/test/sinatra_maruku_test.rb +91 -0
- data/vendor/sinatra-maruku/test/test_helper.rb +21 -0
- data/vendor/sinatra-maruku/test/views/hello.maruku +1 -0
- data/vendor/sinatra-maruku/test/views/layout2.maruku +2 -0
- 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
|
+
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
64
|
+
send(renderer.to_sym, template)
|
63
65
|
end
|
64
|
-
|
65
|
-
|
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.
|
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
|