sinatra-base 1.0 → 1.4.0

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 (101) hide show
  1. data/.yardopts +4 -0
  2. data/AUTHORS +15 -0
  3. data/CHANGES +524 -1
  4. data/Gemfile +82 -0
  5. data/LICENSE +1 -1
  6. data/README.de.rdoc +2093 -0
  7. data/README.es.rdoc +2091 -0
  8. data/README.fr.rdoc +2116 -0
  9. data/README.hu.rdoc +607 -0
  10. data/README.jp.rdoc +514 -23
  11. data/README.pt-br.rdoc +647 -0
  12. data/README.pt-pt.rdoc +646 -0
  13. data/README.rdoc +1580 -205
  14. data/README.ru.rdoc +2015 -0
  15. data/README.zh.rdoc +1816 -0
  16. data/Rakefile +110 -44
  17. data/examples/chat.rb +61 -0
  18. data/examples/simple.rb +3 -0
  19. data/examples/stream.ru +26 -0
  20. data/lib/sinatra.rb +0 -3
  21. data/lib/sinatra/base.rb +923 -393
  22. data/lib/sinatra/main.rb +9 -7
  23. data/lib/sinatra/showexceptions.rb +37 -4
  24. data/lib/sinatra/version.rb +3 -0
  25. data/sinatra-base.gemspec +15 -91
  26. data/test/base_test.rb +2 -2
  27. data/test/builder_test.rb +32 -2
  28. data/test/coffee_test.rb +92 -0
  29. data/test/contest.rb +62 -28
  30. data/test/creole_test.rb +65 -0
  31. data/test/delegator_test.rb +162 -0
  32. data/test/encoding_test.rb +20 -0
  33. data/test/erb_test.rb +25 -2
  34. data/test/extensions_test.rb +1 -1
  35. data/test/filter_test.rb +226 -8
  36. data/test/haml_test.rb +8 -2
  37. data/test/helper.rb +47 -0
  38. data/test/helpers_test.rb +1287 -80
  39. data/test/integration/app.rb +62 -0
  40. data/test/integration_helper.rb +208 -0
  41. data/test/integration_test.rb +82 -0
  42. data/test/less_test.rb +36 -6
  43. data/test/liquid_test.rb +59 -0
  44. data/test/mapped_error_test.rb +84 -7
  45. data/test/markaby_test.rb +80 -0
  46. data/test/markdown_test.rb +81 -0
  47. data/test/middleware_test.rb +1 -1
  48. data/test/nokogiri_test.rb +69 -0
  49. data/test/rack_test.rb +45 -0
  50. data/test/radius_test.rb +59 -0
  51. data/test/rdoc_test.rb +66 -0
  52. data/test/readme_test.rb +136 -0
  53. data/test/request_test.rb +13 -1
  54. data/test/response_test.rb +21 -2
  55. data/test/result_test.rb +5 -5
  56. data/test/route_added_hook_test.rb +1 -1
  57. data/test/routing_test.rb +328 -13
  58. data/test/sass_test.rb +48 -18
  59. data/test/scss_test.rb +88 -0
  60. data/test/server_test.rb +4 -3
  61. data/test/settings_test.rb +191 -21
  62. data/test/sinatra_test.rb +5 -1
  63. data/test/slim_test.rb +88 -0
  64. data/test/static_test.rb +89 -5
  65. data/test/streaming_test.rb +140 -0
  66. data/test/templates_test.rb +143 -4
  67. data/test/textile_test.rb +65 -0
  68. data/test/views/a/in_a.str +1 -0
  69. data/test/views/ascii.erb +2 -0
  70. data/test/views/b/in_b.str +1 -0
  71. data/test/views/calc.html.erb +1 -0
  72. data/test/views/explicitly_nested.str +1 -0
  73. data/test/views/hello.coffee +1 -0
  74. data/test/views/hello.creole +1 -0
  75. data/test/views/hello.liquid +1 -0
  76. data/test/views/hello.mab +1 -0
  77. data/test/views/hello.md +1 -0
  78. data/test/views/hello.nokogiri +1 -0
  79. data/test/views/hello.radius +1 -0
  80. data/test/views/hello.rdoc +1 -0
  81. data/test/views/hello.sass +1 -1
  82. data/test/views/hello.scss +3 -0
  83. data/test/views/hello.slim +1 -0
  84. data/test/views/hello.str +1 -0
  85. data/test/views/hello.textile +1 -0
  86. data/test/views/hello.yajl +1 -0
  87. data/test/views/layout2.liquid +2 -0
  88. data/test/views/layout2.mab +2 -0
  89. data/test/views/layout2.nokogiri +3 -0
  90. data/test/views/layout2.radius +2 -0
  91. data/test/views/layout2.slim +3 -0
  92. data/test/views/layout2.str +2 -0
  93. data/test/views/nested.str +1 -0
  94. data/test/views/utf8.erb +2 -0
  95. data/test/yajl_test.rb +80 -0
  96. metadata +126 -91
  97. data/lib/sinatra/tilt.rb +0 -746
  98. data/test/erubis_test.rb +0 -82
  99. data/test/views/error.erubis +0 -3
  100. data/test/views/hello.erubis +0 -1
  101. data/test/views/layout2.erubis +0 -2
