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
@@ -1,33 +1,57 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  begin
4
4
  require 'sass'
5
5
 
6
6
  class SassTest < Test::Unit::TestCase
7
- def sass_app(&block)
7
+ def sass_app(options = {}, &block)
8
8
  mock_app {
9
9
  set :views, File.dirname(__FILE__) + '/views'
10
+ set options
10
11
  get '/', &block
11
12
  }
12
13
  get '/'
13
14
  end
14
15
 
15
16
  it 'renders inline Sass strings' do
16
- sass_app { sass "#sass\n :background-color #FFF\n" }
17
+ sass_app { sass "#sass\n :background-color white\n" }
17
18
  assert ok?
18
- assert_equal "#sass {\n background-color: #FFF; }\n", body
19
+ assert_equal "#sass {\n background-color: white; }\n", body
20
+ end
21
+
22
+ it 'defaults content type to css' do
23
+ sass_app { sass "#sass\n :background-color white\n" }
24
+ assert ok?
25
+ assert_equal "text/css;charset=utf-8", response['Content-Type']
26
+ end
27
+
28
+ it 'defaults allows setting content type per route' do
29
+ sass_app do
30
+ content_type :html
31
+ sass "#sass\n :background-color white\n"
32
+ end
33
+ assert ok?
34
+ assert_equal "text/html;charset=utf-8", response['Content-Type']
35
+ end
36
+
37
+ it 'defaults allows setting content type globally' do
38
+ sass_app(:sass => { :content_type => 'html' }) do
39
+ sass "#sass\n :background-color white\n"
40
+ end
41
+ assert ok?
42
+ assert_equal "text/html;charset=utf-8", response['Content-Type']
19
43
  end
20
44
 
21
45
  it 'renders .sass files in views path' do
22
46
  sass_app { sass :hello }
23
47
  assert ok?
24
- assert_equal "#sass {\n background-color: #FFF; }\n", body
48
+ assert_equal "#sass {\n background-color: white; }\n", body
25
49
  end
26
50
 
27
51
  it 'ignores the layout option' do
28
52
  sass_app { sass :hello, :layout => :layout2 }
29
53
  assert ok?
30
- assert_equal "#sass {\n background-color: #FFF; }\n", body
54
+ assert_equal "#sass {\n background-color: white; }\n", body
31
55
  end
32
56
 
33
57
  it "raises error if template not found" do
@@ -39,47 +63,53 @@ class SassTest < Test::Unit::TestCase
39
63
 
40
64
  it "passes SASS options to the Sass engine" do
41
65
  sass_app {
42
- sass "#sass\n :background-color #FFF\n :color #000\n", :style => :compact
66
+ sass "#sass\n :background-color white\n :color black\n",
67
+ :style => :compact
43
68
  }
44
69
  assert ok?
45
- assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
70
+ assert_equal "#sass { background-color: white; color: black; }\n", body
46
71
  end
47
72
 
48
73
  it "passes default SASS options to the Sass engine" do
49
74
  mock_app {
50
75
  set :sass, {:style => :compact} # default Sass style is :nested
51
76
  get '/' do
52
- sass "#sass\n :background-color #FFF\n :color #000\n"
77
+ sass "#sass\n :background-color white\n :color black\n"
53
78
  end
54
79
  }
55
80
  get '/'
56
81
  assert ok?
57
- assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
82
+ assert_equal "#sass { background-color: white; color: black; }\n", body
58
83
  end
59
84
 
60
- it "merges the default SASS options with the overrides and passes them to the Sass engine" do
85
+ it "merges the default SASS options with the overrides" do
61
86
  mock_app {
62
- set :sass, {:style => :compact, :attribute_syntax => :alternate } # default Sass attribute_syntax is :normal (with : in front)
87
+ # default Sass attribute_syntax is :normal (with : in front)
88
+ set :sass, {:style => :compact, :attribute_syntax => :alternate }
63
89
  get '/' do
64
- sass "#sass\n background-color: #FFF\n color: #000\n"
90
+ sass "#sass\n background-color: white\n color: black\n"
65
91
  end
66
92
  get '/raised' do
67
- sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded # retains global attribute_syntax settings
93
+ # retains global attribute_syntax settings
94
+ sass "#sass\n :background-color white\n :color black\n",
95
+ :style => :expanded
68
96
  end
69
97
  get '/expanded_normal' do
70
- sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded, :attribute_syntax => :normal
98
+ sass "#sass\n :background-color white\n :color black\n",
99
+ :style => :expanded, :attribute_syntax => :normal
71
100
  end
72
101
  }
