sinatra-sinatra 0.8.9
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/AUTHORS +40 -0
- data/CHANGES +174 -0
- data/LICENSE +22 -0
- data/README.rdoc +545 -0
- data/Rakefile +180 -0
- data/compat/app_test.rb +300 -0
- data/compat/application_test.rb +334 -0
- data/compat/builder_test.rb +101 -0
- data/compat/custom_error_test.rb +62 -0
- data/compat/erb_test.rb +136 -0
- data/compat/events_test.rb +78 -0
- data/compat/filter_test.rb +30 -0
- data/compat/haml_test.rb +233 -0
- data/compat/helper.rb +30 -0
- data/compat/mapped_error_test.rb +72 -0
- data/compat/pipeline_test.rb +71 -0
- data/compat/public/foo.xml +1 -0
- data/compat/sass_test.rb +57 -0
- data/compat/sessions_test.rb +39 -0
- data/compat/streaming_test.rb +121 -0
- data/compat/sym_params_test.rb +19 -0
- data/compat/template_test.rb +30 -0
- data/compat/use_in_file_templates_test.rb +47 -0
- data/compat/views/foo.builder +1 -0
- data/compat/views/foo.erb +1 -0
- data/compat/views/foo.haml +1 -0
- data/compat/views/foo.sass +2 -0
- data/compat/views/foo_layout.erb +2 -0
- data/compat/views/foo_layout.haml +2 -0
- data/compat/views/layout_test/foo.builder +1 -0
- data/compat/views/layout_test/foo.erb +1 -0
- data/compat/views/layout_test/foo.haml +1 -0
- data/compat/views/layout_test/foo.sass +2 -0
- data/compat/views/layout_test/layout.builder +3 -0
- data/compat/views/layout_test/layout.erb +1 -0
- data/compat/views/layout_test/layout.haml +1 -0
- data/compat/views/layout_test/layout.sass +2 -0
- data/compat/views/no_layout/no_layout.builder +1 -0
- data/compat/views/no_layout/no_layout.haml +1 -0
- data/lib/sinatra/base.rb +818 -0
- data/lib/sinatra/compat.rb +239 -0
- data/lib/sinatra/images/404.png +0 -0
- data/lib/sinatra/images/500.png +0 -0
- data/lib/sinatra/main.rb +48 -0
- data/lib/sinatra/test/bacon.rb +17 -0
- data/lib/sinatra/test/rspec.rb +9 -0
- data/lib/sinatra/test/spec.rb +9 -0
- data/lib/sinatra/test/unit.rb +11 -0
- data/lib/sinatra/test.rb +109 -0
- data/lib/sinatra.rb +4 -0
- data/sinatra.gemspec +109 -0
- data/test/base_test.rb +68 -0
- data/test/builder_test.rb +64 -0
- data/test/data/reload_app_file.rb +3 -0
- data/test/erb_test.rb +50 -0
- data/test/filter_test.rb +35 -0
- data/test/haml_test.rb +68 -0
- data/test/helper.rb +20 -0
- data/test/helpers_test.rb +361 -0
- data/test/mapped_error_test.rb +160 -0
- data/test/middleware_test.rb +58 -0
- data/test/options_test.rb +97 -0
- data/test/reload_test.rb +61 -0
- data/test/request_test.rb +9 -0
- data/test/result_test.rb +88 -0
- data/test/routing_test.rb +334 -0
- data/test/sass_test.rb +36 -0
- data/test/sinatra_test.rb +13 -0
- data/test/static_test.rb +57 -0
- data/test/templates_test.rb +88 -0
- data/test/views/hello.builder +1 -0
- data/test/views/hello.erb +1 -0
- data/test/views/hello.haml +1 -0
- data/test/views/hello.sass +2 -0
- data/test/views/hello.test +1 -0
- data/test/views/layout2.builder +3 -0
- data/test/views/layout2.erb +2 -0
- data/test/views/layout2.haml +2 -0
- data/test/views/layout2.test +1 -0
- metadata +161 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class FooError < RuntimeError; end
|
4
|
+
|
5
|
+
context "Mapped errors" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
Sinatra.application = nil
|
9
|
+
Sinatra.application.options.raise_errors = false
|
10
|
+
end
|
11
|
+
|
12
|
+
specify "are rescued and run in context" do
|
13
|
+
|
14
|
+
error FooError do
|
15
|
+
'MAPPED ERROR!'
|
16
|
+
end
|
17
|
+
|
18
|
+
get '/' do
|
19
|
+
raise FooError
|
20
|
+
end
|
21
|
+
|
22
|
+
get_it '/'
|
23
|
+
|
24
|
+
should.be.server_error
|
25
|
+
body.should.equal 'MAPPED ERROR!'
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
specify "renders empty if no each method on result" do
|
30
|
+
|
31
|
+
error FooError do
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
get '/' do
|
36
|
+
raise FooError
|
37
|
+
end
|
38
|
+
|
39
|
+
get_it '/'
|
40
|
+
|
41
|
+
should.be.server_error
|
42
|
+
body.should.be.empty
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
specify "doesn't override status if set" do
|
47
|
+
|
48
|
+
error FooError do
|
49
|
+
status(200)
|
50
|
+
end
|
51
|
+
|
52
|
+
get '/' do
|
53
|
+
raise FooError
|
54
|
+
end
|
55
|
+
|
56
|
+
get_it '/'
|
57
|
+
|
58
|
+
should.be.ok
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "raises errors when the raise_errors option is set" do
|
63
|
+
Sinatra.application.options.raise_errors = true
|
64
|
+
error FooError do
|
65
|
+
end
|
66
|
+
get '/' do
|
67
|
+
raise FooError
|
68
|
+
end
|
69
|
+
assert_raises(FooError) { get_it('/') }
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class UpcaseMiddleware
|
4
|
+
def initialize(app, *args, &block)
|
5
|
+
@app = app
|
6
|
+
@args = args
|
7
|
+
@block = block
|
8
|
+
end
|
9
|
+
def call(env)
|
10
|
+
env['PATH_INFO'] = env['PATH_INFO'].to_s.upcase
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "Middleware Pipelines" do
|
16
|
+
|
17
|
+
setup do
|
18
|
+
Sinatra.application = nil
|
19
|
+
@app = Sinatra.application
|
20
|
+
end
|
21
|
+
|
22
|
+
teardown do
|
23
|
+
Sinatra.application = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# Sessions and logging are tested elsewhere. This is a bad test because it
|
27
|
+
# asserts things about the implementation and not the effect.
|
28
|
+
xspecify "includes default middleware with options set" do
|
29
|
+
@app.set_options :sessions => true, :logging => true
|
30
|
+
@app.send(:optional_middleware).should.include([Rack::Session::Cookie, [], nil])
|
31
|
+
@app.send(:optional_middleware).should.include([Rack::CommonLogger, [], nil])
|
32
|
+
end
|
33
|
+
|
34
|
+
# Bad test.
|
35
|
+
xspecify "does not include default middleware with options unset" do
|
36
|
+
@app.set_options :sessions => false, :logging => false
|
37
|
+
@app.send(:optional_middleware).should.not.include([Rack::Session::Cookie, [], nil])
|
38
|
+
@app.send(:optional_middleware).should.not.include([Rack::CommonLogger, [], nil])
|
39
|
+
end
|
40
|
+
|
41
|
+
# Bad test.
|
42
|
+
xspecify "includes only optional middleware when no explicit middleware added" do
|
43
|
+
@app.set_options :sessions => true, :logging => true
|
44
|
+
@app.send(:middleware).should.equal @app.send(:optional_middleware)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Bad test.
|
48
|
+
xspecify "should clear middleware before reload" do
|
49
|
+
@app.clearables.should.include(@app.send(:explicit_middleware))
|
50
|
+
end
|
51
|
+
|
52
|
+
specify "should add middleware with use" do
|
53
|
+
block = Proc.new { |env| }
|
54
|
+
@app.use UpcaseMiddleware
|
55
|
+
@app.use UpcaseMiddleware, "foo", "bar"
|
56
|
+
@app.use UpcaseMiddleware, "foo", "bar", &block
|
57
|
+
@app.send(:middleware).should.include([UpcaseMiddleware, [], nil])
|
58
|
+
@app.send(:middleware).should.include([UpcaseMiddleware, ["foo", "bar"], nil])
|
59
|
+
@app.send(:middleware).should.include([UpcaseMiddleware, ["foo", "bar"], block])
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "should run middleware added with use" do
|
63
|
+
get('/foo') { "FAIL!" }
|
64
|
+
get('/FOO') { "PASS!" }
|
65
|
+
use UpcaseMiddleware
|
66
|
+
get_it '/foo'
|
67
|
+
should.be.ok
|
68
|
+
body.should.equal "PASS!"
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<foo></foo>
|
data/compat/sass_test.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Sass" do
|
4
|
+
|
5
|
+
setup do
|
6
|
+
Sinatra.application = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Templates (in general)" do
|
10
|
+
|
11
|
+
setup do
|
12
|
+
Sinatra.application = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "are read from files if Symbols" do
|
16
|
+
|
17
|
+
get '/from_file' do
|
18
|
+
sass :foo, :views_directory => File.dirname(__FILE__) + "/views"
|
19
|
+
end
|
20
|
+
|
21
|
+
get_it '/from_file'
|
22
|
+
should.be.ok
|
23
|
+
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "raise an error if template not found" do
|
28
|
+
get '/' do
|
29
|
+
sass :not_found
|
30
|
+
end
|
31
|
+
|
32
|
+
lambda { get_it '/' }.should.raise(Errno::ENOENT)
|
33
|
+
end
|
34
|
+
|
35
|
+
specify "ignore default layout file with .sass extension" do
|
36
|
+
get '/' do
|
37
|
+
sass :foo, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
|
38
|
+
end
|
39
|
+
|
40
|
+
get_it '/'
|
41
|
+
should.be.ok
|
42
|
+
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
specify "ignore explicitly specified layout file" do
|
46
|
+
get '/' do
|
47
|
+
sass :foo, :layout => :layout, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
|
48
|
+
end
|
49
|
+
|
50
|
+
get_it '/'
|
51
|
+
should.be.ok
|
52
|
+
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Sessions" do
|
4
|
+
|
5
|
+
setup { Sinatra.application = nil }
|
6
|
+
|
7
|
+
specify "should be off by default" do
|
8
|
+
get '/asdf' do
|
9
|
+
session[:test] = true
|
10
|
+
"asdf"
|
11
|
+
end
|
12
|
+
|
13
|
+
get '/test' do
|
14
|
+
session[:test] == true ? "true" : "false"
|
15
|
+
end
|
16
|
+
|
17
|
+
get_it '/asdf', {}, 'HTTP_HOST' => 'foo.sinatrarb.com'
|
18
|
+
assert ok?
|
19
|
+
assert !include?('Set-Cookie')
|
20
|
+
end
|
21
|
+
|
22
|
+
specify "should be able to store data accross requests" do
|
23
|
+
set_option :sessions, true
|
24
|
+
|
25
|
+
get '/foo' do
|
26
|
+
session[:test] = true
|
27
|
+
"asdf"
|
28
|
+
end
|
29
|
+
|
30
|
+
get '/bar' do
|
31
|
+
session[:test] == true ? "true" : "false"
|
32
|
+
end
|
33
|
+
|
34
|
+
get_it '/foo', :env => { :host => 'foo.sinatrarb.com' }
|
35
|
+
assert ok?
|
36
|
+
assert include?('Set-Cookie')
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Static files (by default)" do
|
4
|
+
|
5
|
+
setup do
|
6
|
+
Sinatra.application = nil
|
7
|
+
Sinatra.application.options.public = File.dirname(__FILE__) + '/public'
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "are served from root/public" do
|
11
|
+
get_it '/foo.xml'
|
12
|
+
should.be.ok
|
13
|
+
headers['Content-Length'].should.equal '12'
|
14
|
+
headers['Content-Type'].should.equal 'application/xml'
|
15
|
+
body.should.equal "<foo></foo>\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "are not served when verb is not GET or HEAD" do
|
19
|
+
post_it '/foo.xml'
|
20
|
+
# these should actually be giving back a 405 Method Not Allowed but that
|
21
|
+
# complicates the routing logic quite a bit.
|
22
|
+
should.be.not_found
|
23
|
+
status.should.equal 404
|
24
|
+
end
|
25
|
+
|
26
|
+
specify "are served when verb is HEAD but missing a body" do
|
27
|
+
head_it '/foo.xml'
|
28
|
+
should.be.ok
|
29
|
+
headers['Content-Length'].should.equal '12'
|
30
|
+
headers['Content-Type'].should.equal 'application/xml'
|
31
|
+
body.should.equal ""
|
32
|
+
end
|
33
|
+
|
34
|
+
# static files override dynamic/internal events and ...
|
35
|
+
specify "are served when conflicting events exists" do
|
36
|
+
get '/foo.xml' do
|
37
|
+
'this is not foo.xml!'
|
38
|
+
end
|
39
|
+
get_it '/foo.xml'
|
40
|
+
should.be.ok
|
41
|
+
body.should.equal "<foo></foo>\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
specify "are irrelevant when request_method is not GET/HEAD" do
|
45
|
+
put '/foo.xml' do
|
46
|
+
'putted!'
|
47
|
+
end
|
48
|
+
put_it '/foo.xml'
|
49
|
+
should.be.ok
|
50
|
+
body.should.equal 'putted!'
|
51
|
+
|
52
|
+
get_it '/foo.xml'
|
53
|
+
should.be.ok
|
54
|
+
body.should.equal "<foo></foo>\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "include a Last-Modified header" do
|
58
|
+
last_modified = File.mtime(Sinatra.application.options.public + '/foo.xml')
|
59
|
+
get_it('/foo.xml')
|
60
|
+
should.be.ok
|
61
|
+
body.should.not.be.empty
|
62
|
+
headers['Last-Modified'].should.equal last_modified.httpdate
|
63
|
+
end
|
64
|
+
|
65
|
+
# Deprecated. Use: ConditionalGet middleware.
|
66
|
+
specify "are not served when If-Modified-Since matches" do
|
67
|
+
last_modified = File.mtime(Sinatra.application.options.public + '/foo.xml')
|
68
|
+
@request = Rack::MockRequest.new(Sinatra.application)
|
69
|
+
@response = @request.get('/foo.xml', 'HTTP_IF_MODIFIED_SINCE' => last_modified.httpdate)
|
70
|
+
status.should.equal 304
|
71
|
+
body.should.be.empty
|
72
|
+
end
|
73
|
+
|
74
|
+
specify "should omit Content-Disposition headers" do
|
75
|
+
get_it('/foo.xml')
|
76
|
+
should.be.ok
|
77
|
+
headers['Content-Disposition'].should.be.nil
|
78
|
+
headers['Content-Transfer-Encoding'].should.be.nil
|
79
|
+
end
|
80
|
+
|
81
|
+
specify "should be served even if their path is url escaped" do
|
82
|
+
get_it('/fo%6f.xml')
|
83
|
+
should.be.ok
|
84
|
+
body.should.equal "<foo></foo>\n"
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
context "SendData" do
|
90
|
+
|
91
|
+
setup do
|
92
|
+
Sinatra.application = nil
|
93
|
+
end
|
94
|
+
|
95
|
+
# Deprecated. send_data is going away.
|
96
|
+
xspecify "should send the data with options" do
|
97
|
+
get '/' do
|
98
|
+
send_data 'asdf', :status => 500
|
99
|
+
end
|
100
|
+
|
101
|
+
get_it '/'
|
102
|
+
|
103
|
+
should.be.server_error
|
104
|
+
body.should.equal 'asdf'
|
105
|
+
end
|
106
|
+
|
107
|
+
# Deprecated. The Content-Disposition is no longer handled by sendfile.
|
108
|
+
specify "should include a Content-Disposition header" do
|
109
|
+
get '/' do
|
110
|
+
send_file File.dirname(__FILE__) + '/public/foo.xml'
|
111
|
+
end
|
112
|
+
|
113
|
+
get_it '/'
|
114
|
+
|
115
|
+
should.be.ok
|
116
|
+
headers['Content-Disposition'].should.not.be.nil
|
117
|
+
headers['Content-Disposition'].should.equal 'attachment; filename="foo.xml"'
|
118
|
+
headers['Content-Transfer-Encoding'].should.equal 'binary'
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Symbol Params" do
|
4
|
+
|
5
|
+
setup do
|
6
|
+
Sinatra.application = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
specify "should be accessable as Strings or Symbols" do
|
10
|
+
get '/' do
|
11
|
+
params[:foo] + params['foo']
|
12
|
+
end
|
13
|
+
|
14
|
+
get_it '/', :foo => "X"
|
15
|
+
assert_equal('XX', body)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Templates" do
|
4
|
+
|
5
|
+
specify "are read from files if Symbols" do
|
6
|
+
|
7
|
+
get '/from_file' do
|
8
|
+
@name = 'Alena'
|
9
|
+
erb :foo, :views_directory => File.dirname(__FILE__) + "/views"
|
10
|
+
end
|
11
|
+
|
12
|
+
get_it '/from_file'
|
13
|
+
|
14
|
+
body.should.equal 'You rock Alena!'
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "use layout.ext by default if available" do
|
19
|
+
|
20
|
+
get '/layout_from_file' do
|
21
|
+
erb :foo, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
|
22
|
+
end
|
23
|
+
|
24
|
+
get_it '/layout_from_file'
|
25
|
+
should.be.ok
|
26
|
+
body.should.equal "x This is foo! x \n"
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Rendering in file templates" do
|
4
|
+
|
5
|
+
setup do
|
6
|
+
Sinatra.application = nil
|
7
|
+
use_in_file_templates!
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "should set template" do
|
11
|
+
assert Sinatra.application.templates[:foo]
|
12
|
+
end
|
13
|
+
|
14
|
+
specify "should set layout" do
|
15
|
+
assert Sinatra.application.templates[:layout]
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should render without layout if specified" do
|
19
|
+
get '/' do
|
20
|
+
haml :foo, :layout => false
|
21
|
+
end
|
22
|
+
|
23
|
+
get_it '/'
|
24
|
+
assert_equal "this is foo\n", body
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "should render with layout if specified" do
|
28
|
+
get '/' do
|
29
|
+
haml :foo
|
30
|
+
end
|
31
|
+
|
32
|
+
get_it '/'
|
33
|
+
assert_equal "X\nthis is foo\nX\n", body
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
__END__
|
39
|
+
|
40
|
+
@@ foo
|
41
|
+
this is foo
|
42
|
+
|
43
|
+
@@ layout
|
44
|
+
X
|
45
|
+
= yield
|
46
|
+
X
|
47
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
xml.exclaim "You rock #{@name}!"
|
@@ -0,0 +1 @@
|
|
1
|
+
You rock <%= @name %>!
|
@@ -0,0 +1 @@
|
|
1
|
+
== You rock #{@name}!
|
@@ -0,0 +1 @@
|
|
1
|
+
xml.this "is foo!"
|
@@ -0,0 +1 @@
|
|
1
|
+
This is foo!
|
@@ -0,0 +1 @@
|
|
1
|
+
This is foo!
|
@@ -0,0 +1 @@
|
|
1
|
+
x <%= yield %> x
|
@@ -0,0 +1 @@
|
|
1
|
+
== x #{yield} x
|
@@ -0,0 +1 @@
|
|
1
|
+
xml.foo "No Layout!"
|
@@ -0,0 +1 @@
|
|
1
|
+
%h1 No Layout!
|