@@ -0,0 +1,65 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ begin
4
+ require 'creole'
5
+
6
+ class CreoleTest < Test::Unit::TestCase
7
+ def creole_app(&block)
8
+ mock_app do
9
+ set :views, File.dirname(__FILE__) + '/views'
10
+ get '/', &block
11
+ end
12
+ get '/'
13
+ end
14
+
15
+ it 'renders inline creole strings' do
16
+ creole_app { creole '= Hiya' }
17
+ assert ok?
18
+ assert_body "<h1>Hiya</h1>"
19
+ end
20
+
21
+ it 'renders .creole files in views path' do
22
+ creole_app { creole :hello }
23
+ assert ok?
24
+ assert_body "<h1>Hello From Creole</h1>"
25
+ end
26
+
27
+ it "raises error if template not found" do
28
+ mock_app { get('/') { creole :no_such_template } }
29
+ assert_raise(Errno::ENOENT) { get('/') }
30
+ end
31
+
32
+ it "renders with inline layouts" do
33
+ mock_app do
34
+ layout { 'THIS. IS. #{yield.upcase}!' }
35
+ get('/') { creole 'Sparta', :layout_engine => :str }
36
+ end
37
+ get '/'
38
+ assert ok?
39
+ assert_like 'THIS. IS. <P>SPARTA</P>!', body
40
+ end
41
+
42
+ it "renders with file layouts" do
43
+ creole_app { creole 'Hello World', :layout => :layout2, :layout_engine => :erb }
44
+ assert ok?
45
+ assert_body "ERB Layout!\n<p>Hello World</p>"
46
+ end
47
+
48
+ it "can be used in a nested fashion for partials and whatnot" do
49
+ mock_app do
50
+ template(:inner) { "hi" }
51
+ template(:outer) { "<outer><%= creole :inner %></outer>" }
52
+ get '/' do
53
+ erb :outer
54
+ end
55
+ end
56
+
57
+ get '/'
58
+ assert ok?
59
+ assert_like '<outer><p>hi</p></outer>', body
60
+ end
61
+ end
62
+
63
+ rescue LoadError
64
+ warn "#{$!.to_s}: skipping creole tests"
65
+ end
@@ -0,0 +1,162 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class DelegatorTest < Test::Unit::TestCase
4
+ class Mirror
5
+ attr_reader :last_call
6
+ def method_missing(*a, &b)
7
+ @last_call = [*a.map(&:to_s)]
8
+ @last_call << b if b
9
+ end
10
+ end
11
+
12
+ def self.delegates(name)
13
+ it "delegates #{name}" do
14
+ m = mirror { send name }
15
+ assert_equal [name.to_s], m.last_call
16
+ end
17
+
18
+ it "delegates #{name} with arguments" do
19
+ m = mirror { send name, "foo", "bar" }
20
+ assert_equal [name.to_s, "foo", "bar"], m.last_call
21
+ end
22
+
23
+ it "delegates #{name} with block" do
24
+ block = proc { }
25
+ m = mirror { send(name, &block) }
26
+ assert_equal [name.to_s, block], m.last_call
27
+ end
28
+ end
29
+
30
+ setup do
31
+ @target_was = Sinatra::Delegator.target
32
+ end
33
+
34
+ def teardown
35
+ Sinatra::Delegator.target = @target_was
36
+ end
37
+
38
+ def delegation_app(&block)
39
+ mock_app { Sinatra::Delegator.target = self }
40
+ delegate(&block)
41
+ end
42
+
43
+ def mirror(&block)
44
+ mirror = Mirror.new
45
+ Sinatra::Delegator.target = mirror
46
+ delegate(&block)
47
+ end
48
+
49
+ def delegate(&block)
50
+ assert Sinatra::Delegator.target != Sinatra::Application
51
+ Object.new.extend(Sinatra::Delegator).instance_eval(&block) if block
52
+ Sinatra::Delegator.target
53
+ end
54
+
55
+ def target
56
+ Sinatra::Delegator.target
57
+ end
58
+
59
+ it 'defaults to Sinatra::Application as target' do
60
+ assert_equal Sinatra::Application, Sinatra::Delegator.target
61
+ end
62
+
63
+ %w[get put post delete options patch].each do |verb|
64
+ it "delegates #{verb} correctly" do
65
+ delegation_app do
66
+ send verb, '/hello' do
67
+ 'Hello World'
68
+ end
69
+ end
70
+
71
+ request = Rack::MockRequest.new(@app)
72
+ response = request.request(verb.upcase, '/hello', {})
73
+ assert response.ok?
74
+ assert_equal 'Hello World', response.body
75
+ end
76
+ end
77
+
78
+ it "delegates head correctly" do
79
+ delegation_app do
80
+ head '/hello' do
81
+ response['X-Hello'] = 'World!'
82
+ 'remove me'
83
+ end
84
+ end
85
+
86
+ request = Rack::MockRequest.new(@app)
87
+ response = request.request('HEAD', '/hello', {})
88
+ assert response.ok?
89
+ assert_equal 'World!', response['X-Hello']
90
+ assert_equal '', response.body
91
+ end
92
+
93
+ it "registers extensions with the delegation target" do
94
+ app, mixin = mirror, Module.new
95
+ Sinatra.register mixin
96
+ assert_equal ["register", mixin.to_s], app.last_call
97
+ end
98
+
99
+ it "registers helpers with the delegation target" do
100
+ app, mixin = mirror, Module.new
101
+ Sinatra.helpers mixin
102
+ assert_equal ["helpers", mixin.to_s], app.last_call
103
+ end
104
+
105
+ it "registers helpers with the delegation target" do
106
+ app, mixin = mirror, Module.new
107
+ Sinatra.use mixin
108
+ assert_equal ["use", mixin.to_s], app.last_call
109
+ end
110
+
111
+ it "should work with method_missing proxies for options" do
112
+ mixin = Module.new do
113
+ def respond_to?(method, *)
114
+ method.to_sym == :options or super
115
+ end
116
+
117
+ def method_missing(method, *args, &block)
118
+ return super unless method.to_sym == :options
119
+ {:some => :option}
120
+ end
121
+ end
122
+
123
+ value = nil
124
+ mirror do
125
+ extend mixin
126
+ value = options
127
+ end
128
+
129
+ assert_equal({:some => :option}, value)
130
+ end
131
+
132
+ it "delegates crazy method names" do
133
+ Sinatra::Delegator.delegate "foo:bar:"
134
+ method = mirror { send "foo:bar:" }.last_call.first
135
+ assert_equal "foo:bar:", method
136
+ end
137
+
138
+ delegates 'get'
139
+ delegates 'patch'
140
+ delegates 'put'
141
+ delegates 'post'
142
+ delegates 'delete'
143
+ delegates 'head'
144
+ delegates 'options'
145
+ delegates 'template'
146
+ delegates 'layout'
147
+ delegates 'before'
148
+ delegates 'after'
149
+ delegates 'error'
150
+ delegates 'not_found'
151
+ delegates 'configure'
152
+ delegates 'set'
153
+ delegates 'mime_type'
154
+ delegates 'enable'
155
+ delegates 'disable'
156
+ delegates 'use'
157
+ delegates 'development?'
158
+ delegates 'test?'
159
+ delegates 'production?'
160
+ delegates 'helpers'
161
+ delegates 'settings'
162
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path('../helper', __FILE__)
3
+ require 'erb'
4
+
5
+ class BaseTest < Test::Unit::TestCase
6
+ setup do
7
+ @base = Sinatra.new(Sinatra::Base)
8
+ @base.set :views, File.dirname(__FILE__) + "/views"
9
+ end
10
+
11
+ it 'allows unicode strings in ascii templates per default (1.9)' do
12
+ next unless defined? Encoding
13
+ @base.new!.erb(File.read(@base.views + "/ascii.erb").encode("ASCII"), {}, :value => "åkej")
14
+ end
15
+
16
+ it 'allows ascii strings in unicode templates per default (1.9)' do
17
+ next unless defined? Encoding
18
+ @base.new!.erb(:utf8, {}, :value => "Some Lyrics".encode("ASCII"))
19
+ end
20
+ end
@@ -1,6 +1,15 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  class ERBTest < Test::Unit::TestCase
4
+ def engine
5
+ Tilt::ERBTemplate
6
+ end
7
+
8
+ def setup
9
+ Tilt.prefer engine, :erb
10
+ super
11
+ end
12
+
4
13
  def erb_app(&block)
