adamwiggins-sinatra 0.8.9 → 0.10.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/AUTHORS +8 -7
- data/CHANGES +211 -1
- data/LICENSE +1 -1
- data/README.rdoc +183 -139
- data/Rakefile +20 -81
- data/lib/sinatra.rb +5 -1
- data/lib/sinatra/base.rb +569 -278
- data/lib/sinatra/main.rb +12 -25
- data/lib/sinatra/showexceptions.rb +303 -0
- data/sinatra.gemspec +20 -44
- data/test/base_test.rb +140 -52
- data/test/builder_test.rb +14 -17
- data/test/contest.rb +64 -0
- data/test/erb_test.rb +42 -16
- data/test/extensions_test.rb +100 -0
- data/test/filter_test.rb +85 -13
- data/test/haml_test.rb +39 -21
- data/test/helper.rb +76 -0
- data/test/helpers_test.rb +219 -84
- data/test/mapped_error_test.rb +168 -146
- data/test/middleware_test.rb +22 -17
- data/test/options_test.rb +323 -54
- data/test/render_backtrace_test.rb +145 -0
- data/test/request_test.rb +28 -6
- data/test/response_test.rb +42 -0
- data/test/result_test.rb +27 -21
- data/test/route_added_hook_test.rb +59 -0
- data/test/routing_test.rb +558 -77
- data/test/sass_test.rb +52 -13
- data/test/server_test.rb +47 -0
- data/test/sinatra_test.rb +3 -5
- data/test/static_test.rb +57 -30
- data/test/templates_test.rb +74 -25
- data/test/views/error.builder +3 -0
- data/test/views/error.erb +3 -0
- data/test/views/error.haml +3 -0
- data/test/views/error.sass +2 -0
- data/test/views/foo/hello.test +1 -0
- metadata +50 -46
- data/compat/app_test.rb +0 -300
- data/compat/application_test.rb +0 -334
- data/compat/builder_test.rb +0 -101
- data/compat/custom_error_test.rb +0 -62
- data/compat/erb_test.rb +0 -136
- data/compat/events_test.rb +0 -75
- data/compat/filter_test.rb +0 -30
- data/compat/haml_test.rb +0 -233
- data/compat/helper.rb +0 -21
- data/compat/mapped_error_test.rb +0 -72
- data/compat/pipeline_test.rb +0 -71
- data/compat/public/foo.xml +0 -1
- data/compat/sass_test.rb +0 -57
- data/compat/sessions_test.rb +0 -39
- data/compat/streaming_test.rb +0 -121
- data/compat/sym_params_test.rb +0 -19
- data/compat/template_test.rb +0 -30
- data/compat/use_in_file_templates_test.rb +0 -47
- data/compat/views/foo.builder +0 -1
- data/compat/views/foo.erb +0 -1
- data/compat/views/foo.haml +0 -1
- data/compat/views/foo.sass +0 -2
- data/compat/views/foo_layout.erb +0 -2
- data/compat/views/foo_layout.haml +0 -2
- data/compat/views/layout_test/foo.builder +0 -1
- data/compat/views/layout_test/foo.erb +0 -1
- data/compat/views/layout_test/foo.haml +0 -1
- data/compat/views/layout_test/foo.sass +0 -2
- data/compat/views/layout_test/layout.builder +0 -3
- data/compat/views/layout_test/layout.erb +0 -1
- data/compat/views/layout_test/layout.haml +0 -1
- data/compat/views/layout_test/layout.sass +0 -2
- data/compat/views/no_layout/no_layout.builder +0 -1
- data/compat/views/no_layout/no_layout.haml +0 -1
- data/lib/sinatra/compat.rb +0 -239
- data/lib/sinatra/test.rb +0 -112
- data/lib/sinatra/test/rspec.rb +0 -2
- data/lib/sinatra/test/spec.rb +0 -2
- data/lib/sinatra/test/unit.rb +0 -11
- data/test/reload_test.rb +0 -65
data/test/filter_test.rb
CHANGED
@@ -1,28 +1,24 @@
|
|
1
|
-
require '
|
2
|
-
require 'sinatra/base'
|
3
|
-
require 'sinatra/test'
|
4
|
-
|
5
|
-
describe "Filters" do
|
6
|
-
include Sinatra::Test
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
7
2
|
|
3
|
+
class FilterTest < Test::Unit::TestCase
|
8
4
|
it "executes filters in the order defined" do
|
9
5
|
count = 0
|
10
6
|
mock_app do
|
11
7
|
get('/') { 'Hello World' }
|
12
8
|
before {
|
13
|
-
|
9
|
+
assert_equal 0, count
|
14
10
|
count = 1
|
15
11
|
}
|
16
12
|
before {
|
17
|
-
|
13
|
+
assert_equal 1, count
|
18
14
|
count = 2
|
19
15
|
}
|
20
16
|
end
|
21
17
|
|
22
18
|
get '/'
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
assert ok?
|
20
|
+
assert_equal 2, count
|
21
|
+
assert_equal 'Hello World', body
|
26
22
|
end
|
27
23
|
|
28
24
|
it "allows filters to modify the request" do
|
@@ -33,7 +29,83 @@ describe "Filters" do
|
|
33
29
|
}
|
34
30
|
|
35
31
|
get '/foo'
|
36
|
-
|
37
|
-
|
32
|
+
assert ok?
|
33
|
+
assert_equal 'bar', body
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can modify instance variables available to routes" do
|
37
|
+
mock_app {
|
38
|
+
before { @foo = 'bar' }
|
39
|
+
get('/foo') { @foo }
|
40
|
+
}
|
41
|
+
|
42
|
+
get '/foo'
|
43
|
+
assert ok?
|
44
|
+
assert_equal 'bar', body
|
45
|
+
end
|
46
|
+
|
47
|
+
it "allows redirects in filters" do
|
48
|
+
mock_app {
|
49
|
+
before { redirect '/bar' }
|
50
|
+
get('/foo') do
|
51
|
+
fail 'before block should have halted processing'
|
52
|
+
'ORLY?!'
|
53
|
+
end
|
54
|
+
}
|
55
|
+
|
56
|
+
get '/foo'
|
57
|
+
assert redirect?
|
58
|
+
assert_equal '/bar', response['Location']
|
59
|
+
assert_equal '', body
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does not modify the response with its return value" do
|
63
|
+
mock_app {
|
64
|
+
before { 'Hello World!' }
|
65
|
+
get '/foo' do
|
66
|
+
assert_equal [], response.body
|
67
|
+
'cool'
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
get '/foo'
|
72
|
+
assert ok?
|
73
|
+
assert_equal 'cool', body
|
74
|
+
end
|
75
|
+
|
76
|
+
it "does modify the response with halt" do
|
77
|
+
mock_app {
|
78
|
+
before { halt 302, 'Hi' }
|
79
|
+
get '/foo' do
|
80
|
+
"should not happen"
|
81
|
+
end
|
82
|
+
}
|
83
|
+
|
84
|
+
get '/foo'
|
85
|
+
assert_equal 302, response.status
|
86
|
+
assert_equal 'Hi', body
|
87
|
+
end
|
88
|
+
|
89
|
+
it "gives you access to params" do
|
90
|
+
mock_app {
|
91
|
+
before { @foo = params['foo'] }
|
92
|
+
get('/foo') { @foo }
|
93
|
+
}
|
94
|
+
|
95
|
+
get '/foo?foo=cool'
|
96
|
+
assert ok?
|
97
|
+
assert_equal 'cool', body
|
98
|
+
end
|
99
|
+
|
100
|
+
it "runs filters defined in superclasses" do
|
101
|
+
base = Class.new(Sinatra::Base)
|
102
|
+
base.before { @foo = 'hello from superclass' }
|
103
|
+
|
104
|
+
mock_app(base) {
|
105
|
+
get('/foo') { @foo }
|
106
|
+
}
|
107
|
+
|
108
|
+
get '/foo'
|
109
|
+
assert_equal 'hello from superclass', body
|
38
110
|
end
|
39
111
|
end
|
data/test/haml_test.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require 'sinatra/test'
|
4
|
-
|
5
|
-
describe "HAML Templates" do
|
6
|
-
include Sinatra::Test
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
require 'haml'
|
7
3
|
|
4
|
+
class HAMLTest < Test::Unit::TestCase
|
8
5
|
def haml_app(&block)
|
9
6
|
mock_app {
|
10
7
|
set :views, File.dirname(__FILE__) + '/views'
|
@@ -15,14 +12,14 @@ describe "HAML Templates" do
|
|
15
12
|
|
16
13
|
it 'renders inline HAML strings' do
|
17
14
|
haml_app { haml '%h1 Hiya' }
|
18
|
-
|
19
|
-
|
15
|
+
assert ok?
|
16
|
+
assert_equal "<h1>Hiya</h1>\n", body
|
20
17
|
end
|
21
18
|
|
22
19
|
it 'renders .haml files in views path' do
|
23
20
|
haml_app { haml :hello }
|
24
|
-
|
25
|
-
|
21
|
+
assert ok?
|
22
|
+
assert_equal "<h1>Hello From Haml</h1>\n", body
|
26
23
|
end
|
27
24
|
|
28
25
|
it "renders with inline layouts" do
|
@@ -31,31 +28,34 @@ describe "HAML Templates" do
|
|
31
28
|
get('/') { haml '%em Sparta' }
|
32
29
|
}
|
33
30
|
get '/'
|
34
|
-
|
35
|
-
|
31
|
+
assert ok?
|
32
|
+
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>\n", body
|
36
33
|
end
|
37
34
|
|
38
35
|
it "renders with file layouts" do
|
39
36
|
haml_app {
|
40
37
|
haml 'Hello World', :layout => :layout2
|
41
38
|
}
|
42
|
-
|
43
|
-
|
39
|
+
assert ok?
|
40
|
+
assert_equal "<h1>HAML Layout!</h1>\n<p>Hello World</p>\n", body
|
44
41
|
end
|
45
42
|
|
46
43
|
it "raises error if template not found" do
|
47
44
|
mock_app {
|
48
45
|
get('/') { haml :no_such_template }
|
49
46
|
}
|
50
|
-
|
47
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
51
48
|
end
|
52
49
|
|
53
50
|
it "passes HAML options to the Haml engine" do
|
54
|
-
|
55
|
-
|
51
|
+
mock_app {
|
52
|
+
get '/' do
|
53
|
+
haml "!!!\n%h1 Hello World", :format => :html5
|
54
|
+
end
|
56
55
|
}
|
57
|
-
|
58
|
-
|
56
|
+
get '/'
|
57
|
+
assert ok?
|
58
|
+
assert_equal "<!DOCTYPE html>\n<h1>Hello World</h1>\n", body
|
59
59
|
end
|
60
60
|
|
61
61
|
it "passes default HAML options to the Haml engine" do
|
@@ -66,7 +66,25 @@ describe "HAML Templates" do
|
|
66
66
|
end
|
67
67
|
}
|
68
68
|
get '/'
|
69
|
-
|
70
|
-
|
69
|
+
assert ok?
|
70
|
+
assert_equal "<!DOCTYPE html>\n<h1>Hello World</h1>\n", body
|
71
|
+
end
|
72
|
+
|
73
|
+
it "merges the default HAML options with the overrides and passes them to the Haml engine" do
|
74
|
+
mock_app {
|
75
|
+
set :haml, {:format => :html5, :attr_wrapper => '"'} # default HAML attr are <tag attr='single-quoted'>
|
76
|
+
get '/' do
|
77
|
+
haml "!!!\n%h1{:class => :header} Hello World"
|
78
|
+
end
|
79
|
+
get '/html4' do
|
80
|
+
haml "!!!\n%h1{:class => 'header'} Hello World", :format => :html4
|
81
|
+
end
|
82
|
+
}
|
83
|
+
get '/'
|
84
|
+
assert ok?
|
85
|
+
assert_equal "<!DOCTYPE html>\n<h1 class=\"header\">Hello World</h1>\n", body
|
86
|
+
get '/html4'
|
87
|
+
assert ok?
|
88
|
+
assert_match(/^<!DOCTYPE html PUBLIC (.*) HTML 4.01/, body)
|
71
89
|
end
|
72
90
|
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rack'
|
5
|
+
rescue LoadError
|
6
|
+
require 'rubygems'
|
7
|
+
require 'rack'
|
8
|
+
end
|
9
|
+
|
10
|
+
testdir = File.dirname(__FILE__)
|
11
|
+
$LOAD_PATH.unshift testdir unless $LOAD_PATH.include?(testdir)
|
12
|
+
|
13
|
+
libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
|
14
|
+
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
15
|
+
|
16
|
+
require 'contest'
|
17
|
+
require 'rack/test'
|
18
|
+
require 'sinatra/base'
|
19
|
+
|
20
|
+
class Sinatra::Base
|
21
|
+
# Allow assertions in request context
|
22
|
+
include Test::Unit::Assertions
|
23
|
+
end
|
24
|
+
|
25
|
+
Sinatra::Base.set :environment, :test
|
26
|
+
|
27
|
+
class Test::Unit::TestCase
|
28
|
+
include Rack::Test::Methods
|
29
|
+
|
30
|
+
class << self
|
31
|
+
alias_method :it, :test
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :response, :last_response
|
35
|
+
|
36
|
+
setup do
|
37
|
+
Sinatra::Base.set :environment, :test
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sets up a Sinatra::Base subclass defined with the block
|
41
|
+
# given. Used in setup or individual spec methods to establish
|
42
|
+
# the application.
|
43
|
+
def mock_app(base=Sinatra::Base, &block)
|
44
|
+
@app = Sinatra.new(base, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def app
|
48
|
+
Rack::Lint.new(@app)
|
49
|
+
end
|
50
|
+
|
51
|
+
def body
|
52
|
+
response.body.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
# Delegate other missing methods to response.
|
56
|
+
def method_missing(name, *args, &block)
|
57
|
+
if response && response.respond_to?(name)
|
58
|
+
response.send(name, *args, &block)
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Also check response since we delegate there.
|
65
|
+
def respond_to?(symbol, include_private=false)
|
66
|
+
super || (response && response.respond_to?(symbol, include_private))
|
67
|
+
end
|
68
|
+
|
69
|
+
# Do not output warnings for the duration of the block.
|
70
|
+
def silence_warnings
|
71
|
+
$VERBOSE, v = nil, $VERBOSE
|
72
|
+
yield
|
73
|
+
ensure
|
74
|
+
$VERBOSE = v
|
75
|
+
end
|
76
|
+
end
|
data/test/helpers_test.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
|
-
require '
|
2
|
-
require 'sinatra/base'
|
3
|
-
require 'sinatra/test'
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
4
2
|
|
5
|
-
class Test::Unit::TestCase
|
6
|
-
|
7
|
-
|
3
|
+
class HelpersTest < Test::Unit::TestCase
|
4
|
+
def test_default
|
5
|
+
assert true
|
6
|
+
end
|
8
7
|
|
9
|
-
describe '
|
10
|
-
describe '#status' do
|
8
|
+
describe 'status' do
|
11
9
|
setup do
|
12
10
|
mock_app {
|
13
11
|
get '/' do
|
@@ -19,11 +17,11 @@ describe 'Sinatra::Helpers' do
|
|
19
17
|
|
20
18
|
it 'sets the response status code' do
|
21
19
|
get '/'
|
22
|
-
response.status
|
20
|
+
assert_equal 207, response.status
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
26
|
-
describe '
|
24
|
+
describe 'body' do
|
27
25
|
it 'takes a block for defered body generation' do
|
28
26
|
mock_app {
|
29
27
|
get '/' do
|
@@ -32,7 +30,7 @@ describe 'Sinatra::Helpers' do
|
|
32
30
|
}
|
33
31
|
|
34
32
|
get '/'
|
35
|
-
|
33
|
+
assert_equal 'Hello World', body
|
36
34
|
end
|
37
35
|
|
38
36
|
it 'takes a String, Array, or other object responding to #each' do
|
@@ -43,11 +41,11 @@ describe 'Sinatra::Helpers' do
|
|
43
41
|
}
|
44
42
|
|
45
43
|
get '/'
|
46
|
-
|
44
|
+
assert_equal 'Hello World', body
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
50
|
-
describe '
|
48
|
+
describe 'redirect' do
|
51
49
|
it 'uses a 302 when only a path is given' do
|
52
50
|
mock_app {
|
53
51
|
get '/' do
|
@@ -57,9 +55,9 @@ describe 'Sinatra::Helpers' do
|
|
57
55
|
}
|
58
56
|
|
59
57
|
get '/'
|
60
|
-
|
61
|
-
body
|
62
|
-
response['Location']
|
58
|
+
assert_equal 302, status
|
59
|
+
assert_equal '', body
|
60
|
+
assert_equal '/foo', response['Location']
|
63
61
|
end
|
64
62
|
|
65
63
|
it 'uses the code given when specified' do
|
@@ -71,13 +69,26 @@ describe 'Sinatra::Helpers' do
|
|
71
69
|
}
|
72
70
|
|
73
71
|
get '/'
|
74
|
-
|
75
|
-
body
|
76
|
-
response['Location']
|
72
|
+
assert_equal 301, status
|
73
|
+
assert_equal '', body
|
74
|
+
assert_equal '/foo', response['Location']
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'redirects back to request.referer when passed back' do
|
78
|
+
mock_app {
|
79
|
+
get '/try_redirect' do
|
80
|
+
redirect back
|
81
|
+
end
|
82
|
+
}
|
83
|
+
|
84
|
+
request = Rack::MockRequest.new(@app)
|
85
|
+
response = request.get('/try_redirect', 'HTTP_REFERER' => '/foo')
|
86
|
+
assert_equal 302, response.status
|
87
|
+
assert_equal '/foo', response['Location']
|
77
88
|
end
|
78
89
|
end
|
79
90
|
|
80
|
-
describe '
|
91
|
+
describe 'error' do
|
81
92
|
it 'sets a status code and halts' do
|
82
93
|
mock_app {
|
83
94
|
get '/' do
|
@@ -87,8 +98,8 @@ describe 'Sinatra::Helpers' do
|
|
87
98
|
}
|
88
99
|
|
89
100
|
get '/'
|
90
|
-
|
91
|
-
body
|
101
|
+
assert_equal 501, status
|
102
|
+
assert_equal '', body
|
92
103
|
end
|
93
104
|
|
94
105
|
it 'takes an optional body' do
|
@@ -100,8 +111,8 @@ describe 'Sinatra::Helpers' do
|
|
100
111
|
}
|
101
112
|
|
102
113
|
get '/'
|
103
|
-
|
104
|
-
|
114
|
+
assert_equal 501, status
|
115
|
+
assert_equal 'FAIL', body
|
105
116
|
end
|
106
117
|
|
107
118
|
it 'uses a 500 status code when first argument is a body' do
|
@@ -113,12 +124,12 @@ describe 'Sinatra::Helpers' do
|
|
113
124
|
}
|
114
125
|
|
115
126
|
get '/'
|
116
|
-
|
117
|
-
|
127
|
+
assert_equal 500, status
|
128
|
+
assert_equal 'FAIL', body
|
118
129
|
end
|
119
130
|
end
|
120
131
|
|
121
|
-
describe '
|
132
|
+
describe 'not_found' do
|
122
133
|
it 'halts with a 404 status' do
|
123
134
|
mock_app {
|
124
135
|
get '/' do
|
@@ -128,12 +139,42 @@ describe 'Sinatra::Helpers' do
|
|
128
139
|
}
|
129
140
|
|
130
141
|
get '/'
|
131
|
-
|
132
|
-
body
|
142
|
+
assert_equal 404, status
|
143
|
+
assert_equal '', body
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe 'headers' do
|
148
|
+
it 'sets headers on the response object when given a Hash' do
|
149
|
+
mock_app {
|
150
|
+
get '/' do
|
151
|
+
headers 'X-Foo' => 'bar', 'X-Baz' => 'bling'
|
152
|
+
'kthx'
|
153
|
+
end
|
154
|
+
}
|
155
|
+
|
156
|
+
get '/'
|
157
|
+
assert ok?
|
158
|
+
assert_equal 'bar', response['X-Foo']
|
159
|
+
assert_equal 'bling', response['X-Baz']
|
160
|
+
assert_equal 'kthx', body
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'returns the response headers hash when no hash provided' do
|
164
|
+
mock_app {
|
165
|
+
get '/' do
|
166
|
+
headers['X-Foo'] = 'bar'
|
167
|
+
'kthx'
|
168
|
+
end
|
169
|
+
}
|
170
|
+
|
171
|
+
get '/'
|
172
|
+
assert ok?
|
173
|
+
assert_equal 'bar', response['X-Foo']
|
133
174
|
end
|
134
175
|
end
|
135
176
|
|
136
|
-
describe '
|
177
|
+
describe 'session' do
|
137
178
|
it 'uses the existing rack.session' do
|
138
179
|
mock_app {
|
139
180
|
get '/' do
|
@@ -141,44 +182,48 @@ describe 'Sinatra::Helpers' do
|
|
141
182
|
end
|
142
183
|
}
|
143
184
|
|
144
|
-
get '/',
|
145
|
-
|
185
|
+
get '/', {}, { 'rack.session' => { :foo => 'bar' } }
|
186
|
+
assert_equal 'bar', body
|
146
187
|
end
|
147
188
|
|
148
189
|
it 'creates a new session when none provided' do
|
149
190
|
mock_app {
|
150
191
|
get '/' do
|
151
|
-
session.
|
192
|
+
assert session.empty?
|
152
193
|
session[:foo] = 'bar'
|
153
194
|
'Hi'
|
154
195
|
end
|
155
196
|
}
|
156
197
|
|
157
198
|
get '/'
|
158
|
-
|
199
|
+
assert_equal 'Hi', body
|
159
200
|
end
|
160
201
|
end
|
161
202
|
|
162
|
-
describe '
|
203
|
+
describe 'media_type' do
|
163
204
|
include Sinatra::Helpers
|
205
|
+
|
164
206
|
it "looks up media types in Rack's MIME registry" do
|
165
207
|
Rack::Mime::MIME_TYPES['.foo'] = 'application/foo'
|
166
|
-
|
167
|
-
media_type('.foo')
|
168
|
-
|
208
|
+
assert_equal 'application/foo', media_type('foo')
|
209
|
+
assert_equal 'application/foo', media_type('.foo')
|
210
|
+
assert_equal 'application/foo', media_type(:foo)
|
169
211
|
end
|
212
|
+
|
170
213
|
it 'returns nil when given nil' do
|
171
|
-
media_type(nil).
|
214
|
+
assert media_type(nil).nil?
|
172
215
|
end
|
216
|
+
|
173
217
|
it 'returns nil when media type not registered' do
|
174
|
-
media_type(:bizzle).
|
218
|
+
assert media_type(:bizzle).nil?
|
175
219
|
end
|
220
|
+
|
176
221
|
it 'returns the argument when given a media type string' do
|
177
|
-
|
222
|
+
assert_equal 'text/plain', media_type('text/plain')
|
178
223
|
end
|
179
224
|
end
|
180
225
|
|
181
|
-
describe '
|
226
|
+
describe 'content_type' do
|
182
227
|
it 'sets the Content-Type header' do
|
183
228
|
mock_app {
|
184
229
|
get '/' do
|
@@ -188,8 +233,8 @@ describe 'Sinatra::Helpers' do
|
|
188
233
|
}
|
189
234
|
|
190
235
|
get '/'
|
191
|
-
response['Content-Type']
|
192
|
-
|
236
|
+
assert_equal 'text/plain', response['Content-Type']
|
237
|
+
assert_equal 'Hello World', body
|
193
238
|
end
|
194
239
|
|
195
240
|
it 'takes media type parameters (like charset=)' do
|
@@ -201,9 +246,9 @@ describe 'Sinatra::Helpers' do
|
|
201
246
|
}
|
202
247
|
|
203
248
|
get '/'
|
204
|
-
|
205
|
-
|
206
|
-
|
249
|
+
assert ok?
|
250
|
+
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
251
|
+
assert_equal "<h1>Hello, World</h1>", body
|
207
252
|
end
|
208
253
|
|
209
254
|
it "looks up symbols in Rack's mime types dictionary" do
|
@@ -216,9 +261,9 @@ describe 'Sinatra::Helpers' do
|
|
216
261
|
}
|
217
262
|
|
218
263
|
get '/foo.xml'
|
219
|
-
|
220
|
-
response['Content-Type']
|
221
|
-
|
264
|
+
assert ok?
|
265
|
+
assert_equal 'application/foo', response['Content-Type']
|
266
|
+
assert_equal 'I AM FOO', body
|
222
267
|
end
|
223
268
|
|
224
269
|
it 'fails when no mime type is registered for the argument provided' do
|
@@ -229,25 +274,26 @@ describe 'Sinatra::Helpers' do
|
|
229
274
|
end
|
230
275
|
}
|
231
276
|
|
232
|
-
|
277
|
+
assert_raise(RuntimeError) { get '/foo.xml' }
|
233
278
|
end
|
234
279
|
end
|
235
280
|
|
236
|
-
describe '
|
237
|
-
|
281
|
+
describe 'send_file' do
|
282
|
+
setup do
|
238
283
|
@file = File.dirname(__FILE__) + '/file.txt'
|
239
284
|
File.open(@file, 'wb') { |io| io.write('Hello World') }
|
240
|
-
|
241
|
-
|
285
|
+
end
|
286
|
+
|
287
|
+
def teardown
|
242
288
|
File.unlink @file
|
243
289
|
@file = nil
|
244
|
-
|
290
|
+
end
|
245
291
|
|
246
|
-
def send_file_app
|
292
|
+
def send_file_app(opts={})
|
247
293
|
path = @file
|
248
294
|
mock_app {
|
249
295
|
get '/file.txt' do
|
250
|
-
send_file path
|
296
|
+
send_file path, opts
|
251
297
|
end
|
252
298
|
}
|
253
299
|
end
|
@@ -255,26 +301,26 @@ describe 'Sinatra::Helpers' do
|
|
255
301
|
it "sends the contents of the file" do
|
256
302
|
send_file_app
|
257
303
|
get '/file.txt'
|
258
|
-
|
259
|
-
|
304
|
+
assert ok?
|
305
|
+
assert_equal 'Hello World', body
|
260
306
|
end
|
261
307
|
|
262
308
|
it 'sets the Content-Type response header if a mime-type can be located' do
|
263
309
|
send_file_app
|
264
310
|
get '/file.txt'
|
265
|
-
response['Content-Type']
|
311
|
+
assert_equal 'text/plain', response['Content-Type']
|
266
312
|
end
|
267
313
|
|
268
314
|
it 'sets the Content-Length response header' do
|
269
315
|
send_file_app
|
270
316
|
get '/file.txt'
|
271
|
-
|
317
|
+
assert_equal 'Hello World'.length.to_s, response['Content-Length']
|
272
318
|
end
|
273
319
|
|
274
320
|
it 'sets the Last-Modified response header' do
|
275
321
|
send_file_app
|
276
322
|
get '/file.txt'
|
277
|
-
|
323
|
+
assert_equal File.mtime(@file).httpdate, response['Last-Modified']
|
278
324
|
end
|
279
325
|
|
280
326
|
it "returns a 404 when not found" do
|
@@ -284,12 +330,30 @@ describe 'Sinatra::Helpers' do
|
|
284
330
|
end
|
285
331
|
}
|
286
332
|
get '/'
|
287
|
-
|
333
|
+
assert not_found?
|
334
|
+
end
|
335
|
+
|
336
|
+
it "does not set the Content-Disposition header by default" do
|
337
|
+
send_file_app
|
338
|
+
get '/file.txt'
|
339
|
+
assert_nil response['Content-Disposition']
|
340
|
+
end
|
341
|
+
|
342
|
+
it "sets the Content-Disposition header when :disposition set to 'attachment'" do
|
343
|
+
send_file_app :disposition => 'attachment'
|
344
|
+
get '/file.txt'
|
345
|
+
assert_equal 'attachment; filename="file.txt"', response['Content-Disposition']
|
346
|
+
end
|
347
|
+
|
348
|
+
it "sets the Content-Disposition header when :filename provided" do
|
349
|
+
send_file_app :filename => 'foo.txt'
|
350
|
+
get '/file.txt'
|
351
|
+
assert_equal 'attachment; filename="foo.txt"', response['Content-Disposition']
|
288
352
|
end
|
289
353
|
end
|
290
354
|
|
291
|
-
describe '
|
292
|
-
|
355
|
+
describe 'last_modified' do
|
356
|
+
setup do
|
293
357
|
now = Time.now
|
294
358
|
mock_app {
|
295
359
|
get '/' do
|
@@ -303,24 +367,24 @@ describe 'Sinatra::Helpers' do
|
|
303
367
|
|
304
368
|
it 'sets the Last-Modified header to a valid RFC 2616 date value' do
|
305
369
|
get '/'
|
306
|
-
response['Last-Modified']
|
370
|
+
assert_equal @now.httpdate, response['Last-Modified']
|
307
371
|
end
|
308
372
|
|
309
373
|
it 'returns a body when conditional get misses' do
|
310
374
|
get '/'
|
311
|
-
|
312
|
-
|
375
|
+
assert_equal 200, status
|
376
|
+
assert_equal 'Boo!', body
|
313
377
|
end
|
314
378
|
|
315
379
|
it 'halts when a conditional GET matches' do
|
316
|
-
get '/',
|
317
|
-
|
318
|
-
body
|
380
|
+
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => @now.httpdate }
|
381
|
+
assert_equal 304, status
|
382
|
+
assert_equal '', body
|
319
383
|
end
|
320
384
|
end
|
321
385
|
|
322
|
-
describe '
|
323
|
-
|
386
|
+
describe 'etag' do
|
387
|
+
setup do
|
324
388
|
mock_app {
|
325
389
|
get '/' do
|
326
390
|
body { 'Hello World' }
|
@@ -332,25 +396,25 @@ describe 'Sinatra::Helpers' do
|
|
332
396
|
|
333
397
|
it 'sets the ETag header' do
|
334
398
|
get '/'
|
335
|
-
response['ETag']
|
399
|
+
assert_equal '"FOO"', response['ETag']
|
336
400
|
end
|
337
401
|
|
338
402
|
it 'returns a body when conditional get misses' do
|
339
403
|
get '/'
|
340
|
-
|
341
|
-
|
404
|
+
assert_equal 200, status
|
405
|
+
assert_equal 'Boo!', body
|
342
406
|
end
|
343
407
|
|
344
408
|
it 'halts when a conditional GET matches' do
|
345
|
-
get '/',
|
346
|
-
|
347
|
-
body
|
409
|
+
get '/', {}, { 'HTTP_IF_NONE_MATCH' => '"FOO"' }
|
410
|
+
assert_equal 304, status
|
411
|
+
assert_equal '', body
|
348
412
|
end
|
349
413
|
|
350
414
|
it 'should handle multiple ETag values in If-None-Match header' do
|
351
|
-
get '/',
|
352
|
-
|
353
|
-
body
|
415
|
+
get '/', {}, { 'HTTP_IF_NONE_MATCH' => '"BAR", *' }
|
416
|
+
assert_equal 304, status
|
417
|
+
assert_equal '', body
|
354
418
|
end
|
355
419
|
|
356
420
|
it 'uses a weak etag with the :weak option' do
|
@@ -361,8 +425,79 @@ describe 'Sinatra::Helpers' do
|
|
361
425
|
end
|
362
426
|
}
|
363
427
|
get '/'
|
364
|
-
|
428
|
+
assert_equal 'W/"FOO"', response['ETag']
|
365
429
|
end
|
430
|
+
end
|
431
|
+
|
432
|
+
describe 'back' do
|
433
|
+
it "makes redirecting back pretty" do
|
434
|
+
mock_app {
|
435
|
+
get '/foo' do
|
436
|
+
redirect back
|
437
|
+
end
|
438
|
+
}
|
439
|
+
|
440
|
+
get '/foo', {}, 'HTTP_REFERER' => 'http://github.com'
|
441
|
+
assert redirect?
|
442
|
+
assert_equal "http://github.com", response.location
|
443
|
+
end
|
444
|
+
end
|
366
445
|
|
446
|
+
module ::HelperOne; def one; '1'; end; end
|
447
|
+
module ::HelperTwo; def two; '2'; end; end
|
448
|
+
|
449
|
+
describe 'Adding new helpers' do
|
450
|
+
it 'takes a list of modules to mix into the app' do
|
451
|
+
mock_app {
|
452
|
+
helpers ::HelperOne, ::HelperTwo
|
453
|
+
|
454
|
+
get '/one' do
|
455
|
+
one
|
456
|
+
end
|
457
|
+
|
458
|
+
get '/two' do
|
459
|
+
two
|
460
|
+
end
|
461
|
+
}
|
462
|
+
|
463
|
+
get '/one'
|
464
|
+
assert_equal '1', body
|
465
|
+
|
466
|
+
get '/two'
|
467
|
+
assert_equal '2', body
|
468
|
+
end
|
469
|
+
|
470
|
+
it 'takes a block to mix into the app' do
|
471
|
+
mock_app {
|
472
|
+
helpers do
|
473
|
+
def foo
|
474
|
+
'foo'
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
get '/' do
|
479
|
+
foo
|
480
|
+
end
|
481
|
+
}
|
482
|
+
|
483
|
+
get '/'
|
484
|
+
assert_equal 'foo', body
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'evaluates the block in class context so that methods can be aliased' do
|
488
|
+
mock_app {
|
489
|
+
helpers do
|
490
|
+
alias_method :h, :escape_html
|
491
|
+
end
|
492
|
+
|
493
|
+
get '/' do
|
494
|
+
h('42 < 43')
|
495
|
+
end
|
496
|
+
}
|
497
|
+
|
498
|
+
get '/'
|
499
|
+
assert ok?
|
500
|
+
assert_equal '42 < 43', body
|
501
|
+
end
|
367
502
|
end
|
368
503
|
end
|