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,160 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class FooError < RuntimeError
4
+ end
5
+
6
+ class FooNotFound < Sinatra::NotFound
7
+ end
8
+
9
+ describe 'Exception Mappings' do
10
+ it 'invokes handlers registered with ::error when raised' do
11
+ mock_app {
12
+ set :raise_errors, false
13
+ error(FooError) { 'Foo!' }
14
+ get '/' do
15
+ raise FooError
16
+ end
17
+ }
18
+ get '/'
19
+ assert_equal 500, status
20
+ assert_equal 'Foo!', body
21
+ end
22
+
23
+ it 'uses the Exception handler if no matching handler found' do
24
+ mock_app {
25
+ set :raise_errors, false
26
+ error(Exception) { 'Exception!' }
27
+ get '/' do
28
+ raise FooError
29
+ end
30
+ }
31
+ get '/'
32
+ assert_equal 500, status
33
+ assert_equal 'Exception!', body
34
+ end
35
+
36
+ it "sets env['sinatra.error'] to the rescued exception" do
37
+ mock_app {
38
+ set :raise_errors, false
39
+ error(FooError) {
40
+ assert env.include?('sinatra.error')
41
+ assert env['sinatra.error'].kind_of?(FooError)
42
+ 'looks good'
43
+ }
44
+ get '/' do
45
+ raise FooError
46
+ end
47
+ }
48
+ get '/'
49
+ assert_equal 'looks good', body
50
+ end
51
+
52
+ it 'dumps errors to rack.errors when dump_errors is enabled' do
53
+ mock_app {
54
+ set :raise_errors, false
55
+ set :dump_errors, true
56
+ get('/') { raise FooError, 'BOOM!' }
57
+ }
58
+
59
+ get '/'
60
+ assert_equal 500, status
61
+ assert @response.errors =~ /FooError - BOOM!:/
62
+ end
63
+
64
+ it "raises without calling the handler when the raise_errors options is set" do
65
+ mock_app {
66
+ set :raise_errors, true
67
+ error(FooError) { "she's not there." }
68
+ get '/' do
69
+ raise FooError
70
+ end
71
+ }
72
+ assert_raise(FooError) { get '/' }
73
+ end
74
+
75
+ it "never raises Sinatra::NotFound beyond the application" do
76
+ mock_app {
77
+ set :raise_errors, true
78
+ get '/' do
79
+ raise Sinatra::NotFound
80
+ end
81
+ }
82
+ assert_nothing_raised { get '/' }
83
+ assert_equal 404, status
84
+ end
85
+
86
+ it "cascades for subclasses of Sinatra::NotFound" do
87
+ mock_app {
88
+ set :raise_errors, true
89
+ error(FooNotFound) { "foo! not found." }
90
+ get '/' do
91
+ raise FooNotFound
92
+ end
93
+ }
94
+ assert_nothing_raised { get '/' }
95
+ assert_equal 404, status
96
+ assert_equal 'foo! not found.', body
97
+ end
98
+
99
+ it 'has a not_found method for backwards compatibility' do
100
+ mock_app {
101
+ not_found do
102
+ "Lost, are we?"
103
+ end
104
+ }
105
+
106
+ get '/test'
107
+ assert_equal 404, status
108
+ assert_equal "Lost, are we?", body
109
+ end
110
+ end
111
+
112
+ describe 'Custom Error Pages' do
113
+ it 'allows numeric status code mappings to be registered with ::error' do
114
+ mock_app {
115
+ set :raise_errors, false
116
+ error(500) { 'Foo!' }
117
+ get '/' do
118
+ [500, {}, 'Internal Foo Error']
119
+ end
120
+ }
121
+ get '/'
122
+ assert_equal 500, status
123
+ assert_equal 'Foo!', body
124
+ end
125
+
126
+ it 'allows ranges of status code mappings to be registered with :error' do
127
+ mock_app {
128
+ set :raise_errors, false
129
+ error(500..550) { "Error: #{response.status}" }
130
+ get '/' do
131
+ [507, {}, 'A very special error']
132
+ end
133
+ }
134
+ get '/'
135
+ assert_equal 507, status
136
+ assert_equal 'Error: 507', body
137
+ end
138
+
139
+ class FooError < RuntimeError
140
+ end
141
+
142
+ it 'runs after exception mappings and overwrites body' do
143
+ mock_app {
144
+ set :raise_errors, false
145
+ error FooError do
146
+ response.status = 502
147
+ 'from exception mapping'
148
+ end
149
+ error(500) { 'from 500 handler' }
150
+ error(502) { 'from custom error page' }
151
+
152
+ get '/' do
153
+ raise FooError
154
+ end
155
+ }
156
+ get '/'
157
+ assert_equal 502, status
158
+ assert_equal 'from custom error page', body
159
+ end
160
+ end
@@ -0,0 +1,60 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe "Middleware" do
4
+ before do
5
+ @app = mock_app(Sinatra::Default) {
6
+ get '/*' do
7
+ response.headers['X-Tests'] = env['test.ran'].
8
+ map { |n| n.split('::').last }.
9
+ join(', ')
10
+ env['PATH_INFO']
11
+ end
12
+ }
13
+ end
14
+
15
+ class MockMiddleware < Struct.new(:app)
16
+ def call(env)
17
+ (env['test.ran'] ||= []) << self.class.to_s
18
+ app.call(env)
19
+ end
20
+ end
21
+
22
+ class UpcaseMiddleware < MockMiddleware
23
+ def call(env)
24
+ env['PATH_INFO'] = env['PATH_INFO'].upcase
25
+ super
26
+ end
27
+ end
28
+
29
+ it "is added with Sinatra::Application.use" do
30
+ @app.use UpcaseMiddleware
31
+ get '/hello-world'
32
+ assert ok?
33
+ assert_equal '/HELLO-WORLD', body
34
+ end
35
+
36
+ class DowncaseMiddleware < MockMiddleware
37
+ def call(env)
38
+ env['PATH_INFO'] = env['PATH_INFO'].downcase
39
+ super
40
+ end
41
+ end
42
+
43
+ it "runs in the order defined" do
44
+ @app.use UpcaseMiddleware
45
+ @app.use DowncaseMiddleware
46
+ get '/Foo'
47
+ assert_equal "/foo", body
48
+ assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests']
49
+ end
50
+
51
+ it "resets the prebuilt pipeline when new middleware is added" do
52
+ @app.use UpcaseMiddleware
53
+ get '/Foo'
54
+ assert_equal "/FOO", body
55
+ @app.use DowncaseMiddleware
56
+ get '/Foo'
57
+ assert_equal '/foo', body
58
+ assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests']
59
+ end
60
+ end
@@ -0,0 +1,374 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'Options' do
4
+ before do
5
+ restore_default_options
6
+ @app = Sinatra.new
7
+ end
8
+
9
+ it 'sets options to literal values' do
10
+ @app.set(:foo, 'bar')
11
+ assert @app.respond_to?(:foo)
12
+ assert_equal 'bar', @app.foo
13
+ end
14
+
15
+ it 'sets options to Procs' do
16
+ @app.set(:foo, Proc.new { 'baz' })
17
+ assert @app.respond_to?(:foo)
18
+ assert_equal 'baz', @app.foo
19
+ end
20
+
21
+ it "sets multiple options with a Hash" do
22
+ @app.set :foo => 1234,
23
+ :bar => 'Hello World',
24
+ :baz => Proc.new { 'bizzle' }
25
+ assert_equal 1234, @app.foo
26
+ assert_equal 'Hello World', @app.bar
27
+ assert_equal 'bizzle', @app.baz
28
+ end
29
+
30
+ it 'inherits option methods when subclassed' do
31
+ @app.set :foo, 'bar'
32
+ @app.set :biz, Proc.new { 'baz' }
33
+
34
+ sub = Class.new(@app)
35
+ assert sub.respond_to?(:foo)
36
+ assert_equal 'bar', sub.foo
37
+ assert sub.respond_to?(:biz)
38
+ assert_equal 'baz', sub.biz
39
+ end
40
+
41
+ it 'overrides options in subclass' do
42
+ @app.set :foo, 'bar'
43
+ @app.set :biz, Proc.new { 'baz' }
44
+ sub = Class.new(@app)
45
+ sub.set :foo, 'bling'
46
+ assert_equal 'bling', sub.foo
47
+ assert_equal 'bar', @app.foo
48
+ end
49
+
50
+ it 'creates setter methods when first defined' do
51
+ @app.set :foo, 'bar'
52
+ assert @app.respond_to?('foo=')
53
+ @app.foo = 'biz'
54
+ assert_equal 'biz', @app.foo
55
+ end
56
+
57
+ it 'creates predicate methods when first defined' do
58
+ @app.set :foo, 'hello world'
59
+ assert @app.respond_to?(:foo?)
60
+ assert @app.foo?
61
+ @app.set :foo, nil
62
+ assert !@app.foo?
63
+ end
64
+
65
+ it 'uses existing setter methods if detected' do
66
+ class << @app
67
+ def foo
68
+ @foo
69
+ end
70
+ def foo=(value)
71
+ @foo = 'oops'
72
+ end
73
+ end
74
+
75
+ @app.set :foo, 'bam'
76
+ assert_equal 'oops', @app.foo
77
+ end
78
+
79
+ it "sets multiple options to true with #enable" do
80
+ @app.enable :sessions, :foo, :bar
81
+ assert @app.sessions
82
+ assert @app.foo
83
+ assert @app.bar
84
+ end
85
+
86
+ it "sets multiple options to false with #disable" do
87
+ @app.disable :sessions, :foo, :bar
88
+ assert !@app.sessions
89
+ assert !@app.foo
90
+ assert !@app.bar
91
+ end
92
+
93
+ it 'enables MethodOverride middleware when :methodoverride is enabled' do
94
+ @app.set :methodoverride, true
95
+ @app.put('/') { 'okay' }
96
+ post '/', {'_method'=>'PUT'}, {}
97
+ assert_equal 200, status
98
+ assert_equal 'okay', body
99
+ end
100
+ end
101
+
102
+ describe_option 'clean_trace' do
103
+ def clean_backtrace(trace)
104
+ @base.new.send(:clean_backtrace, trace)
105
+ end
106
+
107
+ it 'is enabled on Base' do
108
+ assert @base.clean_trace?
109
+ end
110
+
111
+ it 'is enabled on Default' do
112
+ assert @default.clean_trace?
113
+ end
114
+
115
+ it 'does nothing when disabled' do
116
+ backtrace = [
117
+ "./lib/sinatra/base.rb",
118
+ "./myapp:42",
119
+ ("#{Gem.dir}/some/lib.rb" if defined?(Gem))
120
+ ].compact
121
+ @base.set :clean_trace, false
122
+ assert_equal backtrace, clean_backtrace(backtrace)
123
+ end
124
+
125
+ it 'removes sinatra lib paths from backtrace when enabled' do
126
+ backtrace = [
127
+ "./lib/sinatra/base.rb",
128
+ "./lib/sinatra/compat.rb:42",
129
+ "./lib/sinatra/main.rb:55 in `foo'"
130
+ ]
131
+ assert clean_backtrace(backtrace).empty?
132
+ end
133
+
134
+ it 'removes ./ prefix from backtrace paths when enabled' do
135
+ assert_equal ['myapp.rb:42'], clean_backtrace(['./myapp.rb:42'])
136
+ end
137
+
138
+ if defined?(Gem)
139
+ it 'removes gem lib paths from backtrace when enabled' do
140
+ assert clean_backtrace(["#{Gem.dir}/some/lib"]).empty?
141
+ end
142
+ end
143
+ end
144
+
145
+ describe_option 'run' do
146
+ it 'is disabled on Base' do
147
+ assert ! @base.run?
148
+ end
149
+
150
+ it 'is enabled on Default when not in test environment' do
151
+ assert @default.development?
152
+ assert @default.run?
153
+
154
+ @default.set :environment, :development
155
+ assert @default.run?
156
+ end
157
+
158
+ # TODO: it 'is enabled when $0 == app_file'
159
+ end
160
+
161
+ describe_option 'raise_errors' do
162
+ it 'is enabled on Base' do
163
+ assert @base.raise_errors?
164
+ end
165
+
166
+ it 'is enabled on Default only in test' do
167
+ @default.set(:environment, :development)
168
+ assert @default.development?
169
+ assert ! @default.raise_errors?, "disabled development"
170
+
171
+ @default.set(:environment, :production)
172
+ assert ! @default.raise_errors?
173
+
174
+ @default.set(:environment, :test)
175
+ assert @default.raise_errors?
176
+ end
177
+ end
178
+
179
+ describe_option 'dump_errors' do
180
+ it 'is disabled on Base' do
181
+ assert ! @base.dump_errors?
182
+ end
183
+
184
+ it 'is enabled on Default' do
185
+ assert @default.dump_errors?
186
+ end
187
+
188
+ it 'dumps exception with backtrace to rack.errors' do
189
+ Sinatra::Default.disable(:raise_errors)
190
+
191
+ mock_app(Sinatra::Default) {
192
+ error do
193
+ error = @env['rack.errors'].instance_variable_get(:@error)
194
+ error.rewind
195
+
196
+ error.read
197
+ end
198
+
199
+ get '/' do
200
+ raise
201
+ end
202
+ }
203
+
204
+ get '/'
205
+ assert body.include?("RuntimeError") && body.include?("options_test.rb")
206
+ end
207
+ end
208
+
209
+ describe_option 'sessions' do
210
+ it 'is disabled on Base' do
211
+ assert ! @base.sessions?
212
+ end
213
+
214
+ it 'is disabled on Default' do
215
+ assert ! @default.sessions?
216
+ end
217
+
218
+ # TODO: it 'uses Rack::Session::Cookie when enabled' do
219
+ end
220
+
221
+ describe_option 'logging' do
222
+ it 'is disabled on Base' do
223
+ assert ! @base.logging?
224
+ end
225
+
226
+ it 'is enabled on Default when not in test environment' do
227
+ assert @default.logging?
228
+
229
+ @default.set :environment, :test
230
+ assert ! @default.logging
231
+ end
232
+
233
+ # TODO: it 'uses Rack::CommonLogger when enabled' do
234
+ end
235
+
236
+ describe_option 'static' do
237
+ it 'is disabled on Base' do
238
+ assert ! @base.static?
239
+ end
240
+
241
+ it 'is enabled on Default' do
242
+ assert @default.static?
243
+ end
244
+
245
+ # TODO: it setup static routes if public is enabled
246
+ # TODO: however, that's already tested in static_test so...
247
+ end
248
+
249
+ describe_option 'host' do
250
+ it 'defaults to 0.0.0.0' do
251
+ assert_equal '0.0.0.0', @base.host
252
+ assert_equal '0.0.0.0', @default.host
253
+ end
254
+ end
255
+
256
+ describe_option 'port' do
257
+ it 'defaults to 4567' do
258
+ assert_equal 4567, @base.port
259
+ assert_equal 4567, @default.port
260
+ end
261
+ end
262
+
263
+ describe_option 'server' do
264
+ it 'is one of thin, mongrel, webrick' do
265
+ assert_equal %w[thin mongrel webrick], @base.server
266
+ assert_equal %w[thin mongrel webrick], @default.server
267
+ end
268
+ end
269
+
270
+ describe_option 'app_file' do
271
+ it 'is nil' do
272
+ assert @base.app_file.nil?
273
+ assert @default.app_file.nil?
274
+ end
275
+ end
276
+
277
+ describe_option 'root' do
278
+ it 'is nil if app_file is not set' do
279
+ assert @base.root.nil?
280
+ assert @default.root.nil?
281
+ end
282
+
283
+ it 'is equal to the expanded basename of app_file' do
284
+ @base.app_file = __FILE__
285
+ assert_equal File.expand_path(File.dirname(__FILE__)), @base.root
286
+
287
+ @default.app_file = __FILE__
288
+ assert_equal File.expand_path(File.dirname(__FILE__)), @default.root
289
+ end
290
+ end
291
+
292
+ describe_option 'views' do
293
+ it 'is nil if root is not set' do
294
+ assert @base.views.nil?
295
+ assert @default.views.nil?
296
+ end
297
+
298
+ it 'is set to root joined with views/' do
299
+ @base.root = File.dirname(__FILE__)
300
+ assert_equal File.dirname(__FILE__) + "/views", @base.views
301
+
302
+ @default.root = File.dirname(__FILE__)
303
+ assert_equal File.dirname(__FILE__) + "/views", @default.views
304
+ end
305
+ end
306
+
307
+ describe_option 'public' do
308
+ it 'is nil if root is not set' do
309
+ assert @base.public.nil?
310
+ assert @default.public.nil?
311
+ end
312
+
313
+ it 'is set to root joined with public/' do
314
+ @base.root = File.dirname(__FILE__)
315
+ assert_equal File.dirname(__FILE__) + "/public", @base.public
316
+
317
+ @default.root = File.dirname(__FILE__)
318
+ assert_equal File.dirname(__FILE__) + "/public", @default.public
319
+ end
320
+ end
321
+
322
+ describe_option 'reload' do
323
+ it 'is enabled when
324
+ app_file is set,
325
+ is not a rackup file,
326
+ and we are in development' do
327
+ @base.app_file = __FILE__
328
+ @base.set(:environment, :development)
329
+ assert @base.reload?
330
+
331
+ @default.app_file = __FILE__
332
+ @default.set(:environment, :development)
333
+ assert @default.reload?
334
+ end
335
+
336
+ it 'is disabled if app_file is not set' do
337
+ assert ! @base.reload?
338
+ assert ! @default.reload?
339
+ end
340
+
341
+ it 'is disabled if app_file is a rackup file' do
342
+ @base.app_file = 'config.ru'
343
+ assert ! @base.reload?
344
+
345
+ @default.app_file = 'config.ru'
346
+ assert ! @base.reload?
347
+ end
348
+
349
+ it 'is disabled if we are not in development' do
350
+ @base.set(:environment, :foo)
351
+ assert ! @base.reload
352
+
353
+ @default.set(:environment, :bar)
354
+ assert ! @default.reload
355
+ end
356
+ end
357
+
358
+ describe_option 'lock' do
359
+ it 'is enabled when reload is enabled' do
360
+ @base.enable(:reload)
361
+ assert @base.lock?
362
+
363
+ @default.enable(:reload)
364
+ assert @default.lock?
365
+ end
366
+
367
+ it 'is disabled when reload is disabled' do
368
+ @base.disable(:reload)
369
+ assert ! @base.lock?
370
+
371
+ @default.disable(:reload)
372
+ assert ! @default.lock?
373
+ end
374
+ end