5
14
  mock_app {
6
15
  set :views, File.dirname(__FILE__) + '/views'
@@ -9,6 +18,10 @@ class ERBTest < Test::Unit::TestCase
9
18
  get '/'
10
19
  end
11
20
 
21
+ it 'uses the correct engine' do
22
+ assert_equal engine, Tilt[:erb]
23
+ end
24
+
12
25
  it 'renders inline ERB strings' do
13
26
  erb_app { erb '<%= 1 + 1 %>' }
14
27
  assert ok?
@@ -45,7 +58,7 @@ class ERBTest < Test::Unit::TestCase
45
58
  erb 'Hello World', :layout => :layout2
46
59
  }
47
60
  assert ok?
48
- assert_equal "ERB Layout!\nHello World\n", body
61
+ assert_body "ERB Layout!\nHello World"
49
62
  end
50
63
 
51
64
  it "renders erb with blocks" do
@@ -79,3 +92,13 @@ class ERBTest < Test::Unit::TestCase
79
92
  assert_equal '<outer><inner>hi</inner></outer>', body
80
93
  end
81
94
  end
95
+
96
+
97
+ begin
98
+ require 'erubis'
99
+ class ErubisTest < ERBTest
100
+ def engine; Tilt::ErubisTemplate end
101
+ end
102
+ rescue LoadError
103
+ warn "#{$!.to_s}: skipping erubis tests"
104
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  class ExtensionsTest < Test::Unit::TestCase
4
4
  module FooExtensions
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  class BeforeFilterTest < Test::Unit::TestCase
4
4
  it "executes filters in the order defined" do
