adamwiggins-sinatra 0.8.9 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/AUTHORS +8 -7
  2. data/CHANGES +211 -1
  3. data/LICENSE +1 -1
  4. data/README.rdoc +183 -139
  5. data/Rakefile +20 -81
  6. data/lib/sinatra.rb +5 -1
  7. data/lib/sinatra/base.rb +569 -278
  8. data/lib/sinatra/main.rb +12 -25
  9. data/lib/sinatra/showexceptions.rb +303 -0
  10. data/sinatra.gemspec +20 -44
  11. data/test/base_test.rb +140 -52
  12. data/test/builder_test.rb +14 -17
  13. data/test/contest.rb +64 -0
  14. data/test/erb_test.rb +42 -16
  15. data/test/extensions_test.rb +100 -0
  16. data/test/filter_test.rb +85 -13
  17. data/test/haml_test.rb +39 -21
  18. data/test/helper.rb +76 -0
  19. data/test/helpers_test.rb +219 -84
  20. data/test/mapped_error_test.rb +168 -146
  21. data/test/middleware_test.rb +22 -17
  22. data/test/options_test.rb +323 -54
  23. data/test/render_backtrace_test.rb +145 -0
  24. data/test/request_test.rb +28 -6
  25. data/test/response_test.rb +42 -0
  26. data/test/result_test.rb +27 -21
  27. data/test/route_added_hook_test.rb +59 -0
  28. data/test/routing_test.rb +558 -77
  29. data/test/sass_test.rb +52 -13
  30. data/test/server_test.rb +47 -0
  31. data/test/sinatra_test.rb +3 -5
  32. data/test/static_test.rb +57 -30
  33. data/test/templates_test.rb +74 -25
  34. data/test/views/error.builder +3 -0
  35. data/test/views/error.erb +3 -0
  36. data/test/views/error.haml +3 -0
  37. data/test/views/error.sass +2 -0
  38. data/test/views/foo/hello.test +1 -0
  39. metadata +50 -46
  40. data/compat/app_test.rb +0 -300
  41. data/compat/application_test.rb +0 -334
  42. data/compat/builder_test.rb +0 -101
  43. data/compat/custom_error_test.rb +0 -62
  44. data/compat/erb_test.rb +0 -136
  45. data/compat/events_test.rb +0 -75
  46. data/compat/filter_test.rb +0 -30
  47. data/compat/haml_test.rb +0 -233
  48. data/compat/helper.rb +0 -21
  49. data/compat/mapped_error_test.rb +0 -72
  50. data/compat/pipeline_test.rb +0 -71
  51. data/compat/public/foo.xml +0 -1
  52. data/compat/sass_test.rb +0 -57
  53. data/compat/sessions_test.rb +0 -39
  54. data/compat/streaming_test.rb +0 -121
  55. data/compat/sym_params_test.rb +0 -19
  56. data/compat/template_test.rb +0 -30
  57. data/compat/use_in_file_templates_test.rb +0 -47
  58. data/compat/views/foo.builder +0 -1
  59. data/compat/views/foo.erb +0 -1
  60. data/compat/views/foo.haml +0 -1
  61. data/compat/views/foo.sass +0 -2
  62. data/compat/views/foo_layout.erb +0 -2
  63. data/compat/views/foo_layout.haml +0 -2
  64. data/compat/views/layout_test/foo.builder +0 -1
  65. data/compat/views/layout_test/foo.erb +0 -1
  66. data/compat/views/layout_test/foo.haml +0 -1
  67. data/compat/views/layout_test/foo.sass +0 -2
  68. data/compat/views/layout_test/layout.builder +0 -3
  69. data/compat/views/layout_test/layout.erb +0 -1
  70. data/compat/views/layout_test/layout.haml +0 -1
  71. data/compat/views/layout_test/layout.sass +0 -2
  72. data/compat/views/no_layout/no_layout.builder +0 -1
  73. data/compat/views/no_layout/no_layout.haml +0 -1
  74. data/lib/sinatra/compat.rb +0 -239
  75. data/lib/sinatra/test.rb +0 -112
  76. data/lib/sinatra/test/rspec.rb +0 -2
  77. data/lib/sinatra/test/spec.rb +0 -2
  78. data/lib/sinatra/test/unit.rb +0 -11
  79. data/test/reload_test.rb +0 -65
@@ -1,28 +1,24 @@
1
- require 'test/spec'
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
- count.should.be 0
9
+ assert_equal 0, count
14
10
  count = 1
15
11
  }
16
12
  before {
17
- count.should.be 1
13
+ assert_equal 1, count
18
14
  count = 2
19
15
  }
20
16
  end
21
17
 
22
18
  get '/'
23
- should.be.ok
24
- count.should.be 2
25
- body.should.equal 'Hello World'
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
- should.be.ok
37
- body.should.be == 'bar'
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
@@ -1,10 +1,7 @@
1
- require 'test/spec'
2
- require 'sinatra/base'
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
- should.be.ok
19
- body.should.equal "<h1>Hiya</h1>\n"
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
- should.be.ok
25
- body.should.equal "<h1>Hello From Haml</h1>\n"
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
- should.be.ok
35
- body.should.equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>\n"
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
- should.be.ok
43
- body.should.equal "<h1>HAML Layout!</h1>\n<p>Hello World</p>\n"
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
- lambda { get('/') }.should.raise(Errno::ENOENT)
47
+ assert_raise(Errno::ENOENT) { get('/') }
51
48
  end
