darkhelmet-sinatra 0.9.0.5

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