@@ -55,7 +55,7 @@ class BeforeFilterTest < Test::Unit::TestCase
55
55
 
56
56
  get '/foo'
57
57
  assert redirect?
58
- assert_equal '/bar', response['Location']
58
+ assert_equal 'http://example.org/bar', response['Location']
59
59
  assert_equal '', body
60
60
  end
61
61
 
@@ -97,6 +97,17 @@ class BeforeFilterTest < Test::Unit::TestCase
97
97
  assert_equal 'cool', body
98
98
  end
99
99
 
100
+ it "properly unescapes parameters" do
101
+ mock_app {
102
+ before { @foo = params['foo'] }
103
+ get('/foo') { @foo }
104
+ }
105
+
106
+ get '/foo?foo=bar%3Abaz%2Fbend'
107
+ assert ok?
108
+ assert_equal 'bar:baz/bend', body
109
+ end
110
+
100
111
  it "runs filters defined in superclasses" do
101
112
  base = Class.new(Sinatra::Base)
102
113
  base.before { @foo = 'hello from superclass' }
@@ -114,13 +125,36 @@ class BeforeFilterTest < Test::Unit::TestCase
114
125
  mock_app {
115
126
  before { ran_filter = true }
116
127
  set :static, true
117
- set :public, File.dirname(__FILE__)
128
+ set :public_folder, File.dirname(__FILE__)
118
129
  }
119
130
  get "/#{File.basename(__FILE__)}"
120
131
  assert ok?
121
132
  assert_equal File.read(__FILE__), body
122
133
  assert !ran_filter
123
134
  end
