darkhelmet-sinatra 0.9.0.5

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