eac-rack 1.1.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/COPYING +18 -0
- data/KNOWN-ISSUES +21 -0
- data/README +399 -0
- data/bin/rackup +4 -0
- data/contrib/rack_logo.svg +111 -0
- data/example/lobster.ru +4 -0
- data/example/protectedlobster.rb +14 -0
- data/example/protectedlobster.ru +8 -0
- data/lib/rack.rb +92 -0
- data/lib/rack/adapter/camping.rb +22 -0
- data/lib/rack/auth/abstract/handler.rb +37 -0
- data/lib/rack/auth/abstract/request.rb +37 -0
- data/lib/rack/auth/basic.rb +58 -0
- data/lib/rack/auth/digest/md5.rb +124 -0
- data/lib/rack/auth/digest/nonce.rb +51 -0
- data/lib/rack/auth/digest/params.rb +55 -0
- data/lib/rack/auth/digest/request.rb +40 -0
- data/lib/rack/builder.rb +80 -0
- data/lib/rack/cascade.rb +41 -0
- data/lib/rack/chunked.rb +49 -0
- data/lib/rack/commonlogger.rb +49 -0
- data/lib/rack/conditionalget.rb +47 -0
- data/lib/rack/config.rb +15 -0
- data/lib/rack/content_length.rb +29 -0
- data/lib/rack/content_type.rb +23 -0
- data/lib/rack/deflater.rb +96 -0
- data/lib/rack/directory.rb +157 -0
- data/lib/rack/etag.rb +23 -0
- data/lib/rack/file.rb +90 -0
- data/lib/rack/handler.rb +88 -0
- data/lib/rack/handler/cgi.rb +61 -0
- data/lib/rack/handler/evented_mongrel.rb +8 -0
- data/lib/rack/handler/fastcgi.rb +89 -0
- data/lib/rack/handler/lsws.rb +63 -0
- data/lib/rack/handler/mongrel.rb +90 -0
- data/lib/rack/handler/scgi.rb +62 -0
- data/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/lib/rack/handler/thin.rb +18 -0
- data/lib/rack/handler/webrick.rb +69 -0
- data/lib/rack/head.rb +19 -0
- data/lib/rack/lint.rb +575 -0
- data/lib/rack/lobster.rb +65 -0
- data/lib/rack/lock.rb +16 -0
- data/lib/rack/logger.rb +20 -0
- data/lib/rack/methodoverride.rb +27 -0
- data/lib/rack/mime.rb +206 -0
- data/lib/rack/mock.rb +189 -0
- data/lib/rack/nulllogger.rb +18 -0
- data/lib/rack/recursive.rb +57 -0
- data/lib/rack/reloader.rb +109 -0
- data/lib/rack/request.rb +271 -0
- data/lib/rack/response.rb +149 -0
- data/lib/rack/rewindable_input.rb +100 -0
- data/lib/rack/runtime.rb +27 -0
- data/lib/rack/sendfile.rb +142 -0
- data/lib/rack/server.rb +212 -0
- data/lib/rack/session/abstract/id.rb +140 -0
- data/lib/rack/session/cookie.rb +90 -0
- data/lib/rack/session/memcache.rb +119 -0
- data/lib/rack/session/pool.rb +100 -0
- data/lib/rack/showexceptions.rb +349 -0
- data/lib/rack/showstatus.rb +106 -0
- data/lib/rack/static.rb +38 -0
- data/lib/rack/urlmap.rb +56 -0
- data/lib/rack/utils.rb +614 -0
- data/rack.gemspec +38 -0
- data/test/spec_rack_auth_basic.rb +73 -0
- data/test/spec_rack_auth_digest.rb +226 -0
- data/test/spec_rack_builder.rb +84 -0
- data/test/spec_rack_camping.rb +51 -0
- data/test/spec_rack_cascade.rb +48 -0
- data/test/spec_rack_cgi.rb +89 -0
- data/test/spec_rack_chunked.rb +62 -0
- data/test/spec_rack_commonlogger.rb +61 -0
- data/test/spec_rack_conditionalget.rb +41 -0
- data/test/spec_rack_config.rb +24 -0
- data/test/spec_rack_content_length.rb +43 -0
- data/test/spec_rack_content_type.rb +30 -0
- data/test/spec_rack_deflater.rb +127 -0
- data/test/spec_rack_directory.rb +61 -0
- data/test/spec_rack_etag.rb +17 -0
- data/test/spec_rack_fastcgi.rb +89 -0
- data/test/spec_rack_file.rb +75 -0
- data/test/spec_rack_handler.rb +43 -0
- data/test/spec_rack_head.rb +30 -0
- data/test/spec_rack_lint.rb +528 -0
- data/test/spec_rack_lobster.rb +45 -0
- data/test/spec_rack_lock.rb +38 -0
- data/test/spec_rack_logger.rb +21 -0
- data/test/spec_rack_methodoverride.rb +60 -0
- data/test/spec_rack_mock.rb +243 -0
- data/test/spec_rack_mongrel.rb +189 -0
- data/test/spec_rack_nulllogger.rb +13 -0
- data/test/spec_rack_recursive.rb +77 -0
- data/test/spec_rack_request.rb +545 -0
- data/test/spec_rack_response.rb +221 -0
- data/test/spec_rack_rewindable_input.rb +118 -0
- data/test/spec_rack_runtime.rb +35 -0
- data/test/spec_rack_sendfile.rb +86 -0
- data/test/spec_rack_session_cookie.rb +73 -0
- data/test/spec_rack_session_memcache.rb +273 -0
- data/test/spec_rack_session_pool.rb +172 -0
- data/test/spec_rack_showexceptions.rb +21 -0
- data/test/spec_rack_showstatus.rb +72 -0
- data/test/spec_rack_static.rb +37 -0
- data/test/spec_rack_thin.rb +91 -0
- data/test/spec_rack_urlmap.rb +215 -0
- data/test/spec_rack_utils.rb +554 -0
- data/test/spec_rack_webrick.rb +130 -0
- data/test/spec_rackup.rb +154 -0
- metadata +311 -0
data/rack.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "eac-rack"
|
3
|
+
s.version = "1.1.1"
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.summary = "a modular Ruby webserver interface"
|
6
|
+
|
7
|
+
s.description = <<-EOF
|
8
|
+
Rack provides minimal, modular and adaptable interface for developing
|
9
|
+
web applications in Ruby. By wrapping HTTP requests and responses in
|
10
|
+
the simplest way possible, it unifies and distills the API for web
|
11
|
+
servers, web frameworks, and software in between (the so-called
|
12
|
+
middleware) into a single method call.
|
13
|
+
|
14
|
+
Also see http://rack.rubyforge.org.
|
15
|
+
EOF
|
16
|
+
|
17
|
+
s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] +
|
18
|
+
%w(COPYING KNOWN-ISSUES rack.gemspec README)
|
19
|
+
s.bindir = 'bin'
|
20
|
+
s.executables << 'rackup'
|
21
|
+
s.require_path = 'lib'
|
22
|
+
s.has_rdoc = true
|
23
|
+
s.extra_rdoc_files = ['README', 'KNOWN-ISSUES']
|
24
|
+
s.test_files = Dir['test/{test,spec}_*.rb']
|
25
|
+
|
26
|
+
s.author = 'Christian Neukirchen'
|
27
|
+
s.email = 'chneukirchen@gmail.com'
|
28
|
+
s.homepage = 'http://rack.rubyforge.org'
|
29
|
+
#s.rubyforge_project = 'rack'
|
30
|
+
|
31
|
+
s.add_development_dependency 'test-spec'
|
32
|
+
|
33
|
+
s.add_development_dependency 'camping'
|
34
|
+
s.add_development_dependency 'fcgi'
|
35
|
+
s.add_development_dependency 'memcache-client'
|
36
|
+
s.add_development_dependency 'mongrel'
|
37
|
+
s.add_development_dependency 'thin'
|
38
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
require 'rack/auth/basic'
|
4
|
+
require 'rack/mock'
|
5
|
+
|
6
|
+
context 'Rack::Auth::Basic' do
|
7
|
+
|
8
|
+
def realm
|
9
|
+
'WallysWorld'
|
10
|
+
end
|
11
|
+
|
12
|
+
def unprotected_app
|
13
|
+
lambda { |env| [ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ] }
|
14
|
+
end
|
15
|
+
|
16
|
+
def protected_app
|
17
|
+
app = Rack::Auth::Basic.new(unprotected_app) { |username, password| 'Boss' == username }
|
18
|
+
app.realm = realm
|
19
|
+
app
|
20
|
+
end
|
21
|
+
|
22
|
+
setup do
|
23
|
+
@request = Rack::MockRequest.new(protected_app)
|
24
|
+
end
|
25
|
+
|
26
|
+
def request_with_basic_auth(username, password, &block)
|
27
|
+
request 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack("m*"), &block
|
28
|
+
end
|
29
|
+
|
30
|
+
def request(headers = {})
|
31
|
+
yield @request.get('/', headers)
|
32
|
+
end
|
33
|
+
|
34
|
+
def assert_basic_auth_challenge(response)
|
35
|
+
response.should.be.a.client_error
|
36
|
+
response.status.should.equal 401
|
37
|
+
response.should.include 'WWW-Authenticate'
|
38
|
+
response.headers['WWW-Authenticate'].should =~ /Basic realm="#{Regexp.escape(realm)}"/
|
39
|
+
response.body.should.be.empty
|
40
|
+
end
|
41
|
+
|
42
|
+
specify 'should challenge correctly when no credentials are specified' do
|
43
|
+
request do |response|
|
44
|
+
assert_basic_auth_challenge response
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
specify 'should rechallenge if incorrect credentials are specified' do
|
49
|
+
request_with_basic_auth 'joe', 'password' do |response|
|
50
|
+
assert_basic_auth_challenge response
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
specify 'should return application output if correct credentials are specified' do
|
55
|
+
request_with_basic_auth 'Boss', 'password' do |response|
|
56
|
+
response.status.should.equal 200
|
57
|
+
response.body.to_s.should.equal 'Hi Boss'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
specify 'should return 400 Bad Request if different auth scheme used' do
|
62
|
+
request 'HTTP_AUTHORIZATION' => 'Digest params' do |response|
|
63
|
+
response.should.be.a.client_error
|
64
|
+
response.status.should.equal 400
|
65
|
+
response.should.not.include 'WWW-Authenticate'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
specify 'realm as optional constructor arg' do
|
70
|
+
app = Rack::Auth::Basic.new(unprotected_app, realm) { true }
|
71
|
+
assert_equal realm, app.realm
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
require 'rack/auth/digest/md5'
|
4
|
+
require 'rack/mock'
|
5
|
+
|
6
|
+
context 'Rack::Auth::Digest::MD5' do
|
7
|
+
|
8
|
+
def realm
|
9
|
+
'WallysWorld'
|
10
|
+
end
|
11
|
+
|
12
|
+
def unprotected_app
|
13
|
+
lambda do |env|
|
14
|
+
[ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def protected_app
|
19
|
+
app = Rack::Auth::Digest::MD5.new(unprotected_app) do |username|
|
20
|
+
{ 'Alice' => 'correct-password' }[username]
|
21
|
+
end
|
22
|
+
app.realm = realm
|
23
|
+
app.opaque = 'this-should-be-secret'
|
24
|
+
app
|
25
|
+
end
|
26
|
+
|
27
|
+
def protected_app_with_hashed_passwords
|
28
|
+
app = Rack::Auth::Digest::MD5.new(unprotected_app) do |username|
|
29
|
+
username == 'Alice' ? Digest::MD5.hexdigest("Alice:#{realm}:correct-password") : nil
|
30
|
+
end
|
31
|
+
app.realm = realm
|
32
|
+
app.opaque = 'this-should-be-secret'
|
33
|
+
app.passwords_hashed = true
|
34
|
+
app
|
35
|
+
end
|
36
|
+
|
37
|
+
def partially_protected_app
|
38
|
+
Rack::URLMap.new({
|
39
|
+
'/' => unprotected_app,
|
40
|
+
'/protected' => protected_app
|
41
|
+
})
|
42
|
+
end
|
43
|
+
|
44
|
+
def protected_app_with_method_override
|
45
|
+
Rack::MethodOverride.new(protected_app)
|
46
|
+
end
|
47
|
+
|
48
|
+
setup do
|
49
|
+
@request = Rack::MockRequest.new(protected_app)
|
50
|
+
end
|
51
|
+
|
52
|
+
def request(method, path, headers = {}, &block)
|
53
|
+
response = @request.request(method, path, headers)
|
54
|
+
block.call(response) if block
|
55
|
+
return response
|
56
|
+
end
|
57
|
+
|
58
|
+
class MockDigestRequest
|
59
|
+
def initialize(params)
|
60
|
+
@params = params
|
61
|
+
end
|
62
|
+
def method_missing(sym)
|
63
|
+
if @params.has_key? k = sym.to_s
|
64
|
+
return @params[k]
|
65
|
+
end
|
66
|
+
super
|
67
|
+
end
|
68
|
+
def method
|
69
|
+
@params['method']
|
70
|
+
end
|
71
|
+
def response(password)
|
72
|
+
Rack::Auth::Digest::MD5.new(nil).send :digest, self, password
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def request_with_digest_auth(method, path, username, password, options = {}, &block)
|
77
|
+
request_options = {}
|
78
|
+
request_options[:input] = options.delete(:input) if options.include? :input
|
79
|
+
|
80
|
+
response = request(method, path, request_options)
|
81
|
+
|
82
|
+
return response unless response.status == 401
|
83
|
+
|
84
|
+
if wait = options.delete(:wait)
|
85
|
+
sleep wait
|
86
|
+
end
|
87
|
+
|
88
|
+
challenge = response['WWW-Authenticate'].split(' ', 2).last
|
89
|
+
|
90
|
+
params = Rack::Auth::Digest::Params.parse(challenge)
|
91
|
+
|
92
|
+
params['username'] = username
|
93
|
+
params['nc'] = '00000001'
|
94
|
+
params['cnonce'] = 'nonsensenonce'
|
95
|
+
params['uri'] = path
|
96
|
+
|
97
|
+
params['method'] = method
|
98
|
+
|
99
|
+
params.update options
|
100
|
+
|
101
|
+
params['response'] = MockDigestRequest.new(params).response(password)
|
102
|
+
|
103
|
+
request(method, path, request_options.merge('HTTP_AUTHORIZATION' => "Digest #{params}"), &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
def assert_digest_auth_challenge(response)
|
107
|
+
response.should.be.a.client_error
|
108
|
+
response.status.should.equal 401
|
109
|
+
response.should.include 'WWW-Authenticate'
|
110
|
+
response.headers['WWW-Authenticate'].should =~ /^Digest /
|
111
|
+
response.body.should.be.empty
|
112
|
+
end
|
113
|
+
|
114
|
+
def assert_bad_request(response)
|
115
|
+
response.should.be.a.client_error
|
116
|
+
response.status.should.equal 400
|
117
|
+
response.should.not.include 'WWW-Authenticate'
|
118
|
+
end
|
119
|
+
|
120
|
+
specify 'should challenge when no credentials are specified' do
|
121
|
+
request 'GET', '/' do |response|
|
122
|
+
assert_digest_auth_challenge response
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
specify 'should return application output if correct credentials given' do
|
127
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password' do |response|
|
128
|
+
response.status.should.equal 200
|
129
|
+
response.body.to_s.should.equal 'Hi Alice'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
specify 'should return application output if correct credentials given (hashed passwords)' do
|
134
|
+
@request = Rack::MockRequest.new(protected_app_with_hashed_passwords)
|
135
|
+
|
136
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password' do |response|
|
137
|
+
response.status.should.equal 200
|
138
|
+
response.body.to_s.should.equal 'Hi Alice'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
specify 'should rechallenge if incorrect username given' do
|
143
|
+
request_with_digest_auth 'GET', '/', 'Bob', 'correct-password' do |response|
|
144
|
+
assert_digest_auth_challenge response
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
specify 'should rechallenge if incorrect password given' do
|
149
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'wrong-password' do |response|
|
150
|
+
assert_digest_auth_challenge response
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
specify 'should rechallenge with stale parameter if nonce is stale' do
|
155
|
+
begin
|
156
|
+
Rack::Auth::Digest::Nonce.time_limit = 1
|
157
|
+
|
158
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', :wait => 2 do |response|
|
159
|
+
assert_digest_auth_challenge response
|
160
|
+
response.headers['WWW-Authenticate'].should =~ /\bstale=true\b/
|
161
|
+
end
|
162
|
+
ensure
|
163
|
+
Rack::Auth::Digest::Nonce.time_limit = nil
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
specify 'should return 400 Bad Request if incorrect qop given' do
|
168
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', 'qop' => 'auth-int' do |response|
|
169
|
+
assert_bad_request response
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
specify 'should return 400 Bad Request if incorrect uri given' do
|
174
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', 'uri' => '/foo' do |response|
|
175
|
+
assert_bad_request response
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
specify 'should return 400 Bad Request if different auth scheme used' do
|
180
|
+
request 'GET', '/', 'HTTP_AUTHORIZATION' => 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==' do |response|
|
181
|
+
assert_bad_request response
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
specify 'should not require credentials for unprotected path' do
|
186
|
+
@request = Rack::MockRequest.new(partially_protected_app)
|
187
|
+
request 'GET', '/' do |response|
|
188
|
+
response.should.be.ok
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
specify 'should challenge when no credentials are specified for protected path' do
|
193
|
+
@request = Rack::MockRequest.new(partially_protected_app)
|
194
|
+
request 'GET', '/protected' do |response|
|
195
|
+
assert_digest_auth_challenge response
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
specify 'should return application output if correct credentials given for protected path' do
|
200
|
+
@request = Rack::MockRequest.new(partially_protected_app)
|
201
|
+
request_with_digest_auth 'GET', '/protected', 'Alice', 'correct-password' do |response|
|
202
|
+
response.status.should.equal 200
|
203
|
+
response.body.to_s.should.equal 'Hi Alice'
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
specify 'should return application output if correct credentials given for POST' do
|
208
|
+
request_with_digest_auth 'POST', '/', 'Alice', 'correct-password' do |response|
|
209
|
+
response.status.should.equal 200
|
210
|
+
response.body.to_s.should.equal 'Hi Alice'
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
specify 'should return application output if correct credentials given for PUT (using method override of POST)' do
|
215
|
+
@request = Rack::MockRequest.new(protected_app_with_method_override)
|
216
|
+
request_with_digest_auth 'POST', '/', 'Alice', 'correct-password', :input => "_method=put" do |response|
|
217
|
+
response.status.should.equal 200
|
218
|
+
response.body.to_s.should.equal 'Hi Alice'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
specify 'realm as optional constructor arg' do
|
223
|
+
app = Rack::Auth::Digest::MD5.new(unprotected_app, realm) { true }
|
224
|
+
assert_equal realm, app.realm
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
require 'rack/builder'
|
4
|
+
require 'rack/mock'
|
5
|
+
require 'rack/showexceptions'
|
6
|
+
require 'rack/auth/basic'
|
7
|
+
|
8
|
+
context "Rack::Builder" do
|
9
|
+
specify "chains apps by default" do
|
10
|
+
app = Rack::Builder.new do
|
11
|
+
use Rack::ShowExceptions
|
12
|
+
run lambda { |env| raise "bzzzt" }
|
13
|
+
end.to_app
|
14
|
+
|
15
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
16
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
17
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "has implicit #to_app" do
|
21
|
+
app = Rack::Builder.new do
|
22
|
+
use Rack::ShowExceptions
|
23
|
+
run lambda { |env| raise "bzzzt" }
|
24
|
+
end
|
25
|
+
|
26
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
27
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
28
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
29
|
+
end
|
30
|
+
|
31
|
+
specify "supports blocks on use" do
|
32
|
+
app = Rack::Builder.new do
|
33
|
+
use Rack::ShowExceptions
|
34
|
+
use Rack::Auth::Basic do |username, password|
|
35
|
+
'secret' == password
|
36
|
+
end
|
37
|
+
|
38
|
+
run lambda { |env| [200, {}, ['Hi Boss']] }
|
39
|
+
end
|
40
|
+
|
41
|
+
response = Rack::MockRequest.new(app).get("/")
|
42
|
+
response.should.be.client_error
|
43
|
+
response.status.should.equal 401
|
44
|
+
|
45
|
+
# with auth...
|
46
|
+
response = Rack::MockRequest.new(app).get("/",
|
47
|
+
'HTTP_AUTHORIZATION' => 'Basic ' + ["joe:secret"].pack("m*"))
|
48
|
+
response.status.should.equal 200
|
49
|
+
response.body.to_s.should.equal 'Hi Boss'
|
50
|
+
end
|
51
|
+
|
52
|
+
specify "has explicit #to_app" do
|
53
|
+
app = Rack::Builder.app do
|
54
|
+
use Rack::ShowExceptions
|
55
|
+
run lambda { |env| raise "bzzzt" }
|
56
|
+
end
|
57
|
+
|
58
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
59
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
60
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
61
|
+
end
|
62
|
+
|
63
|
+
specify "apps are initialized once" do
|
64
|
+
app = Rack::Builder.new do
|
65
|
+
class AppClass
|
66
|
+
def initialize
|
67
|
+
@called = 0
|
68
|
+
end
|
69
|
+
def call(env)
|
70
|
+
raise "bzzzt" if @called > 0
|
71
|
+
@called += 1
|
72
|
+
[200, {'Content-Type' => 'text/plain'}, ['OK']]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
use Rack::ShowExceptions
|
77
|
+
run AppClass.new
|
78
|
+
end
|
79
|
+
|
80
|
+
Rack::MockRequest.new(app).get("/").status.should.equal 200
|
81
|
+
Rack::MockRequest.new(app).get("/").should.be.server_error
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
require 'stringio'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rack/mock'
|
7
|
+
|
8
|
+
$-w, w = nil, $-w # yuck
|
9
|
+
require 'camping'
|
10
|
+
require 'rack/adapter/camping'
|
11
|
+
|
12
|
+
Camping.goes :CampApp
|
13
|
+
module CampApp
|
14
|
+
module Controllers
|
15
|
+
class HW < R('/')
|
16
|
+
def get
|
17
|
+
@headers["X-Served-By"] = URI("http://rack.rubyforge.org")
|
18
|
+
"Camping works!"
|
19
|
+
end
|
20
|
+
|
21
|
+
def post
|
22
|
+
"Data: #{input.foo}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
$-w = w
|
28
|
+
|
29
|
+
context "Rack::Adapter::Camping" do
|
30
|
+
specify "works with GET" do
|
31
|
+
res = Rack::MockRequest.new(Rack::Adapter::Camping.new(CampApp)).
|
32
|
+
get("/")
|
33
|
+
|
34
|
+
res.should.be.ok
|
35
|
+
res["Content-Type"].should.equal "text/html"
|
36
|
+
res["X-Served-By"].should.equal "http://rack.rubyforge.org"
|
37
|
+
|
38
|
+
res.body.should.equal "Camping works!"
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "works with POST" do
|
42
|
+
res = Rack::MockRequest.new(Rack::Adapter::Camping.new(CampApp)).
|
43
|
+
post("/", :input => "foo=bar")
|
44
|
+
|
45
|
+
res.should.be.ok
|
46
|
+
res.body.should.equal "Data: bar"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue LoadError
|
50
|
+
$stderr.puts "Skipping Rack::Adapter::Camping tests (Camping is required). `gem install camping` and try again."
|
51
|
+
end
|