sinatra-sinatra 0.9.0.5 → 0.9.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/CHANGES +40 -2
- data/README.rdoc +3 -3
- data/compat/app_test.rb +0 -19
- data/compat/application_test.rb +0 -72
- data/compat/pipeline_test.rb +0 -26
- data/compat/sessions_test.rb +3 -0
- data/compat/streaming_test.rb +4 -4
- data/lib/sinatra/base.rb +96 -81
- data/lib/sinatra/compat.rb +11 -0
- data/lib/sinatra/test/bacon.rb +2 -0
- data/lib/sinatra/test/rspec.rb +2 -0
- data/lib/sinatra/test/spec.rb +2 -0
- data/lib/sinatra/test/unit.rb +2 -0
- data/lib/sinatra/test.rb +34 -35
- data/sinatra.gemspec +3 -3
- data/test/base_test.rb +105 -56
- data/test/erb_test.rb +31 -0
- data/test/extensions_test.rb +21 -0
- data/test/helper.rb +38 -8
- data/test/helpers_test.rb +28 -0
- data/test/middleware_test.rb +8 -0
- data/test/options_test.rb +243 -9
- data/test/routing_test.rb +61 -2
- data/test/test_test.rb +125 -8
- metadata +6 -2
data/lib/sinatra/test.rb
CHANGED
@@ -1,41 +1,40 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
|
3
3
|
module Sinatra
|
4
|
-
|
5
4
|
module Test
|
6
5
|
include Rack::Utils
|
7
6
|
|
8
7
|
attr_reader :app, :request, :response
|
9
8
|
|
10
|
-
def
|
9
|
+
def self.deprecate(framework)
|
10
|
+
warn <<-EOF
|
11
|
+
Warning: support for the #{framework} testing framework is deprecated and
|
12
|
+
will be dropped in Sinatra 1.0. See <http://sinatra.github.com/testing.html>
|
13
|
+
for more information.
|
14
|
+
EOF
|
15
|
+
end
|
16
|
+
|
17
|
+
def make_request(verb, path, body=nil, options={})
|
11
18
|
@app = Sinatra::Application if @app.nil? && defined?(Sinatra::Application)
|
12
19
|
fail "@app not set - cannot make request" if @app.nil?
|
20
|
+
|
13
21
|
@request = Rack::MockRequest.new(@app)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
[{}, data]
|
29
|
-
end
|
30
|
-
when 0
|
31
|
-
[{}, '']
|
32
|
-
else
|
33
|
-
raise ArgumentError, "zero, one, or two arguments expected"
|
34
|
-
end
|
35
|
-
opts = rack_opts(opts)
|
36
|
-
opts[:input] ||= input
|
22
|
+
options = { :lint => true }.merge(options || {})
|
23
|
+
|
24
|
+
case
|
25
|
+
when body.respond_to?(:to_hash)
|
26
|
+
options.merge! body.delete(:env) if body.key?(:env)
|
27
|
+
options[:input] = param_string(body)
|
28
|
+
when body.respond_to?(:to_str)
|
29
|
+
options[:input] = body
|
30
|
+
when body.nil?
|
31
|
+
options[:input] = ''
|
32
|
+
else
|
33
|
+
raise ArgumentError, "body must be a Hash, String, or nil"
|
34
|
+
end
|
35
|
+
|
37
36
|
yield @request if block_given?
|
38
|
-
@response = @request.request(verb, path,
|
37
|
+
@response = @request.request(verb, path, rack_options(options))
|
39
38
|
end
|
40
39
|
|
41
40
|
def get(path, *args, &b) ; make_request('GET', path, *args, &b) ; end
|
@@ -67,18 +66,18 @@ module Sinatra
|
|
67
66
|
|
68
67
|
private
|
69
68
|
|
70
|
-
|
71
|
-
:accept
|
72
|
-
:agent
|
73
|
-
:host
|
74
|
-
:session
|
75
|
-
:cookies
|
76
|
-
:content_type =>
|
69
|
+
RACK_OPTIONS = {
|
70
|
+
:accept => 'HTTP_ACCEPT',
|
71
|
+
:agent => 'HTTP_USER_AGENT',
|
72
|
+
:host => 'HTTP_HOST',
|
73
|
+
:session => 'rack.session',
|
74
|
+
:cookies => 'HTTP_COOKIE',
|
75
|
+
:content_type => 'CONTENT_TYPE'
|
77
76
|
}
|
78
77
|
|
79
|
-
def
|
78
|
+
def rack_options(opts)
|
80
79
|
opts.merge(:lint => true).inject({}) do |hash,(key,val)|
|
81
|
-
key =
|
80
|
+
key = RACK_OPTIONS[key] || key
|
82
81
|
hash[key] = val
|
83
82
|
hash
|
84
83
|
end
|
data/sinatra.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
4
|
|
5
5
|
s.name = 'sinatra'
|
6
|
-
s.version = '0.9.
|
7
|
-
s.date = '2009-
|
6
|
+
s.version = '0.9.1'
|
7
|
+
s.date = '2009-03-01'
|
8
8
|
|
9
9
|
s.description = "Classy web-development dressed in a DSL"
|
10
10
|
s.summary = "Classy web-development dressed in a DSL"
|
@@ -104,7 +104,7 @@ Gem::Specification.new do |s|
|
|
104
104
|
s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
|
105
105
|
|
106
106
|
s.extra_rdoc_files = %w[README.rdoc LICENSE]
|
107
|
-
s.add_dependency 'rack', '>= 0.9.1'
|
107
|
+
s.add_dependency 'rack', '>= 0.9.1', '< 1.0'
|
108
108
|
|
109
109
|
s.has_rdoc = true
|
110
110
|
s.homepage = "http://sinatra.rubyforge.org"
|
data/test/base_test.rb
CHANGED
@@ -1,81 +1,130 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/helper'
|
2
2
|
|
3
|
-
describe 'Sinatra::Base' do
|
4
|
-
|
5
|
-
|
3
|
+
describe 'Sinatra::Base subclasses' do
|
4
|
+
|
5
|
+
class TestApp < Sinatra::Base
|
6
|
+
get '/' do
|
7
|
+
'Hello World'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'include Rack::Utils' do
|
12
|
+
assert TestApp.included_modules.include?(Rack::Utils)
|
6
13
|
end
|
7
14
|
|
8
|
-
it '
|
9
|
-
|
10
|
-
get '/' do
|
11
|
-
'Hello World'
|
12
|
-
end
|
13
|
-
}
|
14
|
-
assert @app.respond_to?(:call)
|
15
|
+
it 'processes requests with #call' do
|
16
|
+
assert TestApp.respond_to?(:call)
|
15
17
|
|
16
|
-
request = Rack::MockRequest.new(
|
18
|
+
request = Rack::MockRequest.new(TestApp)
|
17
19
|
response = request.get('/')
|
18
20
|
assert response.ok?
|
19
21
|
assert_equal 'Hello World', response.body
|
20
22
|
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
class TestApp < Sinatra::Base
|
25
|
+
get '/state' do
|
26
|
+
body = "Foo: #{@foo}"
|
27
|
+
@foo = 'discard'
|
28
|
+
body
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not maintain state between requests' do
|
33
|
+
request = Rack::MockRequest.new(TestApp)
|
34
|
+
2.times do
|
35
|
+
response = request.get('/state')
|
36
|
+
assert response.ok?
|
37
|
+
assert_equal 'Foo: ', response.body
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "Sinatra::Base as Rack middleware" do
|
43
|
+
|
44
|
+
app = lambda { |env|
|
45
|
+
[210, {'X-Downstream' => 'true'}, ['Hello from downstream']] }
|
46
|
+
|
47
|
+
class TestMiddleware < Sinatra::Base
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'creates a middleware that responds to #call with .new' do
|
51
|
+
middleware = TestMiddleware.new(app)
|
52
|
+
assert middleware.respond_to?(:call)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'exposes the downstream app' do
|
56
|
+
middleware = TestMiddleware.new(app)
|
34
57
|
assert_same app, middleware.app
|
58
|
+
end
|
59
|
+
|
60
|
+
class TestMiddleware < Sinatra::Base
|
61
|
+
get '/' do
|
62
|
+
'Hello from middleware'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
middleware = TestMiddleware.new(app)
|
67
|
+
request = Rack::MockRequest.new(middleware)
|
35
68
|
|
36
|
-
|
69
|
+
it 'intercepts requests' do
|
37
70
|
response = request.get('/')
|
38
71
|
assert response.ok?
|
39
|
-
assert_equal 'Hello
|
72
|
+
assert_equal 'Hello from middleware', response.body
|
73
|
+
end
|
40
74
|
|
41
|
-
|
42
|
-
|
43
|
-
assert_equal
|
75
|
+
it 'automatically forwards requests downstream when no matching route found' do
|
76
|
+
response = request.get('/missing')
|
77
|
+
assert_equal 210, response.status
|
78
|
+
assert_equal 'Hello from downstream', response.body
|
44
79
|
end
|
45
80
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
81
|
+
class TestMiddleware < Sinatra::Base
|
82
|
+
get '/low-level-forward' do
|
83
|
+
app.call(env)
|
84
|
+
end
|
85
|
+
end
|
52
86
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
87
|
+
it 'can call the downstream app directly and return result' do
|
88
|
+
response = request.get('/low-level-forward')
|
89
|
+
assert_equal 210, response.status
|
90
|
+
assert_equal 'true', response['X-Downstream']
|
91
|
+
assert_equal 'Hello from downstream', response.body
|
92
|
+
end
|
57
93
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
94
|
+
class TestMiddleware < Sinatra::Base
|
95
|
+
get '/explicit-forward' do
|
96
|
+
response['X-Middleware'] = 'true'
|
97
|
+
res = forward
|
98
|
+
assert_nil res
|
99
|
+
assert_equal 210, response.status
|
100
|
+
assert_equal 'true', response['X-Downstream']
|
101
|
+
assert_equal ['Hello from downstream'], response.body
|
102
|
+
'Hello after explicit forward'
|
103
|
+
end
|
104
|
+
end
|
62
105
|
|
63
|
-
|
64
|
-
response = request.get('/
|
65
|
-
|
66
|
-
assert_equal '
|
106
|
+
it 'forwards the request downstream and integrates the response into the current context' do
|
107
|
+
response = request.get('/explicit-forward')
|
108
|
+
assert_equal 210, response.status
|
109
|
+
assert_equal 'true', response['X-Downstream']
|
110
|
+
assert_equal 'Hello after explicit forward', response.body
|
111
|
+
assert_equal '28', response['Content-Length']
|
112
|
+
end
|
113
|
+
|
114
|
+
app_content_length = lambda {|env|
|
115
|
+
[200, {'Content-Length' => '16'}, 'From downstream!']}
|
116
|
+
class TestMiddlewareContentLength < Sinatra::Base
|
117
|
+
get '/forward' do
|
118
|
+
res = forward
|
119
|
+
'From after explicit forward!'
|
120
|
+
end
|
67
121
|
end
|
68
122
|
|
69
|
-
|
70
|
-
|
71
|
-
get '/foo' do
|
72
|
-
redirect back
|
73
|
-
end
|
74
|
-
}
|
123
|
+
middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
|
124
|
+
request_content_length = Rack::MockRequest.new(middleware_content_length)
|
75
125
|
|
76
|
-
|
77
|
-
response =
|
78
|
-
|
79
|
-
assert_equal "http://github.com", response.location
|
126
|
+
it "sets content length for last response" do
|
127
|
+
response = request_content_length.get('/forward')
|
128
|
+
assert_equal '28', response['Content-Length']
|
80
129
|
end
|
81
130
|
end
|
data/test/erb_test.rb
CHANGED
@@ -47,4 +47,35 @@ describe "ERB Templates" do
|
|
47
47
|
assert ok?
|
48
48
|
assert_equal "ERB Layout!\nHello World\n", body
|
49
49
|
end
|
50
|
+
|
51
|
+
it "renders erb with blocks" do
|
52
|
+
mock_app {
|
53
|
+
def container
|
54
|
+
@_out_buf << "THIS."
|
55
|
+
yield
|
56
|
+
@_out_buf << "SPARTA!"
|
57
|
+
end
|
58
|
+
def is; "IS." end
|
59
|
+
get '/' do
|
60
|
+
erb '<% container do %> <%= is %> <% end %>'
|
61
|
+
end
|
62
|
+
}
|
63
|
+
get '/'
|
64
|
+
assert ok?
|
65
|
+
assert_equal 'THIS. IS. SPARTA!', body
|
66
|
+
end
|
67
|
+
|
68
|
+
it "can be used in a nested fashion for partials and whatnot" do
|
69
|
+
mock_app {
|
70
|
+
template(:inner) { "<inner><%= 'hi' %></inner>" }
|
71
|
+
template(:outer) { "<outer><%= erb :inner %></outer>" }
|
72
|
+
get '/' do
|
73
|
+
erb :outer
|
74
|
+
end
|
75
|
+
}
|
76
|
+
|
77
|
+
get '/'
|
78
|
+
assert ok?
|
79
|
+
assert_equal '<outer><inner>hi</inner></outer>', body
|
80
|
+
end
|
50
81
|
end
|
data/test/extensions_test.rb
CHANGED
@@ -60,4 +60,25 @@ describe 'Registering extensions' do
|
|
60
60
|
assert !Sinatra::Base.respond_to?(:baz)
|
61
61
|
assert Sinatra::Default.respond_to?(:baz)
|
62
62
|
end
|
63
|
+
|
64
|
+
module BizzleExtension
|
65
|
+
def bizzle
|
66
|
+
bizzle_option
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.registered(base)
|
70
|
+
fail "base should be BizzleApp" unless base == BizzleApp
|
71
|
+
fail "base should have already extended BizzleExtension" unless base.respond_to?(:bizzle)
|
72
|
+
base.set :bizzle_option, 'bizzle!'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class BizzleApp < Sinatra::Base
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'sends .registered to the extension module after extending the class' do
|
80
|
+
BizzleApp.register BizzleExtension
|
81
|
+
assert_equal 'bizzle!', BizzleApp.bizzle_option
|
82
|
+
assert_equal 'bizzle!', BizzleApp.bizzle
|
83
|
+
end
|
63
84
|
end
|
data/test/helper.rb
CHANGED
@@ -8,21 +8,40 @@ end
|
|
8
8
|
libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
|
9
9
|
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
10
10
|
|
11
|
-
require '
|
12
|
-
require 'sinatra/test
|
11
|
+
require 'test/unit'
|
12
|
+
require 'sinatra/test'
|
13
|
+
|
14
|
+
class Sinatra::Base
|
15
|
+
# Allow assertions in request context
|
16
|
+
include Test::Unit::Assertions
|
17
|
+
end
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
include Sinatra::Test
|
21
|
+
|
22
|
+
def setup
|
23
|
+
Sinatra::Default.set :environment, :test
|
24
|
+
end
|
13
25
|
|
14
|
-
module Sinatra::Test
|
15
26
|
# Sets up a Sinatra::Base subclass defined with the block
|
16
27
|
# given. Used in setup or individual spec methods to establish
|
17
28
|
# the application.
|
18
29
|
def mock_app(base=Sinatra::Base, &block)
|
19
30
|
@app = Sinatra.new(base, &block)
|
20
31
|
end
|
21
|
-
end
|
22
32
|
|
23
|
-
|
24
|
-
|
25
|
-
|
33
|
+
def restore_default_options
|
34
|
+
Sinatra::Default.set(
|
35
|
+
:environment => :development,
|
36
|
+
:raise_errors => Proc.new { test? },
|
37
|
+
:dump_errors => true,
|
38
|
+
:sessions => false,
|
39
|
+
:logging => Proc.new { ! test? },
|
40
|
+
:methodoverride => true,
|
41
|
+
:static => true,
|
42
|
+
:run => Proc.new { ! test? }
|
43
|
+
)
|
44
|
+
end
|
26
45
|
end
|
27
46
|
|
28
47
|
##
|
@@ -31,7 +50,7 @@ end
|
|
31
50
|
# chris@ozmm.org
|
32
51
|
#
|
33
52
|
def describe(*args, &block)
|
34
|
-
return super unless (name = args.first) && block
|
53
|
+
return super unless (name = args.first.capitalize) && block
|
35
54
|
name = "#{name.gsub(/\W/, '')}Test"
|
36
55
|
Object.send :const_set, name, Class.new(Test::Unit::TestCase)
|
37
56
|
klass = Object.const_get(name)
|
@@ -44,6 +63,17 @@ def describe(*args, &block)
|
|
44
63
|
def self.after(&block) define_method(:teardown, &block) end
|
45
64
|
end
|
46
65
|
klass.class_eval &block
|
66
|
+
klass
|
67
|
+
end
|
68
|
+
|
69
|
+
def describe_option(name, &block)
|
70
|
+
klass = describe("Option #{name}", &block)
|
71
|
+
klass.before do
|
72
|
+
restore_default_options
|
73
|
+
@base = Sinatra.new
|
74
|
+
@default = Class.new(Sinatra::Default)
|
75
|
+
end
|
76
|
+
klass
|
47
77
|
end
|
48
78
|
|
49
79
|
# Do not output warnings for the duration of the block.
|
data/test/helpers_test.rb
CHANGED
@@ -68,6 +68,20 @@ describe 'Helpers#redirect' do
|
|
68
68
|
assert_equal '', body
|
69
69
|
assert_equal '/foo', response['Location']
|
70
70
|
end
|
71
|
+
|
72
|
+
it 'redirects back to request.referer when passed back' do
|
73
|
+
mock_app {
|
74
|
+
get '/try_redirect' do
|
75
|
+
redirect back
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
request = Rack::MockRequest.new(@app)
|
80
|
+
response = request.get('/try_redirect', 'HTTP_REFERER' => '/foo')
|
81
|
+
assert_equal 302, response.status
|
82
|
+
assert_equal '/foo', response['Location']
|
83
|
+
end
|
84
|
+
|
71
85
|
end
|
72
86
|
|
73
87
|
describe 'Helpers#error' do
|
@@ -380,6 +394,20 @@ describe 'Helpers#etag' do
|
|
380
394
|
end
|
381
395
|
end
|
382
396
|
|
397
|
+
describe 'Helpers#back' do
|
398
|
+
it "makes redirecting back pretty" do
|
399
|
+
mock_app {
|
400
|
+
get '/foo' do
|
401
|
+
redirect back
|
402
|
+
end
|
403
|
+
}
|
404
|
+
|
405
|
+
get '/foo', {}, 'HTTP_REFERER' => 'http://github.com'
|
406
|
+
assert redirect?
|
407
|
+
assert_equal "http://github.com", response.location
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
383
411
|
module HelperOne; def one; '1'; end; end
|
384
412
|
module HelperTwo; def two; '2'; end; end
|
385
413
|
|
data/test/middleware_test.rb
CHANGED
@@ -57,4 +57,12 @@ describe "Middleware" do
|
|
57
57
|
assert_equal '/foo', body
|
58
58
|
assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests']
|
59
59
|
end
|
60
|
+
|
61
|
+
it "works when app is used as middleware" do
|
62
|
+
@app.use UpcaseMiddleware
|
63
|
+
@app = @app.new
|
64
|
+
get '/Foo'
|
65
|
+
assert_equal "/FOO", body
|
66
|
+
assert_equal "UpcaseMiddleware", response['X-Tests']
|
67
|
+
end
|
60
68
|
end
|