sinatra 0.3.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

Files changed (82) hide show
  1. data/AUTHORS +40 -0
  2. data/CHANGES +189 -0
  3. data/README.rdoc +146 -117
  4. data/Rakefile +33 -10
  5. data/{test → compat}/app_test.rb +11 -10
  6. data/{test → compat}/application_test.rb +10 -5
  7. data/compat/builder_test.rb +101 -0
  8. data/{test → compat}/custom_error_test.rb +0 -0
  9. data/compat/erb_test.rb +136 -0
  10. data/{test → compat}/events_test.rb +16 -3
  11. data/compat/filter_test.rb +30 -0
  12. data/compat/haml_test.rb +233 -0
  13. data/compat/helper.rb +30 -0
  14. data/compat/mapped_error_test.rb +72 -0
  15. data/{test → compat}/pipeline_test.rb +9 -4
  16. data/{test → compat}/public/foo.xml +0 -0
  17. data/compat/sass_test.rb +57 -0
  18. data/{test → compat}/sessions_test.rb +0 -0
  19. data/{test → compat}/streaming_test.rb +4 -1
  20. data/{test → compat}/sym_params_test.rb +0 -0
  21. data/{test → compat}/template_test.rb +0 -0
  22. data/{test → compat}/use_in_file_templates_test.rb +0 -0
  23. data/{test → compat}/views/foo.builder +0 -0
  24. data/{test → compat}/views/foo.erb +0 -0
  25. data/{test → compat}/views/foo.haml +0 -0
  26. data/{test → compat}/views/foo.sass +0 -0
  27. data/{test → compat}/views/foo_layout.erb +0 -0
  28. data/{test → compat}/views/foo_layout.haml +0 -0
  29. data/{test → compat}/views/layout_test/foo.builder +0 -0
  30. data/{test → compat}/views/layout_test/foo.erb +0 -0
  31. data/{test → compat}/views/layout_test/foo.haml +0 -0
  32. data/{test → compat}/views/layout_test/foo.sass +0 -0
  33. data/{test → compat}/views/layout_test/layout.builder +0 -0
  34. data/{test → compat}/views/layout_test/layout.erb +0 -0
  35. data/{test → compat}/views/layout_test/layout.haml +0 -0
  36. data/{test → compat}/views/layout_test/layout.sass +0 -0
  37. data/{test → compat}/views/no_layout/no_layout.builder +0 -0
  38. data/{test → compat}/views/no_layout/no_layout.haml +0 -0
  39. data/lib/sinatra.rb +6 -1484
  40. data/lib/sinatra/base.rb +838 -0
  41. data/lib/sinatra/compat.rb +239 -0
  42. data/{images → lib/sinatra/images}/404.png +0 -0
  43. data/{images → lib/sinatra/images}/500.png +0 -0
  44. data/lib/sinatra/main.rb +48 -0
  45. data/lib/sinatra/test.rb +114 -0
  46. data/lib/sinatra/test/bacon.rb +17 -0
  47. data/lib/sinatra/test/rspec.rb +7 -8
  48. data/lib/sinatra/test/spec.rb +3 -4
  49. data/lib/sinatra/test/unit.rb +3 -5
  50. data/sinatra.gemspec +68 -35
  51. data/test/base_test.rb +68 -0
  52. data/test/builder_test.rb +50 -87
  53. data/test/data/reload_app_file.rb +3 -0
  54. data/test/erb_test.rb +38 -124
  55. data/test/filter_test.rb +27 -22
  56. data/test/haml_test.rb +51 -216
  57. data/test/helper.rb +22 -6
  58. data/test/helpers_test.rb +361 -0
  59. data/test/mapped_error_test.rb +137 -49
  60. data/test/middleware_test.rb +58 -0
  61. data/test/options_test.rb +97 -0
  62. data/test/reload_test.rb +61 -0
  63. data/test/request_test.rb +18 -0
  64. data/test/result_test.rb +88 -0
  65. data/test/routing_test.rb +391 -0
  66. data/test/sass_test.rb +27 -48
  67. data/test/sinatra_test.rb +13 -0
  68. data/test/static_test.rb +57 -0
  69. data/test/templates_test.rb +88 -0
  70. data/test/views/hello.builder +1 -0
  71. data/test/views/hello.erb +1 -0
  72. data/test/views/hello.haml +1 -0
  73. data/test/views/hello.sass +2 -0
  74. data/test/views/hello.test +1 -0
  75. data/test/views/layout2.builder +3 -0
  76. data/test/views/layout2.erb +2 -0
  77. data/test/views/layout2.haml +2 -0
  78. data/test/views/layout2.test +1 -0
  79. metadata +80 -48
  80. data/ChangeLog +0 -96
  81. data/lib/sinatra/test/methods.rb +0 -76
  82. data/test/event_context_test.rb +0 -15
