sinatra 1.0 → 1.1.a
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- data/CHANGES +108 -1
- data/LICENSE +1 -1
- data/README.de.rdoc +1024 -0
- data/README.es.rdoc +1047 -0
- data/README.fr.rdoc +1038 -0
- data/README.hu.rdoc +607 -0
- data/README.jp.rdoc +473 -15
- data/README.rdoc +429 -41
- data/Rakefile +17 -6
- data/lib/sinatra/base.rb +357 -158
- data/lib/sinatra/showexceptions.rb +9 -1
- data/sinatra.gemspec +52 -9
- data/test/builder_test.rb +25 -1
- data/test/coffee_test.rb +88 -0
- data/test/encoding_test.rb +18 -0
- data/test/filter_test.rb +61 -2
- data/test/hello.mab +1 -0
- data/test/helper.rb +1 -0
- data/test/helpers_test.rb +141 -37
- data/test/less_test.rb +26 -2
- data/test/liquid_test.rb +58 -0
- data/test/markaby_test.rb +58 -0
- data/test/markdown_test.rb +35 -0
- data/test/nokogiri_test.rb +69 -0
- data/test/radius_test.rb +59 -0
- data/test/rdoc_test.rb +34 -0
- data/test/request_test.rb +12 -0
- data/test/routing_test.rb +35 -1
- data/test/sass_test.rb +46 -16
- data/test/scss_test.rb +88 -0
- data/test/settings_test.rb +32 -0
- data/test/sinatra_test.rb +4 -0
- data/test/static_test.rb +64 -0
- data/test/templates_test.rb +55 -1
- data/test/textile_test.rb +34 -0
- data/test/views/ascii.haml +2 -0
- data/test/views/explicitly_nested.str +1 -0
- data/test/views/hello.coffee +1 -0
- data/test/views/hello.liquid +1 -0
- data/test/views/hello.mab +1 -0
- data/test/views/hello.md +1 -0
- data/test/views/hello.nokogiri +1 -0
- data/test/views/hello.radius +1 -0
- data/test/views/hello.rdoc +1 -0
- data/test/views/hello.sass +1 -1
- data/test/views/hello.scss +3 -0
- data/test/views/hello.str +1 -0
- data/test/views/hello.textile +1 -0
- data/test/views/layout2.liquid +2 -0
- data/test/views/layout2.mab +2 -0
- data/test/views/layout2.nokogiri +3 -0
- data/test/views/layout2.radius +2 -0
- data/test/views/layout2.str +2 -0
- data/test/views/nested.str +1 -0
- data/test/views/utf8.haml +2 -0
- metadata +240 -33
- data/lib/sinatra/tilt.rb +0 -746
data/test/less_test.rb
CHANGED
@@ -2,20 +2,44 @@ require File.dirname(__FILE__) + '/helper'
|
|
2
2
|
require 'less'
|
3
3
|
|
4
4
|
class LessTest < Test::Unit::TestCase
|
5
|
-
def less_app(&block)
|
5
|
+
def less_app(options = {}, &block)
|
6
6
|
mock_app {
|
7
7
|
set :views, File.dirname(__FILE__) + '/views'
|
8
|
+
set options
|
8
9
|
get '/', &block
|
9
10
|
}
|
10
11
|
get '/'
|
11
12
|
end
|
12
13
|
|
13
14
|
it 'renders inline Less strings' do
|
14
|
-
less_app { less "@white_color: #fff; #main { background-color: @white_color }"}
|
15
|
+
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
15
16
|
assert ok?
|
16
17
|
assert_equal "#main { background-color: #ffffff; }\n", body
|
17
18
|
end
|
18
19
|
|
20
|
+
it 'defaults content type to css' do
|
21
|
+
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
22
|
+
assert ok?
|
23
|
+
assert_equal "text/css;charset=utf-8", response['Content-Type']
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'defaults allows setting content type per route' do
|
27
|
+
less_app do
|
28
|
+
content_type :html
|
29
|
+
less "@white_color: #fff; #main { background-color: @white_color }"
|
30
|
+
end
|
31
|
+
assert ok?
|
32
|
+
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'defaults allows setting content type globally' do
|
36
|
+
less_app(:less => { :content_type => 'html' }) do
|
37
|
+
less "@white_color: #fff; #main { background-color: @white_color }"
|
38
|
+
end
|
39
|
+
assert ok?
|
40
|
+
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
41
|
+
end
|
42
|
+
|
19
43
|
it 'renders .less files in views path' do
|
20
44
|
less_app { less :hello }
|
21
45
|
assert ok?
|
data/test/liquid_test.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'liquid'
|
5
|
+
|
6
|
+
class LiquidTest < Test::Unit::TestCase
|
7
|
+
def liquid_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline liquid strings' do
|
16
|
+
liquid_app { liquid '<h1>Hiya</h1>' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal "<h1>Hiya</h1>", body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders .liquid files in views path' do
|
22
|
+
liquid_app { liquid :hello }
|
23
|
+
assert ok?
|
24
|
+
assert_equal "<h1>Hello From Liquid</h1>\n", body
|
25
|
+
end
|
26
|
+
|
27
|
+
it "renders with inline layouts" do
|
28
|
+
mock_app do
|
29
|
+
layout { "<h1>THIS. IS. {{ yield }}</h1>" }
|
30
|
+
get('/') { liquid '<EM>SPARTA</EM>' }
|
31
|
+
end
|
32
|
+
get '/'
|
33
|
+
assert ok?
|
34
|
+
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>", body
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renders with file layouts" do
|
38
|
+
liquid_app { liquid 'Hello World', :layout => :layout2 }
|
39
|
+
assert ok?
|
40
|
+
assert_equal "<h1>Liquid Layout!</h1>\n<p>Hello World</p>\n", body
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises error if template not found" do
|
44
|
+
mock_app { get('/') { liquid :no_such_template } }
|
45
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "allows passing locals" do
|
49
|
+
liquid_app do
|
50
|
+
liquid '{{ value }}', :locals => { :value => 'foo' }
|
51
|
+
end
|
52
|
+
assert ok?
|
53
|
+
assert_equal 'foo', body
|
54
|
+
end
|
55
|
+
end
|
56
|
+
rescue
|
57
|
+
warn "#{$!.to_s}: skipping liquid tests"
|
58
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'markaby'
|
5
|
+
|
6
|
+
class MarkabyTest < Test::Unit::TestCase
|
7
|
+
def markaby_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline markaby strings' do
|
16
|
+
markaby_app { markaby 'h1 "Hiya"' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal "<h1>Hiya</h1>", body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders .markaby files in views path' do
|
22
|
+
markaby_app { markaby :hello }
|
23
|
+
assert ok?
|
24
|
+
assert_equal "<h1>Hello From Markaby</h1>", body
|
25
|
+
end
|
26
|
+
|
27
|
+
it "renders with inline layouts" do
|
28
|
+
mock_app do
|
29
|
+
layout { 'h1 { text "THIS. IS. "; yield }' }
|
30
|
+
get('/') { markaby 'em "SPARTA"' }
|
31
|
+
end
|
32
|
+
get '/'
|
33
|
+
assert ok?
|
34
|
+
assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renders with file layouts" do
|
38
|
+
markaby_app { markaby 'text "Hello World"', :layout => :layout2 }
|
39
|
+
assert ok?
|
40
|
+
assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises error if template not found" do
|
44
|
+
mock_app { get('/') { markaby :no_such_template } }
|
45
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "allows passing locals" do
|
49
|
+
markaby_app do
|
50
|
+
markaby 'text value', :locals => { :value => 'foo' }
|
51
|
+
end
|
52
|
+
assert ok?
|
53
|
+
assert_equal 'foo', body
|
54
|
+
end
|
55
|
+
end
|
56
|
+
rescue
|
57
|
+
warn "#{$!.to_s}: skipping markaby tests"
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
begin
|
4
|
+
fail "rdiscount not available" if defined? JRuby
|
5
|
+
require 'rdiscount'
|
6
|
+
|
7
|
+
class MarkdownTest < Test::Unit::TestCase
|
8
|
+
def markdown_app(&block)
|
9
|
+
mock_app do
|
10
|
+
set :views, File.dirname(__FILE__) + '/views'
|
11
|
+
get '/', &block
|
12
|
+
end
|
13
|
+
get '/'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'renders inline markdown strings' do
|
17
|
+
markdown_app { markdown '# Hiya' }
|
18
|
+
assert ok?
|
19
|
+
assert_equal "<h1>Hiya</h1>\n", body
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'renders .markdown files in views path' do
|
23
|
+
markdown_app { markdown :hello }
|
24
|
+
assert ok?
|
25
|
+
assert_equal "<h1>Hello From Markdown</h1>\n", body
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raises error if template not found" do
|
29
|
+
mock_app { get('/') { markdown :no_such_template } }
|
30
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
rescue
|
34
|
+
warn "#{$!.to_s}: skipping markdown tests"
|
35
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
class NokogiriTest < Test::Unit::TestCase
|
7
|
+
def nokogiri_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline Nokogiri strings' do
|
16
|
+
nokogiri_app { nokogiri 'xml' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal %{<?xml version="1.0"?>\n}, body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders inline blocks' do
|
22
|
+
nokogiri_app do
|
23
|
+
@name = "Frank & Mary"
|
24
|
+
nokogiri do |xml|
|
25
|
+
xml.couple @name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
assert ok?
|
29
|
+
assert_equal "<?xml version=\"1.0\"?>\n<couple>Frank & Mary</couple>\n", body
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'renders .nokogiri files in views path' do
|
33
|
+
nokogiri_app do
|
34
|
+
@name = "Blue"
|
35
|
+
nokogiri :hello
|
36
|
+
end
|
37
|
+
assert ok?
|
38
|
+
assert_equal %(<?xml version="1.0"?>\n<exclaim>You're my boy, Blue!</exclaim>\n), body
|
39
|
+
end
|
40
|
+
|
41
|
+
it "renders with inline layouts" do
|
42
|
+
next if Tilt::VERSION <= "1.1"
|
43
|
+
mock_app do
|
44
|
+
layout { %(xml.layout { xml << yield }) }
|
45
|
+
get('/') { nokogiri %(xml.em 'Hello World') }
|
46
|
+
end
|
47
|
+
get '/'
|
48
|
+
assert ok?
|
49
|
+
assert_equal "<?xml version=\"1.0\"?>\n<layout>\n <em>Hello World</em>\n</layout>\n", body
|
50
|
+
end
|
51
|
+
|
52
|
+
it "renders with file layouts" do
|
53
|
+
next if Tilt::VERSION <= "1.1"
|
54
|
+
nokogiri_app do
|
55
|
+
@name = "Blue"
|
56
|
+
nokogiri %(xml.em 'Hello World'), :layout => :layout2
|
57
|
+
end
|
58
|
+
assert ok?
|
59
|
+
assert_equal "<?xml version=\"1.0\"?>\n<layout>\n <em>Hello World</em>\n</layout>\n", body
|
60
|
+
end
|
61
|
+
|
62
|
+
it "raises error if template not found" do
|
63
|
+
mock_app { get('/') { nokogiri :no_such_template } }
|
64
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
rescue
|
68
|
+
warn "#{$!.to_s}: skipping nokogiri tests"
|
69
|
+
end
|
data/test/radius_test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
begin
|
4
|
+
fail 'Radius broken on 1.9.' if RUBY_VERSION >= '1.9.1'
|
5
|
+
require 'radius'
|
6
|
+
|
7
|
+
class RadiusTest < Test::Unit::TestCase
|
8
|
+
def radius_app(&block)
|
9
|
+
mock_app do
|
10
|
+
set :views, File.dirname(__FILE__) + '/views'
|
11
|
+
get '/', &block
|
12
|
+
end
|
13
|
+
get '/'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'renders inline radius strings' do
|
17
|
+
radius_app { radius '<h1>Hiya</h1>' }
|
18
|
+
assert ok?
|
19
|
+
assert_equal "<h1>Hiya</h1>", body
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'renders .radius files in views path' do
|
23
|
+
radius_app { radius :hello }
|
24
|
+
assert ok?
|
25
|
+
assert_equal "<h1>Hello From Radius</h1>\n", body
|
26
|
+
end
|
27
|
+
|
28
|
+
it "renders with inline layouts" do
|
29
|
+
mock_app do
|
30
|
+
layout { "<h1>THIS. IS. <r:yield /></h1>" }
|
31
|
+
get('/') { radius '<EM>SPARTA</EM>' }
|
32
|
+
end
|
33
|
+
get '/'
|
34
|
+
assert ok?
|
35
|
+
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>", body
|
36
|
+
end
|
37
|
+
|
38
|
+
it "renders with file layouts" do
|
39
|
+
radius_app { radius 'Hello World', :layout => :layout2 }
|
40
|
+
assert ok?
|
41
|
+
assert_equal "<h1>Radius Layout!</h1>\n<p>Hello World</p>\n", body
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises error if template not found" do
|
45
|
+
mock_app { get('/') { radius :no_such_template } }
|
46
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
47
|
+
end
|
48
|
+
|
49
|
+
it "allows passing locals" do
|
50
|
+
radius_app do
|
51
|
+
radius '<r:value />', :locals => { :value => 'foo' }
|
52
|
+
end
|
53
|
+
assert ok?
|
54
|
+
assert_equal 'foo', body
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue
|
58
|
+
warn "#{$!.to_s}: skipping radius tests"
|
59
|
+
end
|
data/test/rdoc_test.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rdoc'
|
5
|
+
|
6
|
+
class RdocTest < Test::Unit::TestCase
|
7
|
+
def rdoc_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline rdoc strings' do
|
16
|
+
rdoc_app { rdoc '= Hiya' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal "<h1>Hiya</h1>\n", body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders .rdoc files in views path' do
|
22
|
+
rdoc_app { rdoc :hello }
|
23
|
+
assert ok?
|
24
|
+
assert_equal "<h1>Hello From RDoc</h1>\n", body
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises error if template not found" do
|
28
|
+
mock_app { get('/') { rdoc :no_such_template } }
|
29
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue
|
33
|
+
warn "#{$!.to_s}: skipping rdoc tests"
|
34
|
+
end
|
data/test/request_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/helper'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
class RequestTest < Test::Unit::TestCase
|
4
5
|
it 'responds to #user_agent' do
|
@@ -30,4 +31,15 @@ class RequestTest < Test::Unit::TestCase
|
|
30
31
|
request = Sinatra::Request.new('HTTP_X_FORWARDED_PROTO' => 'https')
|
31
32
|
assert request.secure?
|
32
33
|
end
|
34
|
+
|
35
|
+
it 'is possible to marshal params' do
|
36
|
+
request = Sinatra::Request.new(
|
37
|
+
'REQUEST_METHOD' => 'PUT',
|
38
|
+
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
39
|
+
'rack.input' => StringIO.new('foo=bar')
|
40
|
+
)
|
41
|
+
params = Sinatra::Base.new.send(:indifferent_hash).replace(request.params)
|
42
|
+
dumped = Marshal.dump(request.params)
|
43
|
+
assert_equal 'bar', Marshal.load(dumped)['foo']
|
44
|
+
end
|
33
45
|
end
|
data/test/routing_test.rb
CHANGED
@@ -80,10 +80,22 @@ class RoutingTest < Test::Unit::TestCase
|
|
80
80
|
|
81
81
|
get '/foo'
|
82
82
|
assert_equal 404, status
|
83
|
-
assert_equal 'text/html', response["Content-Type"]
|
83
|
+
assert_equal 'text/html;charset=utf-8', response["Content-Type"]
|
84
84
|
assert_equal "<h1>Not Found</h1>", response.body
|
85
85
|
end
|
86
86
|
|
87
|
+
it 'matches empty PATH_INFO to "/"' do
|
88
|
+
mock_app {
|
89
|
+
get '/' do
|
90
|
+
'worked'
|
91
|
+
end
|
92
|
+
}
|
93
|
+
|
94
|
+
get '/', {}, "PATH_INFO" => ""
|
95
|
+
assert ok?
|
96
|
+
assert_equal 'worked', body
|
97
|
+
end
|
98
|
+
|
87
99
|
it 'takes multiple definitions of a route' do
|
88
100
|
mock_app {
|
89
101
|
user_agent(/Foo/)
|
@@ -344,6 +356,18 @@ class RoutingTest < Test::Unit::TestCase
|
|
344
356
|
assert_equal 'looks good', body
|
345
357
|
end
|
346
358
|
|
359
|
+
it "matches paths that include ampersands" do
|
360
|
+
mock_app {
|
361
|
+
get '/:name' do
|
362
|
+
'looks good'
|
363
|
+
end
|
364
|
+
}
|
365
|
+
|
366
|
+
get '/foo&bar'
|
367
|
+
assert ok?
|
368
|
+
assert_equal 'looks good', body
|
369
|
+
end
|
370
|
+
|
347
371
|
it "URL decodes named parameters and splats" do
|
348
372
|
mock_app {
|
349
373
|
get '/:foo/*' do
|
@@ -595,6 +619,9 @@ class RoutingTest < Test::Unit::TestCase
|
|
595
619
|
get '/', :provides => :xml do
|
596
620
|
request.env['HTTP_ACCEPT']
|
597
621
|
end
|
622
|
+
get '/foo', :provides => :html do
|
623
|
+
request.env['HTTP_ACCEPT']
|
624
|
+
end
|
598
625
|
}
|
599
626
|
|
600
627
|
get '/', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
@@ -604,6 +631,13 @@ class RoutingTest < Test::Unit::TestCase
|
|
604
631
|
|
605
632
|
get '/', {}, { :accept => 'text/html' }
|
606
633
|
assert !ok?
|
634
|
+
|
635
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html;q=0.9' }
|
636
|
+
assert ok?
|
637
|
+
assert_equal 'text/html;q=0.9', body
|
638
|
+
|
639
|
+
get '/foo', {}, { 'HTTP_ACCEPT' => '' }
|
640
|
+
assert !ok?
|
607
641
|
end
|
608
642
|
|
609
643
|
it "allows multiple mime types for accept header" do
|