135
+
136
+ it 'takes an optional route pattern' do
137
+ ran_filter = false
138
+ mock_app do
139
+ before("/b*") { ran_filter = true }
140
+ get('/foo') { }
141
+ get('/bar') { }
142
+ end
143
+ get '/foo'
144
+ assert !ran_filter
145
+ get '/bar'
146
+ assert ran_filter
147
+ end
148
+
149
+ it 'generates block arguments from route pattern' do
150
+ subpath = nil
151
+ mock_app do
152
+ before("/foo/:sub") { |s| subpath = s }
153
+ get('/foo/*') { }
154
+ end
155
+ get '/foo/bar'
156
+ assert_equal subpath, 'bar'
157
+ end
124
158
  end
125
159
 
126
160
  class AfterFilterTest < Test::Unit::TestCase
@@ -166,7 +200,7 @@ class AfterFilterTest < Test::Unit::TestCase
166
200
 
167
201
  get '/foo'
168
202
  assert redirect?
169
- assert_equal '/bar', response['Location']
203
+ assert_equal 'http://example.org/bar', response['Location']
170
204
  assert_equal '', body
171
205
  end
172
206
 
@@ -198,9 +232,12 @@ class AfterFilterTest < Test::Unit::TestCase
198
232
  count = 2
199
233
  base = Class.new(Sinatra::Base)
200
234
  base.after { count *= 2 }
201
- mock_app(base) {
202
- get('/foo') { count += 2 }
203
- }
235
+ mock_app(base) do
236
+ get('/foo') do
237
+ count += 2
238
+ "ok"
239
+ end
240
+ end
204
241
 
205
242
  get '/foo'
206
243
  assert_equal 8, count
@@ -211,11 +248,192 @@ class AfterFilterTest < Test::Unit::TestCase
211
248
  mock_app {
212
249
  after { ran_filter = true }
213
250
  set :static, true
214
- set :public, File.dirname(__FILE__)
251
+ set :public_folder, File.dirname(__FILE__)
215
252
  }
216
253
  get "/#{File.basename(__FILE__)}"
217
254
  assert ok?
218
255
  assert_equal File.read(__FILE__), body
219
256
  assert !ran_filter
220
257
  end