@@ -0,0 +1,391 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe "Routing" do
4
+ %w[get put post delete head].each do |verb|
5
+ it "defines #{verb.upcase} request handlers with #{verb}" do
6
+ mock_app {
7
+ send verb, '/hello' do
8
+ 'Hello World'
9
+ end
10
+ }
11
+
12
+ request = Rack::MockRequest.new(@app)
13
+ response = request.request(verb.upcase, '/hello', {})
14
+ assert response.ok?
15
+ assert_equal 'Hello World', response.body
16
+ end
17
+ end
18
+
19
+ it "404s when no route satisfies the request" do
20
+ mock_app {
21
+ get('/foo') { }
22
+ }
23
+ get '/bar'
24
+ assert_equal 404, status
25
+ end
26
+
27
+ it "exposes params with indifferent hash" do
28
+ mock_app {
29
+ get '/:foo' do
30
+ assert_equal 'bar', params['foo']
31
+ assert_equal 'bar', params[:foo]
32
+ 'well, alright'
33
+ end
34
+ }
35
+ get '/bar'
36
+ assert_equal 'well, alright', body
37
+ end
38
+
39
+ it "merges named params and query string params in params" do
40
+ mock_app {
41
+ get '/:foo' do
42
+ assert_equal 'bar', params['foo']
43
+ assert_equal 'biz', params['baz']
44
+ end
45
+ }
46
+ get '/bar?baz=biz'
47
+ assert ok?
48
+ end
49
+
50
+ it "supports named params like /hello/:person" do
51
+ mock_app {
52
+ get '/hello/:person' do
53
+ "Hello #{params['person']}"
54
+ end
55
+ }
56
+ get '/hello/Frank'
57
+ assert_equal 'Hello Frank', body
58
+ end
59
+
60
+ it "supports optional named params like /?:foo?/?:bar?" do
61
+ mock_app {
62
+ get '/?:foo?/?:bar?' do
63
+ "foo=#{params[:foo]};bar=#{params[:bar]}"
64
+ end
65
+ }
66
+
67
+ get '/hello/world'
68
+ assert ok?
69
+ assert_equal "foo=hello;bar=world", body
70
+
71
+ get '/hello'
72
+ assert ok?
73
+ assert_equal "foo=hello;bar=", body
74
+
75
+ get '/'
76
+ assert ok?
77
+ assert_equal "foo=;bar=", body
78
+ end
79
+
80
+ it "supports single splat params like /*" do
81
+ mock_app {
82
+ get '/*' do
83
+ assert params['splat'].kind_of?(Array)
84
+ params['splat'].join "\n"
85
+ end
86
+ }
87
+
88
+ get '/foo'
89
+ assert_equal "foo", body
90
+
91
+ get '/foo/bar/baz'
92
+ assert_equal "foo/bar/baz", body
93
+ end
94
+
95
+ it "supports mixing multiple splat params like /*/foo/*/*" do
96
+ mock_app {
97
+ get '/*/foo/*/*' do
98
+ assert params['splat'].kind_of?(Array)
99
+ params['splat'].join "\n"
100
+ end
101
+ }
102
+
103
+ get '/bar/foo/bling/baz/boom'
104
+ assert_equal "bar\nbling\nbaz/boom", body
105
+
106
+ get '/bar/foo/baz'
107
+ assert not_found?
108
+ end
109
+
110
+ it "supports mixing named and splat params like /:foo/*" do
111
+ mock_app {
112
+ get '/:foo/*' do
113
+ assert_equal 'foo', params['foo']
114
+ assert_equal ['bar/baz'], params['splat']
115
+ end
116
+ }
117
+
118
+ get '/foo/bar/baz'
119
+ assert ok?
120
+ end
121
+
122
+ it "supports basic nested params" do
123
+ mock_app {
124
+ get '/hi' do
125
+ params["person"]["name"]
126
+ end
127
+ }
128
+
129
+ get "/hi?person[name]=John+Doe"
130
+ assert ok?
131
+ assert_equal "John Doe", body
132
+ end
133
+
134
+ it "exposes nested params with indifferent hash" do
135
+ mock_app {
136
+ get '/testme' do
137
+ assert_equal 'baz', params['bar']['foo']
138
+ assert_equal 'baz', params['bar'][:foo]
139
+ 'well, alright'
140
+ end
141
+ }
142
+ get '/testme?bar[foo]=baz'
143
+ assert_equal 'well, alright', body
144
+ end
145
+
146
+ it "supports deeply nested params" do
147
+ input = {
148
+ 'browser[chrome][engine][name]' => 'V8',
149
+ 'browser[chrome][engine][version]' => '1.0',
150
+ 'browser[firefox][engine][name]' => 'spidermonkey',
151
+ 'browser[firefox][engine][version]' => '1.7.0',
152
+ 'emacs[map][goto-line]' => 'M-g g',
153
+ 'emacs[version]' => '22.3.1',
154
+ 'paste[name]' => 'hello world',
155
+ 'paste[syntax]' => 'ruby'
156
+ }
157
+ expected = {
158
+ "emacs" => {
159
+ "map" => { "goto-line" => "M-g g" },
160
+ "version" => "22.3.1"
161
+ },
162
+ "browser" => {
163
+ "firefox" => {"engine" => {"name"=>"spidermonkey", "version"=>"1.7.0"}},
164
+ "chrome" => {"engine" => {"name"=>"V8", "version"=>"1.0"}}
165
+ },
166
+ "paste" => {"name"=>"hello world", "syntax"=>"ruby"}
167
+ }
168
+ mock_app {
169
+ get '/foo' do
170
+ assert_equal expected, params
171
+ 'looks good'
172
+ end
173
+ }
174
+ get "/foo?#{param_string(input)}"
175
+ assert ok?
176
+ assert_equal 'looks good', body
177
+ end
178
+
179
+ it "supports paths that include spaces" do
180
+ mock_app {
181
+ get '/path with spaces' do
182
+ 'looks good'
183
+ end
184
+ }
185
+
186
+ get '/path%20with%20spaces'
187
+ assert ok?
188
+ assert_equal 'looks good', body
189
+ end
190
+
191
+ it "URL decodes named parameters and splats" do
192
+ mock_app {
193
+ get '/:foo/*' do
194
+ assert_equal 'hello world', params['foo']
195
+ assert_equal ['how are you'], params['splat']
196
+ nil
197
+ end
198
+ }
199
+
200
+ get '/hello%20world/how%20are%20you'
201
+ assert ok?
202
+ end
203
+
204
+ it 'supports regular expressions' do
205
+ mock_app {
206
+ get(/^\/foo...\/bar$/) do
207
+ 'Hello World'
208
+ end
209
+ }
210
+
211
+ get '/foooom/bar'
212
+ assert ok?
213
+ assert_equal 'Hello World', body
214
+ end
215
+
216
+ it 'makes regular expression captures available in params[:captures]' do
217
+ mock_app {
218
+ get(/^\/fo(.*)\/ba(.*)/) do
219
+ assert_equal ['orooomma', 'f'], params[:captures]
220
+ 'right on'
221
+ end
222
+ }
223
+
224
+ get '/foorooomma/baf'
225
+ assert ok?
226
+ assert_equal 'right on', body
227
+ end
228
+
229
+ it "returns response immediately on halt" do
230
+ mock_app {
231
+ get '/' do
232
+ halt 'Hello World'
233
+ 'Boo-hoo World'
234
+ end
235
+ }
236
+
237
+ get '/'
238
+ assert ok?
239
+ assert_equal 'Hello World', body
240
+ end
241
+
242
+ it "transitions to the next matching route on pass" do
243
+ mock_app {
244
+ get '/:foo' do
245
+ pass
246
+ 'Hello Foo'
247
+ end
248
+
249
+ get '/*' do
250
+ assert !params.include?('foo')
251
+ 'Hello World'
252
+ end
253
+ }
254
+
255
+ get '/bar'
256
+ assert ok?
257
+ assert_equal 'Hello World', body
258
+ end
259
+
260
+ it "transitions to 404 when passed and no subsequent route matches" do
261
+ mock_app {
262
+ get '/:foo' do
263
+ pass
264
+ 'Hello Foo'
265
+ end
266
+ }
267
+
268
+ get '/bar'
269
+ assert not_found?
270
+ end
271
+
272
+ it "passes when matching condition returns false" do
273
+ mock_app {
274
+ condition { params[:foo] == 'bar' }
275
+ get '/:foo' do
276
+ 'Hello World'
277
+ end
278
+ }
279
+
280
+ get '/bar'
281
+ assert ok?
282
+ assert_equal 'Hello World', body
283
+
284
+ get '/foo'
285
+ assert not_found?
286
+ end
287
+
288
+ it "does not pass when matching condition returns nil" do
289
+ mock_app {
290
+ condition { nil }
291
+ get '/:foo' do
292
+ 'Hello World'
293
+ end
294
+ }
295
+
296
+ get '/bar'
297
+ assert ok?
298
+ assert_equal 'Hello World', body
299
+ end
300
+
301
+ it "passes to next route when condition calls pass explicitly" do
302
+ mock_app {
303
+ condition { pass unless params[:foo] == 'bar' }
304
+ get '/:foo' do
305
+ 'Hello World'
306
+ end
307
+ }
308
+
309
+ get '/bar'
310
+ assert ok?
311
+ assert_equal 'Hello World', body
312
+
313
+ get '/foo'
314
+ assert not_found?
315
+ end
316
+
317
+ it "passes to the next route when host_name does not match" do
318
+ mock_app {
319
+ host_name 'example.com'
320
+ get '/foo' do
321
+ 'Hello World'
322
+ end
323
+ }
324
+ get '/foo'
325
+ assert not_found?
326
+
327
+ get '/foo', :env => { 'HTTP_HOST' => 'example.com' }
328
+ assert_equal 200, status
329
+ assert_equal 'Hello World', body
330
+ end
331
+
332
+ it "passes to the next route when user_agent does not match" do
333
+ mock_app {
334
+ user_agent(/Foo/)
335
+ get '/foo' do
336
+ 'Hello World'
337
+ end
338
+ }
339
+ get '/foo'
340
+ assert not_found?
341
+
342
+ get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
343
+ assert_equal 200, status
344
+ assert_equal 'Hello World', body
345
+ end
346
+
347
+ it "makes captures in user agent pattern available in params[:agent]" do
348
+ mock_app {
349
+ user_agent(/Foo (.*)/)
350
+ get '/foo' do
351
+ 'Hello ' + params[:agent].first
352
+ end
353
+ }
354
+ get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
355
+ assert_equal 200, status
356
+ assert_equal 'Hello Bar', body
357
+ end
358
+
359
+ it "filters by accept header" do
360
+ mock_app {
361
+ get '/', :provides => :xml do
362
+ request.env['HTTP_ACCEPT']
363
+ end
364
+ }
365
+
366
+ get '/', :env => { :accept => 'application/xml' }
367
+ assert ok?
368
+ assert_equal 'application/xml', body
369
+ assert_equal 'application/xml', response.headers['Content-Type']
370
+
371
+ get '/', :env => { :accept => 'text/html' }
372
+ assert !ok?
373
+ end
374
+
375
+ it "allows multiple mime types for accept header" do
376
+ types = ['image/jpeg', 'image/pjpeg']
377
+
378
+ mock_app {
379
+ get '/', :provides => types do
380
+ request.env['HTTP_ACCEPT']
381
+ end
382
+ }
383
+
384
+ types.each do |type|
385
+ get '/', :env => { :accept => type }
386
+ assert ok?
387
+ assert_equal type, body
388
+ assert_equal type, response.headers['Content-Type']
389
+ end
390
+ end
391
+ end
@@ -1,57 +1,36 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- context "Sass" do
4
-
5
- setup do
6
- Sinatra.application = nil
3
+ describe "Sass Templates" do
4
+ def sass_app(&block)
5
+ mock_app {
6
+ set :views, File.dirname(__FILE__) + '/views'
7
+ get '/', &block
8
+ }
9
+ get '/'
7
10
  end