73
102
  get '/'
74
103
  assert ok?
75
- assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
104
+ assert_equal "#sass { background-color: white; color: black; }\n", body
76
105
  assert_raise(Sass::SyntaxError) { get('/raised') }
77
106
  get '/expanded_normal'
78
107
  assert ok?
79
- assert_equal "#sass {\n background-color: #FFF;\n color: #000;\n}\n", body
108
+ assert_equal "#sass {\n background-color: white;\n color: black;\n}\n",
109
+ body
80
110
  end
81
111
  end
82
112
 
83
- rescue
113
+ rescue LoadError
84
114
  warn "#{$!.to_s}: skipping sass tests"
85
115
  end
@@ -0,0 +1,88 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ begin
4
+ require 'sass'
5
+
6
+ class ScssTest < Test::Unit::TestCase
7
+ def scss_app(options = {}, &block)
8
+ mock_app {
9
+ set :views, File.dirname(__FILE__) + '/views'
10
+ set options
11
+ get '/', &block
12
+ }
13
+ get '/'
14
+ end
15
+
16
+ it 'renders inline Scss strings' do
17
+ scss_app { scss "#scss {\n background-color: white; }\n" }
18
+ assert ok?
19
+ assert_equal "#scss {\n background-color: white; }\n", body
20
+ end
21
+
22
+ it 'defaults content type to css' do
23
+ scss_app { scss "#scss {\n background-color: white; }\n" }
24
+ assert ok?
25
+ assert_equal "text/css;charset=utf-8", response['Content-Type']
26
+ end
27
+
28
+ it 'defaults allows setting content type per route' do
29
+ scss_app do
30
+ content_type :html
31
+ scss "#scss {\n background-color: white; }\n"
32
+ end
33
+ assert ok?
34
+ assert_equal "text/html;charset=utf-8", response['Content-Type']
35
+ end
36
+
37
+ it 'defaults allows setting content type globally' do
38
+ scss_app(:scss => { :content_type => 'html' }) do
39
+ scss "#scss {\n background-color: white; }\n"
40
+ end
41
+ assert ok?
42
+ assert_equal "text/html;charset=utf-8", response['Content-Type']
43
+ end
44
+
45
+ it 'renders .scss files in views path' do
46
+ scss_app { scss :hello }
47
+ assert ok?
48
+ assert_equal "#scss {\n background-color: white; }\n", body
49
+ end
50
+
51
+ it 'ignores the layout option' do
52
+ scss_app { scss :hello, :layout => :layout2 }
53
+ assert ok?
54
+ assert_equal "#scss {\n background-color: white; }\n", body
55
+ end
56
+
57
+ it "raises error if template not found" do
58
+ mock_app {
59
+ get('/') { scss :no_such_template }
60
+ }
61
+ assert_raise(Errno::ENOENT) { get('/') }
62
+ end
63
+
64
+ it "passes scss options to the scss engine" do
65
+ scss_app {
66
+ scss "#scss {\n background-color: white;\n color: black\n}",
67
+ :style => :compact
68
+ }
69
+ assert ok?
70
+ assert_equal "#scss { background-color: white; color: black; }\n", body
71
+ end
72
+
73
+ it "passes default scss options to the scss engine" do
74
+ mock_app {
75
+ set :scss, {:style => :compact} # default scss style is :nested
76
+ get '/' do
77
+ scss "#scss {\n background-color: white;\n color: black;\n}"
78
+ end
79
+ }
80
+ get '/'
81
+ assert ok?
82
+ assert_equal "#scss { background-color: white; color: black; }\n", body
83
+ end
84
+ end
85
+
86
+ rescue LoadError
87
+ warn "#{$!.to_s}: skipping scss tests"
88
+ end
@@ -1,4 +1,5 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require File.expand_path('../helper', __FILE__)
2
+ require 'stringio'
2
3
 
3
4
  module Rack::Handler
4
5
  class Mock
