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.
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