52
49
 
53
50
  it "passes HAML options to the Haml engine" do
54
- haml_app {
55
- haml "!!!\n%h1 Hello World", :options => {:format => :html5}
51
+ mock_app {
52
+ get '/' do
53
+ haml "!!!\n%h1 Hello World", :format => :html5
54
+ end
56
55
  }
57
- should.be.ok
58
- body.should.equal "<!DOCTYPE html>\n<h1>Hello World</h1>\n"
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
- should.be.ok
70
- body.should.equal "<!DOCTYPE html>\n<h1>Hello World</h1>\n"
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
@@ -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
@@ -1,13 +1,11 @@
1
- require 'test/spec'
2
- require 'sinatra/base'
3
- require 'sinatra/test'
1
+ require File.dirname(__FILE__) + '/helper'
4
2
 
5
- class Test::Unit::TestCase
6
- include Sinatra::Test
7
- end
3
+ class HelpersTest < Test::Unit::TestCase
4
+ def test_default
5
+ assert true
6
+ end
8
7
 
9
- describe 'Sinatra::Helpers' do
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.should.equal 207
20
+ assert_equal 207, response.status
23
21
  end
24
22
  end
25
23
 
26
- describe '#body' do
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
- body.should.equal 'Hello World'
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
- body.should.equal 'Hello World'
44
+ assert_equal 'Hello World', body
47
45
  end
48
46
  end
49
47
 
50
- describe '#redirect' do
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
- status.should.equal 302
61
- body.should.be.empty
62
- response['Location'].should.equal '/foo'
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
- status.should.equal 301
75
- body.should.be.empty
76
- response['Location'].should.equal '/foo'
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 '#error' do
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
- status.should.equal 501
91
- body.should.be.empty
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
- status.should.equal 501
104
- body.should.equal 'FAIL'
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
- status.should.equal 500
117
- body.should.equal 'FAIL'
127
+ assert_equal 500, status
128
+ assert_equal 'FAIL', body
118
129
  end
119
130
  end
120
131
 
121
- describe '#not_found' do
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
- status.should.equal 404
132
- body.should.be.empty
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 '#session' do
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 '/', :env => { 'rack.session' => { :foo => 'bar' } }
145
- body.should.equal 'bar'
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.should.be.empty
192
+ assert session.empty?
152
193
  session[:foo] = 'bar'
153
194
  'Hi'
154
195
  end
155
196
  }
156
197
 
157
198
  get '/'
158
- body.should.equal 'Hi'
199
+ assert_equal 'Hi', body
159
200
  end
160
201
  end
161
202
 
162
- describe '#media_type' do
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
- media_type('foo').should.equal 'application/foo'
167
- media_type('.foo').should.equal 'application/foo'
168
- media_type(:foo).should.equal 'application/foo'
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).should.be.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).should.be.nil
218
+ assert media_type(:bizzle).nil?
175
219
  end
220
+
176
221
  it 'returns the argument when given a media type string' do
177
- media_type('text/plain').should.equal 'text/plain'
222
+ assert_equal 'text/plain', media_type('text/plain')
178
223
  end
179
224
  end
180
225
 
181
- describe '#content_type' do
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'].should.equal 'text/plain'
192
- body.should.equal 'Hello World'
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
- should.be.ok
205
- response['Content-Type'].should.equal 'text/html;charset=utf-8'
206
- body.should.equal "<h1>Hello, World</h1>"
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
- should.be.ok
220
- response['Content-Type'].should.equal 'application/foo'
221
- body.should.equal 'I AM FOO'
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
- lambda { get '/foo.xml' }.should.raise RuntimeError
277
+ assert_raise(RuntimeError) { get '/foo.xml' }
233
278
  end
234
279
  end
235
280
 
236
- describe '#send_file' do
237
- before {
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
- after {
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
- should.be.ok
259
- body.should.equal 'Hello World'
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'].should.equal 'text/plain'
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
- response['Content-Length'].should.equal 'Hello World'.length.to_s
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
- response['Last-Modified'].should.equal File.mtime(@file).httpdate
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
- should.be.not_found
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 '#last_modified' do
292
- before do
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'].should.equal @now.httpdate
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
- status.should.be 200
312
- body.should.equal 'Boo!'
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 '/', :env => { 'HTTP_IF_MODIFIED_SINCE' => @now.httpdate }
317
- status.should.be 304
318
- body.should.be.empty
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 '#etag' do
323
- before do
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'].should.equal '"FOO"'
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
- status.should.be 200
341
- body.should.equal 'Boo!'
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 '/', :env => { 'HTTP_IF_NONE_MATCH' => '"FOO"' }
346
- status.should.be 304
347
- body.should.be.empty
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 '/', :env => { 'HTTP_IF_NONE_MATCH' => '"BAR", *' }
352
- status.should.be 304
353
- body.should.be.empty
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
- response['ETag'].should.equal 'W/"FOO"'
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 &lt; 43', body
501
+ end
367
502
  end
368
503
  end