@@ -25,11 +26,11 @@ class ServerTest < Test::Unit::TestCase
25
26
  set :bind, 'foo.local'
26
27
  set :port, 9001
27
28
  }
28
- $stdout = File.open('/dev/null', 'wb')
29
+ $stderr = StringIO.new
29
30
  end
30
31
 
31
32
  def teardown
32
- $stdout = STDOUT
33
+ $stderr = STDERR
33
34
  end
34
35
 
35
36
  it "locates the appropriate Rack handler and calls ::run" do
@@ -1,12 +1,12 @@
1
- require File.dirname(__FILE__) + '/helper'
1
+ require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  class SettingsTest < Test::Unit::TestCase
4
4
  setup do
5
5
  @base = Sinatra.new(Sinatra::Base)
6
- @base.set :environment, :foo
6
+ @base.set :environment => :foo, :app_file => nil
7
7
 
8
8
  @application = Sinatra.new(Sinatra::Application)
9
- @application.set :environment, :foo
9
+ @application.set :environment => :foo, :app_file => nil
10
10
  end
11
11
 
12
12
  it 'sets settings to literal values' do
@@ -34,6 +34,24 @@ class SettingsTest < Test::Unit::TestCase
34
34
  assert !@base.respond_to?(:fiz)
35
35
  end
36
36
 
37
+ it 'raises an error without value and block' do
38
+ assert_raise(ArgumentError) { @base.set(:fiz) }
39
+ assert !@base.respond_to?(:fiz)
40
+ end
41
+
42
+ it 'allows setting a value to the app class' do
43
+ @base.set :base, @base
44
+ assert @base.respond_to?(:base)
45
+ assert_equal @base, @base.base
46
+ end
47
+
48
+ it 'raises an error with the app class as value and a block' do
49
+ assert_raise ArgumentError do
50
+ @base.set(:fiz, @base) { 'baz' }
51
+ end
52
+ assert !@base.respond_to?(:fiz)
53
+ end
54
+
37
55
  it "sets multiple settings with a Hash" do
38
56
  @base.set :foo => 1234,
39
57
  :bar => 'Hello World',
@@ -43,6 +61,11 @@ class SettingsTest < Test::Unit::TestCase
43
61
  assert_equal 'bizzle', @base.baz
44
62
  end
45
63
 
64
+ it 'sets multiple settings using #each' do
65
+ @base.set [["foo", "bar"]]
66
+ assert_equal "bar", @base.foo
67
+ end
68
+
46
69
  it 'inherits settings methods when subclassed' do
47
70
  @base.set :foo, 'bar'
48
71
  @base.set :biz, Proc.new { 'baz' }
@@ -92,6 +115,32 @@ class SettingsTest < Test::Unit::TestCase
92
115
  assert_equal 'oops', @base.foo
93
116
  end
94
117
 
118
+ it 'merges values of multiple set calls if those are hashes' do
119
+ @base.set :foo, :a => 1
120
+ sub = Class.new(@base)
121
+ sub.set :foo, :b => 2
122
+ assert_equal({:a => 1, :b => 2}, sub.foo)
123
+ end
124
+
125
+ it 'merging does not affect the superclass' do
126
+ @base.set :foo, :a => 1
127
+ sub = Class.new(@base)
128
+ sub.set :foo, :b => 2
129
+ assert_equal({:a => 1}, @base.foo)
130
+ end
131
+
132
+ it 'is possible to change a value from a hash to something else' do
133
+ @base.set :foo, :a => 1
134
+ @base.set :foo, :bar
135
+ assert_equal(:bar, @base.foo)
136
+ end
137
+
138
+ it 'merges values with values of the superclass if those are hashes' do
139
+ @base.set :foo, :a => 1
140
+ @base.set :foo, :b => 2
141
+ assert_equal({:a => 1, :b => 2}, @base.foo)
142
+ end
143
+
95
144
  it "sets multiple settings to true with #enable" do
96
145
  @base.enable :sessions, :foo, :bar
97
146
  assert @base.sessions
@@ -107,7 +156,11 @@ class SettingsTest < Test::Unit::TestCase
107
156
  end
108
157
 
109
158
  it 'is accessible from instances via #settings' do