8
11
 
9
- context "Templates (in general)" do
10
-
11
- setup do
12
- Sinatra.application = nil
13
- end
14
-
15
- specify "are read from files if Symbols" do
16
-
17
- get '/from_file' do
18
- sass :foo, :views_directory => File.dirname(__FILE__) + "/views"
19
- end
20
-
21
- get_it '/from_file'
22
- should.be.ok
23
- body.should.equal "#sass {\n background_color: #FFF; }\n"
24
-
25
- end
26
-
27
- specify "raise an error if template not found" do
28
- get '/' do
29
- sass :not_found
30
- end
31
-
32
- lambda { get_it '/' }.should.raise(Errno::ENOENT)
33
- end
34
-
35
- specify "ignore default layout file with .sass extension" do
36
- get '/' do
37
- sass :foo, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
38
- end
39
-
40
- get_it '/'
41
- should.be.ok
42
- body.should.equal "#sass {\n background_color: #FFF; }\n"
43
- end
44
-
45
- specify "ignore explicitly specified layout file" do
46
- get '/' do
47
- sass :foo, :layout => :layout, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
48
- end
12
+ it 'renders inline Sass strings' do
13
+ sass_app { sass "#sass\n :background-color #FFF\n" }
14
+ assert ok?
15
+ assert_equal "#sass {\n background-color: #FFF; }\n", body
16
+ end
49
17
 
50
- get_it '/'
51
- should.be.ok
52
- body.should.equal "#sass {\n background_color: #FFF; }\n"
53
- end
18
+ it 'renders .sass files in views path' do
19
+ sass_app { sass :hello }
20
+ assert ok?
21
+ assert_equal "#sass {\n background-color: #FFF; }\n", body
22
+ end
54
23
 
24
+ it 'ignores the layout option' do
25
+ sass_app { sass :hello, :layout => :layout2 }
26
+ assert ok?
27
+ assert_equal "#sass {\n background-color: #FFF; }\n", body
55
28
  end
56
29
 
30
+ it "raises error if template not found" do
31
+ mock_app {
32
+ get('/') { sass :no_such_template }
33
+ }
34
+ assert_raise(Errno::ENOENT) { get('/') }
35
+ end
57
36
  end