258
+
259
+ it 'takes an optional route pattern' do
260
+ ran_filter = false
261
+ mock_app do
262
+ after("/b*") { ran_filter = true }
263
+ get('/foo') { }
264
+ get('/bar') { }
265
+ end
266
+ get '/foo'
267
+ assert !ran_filter
268
+ get '/bar'
269
+ assert ran_filter
270
+ end
271
+
272
+ it 'changes to path_info from a pattern matching before filter are respoected when routing' do
273
+ mock_app do
274
+ before('/foo') { request.path_info = '/bar' }
275
+ get('/bar') { 'blah' }
276
+ end
277
+ get '/foo'
278
+ assert ok?
279
+ assert_equal 'blah', body
280
+ end
281
+
282
+ it 'generates block arguments from route pattern' do
283
+ subpath = nil
284
+ mock_app do
285
+ after("/foo/:sub") { |s| subpath = s }
286
+ get('/foo/*') { }
287
+ end
288
+ get '/foo/bar'
289
+ assert_equal subpath, 'bar'
290
+ end
291
+
292
+ it 'is possible to access url params from the route param' do
293
+ ran = false
294
+ mock_app do
295
+ get('/foo/*') { }
296
+ before('/foo/:sub') do
297
+ assert_equal params[:sub], 'bar'
298
+ ran = true
299
+ end
300
+ end
301
+ get '/foo/bar'
302
+ assert ran
303
+ end
304
+
305
+ it 'is possible to apply host_name conditions to before filters with no path' do
306
+ ran = false
307
+ mock_app do
308
+ before(:host_name => 'example.com') { ran = true }
309
+ get('/') { 'welcome' }
310
+ end
311
+ get '/', {}, { 'HTTP_HOST' => 'example.org' }
312
+ assert !ran
313
+ get '/', {}, { 'HTTP_HOST' => 'example.com' }
314
+ assert ran
315
+ end
316
+
317
+ it 'is possible to apply host_name conditions to before filters with a path' do
318
+ ran = false
319
+ mock_app do
320
+ before('/foo', :host_name => 'example.com') { ran = true }
321
+ get('/') { 'welcome' }
322
+ end
323
+ get '/', {}, { 'HTTP_HOST' => 'example.com' }
324
+ assert !ran
325
+ get '/foo', {}, { 'HTTP_HOST' => 'example.org' }
326
+ assert !ran
327
+ get '/foo', {}, { 'HTTP_HOST' => 'example.com' }
328
+ assert ran
329
+ end
330
+
331
+ it 'is possible to apply host_name conditions to after filters with no path' do
332
+ ran = false
333
+ mock_app do
334
+ after(:host_name => 'example.com') { ran = true }
335
+ get('/') { 'welcome' }
336
+ end
337
+ get '/', {}, { 'HTTP_HOST' => 'example.org' }
338
+ assert !ran
339
+ get '/', {}, { 'HTTP_HOST' => 'example.com' }
340
+ assert ran
341
+ end
342
+
343
+ it 'is possible to apply host_name conditions to after filters with a path' do
344
+ ran = false
345
+ mock_app do
346
+ after('/foo', :host_name => 'example.com') { ran = true }
347
+ get('/') { 'welcome' }
348
+ end
349
+ get '/', {}, { 'HTTP_HOST' => 'example.com' }
350
+ assert !ran
351
+ get '/foo', {}, { 'HTTP_HOST' => 'example.org' }
352
+ assert !ran
353
+ get '/foo', {}, { 'HTTP_HOST' => 'example.com' }
354
+ assert ran
355
+ end
356
+
357
+ it 'is possible to apply user_agent conditions to before filters with no path' do
358
+ ran = false
359
+ mock_app do
360
+ before(:user_agent => /foo/) { ran = true }
361
+ get('/') { 'welcome' }
362
+ end
363
+ get '/', {}, { 'HTTP_USER_AGENT' => 'bar' }
364
+ assert !ran
365
+ get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
366
+ assert ran
367
+ end
368
+
369
+ it 'is possible to apply user_agent conditions to before filters with a path' do
370
+ ran = false
371
+ mock_app do
372
+ before('/foo', :user_agent => /foo/) { ran = true }
373
+ get('/') { 'welcome' }
374
+ end
375
+ get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
376
+ assert !ran
377
+ get '/foo', {}, { 'HTTP_USER_AGENT' => 'bar' }
378
+ assert !ran
379
+ get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' }
380
+ assert ran
381
+ end
382
+
383
+ it 'can add params' do
384
+ mock_app do
385
+ before { params['foo'] = 'bar' }
386
+ get('/') { params['foo'] }
387
+ end
388
+
389
+ get '/'
390
+ assert_body 'bar'
391
+ end
392
+
393
+ it 'can remove params' do
394
+ mock_app do
395
+ before { params.delete('foo') }
396
+ get('/') { params['foo'].to_s }
397
+ end
398
+
399
+ get '/?foo=bar'
400
+ assert_body ''
401
+ end
402
+
403
+ it 'is possible to apply user_agent conditions to after filters with no path' do
404
+ ran = false
405
+ mock_app do
406
+ after(:user_agent => /foo/) { ran = true }
407
+ get('/') { 'welcome' }
408
+ end
409
+ get '/', {}, { 'HTTP_USER_AGENT' => 'bar' }
410
+ assert !ran
411
+ get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
412
+ assert ran
413
+ end
414
+
415
+ it 'is possible to apply user_agent conditions to before filters with a path' do
416
+ ran = false
417
+ mock_app do
418
+ after('/foo', :user_agent => /foo/) { ran = true }
419
+ get('/') { 'welcome' }
420
+ end
421
+ get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
422
+ assert !ran
423
+ get '/foo', {}, { 'HTTP_USER_AGENT' => 'bar' }
424
+ assert !ran
425
+ get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' }
426
+ assert ran
427
+ end
428
+
429
+ it 'only triggeres provides condition if conforms with current Content-Type' do
430
+ mock_app do
431
+ before(:provides => :txt) { @type = 'txt' }
432
+ before(:provides => :html) { @type = 'html' }
433
+ get('/') { @type }
434
+ end
435
+
436
+ get '/', {}, { 'HTTP_ACCEPT' => '*' }
437
+ assert_body 'txt'
438
+ end
221
439
  end