110
- assert_equal :foo, @base.new.settings.environment
159
+ assert_equal :foo, @base.new!.settings.environment
160
+ end
161
+
162
+ it 'is accessible from class via #settings' do
163
+ assert_equal :foo, @base.settings.environment
111
164
  end
112
165
 
113
166
  describe 'methodoverride' do
@@ -193,6 +246,32 @@ class SettingsTest < Test::Unit::TestCase
193
246
  assert body.include?("StandardError")
194
247
  assert body.include?("<code>show_exceptions</code> setting")
195
248
  end
249
+
250
+ it 'does not override app-specified error handling when set to :after_handler' do
251
+ ran = false
252
+ mock_app do
253
+ set :show_exceptions, :after_handler
254
+ error(RuntimeError) { ran = true }
255
+ get('/') { raise RuntimeError }
256
+ end
257
+
258
+ get '/'
259
+ assert_equal 500, status
260
+ assert ran
261
+ end
262
+
263
+ it 'does catch any other exceptions when set to :after_handler' do
264
+ ran = false
265
+ mock_app do
266
+ set :show_exceptions, :after_handler
267
+ error(RuntimeError) { ran = true }
268
+ get('/') { raise ArgumentError }
269
+ end
270
+
271
+ get '/'
272
+ assert_equal 500, status
273
+ assert !ran
274
+ end
196
275
  end
197
276
 
198
277
  describe 'dump_errors' do
@@ -227,6 +306,29 @@ class SettingsTest < Test::Unit::TestCase
227
306
  get '/'
228
307
  assert body.include?("RuntimeError") && body.include?("settings_test.rb")
229
308
  end
309
+
310
+ it 'does not dump 404 errors' do
311
+ klass = Sinatra.new(Sinatra::Application)
312
+
313
+ mock_app(klass) {
314
+ enable :dump_errors
315
+ disable :raise_errors
316
+
317
+ error do
318
+ error = @env['rack.errors'].instance_variable_get(:@error)
319
+ error.rewind
320
+
321
+ error.read
322
+ end
323
+
324
+ get '/' do
325
+ raise Sinatra::NotFound
326
+ end
327
+ }
328
+
329
+ get '/'
330
+ assert !body.include?("NotFound") && !body.include?("settings_test.rb")
331
+ end
230
332
  end
231
333
 
232
334
  describe 'sessions' do
@@ -257,13 +359,13 @@ class SettingsTest < Test::Unit::TestCase
257
359
  assert ! @base.static?
258
360
  end
259
361
 
260
- it 'is enabled on Base when public is set and exists' do
362
+ it 'is enabled on Base when public_folder is set and exists' do
261
363
  @base.set :environment, :development
262
- @base.set :public, File.dirname(__FILE__)
364
+ @base.set :public_folder, File.dirname(__FILE__)
263
365
  assert @base.static?
264
366
  end
265
367
 
266
- it 'is enabled on Base when root is set and root/public exists' do
368
+ it 'is enabled on Base when root is set and root/public_folder exists' do
267
369
  @base.set :environment, :development
268
370
  @base.set :root, File.dirname(__FILE__)
269
371
  assert @base.static?
@@ -273,17 +375,36 @@ class SettingsTest < Test::Unit::TestCase
273
375
  assert ! @application.static?
274
376
  end
275
377
 
276
- it 'is enabled on Application when public is set and exists' do
378
+ it 'is enabled on Application when public_folder is set and exists' do
277
379
  @application.set :environment, :development
278
- @application.set :public, File.dirname(__FILE__)
380
+ @application.set :public_folder, File.dirname(__FILE__)
279
381
  assert @application.static?
280
382
  end
281
383
 
282
- it 'is enabled on Application when root is set and root/public exists' do
384
+ it 'is enabled on Application when root is set and root/public_folder exists' do
283
385
  @application.set :environment, :development
284
386
  @application.set :root, File.dirname(__FILE__)
285
387
  assert @application.static?
286
388
  end
389
+
390
+ it 'is possible to use Module#public' do
391
+ @base.send(:define_method, :foo) { }
392
+ @base.send(:private, :foo)
393
+ assert !@base.public_method_defined?(:foo)
394
+ @base.send(:public, :foo)
395
+ assert @base.public_method_defined?(:foo)
396
+ end
397
+
398
+ it 'is possible to use the keyword public in a sinatra app' do
399
+ app = Sinatra.new do
400
+ private
401
+ def priv; end
402
+ public
403
+ def pub; end
404
+ end
405
+ assert !app.public_method_defined?(:priv)
406
+ assert app.public_method_defined?(:pub)
407
+ end
287
408
  end
288
409
 
289
410
  describe 'bind' do
@@ -301,16 +422,20 @@ class SettingsTest < Test::Unit::TestCase
301
422
  end
302
423
 
303
424
  describe 'server' do
304
- it 'is one of thin, mongrel, webrick' do
305
- assert_equal %w[thin mongrel webrick], @base.server
306
- assert_equal %w[thin mongrel webrick], @application.server
425
+ it 'is one of thin, puma, mongrel, webrick' do
426
+ assert_equal %w[thin puma mongrel webrick], @base.server
427
+ assert_equal %w[thin puma mongrel webrick], @application.server
307
428
  end
308
429
  end
309
430
 
310
431
  describe 'app_file' do
311
- it 'is nil' do
312
- assert_nil @base.app_file
313
- assert_nil @application.app_file
432
+ it 'is nil for base classes' do
433
+ assert_nil Sinatra::Base.app_file
434
+ assert_nil Sinatra::Application.app_file
435
+ end
436
+
437
+ it 'defaults to the file subclassing' do
438
+ assert_equal __FILE__, Sinatra.new.app_file
314
439
  end
315
440
  end
316
441
 
@@ -344,18 +469,18 @@ class SettingsTest < Test::Unit::TestCase
344
469
  end
345
470
  end
346
471
 
347
- describe 'public' do
472
+ describe 'public_folder' do
348
473
  it 'is nil if root is not set' do
349
- assert @base.public.nil?
350
- assert @application.public.nil?
474
+ assert @base.public_folder.nil?
475
+ assert @application.public_folder.nil?
351
476
  end
352
477
 
353
478
  it 'is set to root joined with public/' do
354
479
  @base.root = File.dirname(__FILE__)
355
- assert_equal File.dirname(__FILE__) + "/public", @base.public
480
+ assert_equal File.dirname(__FILE__) + "/public", @base.public_folder
356
481
 
357
482
  @application.root = File.dirname(__FILE__)
358
- assert_equal File.dirname(__FILE__) + "/public", @application.public
483
+ assert_equal File.dirname(__FILE__) + "/public", @application.public_folder
359
484
  end
360
485
  end
361
486
 
@@ -365,4 +490,49 @@ class SettingsTest < Test::Unit::TestCase
365
490
  assert ! @application.lock?
366
491
  end
367
492
  end
493
+
494
+ describe 'protection' do
495
+ class MiddlewareTracker < Rack::Builder
496
+ def self.track
497
+ Rack.send :remove_const, :Builder
498
+ Rack.const_set :Builder, MiddlewareTracker
499
+ MiddlewareTracker.used.clear
500
+ yield
501
+ ensure
502
+ Rack.send :remove_const, :Builder
503
+ Rack.const_set :Builder, MiddlewareTracker.superclass
504
+ end
505
+
506
+ def self.used
507
+ @used ||= []
508
+ end
509
+
510
+ def use(middleware, *)
511
+ MiddlewareTracker.used << middleware
512
+ super
513
+ end
514
+ end
515
+
516
+ it 'sets up Rack::Protection' do
517
+ MiddlewareTracker.track do
518
+ Sinatra::Base.new
519
+ assert_include MiddlewareTracker.used, Rack::Protection
520
+ end
521
+ end
522
+
523
+ it 'sets up Rack::Protection::PathTraversal' do
524
+ MiddlewareTracker.track do
525
+ Sinatra::Base.new
526
+ assert_include MiddlewareTracker.used, Rack::Protection::PathTraversal
527
+ end
528
+ end
529
+
530
+ it 'does not set up Rack::Protection::PathTraversal when disabling it' do
531
+ MiddlewareTracker.track do
532
+ Sinatra.new { set :protection, :except => :path_traversal }.new
533
+ assert_include MiddlewareTracker.used, Rack::Protection
534
+ assert !MiddlewareTracker.used.include?(Rack::Protection::PathTraversal)
535
+ end
536
+ end
537
+ end
368
538
  end